Browse Source

dtdocbook: set locale explicitly.

Liang Chang 1 year ago
parent
commit
f63a747814

+ 105 - 55
cde/programs/dtdocbook/dtdocbook2infolib.c

@@ -38,6 +38,7 @@
 #include <string.h>
 #include <errno.h>
 #include <unistd.h>
+#include <locale.h>
 #include <libgen.h> /* for dirname() */
 #include <ctype.h>
 #include <signal.h>
@@ -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 <tmpdir>] [-m <catalog>] [-d <library description>]\n\
-           [-n <library short name>] -l <library> <bookcase-doc>...\n\
-  " EXEC_NAME " tocgen [-h] [-T <tmpdir>] [-m <catalog>] -f <tocfile> [-id <tocid>]\n\
-            [-title <toctitle>] <document>...\n\
-  " EXEC_NAME " update [-h] [-m <catalog>] -l <library> -b <bookcase> <stylesheet>\n\
-  " EXEC_NAME " validate [-h] [-T <tmpdir>] [-m <catalog>] <document>...\n"
+  " EXEC_NAME " admin -L <locale>\n\
+  " EXEC_NAME " build [-h] -L <locale> [-T <tmpdir>] [-m <catalog>]\n\
+                          [-d <library description>] [-n <library short name>]\n\
+		          -l <library> <bookcase-doc>...\n\
+  " EXEC_NAME " tocgen [-h] -L <locale> [-T <tmpdir>] [-m <catalog>]\n\
+                           -f <tocfile> [-id <tocid>] [-title <toctitle>]\n\
+		           <document>...\n\
+  " EXEC_NAME " update [-h] -L <locale> [-m <catalog>] -l <library>\n\
+                           -b <bookcase> <stylesheet>\n\
+  " EXEC_NAME " validate [-h] -L <locale> [-T <tmpdir>] [-m <catalog>]\n\
+                             <document>...\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;
+    char *pm;
+    const char *lc_all;
+    int ec;
+    int il = 0;
 
-    if (!addToEnv("PATH", STR(INFOLIB_LIBEXECDIR), true))
-	die(-1, "%s: could not set PATH\n", EXEC_NAME);
+    if (argc < 2)
+    {
+	pm = NULL;
+	ec = -1;
+	goto usage;
+    }
 
-    gStruct = &globalsStruct;
+    gStruct = &globalsStruct; defaultGlobals();
 
-    if (argc < 2)
-	printUsage((char *)NULL, -1);
+    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;
 
-    defaultGlobals();
+    lc_all = STR(langtbl[gStruct->dtsridx].name);
 
-    if (setenv("LC_CTYPE", STR(langtbl[gStruct->dtsridx].name), 1) == -1)
-	die(-1, "%s: LC_CTYPE: %s\n", EXEC_NAME, strerror(errno));
+    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);
 }

+ 7 - 6
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="[^"]*">\]\]>/<refentry>/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

+ 61 - 63
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,41 +75,69 @@ 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
 
+
+# The user asked for help, give it and exit.
+if (( $help )); then
+    echo "$command_name [options] <file>"
+    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 <basename>.<pid>.log in current directory"
+    echo "    -m <maps>    add <maps> to list of SDATA or CMAP files"
+    echo "    -o <file>    use <file> as the output file name"
+    echo "    -r           remove leftover intermediate files"
+    echo "    -s <dir>     docbook.dcl is in <dir>"
+    echo "    -t <dir>     read translation specs, etc., from <dir>"
+    echo "    -u           do not compress during translation"
+    echo "    -v           verbose"
+    echo "    -x           leave intermediate files, for debugging"
+    echo "    -L <locale>  set the current locale to <locale>"
+    exit 0
+fi
+
+
+# Check for too many input files or none.
+if (( $OPTIND < $# )); then
+    fatal "Too many names after the options, should only be input file name"
+elif (( $OPTIND > $# )); then
+    fatal "No input file name specified"
+fi
+
+
+if [[ $x_locale == "" ]] then
+    fatal "No locale specified"
+fi
+
+# Check for mutually exclusive options.
+if (( $compress && $decompress )); then
+    fatal "$c_and_d are mutually exclusive."
+fi
+
+
 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%%.*}"
@@ -124,73 +150,42 @@ 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"
+    SGML_CATALOG_FILES="${sgml_dir}/catalog"
 else
-    export SGML_CATALOG_FILES="${SGML_CATALOG_FILES}:${sgml_cat}/catalog"
+    SGML_CATALOG_FILES="${SGML_CATALOG_FILES}:${sgml_dir}/catalog"
 fi
 
+
+export PATH="${PATH}:@bindir@"
 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"
+export TPT_LIB="${dtdcbk_datarootdir}/tpt"
+export LOCALE_DIR="${dtdcbk_datarootdir}/locales/${x_locale}"
+export SGML_CATALOG_FILES
 
 
-# The user asked for help, give it and exit.
-if (( $help )); then
-    echo "$command_name [options] <file>"
-    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 <basename>.<pid>.log in current directory"
-    echo "    -m <maps>  add <maps> to list of SDATA or CMAP files"
-    echo "    -o <file>  use <file> as the output file name"
-    echo "    -r         remove leftover intermediate files"
-    echo "    -s <dir>   docbook.dcl is in <dir>"
-    echo "    -t <dir>   read translation specs, etc., from <dir>"
-    echo "    -u         do not compress during translation"
-    echo "    -v         verbose"
-    echo "    -x         leave intermediate files, for debugging"
-    exit 0
+if [[ ! -d $LOCALE_DIR || ! -x $LOCALE_DIR ]] then
+    fatal "$LOCALE_DIR can't be accessed"
 fi
 
 
-# Check for too many input files or none.
-if (( $OPTIND < $# )); then
-    fatal "Too many names after the options, should only be input file name"
-elif (( $OPTIND > $# )); then
-    fatal "No input file name specified"
-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}`
 
-# Check for mutually exclusive options.
-if (( $compress && $decompress )); then
-    fatal "$c_and_d are mutually exclusive."
-fi
-
-
 # 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

+ 28 - 8
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;
+    }
+
+    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;
+    }
 
-    /* ... in expressions (e.g., leave "." as the radix operator) */
-    setlocale(LC_NUMERIC, "C.UTF-8");
+    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 <file>.  Default is standard output.",
   "  -l dir    Set library directory to <dir>. (or env. variable TPT_LIB)",
+  "  -L locale Set the current locale to <locale>",
   "  -I        List all IDs used in the instance",
   "  -W        Do not print warning messages",
   "  -H        Print this help message",