From f63a74781421e422d1a4fada912b8f0fb222a70c Mon Sep 17 00:00:00 2001 From: Liang Chang Date: Mon, 8 Aug 2022 00:38:43 +0000 Subject: [PATCH] dtdocbook: set locale explicitly. --- cde/programs/dtdocbook/dtdocbook2infolib.c | 162 ++++++++++++++------- cde/programs/dtdocbook/dtdocbook2man.in | 13 +- cde/programs/dtdocbook/dtdocbook2sdl.in | 158 ++++++++++---------- cde/programs/dtdocbook/instant/main.c | 36 ++++- 4 files changed, 219 insertions(+), 150 deletions(-) diff --git a/cde/programs/dtdocbook/dtdocbook2infolib.c b/cde/programs/dtdocbook/dtdocbook2infolib.c index ddebc4908..adaea7583 100644 --- a/cde/programs/dtdocbook/dtdocbook2infolib.c +++ b/cde/programs/dtdocbook/dtdocbook2infolib.c @@ -38,6 +38,7 @@ #include #include #include +#include #include /* for dirname() */ #include #include @@ -169,13 +170,17 @@ t_entry langtbl[] = static char *usageMsg1 = "USAGE:\n\ " EXEC_NAME " -h\n\ - " EXEC_NAME " admin\n\ - " EXEC_NAME " build [-h] [-T ] [-m ] [-d ]\n\ - [-n ] -l ...\n\ - " EXEC_NAME " tocgen [-h] [-T ] [-m ] -f [-id ]\n\ - [-title ] ...\n\ - " EXEC_NAME " update [-h] [-m ] -l -b \n\ - " EXEC_NAME " validate [-h] [-T ] [-m ] ...\n" + " EXEC_NAME " admin -L \n\ + " EXEC_NAME " build [-h] -L [-T ] [-m ]\n\ + [-d ] [-n ]\n\ + -l ...\n\ + " EXEC_NAME " tocgen [-h] -L [-T ] [-m ]\n\ + -f [-id ] [-title ]\n\ + ...\n\ + " EXEC_NAME " update [-h] -L [-m ] -l \n\ + -b \n\ + " EXEC_NAME " validate [-h] -L [-T ] [-m ]\n\ + ...\n" "\n" "options:\n"; @@ -215,6 +220,7 @@ static char *buildStyleProlog(void); static char *buildSpec(void); static void defaultGlobals(void); static void checkGlobals(void); +static void setLangIndex(const char * const locale); static int parseArgs(int argc, char *argv[]); static char *parseDocument(int runCmd, ...); static void buildBookcase(char *cmdSrc, char *dirName); @@ -986,45 +992,6 @@ defaultGlobals(void) gStruct->sgmlCatFilesLen = 0; gStruct->sgmlCatFilesMaxLen = 0; - { /* resolve lang from env variable */ - char* lang; - char *s = NULL; - char* code = NULL; - int curLen; - int maxLen = 0; - t_entry* iter; - - if ((lang = getenv("LC_CTYPE")) == NULL) lang = LANG_COMMON; - - lang = XtsNewString(lang); - - s = strchr(lang, '.'); if (s) *s = 0; - - curLen = strlen(lang); - - appendStr(&lang, &curLen, &maxLen, ".UTF-8"); - - /* resolve dtsearch language based on canonical lang */ - - for (iter = langtbl; iter->name; ++iter) { - if (strcmp(lang, iter->name) == 0) { - code = lang; - break; - } - } - - if (!code) code = LANG_COMMON; - - for (iter = langtbl; iter->name; ++iter) { - if (strcmp(iter->name, code) == 0) { - gStruct->dtsridx = iter - langtbl; - break; - } - } - - free(lang); - } - if ((gStruct->sgml = buildSGML()) == NULL) { die(-1, "%s: Cannot find SGML files\n", EXEC_NAME); } @@ -1095,6 +1062,45 @@ checkGlobals(void) checkExec("validator"); } +static void +setLangIndex(const char * const locale) +{ + char* lang; + char *s = NULL; + char* code = NULL; + int curLen; + int maxLen = 0; + t_entry* iter; + + lang = XtsNewString(locale); + + s = strchr(lang, '.'); if (s) *s = 0; + + curLen = strlen(lang); + + appendStr(&lang, &curLen, &maxLen, ".UTF-8"); + + /* resolve dtsearch language based on canonical lang */ + + for (iter = langtbl; iter->name; ++iter) { + if (strcmp(lang, iter->name) == 0) { + code = lang; + break; + } + } + + if (!code) code = LANG_COMMON; + + for (iter = langtbl; iter->name; ++iter) { + if (strcmp(iter->name, code) == 0) { + gStruct->dtsridx = iter - langtbl; + break; + } + } + + free(lang); +} + static void addCatFile(char *catalog, bool needed) { @@ -2278,19 +2284,53 @@ int main(int argc, char *argv[]) { GlobalsStruct globalsStruct; - - if (!addToEnv("PATH", STR(INFOLIB_LIBEXECDIR), true)) - die(-1, "%s: could not set PATH\n", EXEC_NAME); - - gStruct = &globalsStruct; + char *pm; + const char *lc_all; + int ec; + int il = 0; if (argc < 2) - printUsage((char *)NULL, -1); + { + pm = NULL; + ec = -1; + goto usage; + } - defaultGlobals(); + gStruct = &globalsStruct; defaultGlobals(); - if (setenv("LC_CTYPE", STR(langtbl[gStruct->dtsridx].name), 1) == -1) - die(-1, "%s: LC_CTYPE: %s\n", EXEC_NAME, strerror(errno)); + for (int i = 0; i < argc; ++i) + { + if (strcmp(argv[i], "-h") == 0) + { + pm = NULL; + ec = 0; + goto usage; + } + else if (strcmp(argv[i], "-L") == 0) + { + il = 1 + i; + } + } + + if (!(il > 2 && il < argc && isalpha(argv[il][0]))) + { + pm = NULL; + ec = -1; + goto usage; + } + + setLangIndex(argv[il]); + + for (int i = 1 + il; i < argc; ++i) argv[i - 2] = argv[i]; + + argc -= 2; + + lc_all = STR(langtbl[gStruct->dtsridx].name); + + setlocale(LC_ALL, lc_all); + + if (setenv("LC_ALL", lc_all, 1) == -1) + die(-1, "%s: LC_ALL: %s\n", EXEC_NAME, strerror(errno)); if (setenv("SP_CHARSET_FIXED", "1", 1) == -1) die(-1, "%s: SP_CHARSET_FIXED: %s\n", EXEC_NAME, strerror(errno)); @@ -2298,13 +2338,23 @@ main(int argc, char *argv[]) if (setenv("SP_ENCODING", "UTF-8", 1) == -1) die(-1, "%s: SP_ENCODING: %s\n", EXEC_NAME, strerror(errno)); + if (!addToEnv("PATH", STR(INFOLIB_LIBEXECDIR), true)) + die(-1, "%s: could not set PATH\n", EXEC_NAME); + if (!doAdmin(argc, argv) && !doBuild(argc, argv) && !doTocgen(argc, argv) && !doUpdate(argc, argv) && !doValidate(argc, argv) && !doHelp(argc, argv)) - printUsage(EXEC_NAME ": unrecognized subcommand `%s'\n", -1); + { + pm = EXEC_NAME ": unrecognized subcommand\n"; + ec = -1; + goto usage; + } return 0; + +usage: + printUsage(pm, ec); } diff --git a/cde/programs/dtdocbook/dtdocbook2man.in b/cde/programs/dtdocbook/dtdocbook2man.in index a57f2ddc7..5ee47cee5 100755 --- a/cde/programs/dtdocbook/dtdocbook2man.in +++ b/cde/programs/dtdocbook/dtdocbook2man.in @@ -63,11 +63,12 @@ then nroff="| tbl | nroff -man" shift fi -if [ $# -eq 3 ] -then dclfile=$1 - reffile=$2 - manfile=$3 -else echo "usage: dtdocbook2man [-c] dcl-file ref-src-file man-dst-file" +if [ $# -eq 4 ] +then locale=$1 + dclfile=$2 + reffile=$3 + manfile=$4 +else echo "usage: dtdocbook2man [-c] locale dcl-file ref-src-file man-dst-file" exit 1 fi @@ -129,6 +130,6 @@ cat >> /tmp/dtm.$$.psinc <<\! cat $decl $dclfile $reffile | \ sed -e 's/<\!\[[ ]*\%CDE\.C\.CDE;[ ]*\[<[rR]ef[eE]ntry [iI]d="[^"]*">\]\]>//g' | \ $parser $parser_opts | \ -$instant $INSTANT_OPT -croff.cmap -sroff.sdata -tdocbook-to-man.ts > \ +$instant -L$locale -croff.cmap -sroff.sdata -tdocbook-to-man.ts > \ /tmp/dtm.$$.out1 && eval cat /tmp/dtm.$$.psinc /tmp/dtm.$$.out1 $nroff > \ /tmp/dtm.$$.out2 && cp /tmp/dtm.$$.out2 $manfile diff --git a/cde/programs/dtdocbook/dtdocbook2sdl.in b/cde/programs/dtdocbook/dtdocbook2sdl.in index e56d18131..c8c661957 100755 --- a/cde/programs/dtdocbook/dtdocbook2sdl.in +++ b/cde/programs/dtdocbook/dtdocbook2sdl.in @@ -1,7 +1,5 @@ #!@KSH@ -export LC_CTYPE="${LANG}" - # get the name of this command for errors, warnings and messages command_name=`basename $0` @@ -77,95 +75,35 @@ do (u) uncompressed=1;; (v) verbose=1;; (x) debug=1;; + (L) x_locale="$OPTARG";; # undocumented options to be used at build time (H) helptag2="$OPTARG";; (I) instant="$OPTARG";; - (L) x_locale="$OPTARG";; (S) sgmls="$OPTARG";; (?) fatal "Unknown option: -$OPTARG";; esac done -default_charset='UTF-8' -default_locale="en_US.$default_charset" - -# if no -t, use installed dir -prefix="${prefix:-@prefix@}" -exec_prefix="@exec_prefix@" - -export PATH="${PATH}:@bindir@" - -dcbk_name="@PACKAGE_TARNAME@/dtdocbook" - -dtdcbk_libdir="${dtdcbk_libdir:-@libdir@/${dcbk_name}}" -dtdcbk_libexecdir="${dtdcbk_libexecdir:-@libexecdir@/${dcbk_name}}" -dtdcbk_datarootdir="${dtdcbk_datarootdir:-@datarootdir@/${dcbk_name}}" - -# if no -I, use installed one -instant="${instant:-${dtdcbk_libexecdir}/instant/instant}" - -# if no -s, use -t -sgml_dir="${sgml_dir:-${dtdcbk_datarootdir}/sgml}" - -sgml_cat="${sgml_dir}" -sgmls="${sgmls:-onsgmls}" # if no -S, use onsgmls -x_locale="${x_locale:-${LANG}}" # if no -L, use installed one -helptag2="${helptag2:-dthelp_htag2}" # if no -H, use one in PATH - -if [[ $x_locale == *.* ]] then - x_lang="${x_locale%%.*}" - x_charset="${x_locale##*.}" - - if [[ $x_charset != $default_charset ]] then - x_locale="${x_lang}.$default_charset" - fi -else - x_locale="${x_locale}.$default_charset" -fi - -# Set the environment variables for instant(1) to find its files -export TPT_LIB="${dtdcbk_datarootdir}/tpt" -export LOCALE_DIR="${dtdcbk_datarootdir}/locales/${x_locale}" - -if [[ -d $LOCALE_DIR ]] then - export LOCALE_DIR="${dtdcbk_datarootdir}/locales/${default_locale}" -fi - -parser=`basename $sgmls` - -# Set the environment variable for finding the default catalog. -if ([[ "$SGML_CATALOG_FILES" = "" ]]) then - export SGML_CATALOG_FILES="${sgml_cat}/catalog" -else - export SGML_CATALOG_FILES="${SGML_CATALOG_FILES}:${sgml_cat}/catalog" -fi - -export SP_CHARSET_FIXED=1 -export SP_ENCODING="$default_charset" - -# Set the environment variable to be picked up inside instant(1) when it -# goes to call Tcl. -export DBKTCL_DIR="${dtdcbk_libdir}/tcl" - # The user asked for help, give it and exit. if (( $help )); then echo "$command_name [options] " echo "options:" - echo " -c compress an existing SDL file" - echo " -d decompress an existing SDL file" - echo " -g specify additional catalog file (repeatable)" - echo " -h emit this message" - echo " -l leave ..log in current directory" - echo " -m add to list of SDATA or CMAP files" - echo " -o use as the output file name" - echo " -r remove leftover intermediate files" - echo " -s docbook.dcl is in " - echo " -t read translation specs, etc., from " - echo " -u do not compress during translation" - echo " -v verbose" - echo " -x leave intermediate files, for debugging" + echo " -c compress an existing SDL file" + echo " -d decompress an existing SDL file" + echo " -g specify additional catalog file (repeatable)" + echo " -h emit this message" + echo " -l leave ..log in current directory" + echo " -m add to list of SDATA or CMAP files" + echo " -o use as the output file name" + echo " -r remove leftover intermediate files" + echo " -s docbook.dcl is in " + echo " -t read translation specs, etc., from " + echo " -u do not compress during translation" + echo " -v verbose" + echo " -x leave intermediate files, for debugging" + echo " -L set the current locale to " exit 0 fi @@ -178,8 +116,9 @@ elif (( $OPTIND > $# )); then fi -# Get the name of the input file. -iname=`eval echo \\\${\$OPTIND}` +if [[ $x_locale == "" ]] then + fatal "No locale specified" +fi # Check for mutually exclusive options. if (( $compress && $decompress )); then @@ -187,10 +126,66 @@ if (( $compress && $decompress )); then fi +default_charset='UTF-8' + +prefix="${prefix:-@prefix@}" +exec_prefix="@exec_prefix@" + +dcbk_name="@PACKAGE_TARNAME@/dtdocbook" +dtdcbk_libdir="${dtdcbk_libdir:-@libdir@/${dcbk_name}}" +dtdcbk_libexecdir="${dtdcbk_libexecdir:-@libexecdir@/${dcbk_name}}" +dtdcbk_datarootdir="${dtdcbk_datarootdir:-@datarootdir@/${dcbk_name}}" + +sgml_dir="${sgml_dir:-${dtdcbk_datarootdir}/sgml}" + + +if [[ $x_locale == *.* ]] then + x_lang="${x_locale%%.*}" + x_charset="${x_locale##*.}" + + if [[ $x_charset != $default_charset ]] then + x_locale="${x_lang}.$default_charset" + fi +else + x_locale="${x_locale}.$default_charset" +fi + +if ([[ "$SGML_CATALOG_FILES" = "" ]]) then + SGML_CATALOG_FILES="${sgml_dir}/catalog" +else + SGML_CATALOG_FILES="${SGML_CATALOG_FILES}:${sgml_dir}/catalog" +fi + + +export PATH="${PATH}:@bindir@" +export SP_CHARSET_FIXED=1 +export SP_ENCODING="$default_charset" +export DBKTCL_DIR="${dtdcbk_libdir}/tcl" +export TPT_LIB="${dtdcbk_datarootdir}/tpt" +export LOCALE_DIR="${dtdcbk_datarootdir}/locales/${x_locale}" +export SGML_CATALOG_FILES + + +if [[ ! -d $LOCALE_DIR || ! -x $LOCALE_DIR ]] then + fatal "$LOCALE_DIR can't be accessed" +fi + + +# if no -I, use installed one +instant="${instant:-${dtdcbk_libexecdir}/instant/instant}" +sgmls="${sgmls:-onsgmls}" # if no -S, use onsgmls +helptag2="${helptag2:-dthelp_htag2}" # if no -H, use one in PATH + + +# Get the name of the input file. +iname=`eval echo \\\${\$OPTIND}` + # Get the basename and directory of the input file. basename=`basename $iname` dirname=`dirname $iname` +parser=`basename $sgmls` + # Look for an extension on the input file, if it's .sgm (or .sdl for # -c and -d), use it as is, else add the proper extension. @@ -372,12 +367,14 @@ if (( $verbose )); then if [[ $mapfiles != "" ]] then echo " $mapfiles \\\\" fi + echo " -L $x_locale \\\\" echo " -c docbook.cmap \\\\" echo " -t docbook.ts \\\\" echo " $basename.$$.esis" ${instant} -o $basename.out.$$.sdl \ $mapfiles \ - -c docbook.cmap \ + -L $x_locale \ + -c docbook.cmap \ -t docbook.ts \ $basename.$$.esis status=$? @@ -397,6 +394,7 @@ if (( $verbose )); then else ${instant} -o $basename.out.$$.sdl \ $mapfiles \ + -L $x_locale \ -c docbook.cmap \ -t docbook.ts \ $basename.$$.esis 2> $basename.$$.log diff --git a/cde/programs/dtdocbook/instant/main.c b/cde/programs/dtdocbook/instant/main.c index 20e089f69..cdec6defc 100644 --- a/cde/programs/dtdocbook/instant/main.c +++ b/cde/programs/dtdocbook/instant/main.c @@ -103,6 +103,7 @@ static char *tranfile; static char **cmapfile, **sdatafile; static char *start_id; static char *last_file; +static char *locale; static int last_lineno; /* forward references */ @@ -132,16 +133,33 @@ main( char *av[] ) { - char **thisopt; + char **thisopt; + char *s, *lc_all; + Initialize1(av[0]); HandleArgs(ac, av); Initialize2(); - /* use the current locale for all text but use American English ... */ - setlocale(LC_ALL, ""); + if (!(locale && *locale)) { + fprintf(stderr, "Error: No locale specified.\n"); + return 1; + } - /* ... in expressions (e.g., leave "." as the radix operator) */ - setlocale(LC_NUMERIC, "C.UTF-8"); + lc_all = strdup(locale); + lc_all = realloc(lc_all, 7 + strlen(locale)); + + s = strchr(lc_all, '.'); if (s) *s = 0; + + strcat(lc_all, ".UTF-8"); + + setlocale(LC_ALL, lc_all); + + if (setenv("LC_ALL", lc_all, 1) == -1) { + fprintf(stderr, "Error: Can not set locale.\n"); + return 1; + } + + free(lc_all); /* Create a Tcl interpreter. */ interpreter = Tcl_CreateInterp(); @@ -439,13 +457,13 @@ HandleArgs( char **thisopt; int count; - while ((c=getopt(ac, av, "t:vc:s:o:huSxIl:bHVWi:D:Z")) != EOF) { + while ((c=getopt(ac, av, "t:vc:s:o:L:huSxIl:bHVWi:D:Z")) != EOF) { switch (c) { case 't': tranfile = optarg; break; case 'v': do_validate = 1; break; case 's': { - if (thisopt = sdatafile) + if ((thisopt = sdatafile)) { count = 0; while (*thisopt++) @@ -465,7 +483,7 @@ HandleArgs( } case 'c': { - if (thisopt = cmapfile) + if ((thisopt = cmapfile)) { count = 0; while (*thisopt++) @@ -491,6 +509,7 @@ HandleArgs( case 'l': tpt_lib = optarg; break; case 'i': start_id = optarg; break; case 'o': out_file = optarg; break; + case 'L': locale = optarg; break; case 'b': interactive = 1; break; case 'W': warnings = 0; break; case 'V': verbose = 1; break; @@ -534,6 +553,7 @@ static char *help_msg[] = { " -h Print document hierarchy as a tree", " -o file Write output to . Default is standard output.", " -l dir Set library directory to . (or env. variable TPT_LIB)", + " -L locale Set the current locale to ", " -I List all IDs used in the instance", " -W Do not print warning messages", " -H Print this help message",