about summary refs log tree commit diff
path: root/locale
diff options
context:
space:
mode:
Diffstat (limited to 'locale')
-rw-r--r--locale/findlocale.c12
-rw-r--r--locale/loadlocale.c9
-rw-r--r--locale/programs/ld-time.c2
-rw-r--r--locale/programs/locale-spec.c95
-rw-r--r--locale/programs/locale.c32
-rw-r--r--locale/programs/localedef.c16
-rw-r--r--locale/programs/locfile.c21
-rw-r--r--locale/programs/stringtrans.c58
-rw-r--r--locale/setlocale.c11
9 files changed, 180 insertions, 76 deletions
diff --git a/locale/findlocale.c b/locale/findlocale.c
index 5e87a33886..2bcc11193f 100644
--- a/locale/findlocale.c
+++ b/locale/findlocale.c
@@ -170,21 +170,17 @@ _nl_find_locale (const char *locale_path, size_t locale_path_len,
 
   /* Determine the locale name for which loading succeeded.  This
      information comes from the file name.  The form is
-     <path>/<locale>/LC_foo.  We must extract this <locale> part.  */
+     <path>/<locale>/LC_foo.  We must extract the <locale> part.  */
   if (((struct locale_data *) locale_file->data)->name == NULL)
     {
-      char *newp, *cp, *endp;
+      char *cp, *endp;
 
       endp = strrchr (locale_file->filename, '/');
       cp = endp - 1;
       while (cp[-1] != '/')
 	--cp;
-      newp = (char *) malloc (endp - cp + 1);
-      if (newp == NULL)
-	return NULL;
-      memcpy (newp, cp, endp - cp);
-      newp[endp - cp] = '\0';
-      ((struct locale_data *) locale_file->data)->name = newp;
+      ((struct locale_data *) locale_file->data)->name = __strndup (cp,
+								    endp - cp);
     }
   *name = (char *) ((struct locale_data *) locale_file->data)->name;
 
diff --git a/locale/loadlocale.c b/locale/loadlocale.c
index b7eee2e735..464f8ba33f 100644
--- a/locale/loadlocale.c
+++ b/locale/loadlocale.c
@@ -94,7 +94,7 @@ _nl_load_locale (struct loaded_l10nfile *file, int category)
       /* LOCALE/LC_foo is a directory; open LOCALE/LC_foo/SYS_LC_foo
            instead.  */
       char *newp;
-      
+
       __close (fd);
 
       newp = (char *) alloca (strlen (file->filename)
@@ -189,14 +189,15 @@ _nl_load_locale (struct loaded_l10nfile *file, int category)
     }
 
   newdata = malloc (sizeof *newdata +
-		    W (filedata->nstrings) * sizeof (union locale_data_value));
+		    (_nl_category_num_items[category]
+		     * sizeof (union locale_data_value)));
   if (! newdata)
     goto puntmap;
 
   newdata->name = NULL;	/* This will be filled if necessary in findlocale.c. */
   newdata->filedata = (void *) filedata;
   newdata->filesize = st.st_size;
-  newdata->nstrings = W (filedata->nstrings);
+  newdata->nstrings = _nl_category_num_items[category];
   for (cnt = 0; cnt < newdata->nstrings; ++cnt)
     {
       off_t idx = W (filedata->strindex[cnt]);
@@ -234,5 +235,3 @@ _nl_free_locale (const struct locale_data *data)
     }
   free ((void *) data);
 }
