Add normalize_codeset function. We don't want to use the
[kopensolaris-gnu/glibc.git] / locale / programs / localedef.c
index 656377f..34c7394 100644 (file)
@@ -36,7 +36,6 @@
 #include "error.h"
 #include "charset.h"
 #include "locfile.h"
-#include "../intl/loadinfo.h"
 
 /* Undefine the following line in the production version.  */
 /* #define NDEBUG 1 */
@@ -109,7 +108,7 @@ static const struct argp_option options[] =
   { "posix", OPT_POSIX, NULL, 0, N_("Be strictly POSIX conform") },
   { "quiet", OPT_QUIET, NULL, 0,
     N_("Suppress warnings and information messages") },
-  { "verbose", 'V', NULL, 0, N_("print more messages") },
+  { "verbose", 'V', NULL, 0, N_("Print more messages") },
   { NULL, 0, NULL, 0, NULL }
 };
 
@@ -138,6 +137,7 @@ void *xmalloc (size_t __n);
 /* Prototypes for local functions.  */
 static void error_print (void);
 static const char *construct_output_path (char *path);
+static const char *normalize_codeset (const char *codeset, size_t name_len);
 
 
 int
@@ -148,6 +148,7 @@ main (int argc, char *argv[])
   struct charset_t *charset;
   struct localedef_t *localedef;
   struct copy_def_list_t *act_add_locdef;
+  int remaining;
 
   /* Set initial values for global variables.  */
   copy_list = NULL;
@@ -163,29 +164,24 @@ main (int argc, char *argv[])
   textdomain (_libc_intl_domainname);
 
   /* Parse and process arguments.  */
-  argp_parse (&argp, argc, argv, 0, 0, NULL);
-
-  /* XXX POSIX is violated since for unknown option a exit value > 3
-     must be used.  */
+  argp_err_exit_status = 4;
+  argp_parse (&argp, argc, argv, 0, &remaining, NULL);
 
   /* POSIX.2 requires to be verbose about missing characters in the
      character map.  */
   verbose |= posix_conformance;
 
-  if (argc - optind != 1)
+  if (argc - remaining != 1)
     {
       /* We need exactly one non-option parameter.  */
-      argp_help (&argp, stdout, ARGP_HELP_SEE,
+      argp_help (&argp, stdout, ARGP_HELP_SEE | ARGP_HELP_EXIT_ERR,
                 program_invocation_short_name);
-
-      /* XXX Currently POSIX is violated.  We must exit with code 4
-        but the argp_help function currently does not allow this.  */
       exit (4);
     }
 
   /* The parameter describes the output path of the constructed files.
      If the described files cannot be written return a NULL pointer.  */
-  output_path  = construct_output_path (argv[optind]);
+  output_path  = construct_output_path (argv[remaining]);
   cannot_write_why = errno;
 
   /* Now that the parameters are processed we have to reset the local
@@ -244,21 +240,23 @@ main (int argc, char *argv[])
 
          if (! avail)
            {
-             const char *locale_names[] = { "LC_COLLATE", "LC_CTYPE",
-                                            "LC_MONETARY", "LC_NUMERIC",
-                                            "LC_TIME", "LC_MESSAGES" };
+             static const char *locale_names[] =
+             {
+               "LC_COLLATE", "LC_CTYPE", "LC_MONETARY",
+               "LC_NUMERIC", "LC_TIME", "LC_MESSAGES"
+             };
              char *fname;
              int fd;
              struct stat st;
 
-             asprintf (&fname, LOCALE_PATH "/%s/%s", act_add_locdef->name,
+             asprintf (&fname, LOCALEDIR "/%s/%s", act_add_locdef->name,
                        locale_names[cat]);
              fd = open (fname, O_RDONLY);
              if (fd == -1)
                {
                  free (fname);
 
-                 asprintf (&fname, LOCALE_PATH "/%s/%s/SYS_%s",
+                 asprintf (&fname, LOCALEDIR "/%s/%s/SYS_%s",
                            act_add_locdef->name, locale_names[cat],
                            locale_names[cat]);
 
@@ -477,7 +475,7 @@ construct_output_path (char *path)
            ++endp;
 
          if (endp > startp)
-           normal = _nl_normalize_codeset (startp, endp - startp);
+           normal = normalize_codeset (startp, endp - startp);
        }
       else
        /* This is to keep gcc quiet.  */
@@ -514,3 +512,47 @@ construct_output_path (char *path)
 
   return result;
 }
+
+/* Normalize codeset name.  There is no standard for the codeset
+   names.  Normalization allows the user to use any of the common
+   names.  */
+static const char *
+normalize_codeset (codeset, name_len)
+     const char *codeset;
+     size_t name_len;
+{
+  int len = 0;
+  int only_digit = 1;
+  char *retval;
+  char *wp;
+  size_t cnt;
+
+  for (cnt = 0; cnt < name_len; ++cnt)
+    if (isalnum (codeset[cnt]))
+      {
+       ++len;
+
+       if (isalpha (codeset[cnt]))
+         only_digit = 0;
+      }
+
+  retval = (char *) malloc ((only_digit ? 3 : 0) + len + 1);
+
+  if (retval != NULL)
+    {
+      if (only_digit)
+       wp = stpcpy (retval, "iso");
+      else
+       wp = retval;
+
+      for (cnt = 0; cnt < name_len; ++cnt)
+       if (isalpha (codeset[cnt]))
+         *wp++ = tolower (codeset[cnt]);
+       else if (isdigit (codeset[cnt]))
+         *wp++ = codeset[cnt];
+
+      *wp = '\0';
+    }
+
+  return (const char *) retval;
+}