second update 960907 from main archive
[kopensolaris-gnu/glibc.git] / locale / programs / localedef.c
index a98bac4..8eab9c1 100644 (file)
@@ -1,6 +1,6 @@
 /* Copyright (C) 1995, 1996 Free Software Foundation, Inc.
 This file is part of the GNU C Library.
-Contributed by Ulrich Drepper, <drepper@gnu.ai.mit.edu>.
+Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
 
 The GNU C Library is free software; you can redistribute it and/or
 modify it under the terms of the GNU Library General Public License as
@@ -36,6 +36,7 @@ Boston, MA 02111-1307, USA.  */
 #include "error.h"
 #include "charset.h"
 #include "locfile.h"
+#include "../intl/loadinfo.h"
 
 /* Undefine the following line in the production version.  */
 /* #define NDEBUG 1 */
@@ -66,9 +67,6 @@ struct copy_def_list_t *copy_list;
 /* If this is defined be POSIX conform.  */
 int posix_conformance;
 
-/* Name of the running program.  */
-const char *program_name;
-
 /* If not zero give a lot more messages.  */
 int verbose;
 
@@ -95,7 +93,7 @@ void *xmalloc (size_t __n);
 /* Prototypes for local functions.  */
 static void usage (int status) __attribute__ ((noreturn));
 static void error_print (void);
-static const char *construct_output_path (const char *path);
+static const char *construct_output_path (char *path);
 
 
 int
@@ -117,7 +115,6 @@ main (int argc, char *argv[])
   /* Set initial values for global varaibles.  */
   copy_list = NULL;
   posix_conformance = getenv ("POSIXLY_CORRECT") != NULL;
-  program_name = argv[0];
   error_print_progname = error_print;
   verbose = 0;
 
@@ -127,12 +124,7 @@ main (int argc, char *argv[])
   setlocale (LC_CTYPE, "");
 
   /* Initialize the message catalog.  */
-#if 0
-  /* In the final version for glibc we can use the variable.  */
   textdomain (_libc_intl_domainname);
-#else
-  textdomain ("SYS_libc");
-#endif
 
   while ((optchar = getopt_long (argc, argv, "cf:hi:u:vV", long_options, NULL))
          != EOF)
@@ -181,7 +173,8 @@ main (int argc, char *argv[])
   /* Version information is requested.  */
   if (do_version)
     {
-      fprintf (stderr, "%s - GNU %s %s\n", program_name, PACKAGE, VERSION);
+      fprintf (stderr, "%s - GNU %s %s\n", program_invocation_short_name,
+              PACKAGE, VERSION);
       exit (0);
     }
 
@@ -231,7 +224,7 @@ main (int argc, char *argv[])
       for (act_add_locdef = copy_list; act_add_locdef != NULL;
           act_add_locdef = act_add_locdef->next)
        {
-         for (cat = LC_COLLATE; cat <= LC_MESSAGES; ++cat)
+         for (cat = LC_CTYPE; cat <= LC_MESSAGES; ++cat)
            if ((act_add_locdef->mask & (1 << cat)) != 0)
              {
                act_add_locdef->mask &= ~(1 << cat);
@@ -335,7 +328,7 @@ cannot `stat' locale file `%s'"),
        error (4, cannot_write_why, _("cannot write output files to `%s'"),
               output_path);
       else
-       write_all_categories (localedef, output_path);
+       write_all_categories (localedef, charset, output_path);
     }
   else
     error (4, 0, _("no output file produced because warning were issued"));
@@ -388,7 +381,7 @@ usage (int status)
 {
   if (status != 0)
     fprintf (stderr, _("Try `%s --help' for more information.\n"),
-             program_name);
+            program_invocation_name);
   else
     printf (_("\
 Usage: %s [OPTION]... name\n\
@@ -403,8 +396,9 @@ Mandatory arguments to long options are mandatory for short options too.\n\
       --posix               be strictly POSIX conform\n\
 \n\
 System's directory for character maps: %s\n\
-                       locale files  : %s\n"),
-           program_name, CHARMAP_PATH, LOCALE_PATH);
+                       locale files  : %s\n\
+Report bugs to <bug-glibc@prep.ai.mit.edu>.\n"),
+           program_invocation_name, CHARMAP_PATH, LOCALE_PATH);
 
   exit (status);
 }
@@ -424,25 +418,50 @@ error_print ()
    contain a '/' character it is a relativ path.  Otherwise it names the
    locale this definition is for.  */
 static const char *
-construct_output_path (const char *path)
+construct_output_path (char *path)
 {
+  char *normal = NULL;
   char *result;
 
   if (strchr (path, '/') == NULL)
     {
-      /* This is a system path.  */
-      int path_max_len = pathconf (LOCALE_PATH, _PC_PATH_MAX) + 1;
-      result = (char *) xmalloc (path_max_len);
+      /* This is a system path.  First examine whether the locale name
+        contains a reference to the codeset.  This should be
+        normalized.  */
+      char *startp, *endp;
+
+      startp = path;
+      /* We must be prepared for finding a CEN name or a location of
+        the introducing `.' where it is not possible anymore.  */
+      while (*startp != '\0' && *startp != '@' && *startp != '.'
+            && *startp != '+' && *startp != ',')
+       ++startp;
+      if (*startp == '.')
+       {
+         /* We found a codeset specification.  Now find the end.  */
+         endp = ++startp;
+         while (*endp != '\0' && *endp != '@')
+           ++endp;
 
-      snprintf (result, path_max_len, "%s/%s", LOCALE_PATH, path);
+         if (endp > startp)
+           normal = _nl_normalize_codeset (startp, endp - startp);
+       }
+
+      /* We put an additional '\0' at the end of the string because at
+        the end of the function we need another byte for the trailing
+        '/'.  */
+      if (normal == NULL)
+       asprintf (&result, "%s/%s\0", LOCALE_PATH, path);
+      else
+       asprintf (&result, "%s/%.*s%s%s\0", LOCALE_PATH, startp - path, path,
+                 normal, endp);
     }
   else
     {
-      char *t;
-      /* This is a user path.  */
+      /* This is a user path.  Please note the additional byte in the
+        memory allocation.  */
       result = xmalloc (strlen (path) + 2);
-      t = stpcpy (result, path);
-      *t = '\0';
+      strcpy (result, path);
     }
 
   errno = 0;