-
-
diff --git a/locale/programs/ld-time.c b/locale/programs/ld-time.c
index e031b24edc..00f288f69b 100644
--- a/locale/programs/ld-time.c
+++ b/locale/programs/ld-time.c
@@ -257,7 +257,7 @@ time_add (struct linereader *lr, struct localedef_t *locale,
 #define STRARR_ELEM(cat, max)						      \
     case tok_##cat:							      \
       if (time->cur_num_##cat >= max)					      \
-	lr_error (lr, _("						      \
+	lr_error (lr, _("\
 too many values for field `%s' in category `LC_TIME'"),			      \
 		  #cat, "LC_TIME");					      \
       else if (code->val.str.start == NULL)				      \
diff --git a/locale/programs/locale-spec.c b/locale/programs/locale-spec.c
new file mode 100644
index 0000000000..e408421656
--- /dev/null
+++ b/locale/programs/locale-spec.c
@@ -0,0 +1,95 @@
+/* Handle special requests.
+Copyright (C) 1996 Free Software Foundation, Inc.
+This file is part of the GNU C Library.
+Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1996.
+
+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
+published by the Free Software Foundation; either version 2 of the
+License, or (at your option) any later version.
+
+The GNU C Library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with the GNU C Library; see the file COPYING.LIB.  If
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <wchar.h>
+
+#include "localeinfo.h"
+
+
+/* We provide support for some special names.  This helps debugging
+   and may be useful for advanced usage of the provided information
+   outside C.  */
+void
+locale_special (const char *name, int show_category_name,
+		int show_keyword_name)
+{
+  /* "collate-elements": print collation elements of locale.  */
+  if (strcmp (name, "collate-elements") == 0)
+    {
+      size_t nelem = _NL_CURRENT_WORD (LC_COLLATE, _NL_COLLATE_ELEM_HASH_SIZE);
+
+      if (show_category_name)
+	puts ("LC_COLLATE");
+      if (show_keyword_name)
+	fputs ("collate-elements=", stdout);
+
+      if (nelem != 0)
+	{
+	  int first = 1;
+	  size_t cnt;
+
+	  for (cnt = 0; cnt < nelem; ++cnt)
+	    if (__collate_element_hash[2 * cnt] != (~((u_int32_t) 0)))
+	      {
+		size_t idx = __collate_element_hash[2 * cnt];
+
+		printf ("%s<%s>", first ? "" : ";",
+			&__collate_element_strings[idx]);
+
+#if 0
+		/* We don't print the string.  This is only confusing
+		   because only the programs have to know the
+		   encoding.  The code is left in place because it
+		   shows how to get the information.  */
+		{
+		  const wchar_t *wp;
+
+		  idx = __collate_element_hash[2 * cnt + 1];
+		  wp = &__collate_element_values[idx];
+		  while (*wp != L'\0')
+		    {
+		      /********************************************\
+		      |* XXX The element values are really wide	  *|
+		      |* chars.  But we are currently not able to *|
+		      |* print these so fake here.		  *|
+		      \********************************************/
+		      int ch = wctob (*wp++);
+		      if (ch != EOF)
+			putchar (ch);
+		      else
+			fputs ("<???>", stdout);
+		    }
+
+		  putchar ('"');
+		}
+#endif
+		first = 0;
+	      }
+	}
+      putchar ('\n');
+      return;
+    }
+}
diff --git a/locale/programs/locale.c b/locale/programs/locale.c
index 5196fa51fe..a9e415d6b7 100644
--- a/locale/programs/locale.c
+++ b/locale/programs/locale.c
@@ -1,4 +1,7 @@
-/* Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+/* locale - Implementation of the locale program according to POSIX 1003.2
+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>, 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
@@ -12,8 +15,8 @@ Library General Public License for more details.
 
 You should have received a copy of the GNU Library General Public
 License along with the GNU C Library; see the file COPYING.LIB.  If
-not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-Cambridge, MA 02139, USA.  */
+not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA.  */
 
 #ifdef HAVE_CONFIG_H
 # include <config.h>
@@ -105,14 +108,21 @@ struct category
 static struct category category[] =
   {
 #define DEFINE_CATEGORY(category, name, items, postload, in, check, out)      \
-    { _NL_NUM_##category, name, NELEMS (category##_desc) - 1,                 \
-      category##_desc },
+    [category] = { _NL_NUM_##category, name, NELEMS (category##_desc),	      \
+		   category##_desc },
 #include "categories.def"
 #undef DEFINE_CATEGORY
   };
 #define NCATEGORIES NELEMS (category)
 
 
+/* Automatically set variable.  */
+extern const char *__progname;
+
+/* helper function for extended name handling.  */
+extern void locale_special (const char *name, int show_category_name,
+			    int show_keyword_name);
+
 /* Prototypes for local functions.  */
 static void usage (int status) __attribute__ ((noreturn));
 static void write_locales (void);
@@ -146,7 +156,7 @@ main (int argc, char *argv[])
          != EOF)
     switch (optchar)
       {
-      case '\0':
+      case '\0':		/* Long option.  */
 	break;
       case 'a':
 	do_all = 1;
@@ -173,7 +183,7 @@ main (int argc, char *argv[])
   /* Version information is requested.  */
   if (do_version)
     {
-      fprintf (stderr, "GNU %s %s\n", PACKAGE, VERSION);
+      fprintf (stderr, "%s - GNU %s %s\n", __progname, "libc", VERSION);
       exit (EXIT_SUCCESS);
     }
 
@@ -222,7 +232,7 @@ usage (int status)
 {
   if (status != EXIT_SUCCESS)
     fprintf (stderr, gettext ("Try `%s --help' for more information.\n"),
-             program_invocation_name);
+	     __progname);
   else
     printf (gettext ("\
 Usage: %s [OPTION]... name\n\
@@ -235,7 +245,7 @@ Mandatory arguments to long options are mandatory for short options too.\n\
 \n\
   -c, --category-name   write names of selected categories\n\
   -k, --keyword-name    write names of selected keywords\n"),
-	    program_invocation_name);
+	    __progname);
 
   exit (status);
 }
@@ -424,4 +434,8 @@ show_info (const char *name)
 	    return;
 	  }
     }
+
+  /* When we get to here the name is not standard ones.  For testing
+     and perhpas advanced use we allow some more symbols.  */
+  locale_special (name, show_category_name, show_keyword_name);
 }
diff --git a/locale/programs/localedef.c b/locale/programs/localedef.c
index e9fb6d57a6..7a12ac87a5 100644
--- a/locale/programs/localedef.c
+++ b/locale/programs/localedef.c
@@ -67,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;
 
@@ -118,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;
 
@@ -128,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)
@@ -182,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,
+	       "libc", VERSION);
       exit (0);
     }
 
@@ -389,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\
@@ -405,7 +397,7 @@ Mandatory arguments to long options are mandatory for short options too.\n\
 \n\
 System's directory for character maps: %s\n\
                        locale files  : %s\n"),
-	    program_name, CHARMAP_PATH, LOCALE_PATH);
+	    program_invocation_name, CHARMAP_PATH, LOCALE_PATH);
 
   exit (status);
 }
diff --git a/locale/programs/locfile.c b/locale/programs/locfile.c
index 69d976160b..436df2e976 100644
--- a/locale/programs/locfile.c
+++ b/locale/programs/locfile.c
@@ -935,16 +935,29 @@ write_locale_data (const char *output_path, const char *category,
   int fd;
   char *fname;
 
-  asprintf (&fname, "%s%s", output_path, category);
-  fd = creat (fname, 0666);
+  fname = malloc (strlen (output_path) + strlen (category) + 6);
+  if (fname == NULL)
+    error (5, errno, _("memory exhausted"));
+
+  /* Normally we write to the directory pointed to by the OUTPUT_PATH.
+     But for LC_MESSAGES we have to take care for the translation
+     data.  This means we need to have a directory LC_MESSAGES in
+     which we place the file under the name SYS_LC_MESSAGES.  */
+  if (strcmp (category, "LC_MESSAGES") == 0)
+    fd = -1;
+  else
+    {
+      sprintf (fname, "%s%s", output_path, category);
+      fd = creat (fname, 0666);
+    }
+
   if (fd == -1)
     {
       int save_err = errno;
 
       if (errno == EISDIR)
 	{
-	  free (fname);
-	  asprintf (&fname, "%1$s%2$s/SYS_%2$s", output_path, category);
+	  sprintf (fname, "%1$s%2$s/SYS_%2$s", output_path, category);
 	  fd = creat (fname, 0666);
 	  if (fd == -1)
 	    save_err = errno;
diff --git a/locale/programs/stringtrans.c b/locale/programs/stringtrans.c
index 10b04fa62e..6958dd2df8 100644
--- a/locale/programs/stringtrans.c
+++ b/locale/programs/stringtrans.c
@@ -36,16 +36,23 @@ void *xmalloc (size_t __n);
 void *xrealloc (void *__p, size_t __n);
 
 
-#define ADDC(ch)							    \
-  do									    \
-    {									    \
-      if (bufact == bufmax)						    \
-	{								    \
-	  bufmax *= 2;							    \
-	  buf = xrealloc (buf, bufmax);					    \
-	}								    \
-      buf[bufact++] = (ch);						    \
-    }									    \
+#define ADDC(ch)							      \
+  do									      \
+    {									      \
+      char *cp;								      \
+      if (bufact + (encoding_method == ENC_UCS4 ? 4 : 1) >= bufmax)	      \
+	{								      \
+	  bufmax *= 2;							      \
+	  buf = xrealloc (buf, bufmax);					      \
+	}								      \
+      cp = &buf[bufact];						      \
+      if (encode_char (ch, &cp) < 0)					      \
+	{								      \
+	  free (buf);							      \
+	  return NULL;							      \
+	}								      \
+      bufact = cp - buf;						      \
+    }									      \
   while (0)
 
 
@@ -92,31 +99,15 @@ translate_string (char *str, struct charset_t *charset)
 	  return NULL;
 	}
       else
-	{
-	  /* Encode string using current method.  */
-	  char *cp;
-
-	  if (bufmax - bufact < 8)
-	    {
-	      bufmax *= 2;
-	      buf = (char *) xrealloc (buf, bufmax);
-	    }
-
-	  cp = &buf[bufact];
-	  if (encode_char (value, &cp) < 0)
-	    {
-	      free (buf);
-	      return NULL;
-	    }
-	  bufact = cp - buf;
-	}
+	/* Encode string using current method.  */
+	ADDC (value);
 
       str = &tp[1];
     }
 
   ADDC ('\0');
 
-  return buf;;
+  return buf;
 }
 
 
@@ -127,15 +118,22 @@ encode_char (unsigned int value, char **cpp)
     {
     case ENC_UCS1:
       if (value > 255)
-	return -11;
+	return -1;
       *(*cpp)++ = (char) value;
       break;
 
     case ENC_UCS4:
+#if __BYTE_ORDER == __BIG_ENDIAN
       *(*cpp)++ = (char) (value >> 24);
       *(*cpp)++ = (char) ((value >> 16) & 0xff);
       *(*cpp)++ = (char) ((value >> 8) & 0xff);
       *(*cpp)++ = (char) (value & 0xff);
+#else
+      *(*cpp)++ = (char) (value & 0xff);
+      *(*cpp)++ = (char) ((value >>= 8) & 0xff);
+      *(*cpp)++ = (char) ((value >>= 8) & 0xff);
+      *(*cpp)++ = (char) ((value >>= 8) & 0xff);
+#endif
       break;
 
     default:
diff --git a/locale/setlocale.c b/locale/setlocale.c
index eab1a33f89..a32fab330e 100644
--- a/locale/setlocale.c
+++ b/locale/setlocale.c
@@ -53,12 +53,12 @@ static const struct locale_data * *const _nl_current[] =
 /* Array indexed by category of pointers to _nl_C_CATEGORY slots.
    Elements are zero for categories whose data is never used.  */
 const struct locale_data *const _nl_C[] =
-{
+  {
 #define DEFINE_CATEGORY(category, category_name, items, a, b, c, d) \
-  [category] = &_nl_C_##category,
+    [category] = &_nl_C_##category,
 #include "categories.def"
 #undef	DEFINE_CATEGORY
-};
+  };
 
 
 /* Define an array of category names (also the environment variable names),
@@ -169,11 +169,8 @@ new_composite_name (int category, char *newnames[LC_ALL])
 	return (char *) _nl_C_name;
 
       new = malloc (last_len + 1);
-      if (new == NULL)
-	return NULL;
 
-      memcpy (new, newnames[0], last_len + 1);
-      return new;
+      return new == NULL ? NULL : memcpy (new, newnames[0], last_len + 1);
     }
 
   new = malloc (cumlen);