]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
Fri May 3 13:32:08 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu> cvs/libc-960504
authorRoland McGrath <roland@gnu.org>
Fri, 3 May 1996 17:44:31 +0000 (17:44 +0000)
committerRoland McGrath <roland@gnu.org>
Fri, 3 May 1996 17:44:31 +0000 (17:44 +0000)
* intl/Makefile (CPPFLAGS): Change $(nlsdir) to $(i18ndir) in
LOCALE_ALIAS_PATH.

Fri May  3 03:14:02 1996  Ulrich Drepper  <drepper@cygnus.com>

* intl/Makefile (routines): Add l10nflist and explodename.
(distribute): Add loadinfo.h and locale.alias.
(install-others): New variable to install locale.alias.

* intl/dcgettext.c, intl/finddomain.c, intl/gettextP.h,
intl/loadmsgcat.c: Adapt for upcoming gettext-0.10.13.  Some code
is now shared with the locale implementation.

* intl/explodename.c, intl/l10nflist.c, intl/loadinfo.h: New file.
        Extracted from finddomain.c.  This is also used in the locale
        implementation.

* intl/locale.alias: New file.  Locale alias database compatible
        with X Window System's locale alias file.  Can now be used in
        locale and gettext code.

* libio/stdio.h: Add prototypes for asprint and vasprintf.

* locale/C-collate.c, locale/C-ctype.c, locale/C-messages.c,
locale/C-monetary.c, locale/C-numeric.c, locale/C-time.c: Add new
field in structure with name of locale ("C" in this case).

* locale/Makefile (routines): Add findlocale.

* locale/findlocale.c: New file.  Instead of trying to load the
        directly described file we now try to be much smarter when this
        fails.  Use the same code as gettext does.

* locale/loadlocale.c, locale/setlocale.c: Rewrite to know about
        new loading scheme.

* locale/localeinfo.h: Adapt prototypes and declarations for new
setlocale implementation.  Remove definition of u32_t type.  We
now use u_int32_t from <sys/types.h>.

* locale/programs/charset.h (ILLEGAL_CHAR_VALUE): Provide type
        with constant.

* locale/programs/config.h, locale/lc-collate.c,
        locale/localeinfo.h, locale/programs/ld-collate.c,
        locale/programs/ld-ctype.c, locale/programs/ld-messages.c,
        locale/programs/ld-monetary.c, locale/programs/ld-numeric.c,
        locale/programs/ld-time.c, locale/weight.h, string/strcoll.c:
        Change to use u_int32_t and u_int16_t.

* locale/programs/localedef.c (construct_output_path): Change name
        of output locale to contain normalized form of the character set
        portion.

* string/Makefile (routines): Add agrz-ctsep and argz-next.
(tests): Add tst-strlen.

* string/argz-ctsep.c: New file.  Implement reverse operation
from argz-stringify.

* string/argz-next.c: Non-inline version of function from argz.h.

* string/argz.h, string/envz.h: Make usable as global header file.

* string/envz.c: Fix declarations to use size_t where prototypes
say so.

* string/tst-strlen.c: New file.  Another test for critical
        situation in strlen implementations.

* sysdeps/i386/i586/strlen.S: Fix bug with highest byte in word
        being zero.

* wctype/test_wctype.c: Fix controlling comparison after change to
        32 bit character class array.

Fri May  3 12:53:12 1996  Roland McGrath  <roland@delasyd.gnu.ai.mit.edu>

* sysdeps/unix/sysv/linux/sys/socket.h: Remove spurious doubled line.

Thu May  2 22:50:52 1996  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

* sysdeps/unix/sysv/linux/getpriority.c: New file.
* sysdeps/unix/sysv/linux/syscalls.list: Add s_getpriority.

Thu May  2 22:41:31 1996  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

* sysdeps/unix/sysv/linux/m68k/fpu_control.h (_FPU_DEFAULT):
Disable all exceptions.

Thu May  2 22:33:14 1996  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

* sysdeps/m68k/fpu/e_acos.c, sysdeps/m68k/fpu/e_acosf.c,
sysdeps/m68k/fpu/e_fmod.c, sysdeps/m68k/fpu/e_fmodf.c,
sysdeps/m68k/fpu/isinfl.c, sysdeps/m68k/fpu/isnanl.c,
sysdeps/m68k/fpu/s_atan.c, sysdeps/m68k/fpu/s_atanf.c,
sysdeps/m68k/fpu/s_frexp.c, sysdeps/m68k/fpu/s_frexpf.c,
sysdeps/m68k/fpu/s_ilogb.c, sysdeps/m68k/fpu/s_ilogbf.c,
sysdeps/m68k/fpu/s_isinf.c, sysdeps/m68k/fpu/s_isinff.c,
sysdeps/m68k/fpu/s_ldexp.c, sysdeps/m68k/fpu/s_ldexpf.c,
sysdeps/m68k/fpu/s_modf.c, sysdeps/m68k/fpu/s_modff.c: Don't
define __NO_MATH_INLINES, which is already defined on command
line.

Thu May  2 22:18:28 1996  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

* sysdeps/libm-ieee754/e_j0f.c (__ieee754_j0f, __ieee754_y0f):
Replace 0x80000000 by 0x48000000.
* sysdeps/libm-ieee754/e_j1f.c (__ieee754_j1f): Likewise.

Thu May  2 21:30:33 1996  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

* sunrpc/svc_simple.c: Make global variable pl local to
registerrpc.

Thu May  2 00:24:04 1996  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

* time/Makefile (tz-cflags): New variable.
(CFLAGS-tzfile.c): New variable.
(CFLAGS-zic.c): Add $(tz-cflags).
(tz-cc): Remove variable.
($(objpfx)tzfile.o, $(objpfx)zic.o): Remove targets.

* sysdeps/mach/hurd/getcwd.c: Jump out of both loops when we find a
name, instead of checking for reaching end of buffer, which happens
when the match is the last entry in the buffer.

68 files changed:
ChangeLog
intl/Makefile
intl/dcgettext.c
intl/explodename.c [new file with mode: 0644]
intl/finddomain.c
intl/gettextP.h
intl/l10nflist.c [new file with mode: 0644]
intl/loadinfo.h [new file with mode: 0644]
intl/loadmsgcat.c
intl/locale.alias [new file with mode: 0644]
libio/stdio.h
locale/C-collate.c
locale/C-ctype.c
locale/C-messages.c
locale/C-monetary.c
locale/C-numeric.c
locale/C-time.c
locale/Makefile
locale/findlocale.c [new file with mode: 0644]
locale/lc-collate.c
locale/loadlocale.c
locale/localeinfo.h
locale/programs/charset.h
locale/programs/config.h
locale/programs/ld-collate.c
locale/programs/ld-ctype.c
locale/programs/ld-messages.c
locale/programs/ld-monetary.c
locale/programs/ld-numeric.c
locale/programs/ld-time.c
locale/programs/localedef.c
locale/setlocale.c
locale/weight.h
string/Makefile
string/argz-ctsep.c [new file with mode: 0644]
string/argz-next.c [new file with mode: 0644]
string/argz.h
string/envz.c
string/envz.h
string/strcoll.c
string/tst-strlen.c [new file with mode: 0644]
sunrpc/svc_simple.c
sysdeps/i386/i586/strlen.S
sysdeps/libm-ieee754/e_j0f.c
sysdeps/libm-ieee754/e_j1f.c
sysdeps/m68k/fpu/e_acos.c
sysdeps/m68k/fpu/e_acosf.c
sysdeps/m68k/fpu/e_fmod.c
sysdeps/m68k/fpu/e_fmodf.c
sysdeps/m68k/fpu/isinfl.c
sysdeps/m68k/fpu/isnanl.c
sysdeps/m68k/fpu/s_atan.c
sysdeps/m68k/fpu/s_atanf.c
sysdeps/m68k/fpu/s_frexp.c
sysdeps/m68k/fpu/s_frexpf.c
sysdeps/m68k/fpu/s_ilogb.c
sysdeps/m68k/fpu/s_ilogbf.c
sysdeps/m68k/fpu/s_isinf.c
sysdeps/m68k/fpu/s_isinff.c
sysdeps/m68k/fpu/s_ldexp.c
sysdeps/m68k/fpu/s_ldexpf.c
sysdeps/m68k/fpu/s_modf.c
sysdeps/m68k/fpu/s_modff.c
sysdeps/unix/sysv/linux/getpriority.c [new file with mode: 0644]
sysdeps/unix/sysv/linux/m68k/fpu_control.h
sysdeps/unix/sysv/linux/sys/socket.h
sysdeps/unix/sysv/linux/syscalls.list
wctype/test_wctype.c

index 2d530c04e3af542714d4ecd371a18a491929cb36..b4b82d9d473e415248713738e7f14a6432c80ec8 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,134 @@
+Fri May  3 13:32:08 1996  Roland McGrath  <roland@delasyd.gnu.ai.mit.edu>
+
+       * intl/Makefile (CPPFLAGS): Change $(nlsdir) to $(i18ndir) in
+       LOCALE_ALIAS_PATH.
+
+Fri May  3 03:14:02 1996  Ulrich Drepper  <drepper@cygnus.com>
+
+       * intl/Makefile (routines): Add l10nflist and explodename.
+       (distribute): Add loadinfo.h and locale.alias.
+       (install-others): New variable to install locale.alias.
+
+       * intl/dcgettext.c, intl/finddomain.c, intl/gettextP.h,
+       intl/loadmsgcat.c: Adapt for upcoming gettext-0.10.13.  Some code
+       is now shared with the locale implementation.
+
+       * intl/explodename.c, intl/l10nflist.c, intl/loadinfo.h: New file.
+        Extracted from finddomain.c.  This is also used in the locale
+        implementation.
+
+       * intl/locale.alias: New file.  Locale alias database compatible
+        with X Window System's locale alias file.  Can now be used in
+        locale and gettext code.
+
+       * libio/stdio.h: Add prototypes for asprint and vasprintf.
+
+       * locale/C-collate.c, locale/C-ctype.c, locale/C-messages.c,
+       locale/C-monetary.c, locale/C-numeric.c, locale/C-time.c: Add new
+       field in structure with name of locale ("C" in this case).
+
+       * locale/Makefile (routines): Add findlocale.
+
+       * locale/findlocale.c: New file.  Instead of trying to load the
+        directly described file we now try to be much smarter when this
+        fails.  Use the same code as gettext does.
+
+       * locale/loadlocale.c, locale/setlocale.c: Rewrite to know about
+        new loading scheme.
+
+       * locale/localeinfo.h: Adapt prototypes and declarations for new
+       setlocale implementation.  Remove definition of u32_t type.  We
+       now use u_int32_t from <sys/types.h>.
+
+       * locale/programs/charset.h (ILLEGAL_CHAR_VALUE): Provide type
+        with constant.
+
+       * locale/programs/config.h, locale/lc-collate.c,
+        locale/localeinfo.h, locale/programs/ld-collate.c,
+        locale/programs/ld-ctype.c, locale/programs/ld-messages.c,
+        locale/programs/ld-monetary.c, locale/programs/ld-numeric.c,
+        locale/programs/ld-time.c, locale/weight.h, string/strcoll.c:
+        Change to use u_int32_t and u_int16_t.
+
+       * locale/programs/localedef.c (construct_output_path): Change name
+        of output locale to contain normalized form of the character set
+        portion.
+
+       * string/Makefile (routines): Add agrz-ctsep and argz-next.
+       (tests): Add tst-strlen.
+
+       * string/argz-ctsep.c: New file.  Implement reverse operation
+       from argz-stringify.
+
+       * string/argz-next.c: Non-inline version of function from argz.h.
+
+       * string/argz.h, string/envz.h: Make usable as global header file.
+
+       * string/envz.c: Fix declarations to use size_t where prototypes
+       say so.
+
+       * string/tst-strlen.c: New file.  Another test for critical
+        situation in strlen implementations.
+
+       * sysdeps/i386/i586/strlen.S: Fix bug with highest byte in word
+        being zero.
+
+       * wctype/test_wctype.c: Fix controlling comparison after change to
+        32 bit character class array.
+
+Fri May  3 12:53:12 1996  Roland McGrath  <roland@delasyd.gnu.ai.mit.edu>
+
+       * sysdeps/unix/sysv/linux/sys/socket.h: Remove spurious doubled line.
+
+Thu May  2 22:50:52 1996  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>
+
+       * sysdeps/unix/sysv/linux/getpriority.c: New file.
+       * sysdeps/unix/sysv/linux/syscalls.list: Add s_getpriority.
+
+Thu May  2 22:41:31 1996  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>
+
+       * sysdeps/unix/sysv/linux/m68k/fpu_control.h (_FPU_DEFAULT):
+       Disable all exceptions.
+
+Thu May  2 22:33:14 1996  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>
+
+       * sysdeps/m68k/fpu/e_acos.c, sysdeps/m68k/fpu/e_acosf.c,
+       sysdeps/m68k/fpu/e_fmod.c, sysdeps/m68k/fpu/e_fmodf.c,
+       sysdeps/m68k/fpu/isinfl.c, sysdeps/m68k/fpu/isnanl.c,
+       sysdeps/m68k/fpu/s_atan.c, sysdeps/m68k/fpu/s_atanf.c,
+       sysdeps/m68k/fpu/s_frexp.c, sysdeps/m68k/fpu/s_frexpf.c,
+       sysdeps/m68k/fpu/s_ilogb.c, sysdeps/m68k/fpu/s_ilogbf.c,
+       sysdeps/m68k/fpu/s_isinf.c, sysdeps/m68k/fpu/s_isinff.c,
+       sysdeps/m68k/fpu/s_ldexp.c, sysdeps/m68k/fpu/s_ldexpf.c,
+       sysdeps/m68k/fpu/s_modf.c, sysdeps/m68k/fpu/s_modff.c: Don't
+       define __NO_MATH_INLINES, which is already defined on command
+       line.
+
+Thu May  2 22:18:28 1996  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>
+
+       * sysdeps/libm-ieee754/e_j0f.c (__ieee754_j0f, __ieee754_y0f):
+       Replace 0x80000000 by 0x48000000.
+       * sysdeps/libm-ieee754/e_j1f.c (__ieee754_j1f): Likewise.
+
+Thu May  2 21:30:33 1996  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>
+
+       * sunrpc/svc_simple.c: Make global variable pl local to
+       registerrpc.
+
+Thu May  2 00:24:04 1996  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>
+
+       * time/Makefile (tz-cflags): New variable.
+       (CFLAGS-tzfile.c): New variable.
+       (CFLAGS-zic.c): Add $(tz-cflags).
+       (tz-cc): Remove variable.
+       ($(objpfx)tzfile.o, $(objpfx)zic.o): Remove targets.
+
 Wed May  1 09:10:04 1996  Roland McGrath  <roland@delasyd.gnu.ai.mit.edu>
 
+       * sysdeps/mach/hurd/getcwd.c: Jump out of both loops when we find a
+       name, instead of checking for reaching end of buffer, which happens
+       when the match is the last entry in the buffer.
+
        * time/strftime.c: Use canonical autoconf nugget for time.h+sys/time.h
        include.
 
index 159d1b1534eea42cc9d2145106ba4afa18f514f8..9d97088d4ac37d5fa393f0279a9e379934dba6cc 100644 (file)
 subdir = intl
 headers = libintl.h
 routines = bindtextdom dcgettext dgettext gettext      \
-          finddomain loadmsgcat localealias textdomain
-distribute = gettext.h gettextP.h hash-string.h
+          finddomain loadmsgcat localealias textdomain \
+          l10nflist explodename
+distribute = gettext.h gettextP.h hash-string.h loadinfo.h locale.alias
+
+install-others = $(localedir)/locale.alias
 
 include ../Rules
 
 CPPFLAGS += -D'GNULOCALEDIR="$(localedir)"' \
-           -D'LOCALE_ALIAS_PATH="$(localedir):$(nlsdir)"'
+           -D'LOCALE_ALIAS_PATH="$(localedir):$(i18ndir)"'
+
+$(localedir)/locale.alias: locale.alias
+       $(do-install)
 
 ifdef gettext-srcdir
 
 %.h:: ../gpl2lgpl.sed $(gettext-srcdir)/intl/%.glibc; $(copysrc)
 %.c:: ../gpl2lgpl.sed $(gettext-srcdir)/intl/%.c; $(copysrc)
 %.h:: ../gpl2lgpl.sed $(gettext-srcdir)/intl/%.h; $(copysrc)
+locale.alias:: ../gpl2lgpl.sed $(gettext-srcdir)/misc/locale.alias; $(copysrc)
 
 define copysrc
 sed -f $^ > $@.new
index 7d739d32c35cdbcdac6d8b648fb4e10f5816bae6..6c8963f720682443a04890521e57de26c336f013 100644 (file)
@@ -1,8 +1,6 @@
 /* dcgettext.c -- implementation of the dcgettext(3) function
-   Copyright (C) 1995 Free Software Foundation, Inc.
-
-This file is part of the GNU C Library.  Its master source is NOT part of
-the C library, however.  The master source lives in /gd/gnu/lib.
+Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+Written 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
@@ -16,8 +14,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>
@@ -155,7 +153,7 @@ const char _nl_default_dirname[] = GNULOCALEDIR;
 struct binding *_nl_domain_bindings;
 
 /* Prototypes for local functions.  */
-static char *find_msg PARAMS ((struct loaded_domain *domain,
+static char *find_msg PARAMS ((struct loaded_l10nfile *domain_file,
                               const char *msgid));
 static const char *category_to_name PARAMS ((int category));
 static const char *guess_category_value PARAMS ((int category,
@@ -180,7 +178,7 @@ DCGETTEXT (domainname, msgid, category)
      const char *msgid;
      int category;
 {
-  struct loaded_domain *domain;
+  struct loaded_l10nfile *domain;
   struct binding *binding;
   const char *categoryname;
   const char *categoryvalue;
@@ -355,18 +353,21 @@ weak_alias (__dcgettext, dcgettext);
 
 
 static char *
-find_msg (domain, msgid)
-     struct loaded_domain *domain;
+find_msg (domain_file, msgid)
+     struct loaded_l10nfile *domain_file;
      const char *msgid;
 {
   size_t top, act, bottom;
+  struct loaded_domain *domain;
 
-  if (domain->decided == 0)
-    _nl_load_domain (domain);
+  if (domain_file->decided == 0)
+    _nl_load_domain (domain_file);
 
-  if (domain->data == NULL)
+  if (domain_file->data == NULL)
     return NULL;
 
+  domain = (struct loaded_domain *) domain_file->data;
+
   /* Locate the MSGID and its translation.  */
   if (domain->hash_size > 2 && domain->hash_tab != NULL)
     {
@@ -439,7 +440,8 @@ find_msg (domain, msgid)
 
 
 /* Return string representation of locale CATEGORY.  */
-static const char *category_to_name (category)
+static const char *
+category_to_name (category)
      int category;
 {
   const char *retval;
diff --git a/intl/explodename.c b/intl/explodename.c
new file mode 100644 (file)
index 0000000..2fd8be0
--- /dev/null
@@ -0,0 +1,167 @@
+/* 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
+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.  */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "loadinfo.h"
+
+int
+_nl_explode_name (name, language, modifier, territory, codeset,
+                 normalized_codeset, special, sponsor, revision)
+     char *name;
+     const char **language;
+     const char **modifier;
+     const char **territory;
+     const char **codeset;
+     const char **normalized_codeset;
+     const char **special;
+     const char **sponsor;
+     const char **revision;
+{
+  enum { undecided, xpg, cen } syntax;
+  char *cp;
+  int mask;
+  
+  *modifier = NULL;
+  *territory = NULL;
+  *codeset = NULL;
+  *normalized_codeset = NULL;
+  *special = NULL;
+  *sponsor = NULL;
+  *revision = NULL;
+
+  /* Now we determine the single parts of the locale name.  First
+     look for the language.  Termination symbols are `_' and `@' if
+     we use XPG4 style, and `_', `+', and `,' if we use CEN syntax.  */
+  mask = 0;
+  syntax = undecided;
+  *language = cp = name;
+  while (cp[0] != '\0' && cp[0] != '_' && cp[0] != '@'
+        && cp[0] != '+' && cp[0] != ',')
+    ++cp;
+
+  if (*language == cp)
+    /* This does not make sense: language has to be specified.  Use
+       this entry as it is without exploding.  Perhaps it is an alias.  */
+    cp = strchr (*language, '\0');
+  else if (cp[0] == '_')
+    {
+      /* Next is the territory.  */
+      cp[0] = '\0';
+      *territory = ++cp;
+
+      while (cp[0] != '\0' && cp[0] != '.' && cp[0] != '@'
+            && cp[0] != '+' && cp[0] != ',' && cp[0] != '_')
+       ++cp;
+
+      mask |= TERRITORY;
+
+      if (cp[0] == '.')
+       {
+         /* Next is the codeset.  */
+         syntax = xpg;
+         cp[0] = '\0';
+         *codeset = ++cp;
+
+         while (cp[0] != '\0' && cp[0] != '@')
+           ++cp;
+
+         mask |= XPG_CODESET;
+
+         if (*codeset != cp && (*codeset)[0] != '\0')
+           {
+             *normalized_codeset = _nl_normalize_codeset (*codeset,
+                                                          cp - *codeset);
+             if (strcmp (*codeset, *normalized_codeset) == 0)
+               free ((char *) *normalized_codeset);
+             else
+               mask |= XPG_NORM_CODESET;
+           }
+       }
+    }
+
+  if (cp[0] == '@' || (syntax != xpg && cp[0] == '+'))
+    {
+      /* Next is the modifier.  */
+      syntax = cp[0] == '@' ? xpg : cen;
+      cp[0] = '\0';
+      *modifier = ++cp;
+
+      while (syntax == cen && cp[0] != '\0' && cp[0] != '+'
+            && cp[0] != ',' && cp[0] != '_')
+       ++cp;
+
+      mask |= XPG_MODIFIER | CEN_AUDIENCE;
+    }
+
+  if (syntax != xpg && (cp[0] == '+' || cp[0] == ',' || cp[0] == '_'))
+    {
+      syntax = cen;
+
+      if (cp[0] == '+')
+       {
+         /* Next is special application (CEN syntax).  */
+         cp[0] = '\0';
+         *special = ++cp;
+
+         while (cp[0] != '\0' && cp[0] != ',' && cp[0] != '_')
+           ++cp;
+
+         mask |= CEN_SPECIAL;
+       }
+
+      if (cp[0] == ',')
+       {
+         /* Next is sponsor (CEN syntax).  */
+         cp[0] = '\0';
+         *sponsor = ++cp;
+
+         while (cp[0] != '\0' && cp[0] != '_')
+           ++cp;
+
+         mask |= CEN_SPONSOR;
+       }
+
+      if (cp[0] == '_')
+       {
+         /* Next is revision (CEN syntax).  */
+         cp[0] = '\0';
+         *revision = ++cp;
+
+         mask |= CEN_REVISION;
+       }
+    }
+
+  /* For CEN sytnax values it might be important to have the
+     separator character in the file name, not for XPG syntax.  */
+  if (syntax == xpg)
+    {
+      if (*territory != NULL && (*territory)[0] == '\0')
+       mask &= ~TERRITORY;
+
+      if (*codeset != NULL && (*codeset)[0] == '\0')
+       mask &= ~XPG_CODESET;
+
+      if (*modifier != NULL && (*modifier)[0] == '\0')
+       mask &= ~XPG_MODIFIER;
+    }
+
+  return mask;
+}
index 3ced26fa4b849a2fee11cffa8aa935bba341fadd..bb4609e8642eec459c3e1db14ff68c58222f5975 100644 (file)
@@ -1,9 +1,6 @@
 /* finddomain.c -- handle list of needed message catalogs
-   Copyright (C) 1995, 1996 Free Software Foundation, Inc.
-   Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
-
-This file is part of the GNU C Library.  Its master source is NOT part of
-the C library, however.  The master source lives in /gd/gnu/lib.
+Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+Written 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
@@ -17,8 +14,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>
@@ -71,39 +68,8 @@ void free ();
 # define stpcpy(dest, src) __stpcpy(dest, src)
 #endif
 
-/* Encoding of locale name parts.  */
-#define CEN_REVISION           1
-#define CEN_SPONSOR            2
-#define CEN_SPECIAL            4
-#define XPG_NORM_CODESET       8
-#define XPG_CODESET            16
-#define TERRITORY              32
-#define CEN_AUDIENCE           64
-#define XPG_MODIFIER           128
-
-#define CEN_SPECIFIC   (CEN_REVISION|CEN_SPONSOR|CEN_SPECIAL|CEN_AUDIENCE)
-#define XPG_SPECIFIC   (XPG_CODESET|XPG_NORM_CODESET|XPG_MODIFIER)
-
-
 /* List of already loaded domains.  */
-static struct loaded_domain *_nl_loaded_domains;
-
-/* Prototypes for local functions.  */
-static struct loaded_domain *make_entry_rec PARAMS ((const char *dirname,
-                                                    int mask,
-                                                    const char *language,
-                                                    const char *territory,
-                                                    const char *codeset,
-                                                    const char *normalized_codeset,
-                                                    const char *modifier,
-                                                    const char *special,
-                                                    const char *sponsor,
-                                                    const char *revision,
-                                                    const char *domainname,
-                                                    int do_allocate));
-
-/* Normalize name of selected codeset.  */
-static const char *normalize_codeset PARAMS ((const char *codeset));
+static struct loaded_l10nfile *_nl_loaded_domains;
 
 /* Substitution for systems lacking this function in their C library.  */
 #if !_LIBC && !HAVE_STPCPY
@@ -115,29 +81,25 @@ static char *stpcpy__ PARAMS ((char *dest, const char *src));
 /* Return a data structure describing the message catalog described by
    the DOMAINNAME and CATEGORY parameters with respect to the currently
    established bindings.  */
-struct loaded_domain *
+struct loaded_l10nfile *
 _nl_find_domain (dirname, locale, domainname)
      const char *dirname;
      char *locale;
      const char *domainname;
 {
-  enum { undecided, xpg, cen } syntax;
-  struct loaded_domain *retval;
+  struct loaded_l10nfile *retval;
   const char *language;
-  const char *modifier = NULL;
-  const char *territory = NULL;
-  const char *codeset = NULL;
-  const char *normalized_codeset = NULL;
-  const char *special = NULL;
-  const char *sponsor = NULL;
-  const char *revision = NULL;
-  const char *alias_value = NULL;
-  char *cp;
+  const char *modifier;
+  const char *territory;
+  const char *codeset;
+  const char *normalized_codeset;
+  const char *special;
+  const char *sponsor;
+  const char *revision;
+  const char *alias_value;
   int mask;
 
-  /* CATEGORYVALUE now possibly contains a colon separated list of
-     locales.  Each single locale can consist of up to four recognized
-     parts for the XPG syntax:
+  /* LOCALE can consist of up to four recognized parts for the XPG syntax:
 
                language[_territory[.codeset]][@modifier]
 
@@ -160,15 +122,16 @@ _nl_find_domain (dirname, locale, domainname)
 
   /* If we have already tested for this locale entry there has to
      be one data set in the list of loaded domains.  */
-  retval = make_entry_rec (dirname, 0, locale, NULL, NULL, NULL, NULL,
-                          NULL, NULL, NULL, domainname, 0);
+  retval = _nl_make_l10nflist (&_nl_loaded_domains, dirname,
+                              strlen (dirname) + 1, 0, locale, NULL, NULL,
+                              NULL, NULL, NULL, NULL, NULL, domainname, 0);
   if (retval != NULL)
     {
       /* We know something about this locale.  */
       int cnt;
 
       if (retval->decided == 0)
-       _nl_load_domain (retval); /* @@@ */
+       _nl_load_domain (retval);
 
       if (retval->data != NULL)
        return retval;
@@ -181,8 +144,6 @@ _nl_find_domain (dirname, locale, domainname)
          if (retval->successor[cnt]->data != NULL)
            break;
        }
-
-      /* We really found some usable information.  */
       return cnt >= 0 ? retval : NULL;
       /* NOTREACHED */
     }
@@ -204,123 +165,16 @@ _nl_find_domain (dirname, locale, domainname)
   /* Now we determine the single parts of the locale name.  First
      look for the language.  Termination symbols are `_' and `@' if
      we use XPG4 style, and `_', `+', and `,' if we use CEN syntax.  */
-  mask = 0;
-  syntax = undecided;
-  language = cp = locale;
-  while (cp[0] != '\0' && cp[0] != '_' && cp[0] != '@'
-        && cp[0] != '+' && cp[0] != ',')
-    ++cp;
-
-  if (language == cp)
-    /* This does not make sense: language has to be specified.  Use
-       this entry as it is without exploding.  Perhaps it is an alias.  */
-    cp = strchr (language, '\0');
-  else if (cp[0] == '_')
-    {
-      /* Next is the territory.  */
-      cp[0] = '\0';
-      territory = ++cp;
-
-      while (cp[0] != '\0' && cp[0] != '.' && cp[0] != '@'
-            && cp[0] != '+' && cp[0] != ',' && cp[0] != '_')
-       ++cp;
-
-      mask |= TERRITORY;
-
-      if (cp[0] == '.')
-       {
-         /* Next is the codeset.  */
-         syntax = xpg;
-         cp[0] = '\0';
-         codeset = ++cp;
-
-         while (cp[0] != '\0' && cp[0] != '@')
-           ++cp;
-
-         mask |= XPG_CODESET;
-
-         if (codeset != cp && codeset[0] != '\0')
-           {
-             normalized_codeset = normalize_codeset (codeset);
-             if (strcmp (codeset, normalized_codeset) == 0)
-               free ((char *) normalized_codeset);
-             else
-               mask |= XPG_NORM_CODESET;
-           }
-       }
-    }
-
-  if (cp[0] == '@' || (syntax != xpg && cp[0] == '+'))
-    {
-      /* Next is the modifier.  */
-      syntax = cp[0] == '@' ? xpg : cen;
-      cp[0] = '\0';
-      modifier = ++cp;
-
-      while (syntax == cen && cp[0] != '\0' && cp[0] != '+'
-            && cp[0] != ',' && cp[0] != '_')
-       ++cp;
-
-      mask |= XPG_MODIFIER | CEN_AUDIENCE;
-    }
-
-  if (syntax != xpg && (cp[0] == '+' || cp[0] == ',' || cp[0] == '_'))
-    {
-      syntax = cen;
-
-      if (cp[0] == '+')
-       {
-         /* Next is special application (CEN syntax).  */
-         cp[0] = '\0';
-         special = ++cp;
-
-         while (cp[0] != '\0' && cp[0] != ',' && cp[0] != '_')
-           ++cp;
-
-         mask |= CEN_SPECIAL;
-       }
-
-      if (cp[0] == ',')
-       {
-         /* Next is sponsor (CEN syntax).  */
-         cp[0] = '\0';
-         sponsor = ++cp;
-
-         while (cp[0] != '\0' && cp[0] != '_')
-           ++cp;
-
-         mask |= CEN_SPONSOR;
-       }
-
-      if (cp[0] == '_')
-       {
-         /* Next is revision (CEN syntax).  */
-         cp[0] = '\0';
-         revision = ++cp;
-
-         mask |= CEN_REVISION;
-       }
-    }
-
-  /* For CEN sytnax values it might be important to have the
-     separator character in the file name, not for XPG syntax.  */
-  if (syntax == xpg)
-    {
-      if (territory != NULL && territory[0] == '\0')
-       mask &= ~TERRITORY;
-
-      if (codeset != NULL && codeset[0] == '\0')
-       mask &= ~XPG_CODESET;
-
-      if (modifier != NULL && modifier[0] == '\0')
-       mask &= ~XPG_MODIFIER;
-    }
+  mask = _nl_explode_name (locale, &language, &modifier, &territory,
+                          &codeset, &normalized_codeset, &special,
+                          &sponsor, &revision);
 
   /* Create all possible locale entries which might be interested in
      generalzation.  */
-  retval = make_entry_rec (dirname, mask, language, territory, codeset,
-                          normalized_codeset, modifier, special, sponsor,
-                          revision, domainname, 1);
+  retval = _nl_make_l10nflist (&_nl_loaded_domains, dirname,
+                              strlen (dirname) + 1, mask, language, territory,
+                              codeset, normalized_codeset, modifier, special,
+                              sponsor, revision, domainname, 1);
   if (retval == NULL)
     /* This means we are out of core.  */
     return NULL;
@@ -336,12 +190,7 @@ _nl_find_domain (dirname, locale, domainname)
            _nl_load_domain (retval->successor[cnt]);
          if (retval->successor[cnt]->data != NULL)
            break;
-
-         /* Signal that locale is not available.  */
-         retval->successor[cnt] = NULL;
        }
-      if (retval->successor[cnt] == NULL)
-       retval = NULL;
     }
 
   /* The room for an alias was dynamically allocated.  Free it now.  */
@@ -351,215 +200,6 @@ _nl_find_domain (dirname, locale, domainname)
   return retval;
 }
 
-
-static struct loaded_domain *
-make_entry_rec (dirname, mask, language, territory, codeset,
-               normalized_codeset, modifier, special, sponsor, revision,
-               domain, do_allocate)
-     const char *dirname;
-     int mask;
-     const char *language;
-     const char *territory;
-     const char *codeset;
-     const char *normalized_codeset;
-     const char *modifier;
-     const char *special;
-     const char *sponsor;
-     const char *revision;
-     const char *domain;
-     int do_allocate;
-{
-  char *filename = NULL;
-  struct loaded_domain *last = NULL;
-  struct loaded_domain *retval;
-  char *cp;
-  size_t entries;
-  int cnt;
-
-
-  /* Process the current entry described by the MASK only when it is
-     valid.  Because the mask can have in the first call bits from
-     both syntaces set this is necessary to prevent constructing
-     illegal local names.  */
-  /* FIXME: Rewrite because test is necessary only in first round.  */
-  if ((mask & CEN_SPECIFIC) == 0 || (mask & XPG_SPECIFIC) == 0
-      || ((mask & XPG_CODESET) != 0 && (mask & XPG_NORM_CODESET) != 0))
-    {
-      /* Allocate room for the full file name.  */
-      filename = (char *) malloc (strlen (dirname) + 1
-                                 + strlen (language)
-                                 + ((mask & TERRITORY) != 0
-                                    ? strlen (territory) + 1 : 0)
-                                 + ((mask & XPG_CODESET) != 0
-                                    ? strlen (codeset) + 1 : 0)
-                                 + ((mask & XPG_NORM_CODESET) != 0
-                                    ? strlen (normalized_codeset) + 1 : 0)
-                                 + ((mask & XPG_MODIFIER) != 0 ?
-                                    strlen (modifier) + 1 : 0)
-                                 + ((mask & CEN_SPECIAL) != 0
-                                    ? strlen (special) + 1 : 0)
-                                 + ((mask & CEN_SPONSOR) != 0
-                                    ? strlen (sponsor) + 1 : 0)
-                                 + ((mask & CEN_REVISION) != 0
-                                    ? strlen (revision) + 1 : 0) + 1
-                                 + strlen (domain) + 1);
-
-      if (filename == NULL)
-       return NULL;
-
-      retval = NULL;
-      last = NULL;
-
-      /* Construct file name.  */
-      cp = stpcpy (filename, dirname);
-      *cp++ = '/';
-      cp = stpcpy (cp, language);
-
-      if ((mask & TERRITORY) != 0)
-       {
-         *cp++ = '_';
-         cp = stpcpy (cp, territory);
-       }
-      if ((mask & XPG_CODESET) != 0)
-       {
-         *cp++ = '.';
-         cp = stpcpy (cp, codeset);
-       }
-      if ((mask & XPG_NORM_CODESET) != 0)
-       {
-         *cp++ = '.';
-         cp = stpcpy (cp, normalized_codeset);
-       }
-      if ((mask & (XPG_MODIFIER | CEN_AUDIENCE)) != 0)
-       {
-         /* This component can be part of both syntaces but has different
-            leading characters.  For CEN we use `+', else `@'.  */
-         *cp++ = (mask & CEN_AUDIENCE) != 0 ? '+' : '@';
-         cp = stpcpy (cp, modifier);
-       }
-      if ((mask & CEN_SPECIAL) != 0)
-       {
-         *cp++ = '+';
-         cp = stpcpy (cp, special);
-       }
-      if ((mask & CEN_SPONSOR) != 0)
-       {
-         *cp++ = ',';
-         cp = stpcpy (cp, sponsor);
-       }
-      if ((mask & CEN_REVISION) != 0)
-       {
-         *cp++ = '_';
-         cp = stpcpy (cp, revision);
-       }
-
-      *cp++ = '/';
-      stpcpy (cp, domain);
-
-      /* Look in list of already loaded domains whether it is already
-        available.  */
-      last = NULL;
-      for (retval = _nl_loaded_domains; retval != NULL; retval = retval->next)
-       if (retval->filename != NULL)
-         {
-           int compare = strcmp (retval->filename, filename);
-           if (compare == 0)
-             /* We found it!  */
-             break;
-           if (compare < 0)
-             {
-               /* It's not in the list.  */
-               retval = NULL;
-               break;
-             }
-
-           last = retval;
-         }
-
-      if (retval != NULL || do_allocate == 0)
-       {
-         free (filename);
-         return retval;
-       }
-    }
-
-  retval = (struct loaded_domain *) malloc (sizeof (*retval));
-  if (retval == NULL)
-    return NULL;
-
-  retval->filename = filename;
-  retval->decided = 0;
-
-  if (last == NULL)
-    {
-      retval->next = _nl_loaded_domains;
-      _nl_loaded_domains = retval;
-    }
-  else
-    {
-      retval->next = last->next;
-      last->next = retval;
-    }
-
-  entries = 0;
-  for (cnt = 254; cnt >= 0; --cnt)
-    if (cnt < mask && (cnt & ~mask) == 0
-       && ((cnt & CEN_SPECIFIC) == 0 || (cnt & XPG_SPECIFIC) == 0)
-       && ((cnt & XPG_CODESET) == 0 || (cnt & XPG_NORM_CODESET) == 0))
-      retval->successor[entries++] = make_entry_rec (dirname, cnt,
-                                                    language, territory,
-                                                    codeset,
-                                                    normalized_codeset,
-                                                    modifier, special,
-                                                    sponsor, revision,
-                                                    domain, 1);
-  retval->successor[entries] = NULL;
-
-  return retval;
-}
-
-
-static const char *
-normalize_codeset (codeset)
-     const char *codeset;
-{
-  int len = 0;
-  int only_digit = 1;
-  const char *cp;
-  char *retval;
-  char *wp;
-
-  for (cp = codeset; cp[0] != '\0'; ++cp)
-    if (isalnum (cp[0]))
-      {
-       ++len;
-
-       if (isalpha (cp[0]))
-         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 (cp = codeset; cp[0] != '\0'; ++cp)
-       if (isalpha (cp[0]))
-         *wp++ = toupper (cp[0]);
-       else if (isdigit (cp[0]))
-         *wp++ = cp[0];
-
-      *wp = '\0';
-    }
-
-  return (const char *) retval;
-}
-
-
 /* @@ begin of epilog @@ */
 
 /* We don't want libintl.a to depend on any other library.  So we
index 34196a0859e4456443fed4540365ecfd5d197378..c37adaba0f239b3fda4bf571514bc23e4cff684a 100644 (file)
@@ -1,8 +1,6 @@
 /* gettextP.h -- header describing internals of gettext library
-   Copyright (C) 1995, 1996 Free Software Foundation, Inc.
-
-This file is part of the GNU C Library.  Its master source is NOT part of
-the C library, however.  The master source lives in /gd/gnu/lib.
+Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+Written 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
@@ -16,12 +14,14 @@ 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.  */
 
 #ifndef _GETTEXTP_H
 #define _GETTEXTP_H
 
+#include "loadinfo.h"
+
 /* @@ end of prolog @@ */
 
 #ifndef PARAMS
@@ -49,12 +49,6 @@ SWAP (i)
 
 struct loaded_domain
 {
-  struct loaded_domain *next;
-  struct loaded_domain *successor[63];
-
-  const char *filename;
-  int decided;
-
   const char *data;
   int must_swap;
   nls_uint32 nstrings;
@@ -71,12 +65,10 @@ struct binding
   char *dirname;
 };
 
-struct loaded_domain *_nl_find_domain PARAMS ((const char *__dirname,
-                                              char *__locale,
-                                              const char *__domainname));
-void _nl_load_domain PARAMS ((struct loaded_domain *__domain));
-
-const char *_nl_expand_alias PARAMS ((const char *__name));
+struct loaded_l10nfile *_nl_find_domain PARAMS ((const char *__dirname,
+                                                char *__locale,
+                                                const char *__domainname));
+void _nl_load_domain PARAMS ((struct loaded_l10nfile *__domain));
 
 /* @@ begin of epilog @@ */
 
diff --git a/intl/l10nflist.c b/intl/l10nflist.c
new file mode 100644 (file)
index 0000000..b0fdf51
--- /dev/null
@@ -0,0 +1,262 @@
+/* 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
+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.  */
+
+#include <argz.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "loadinfo.h"
+
+/* Return number of bits set in X.  */
+static int pop __P ((int x));
+
+static inline int
+pop (x)
+     int x;
+{
+  /* We assume that no more than 16 bits are used.  */
+  x = ((x & ~0x5555) >> 1) + (x & 0x5555);
+  x = ((x & ~0x3333) >> 2) + (x & 0x3333);
+  x = ((x >> 4) + x) & 0x0f0f;
+  x = ((x >> 8) + x) & 0xff;
+
+  return x;
+}
+
+
+struct loaded_l10nfile *
+_nl_make_l10nflist (l10nfile_list, dirlist, dirlist_len, mask, language,
+                   territory, codeset, normalized_codeset, modifier, special,
+                   sponsor, revision, filename, do_allocate)
+     struct loaded_l10nfile **l10nfile_list;
+     const char *dirlist;
+     size_t dirlist_len;
+     int mask;
+     const char *language;
+     const char *territory;
+     const char *codeset;
+     const char *normalized_codeset;
+     const char *modifier;
+     const char *special;
+     const char *sponsor;
+     const char *revision;
+     const char *filename;
+     int do_allocate;
+{
+  char *abs_filename;
+  struct loaded_l10nfile *last = NULL;
+  struct loaded_l10nfile *retval;
+  char *cp;
+  size_t entries;
+  int cnt;
+
+  /* Allocate room for the full file name.  */
+  abs_filename = (char *) malloc (dirlist_len
+                                 + strlen (language)
+                                 + ((mask & TERRITORY) != 0
+                                    ? strlen (territory) + 1 : 0)
+                                 + ((mask & XPG_CODESET) != 0
+                                    ? strlen (codeset) + 1 : 0)
+                                 + ((mask & XPG_NORM_CODESET) != 0
+                                    ? strlen (normalized_codeset) + 1 : 0)
+                                 + (((mask & XPG_MODIFIER) != 0
+                                     || (mask & CEN_AUDIENCE) != 0) ?
+                                    strlen (modifier) + 1 : 0)
+                                 + ((mask & CEN_SPECIAL) != 0
+                                    ? strlen (special) + 1 : 0)
+                                 + ((mask & CEN_SPONSOR) != 0
+                                    ? strlen (sponsor) + 1 : 0)
+                                 + ((mask & CEN_REVISION) != 0
+                                    ? strlen (revision) + 1 : 0)
+                                 + 1 + strlen (filename) + 1);
+
+  if (abs_filename == NULL)
+    return NULL;
+
+  retval = NULL;
+  last = NULL;
+
+  /* Construct file name.  */
+  memcpy (abs_filename, dirlist, dirlist_len);
+  __argz_stringify (abs_filename, dirlist_len, ':');
+  cp = abs_filename + (dirlist_len - 1);
+  *cp++ = '/';
+  cp = stpcpy (cp, language);
+
+  if ((mask & TERRITORY) != 0)
+    {
+      *cp++ = '_';
+      cp = stpcpy (cp, territory);
+    }
+  if ((mask & XPG_CODESET) != 0)
+    {
+      *cp++ = '.';
+      cp = stpcpy (cp, codeset);
+    }
+  if ((mask & XPG_NORM_CODESET) != 0)
+    {
+      *cp++ = '.';
+      cp = stpcpy (cp, normalized_codeset);
+    }
+  if ((mask & (XPG_MODIFIER | CEN_AUDIENCE)) != 0)
+    {
+      /* This component can be part of both syntaces but has different
+        leading characters.  For CEN we use `+', else `@'.  */
+      *cp++ = (mask & CEN_AUDIENCE) != 0 ? '+' : '@';
+      cp = stpcpy (cp, modifier);
+    }
+  if ((mask & CEN_SPECIAL) != 0)
+    {
+      *cp++ = '+';
+      cp = stpcpy (cp, special);
+    }
+  if ((mask & CEN_SPONSOR) != 0)
+    {
+      *cp++ = ',';
+      cp = stpcpy (cp, sponsor);
+    }
+  if ((mask & CEN_REVISION) != 0)
+    {
+      *cp++ = '_';
+      cp = stpcpy (cp, revision);
+    }
+
+  *cp++ = '/';
+  stpcpy (cp, filename);
+
+  /* Look in list of already loaded domains whether it is already
+     available.  */
+  last = NULL;
+  for (retval = *l10nfile_list; retval != NULL; retval = retval->next)
+    if (retval->filename != NULL)
+      {
+       int compare = strcmp (retval->filename, abs_filename);
+       if (compare == 0)
+         /* We found it!  */
+         break;
+       if (compare < 0)
+         {
+           /* It's not in the list.  */
+           retval = NULL;
+           break;
+         }
+
+       last = retval;
+      }
+
+  if (retval != NULL || do_allocate == 0)
+    {
+      free (abs_filename);
+      return retval;
+    }
+
+  retval = (struct loaded_l10nfile *)
+    malloc (sizeof (*retval) + (__argz_count (dirlist, dirlist_len)
+                               * (1 << pop (mask))
+                               * sizeof (struct loaded_l10nfile *)));
+  if (retval == NULL)
+    return NULL;
+
+  retval->filename = abs_filename;
+  retval->decided = (__argz_count (dirlist, dirlist_len) != 1
+                    || ((mask & XPG_CODESET) != 0
+                        && (mask & XPG_NORM_CODESET) != 0));
+  retval->data = NULL;
+
+  if (last == NULL)
+    {
+      retval->next = *l10nfile_list;
+      *l10nfile_list = retval;
+    }
+  else
+    {
+      retval->next = last->next;
+      last->next = retval;
+    }
+
+  entries = 0;
+  /* If the DIRLIST is a real list the RETVAL entry correcponds not to
+     a real file.  So we have to use the DIRLIST separation machanism
+     of the inner loop.  */
+  cnt = __argz_count (dirlist, dirlist_len) == 1 ? mask - 1 : mask;
+  for (; cnt >= 0; --cnt)
+    if ((cnt & ~mask) == 0
+       && ((cnt & CEN_SPECIFIC) == 0 || (cnt & XPG_SPECIFIC) == 0)
+       && ((cnt & XPG_CODESET) == 0 || (cnt & XPG_NORM_CODESET) == 0))
+      {
+       /* Iterate over all elements of the DIRLIST.  */
+       char *dir = NULL;
+
+       while ((dir = __argz_next ((char *) dirlist, dirlist_len, dir))
+              != NULL)
+         retval->successor[entries++]
+           = _nl_make_l10nflist (l10nfile_list, dir, strlen (dir) + 1, cnt,
+                                 language, territory, codeset,
+                                 normalized_codeset, modifier, special,
+                                 sponsor, revision, filename, 1);
+      }
+  retval->successor[entries] = NULL;
+
+  return retval;
+}
+\f
+/* Normalize codeset name.  There is no standard for the codeset
+   names.  Normalization allows the user to use any of the common
+   names.  */
+const char *
+_nl_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;
+}
diff --git a/intl/loadinfo.h b/intl/loadinfo.h
new file mode 100644 (file)
index 0000000..00aa1c9
--- /dev/null
@@ -0,0 +1,48 @@
+/* Encoding of locale name parts.  */
+#define CEN_REVISION           1
+#define CEN_SPONSOR            2
+#define CEN_SPECIAL            4
+#define XPG_NORM_CODESET       8
+#define XPG_CODESET            16
+#define TERRITORY              32
+#define CEN_AUDIENCE           64
+#define XPG_MODIFIER           128
+
+#define CEN_SPECIFIC   (CEN_REVISION|CEN_SPONSOR|CEN_SPECIAL|CEN_AUDIENCE)
+#define XPG_SPECIFIC   (XPG_CODESET|XPG_NORM_CODESET|XPG_MODIFIER)
+
+
+struct loaded_l10nfile
+{
+  const char *filename;
+  int decided;
+
+  const void *data;
+
+  struct loaded_l10nfile *next;
+  struct loaded_l10nfile *successor[1];
+};
+
+
+extern const char *_nl_normalize_codeset __P ((const char *codeset,
+                                              size_t name_len));
+
+extern struct loaded_l10nfile *
+_nl_make_l10nflist __P ((struct loaded_l10nfile **l10nfile_list,
+                        const char *dirlist, size_t dirlist_len, int mask,
+                        const char *language, const char *territory,
+                        const char *codeset, const char *normalized_codeset,
+                        const char *modifier, const char *special,
+                        const char *sponsor, const char *revision,
+                        const char *filename, int do_allocate));
+
+
+extern const char *_nl_expand_alias __P ((const char *name));
+
+extern int _nl_explode_name __P ((char *name, const char **language,
+                                 const char **modifier,
+                                 const char **territory,
+                                 const char **codeset,
+                                 const char **normalized_codeset,
+                                 const char **special, const char **sponsor,
+                                 const char **revision));
index 0f5bfd5b9d8fcc6527001940f93ad071e8147af0..1daf72a09fb3aac0c02d12851ee51da5f97d1812 100644 (file)
@@ -1,8 +1,6 @@
 /* loadmsgcat.c -- load needed message catalogs
-   Copyright (C) 1995 Software Foundation, Inc.
-
-This file is part of the GNU C Library.  Its master source is NOT part of
-the C library, however.  The master source lives in /gd/gnu/lib.
+Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+Written 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
@@ -16,8 +14,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>
@@ -65,8 +63,8 @@ int _nl_msg_cat_cntr;
 /* Load the message catalogs specified by FILENAME.  If it is no valid
    message catalog do nothing.  */
 void
-_nl_load_domain (domain)
-     struct loaded_domain *domain;
+_nl_load_domain (domain_file)
+     struct loaded_l10nfile *domain_file;
 {
   int fd;
   struct stat st;
@@ -75,19 +73,20 @@ _nl_load_domain (domain)
     || defined _LIBC
   int use_mmap = 0;
 #endif
+  struct loaded_domain *domain;
 
-  domain->decided = 1;
-  domain->data = NULL;
+  domain_file->decided = 1;
+  domain_file->data = NULL;
 
   /* If the record does not represent a valid locale the FILENAME
      might be NULL.  This can happen when according to the given
      specification the locale file name is different for XPG and CEN
      syntax.  */
-  if (domain->filename == NULL)
+  if (domain_file->filename == NULL)
     return;
 
   /* Try to open the addressed file.  */
-  fd = open (domain->filename, O_RDONLY);
+  fd = open (domain_file->filename, O_RDONLY);
   if (fd == -1)
     return;
 
@@ -160,6 +159,12 @@ _nl_load_domain (domain)
       return;
     }
 
+  domain_file->data
+    = (struct loaded_domain *) malloc (sizeof (struct loaded_domain *));
+  if (domain->data == NULL)
+    return;
+
+  domain = (struct loaded_domain *) domain_file->data;
   domain->data = (char *) data;
   domain->must_swap = data->magic != _MAGIC;
 
@@ -185,11 +190,12 @@ _nl_load_domain (domain)
       else
 #endif
        free (data);
-      domain->data = NULL;
+      free (domain);
+      domain_file->data = NULL;
       return;
     }
 
   /* Show that one domain is changed.  This might make some cached
-     translation invalid.  */
+     translations invalid.  */
   ++_nl_msg_cat_cntr;
 }
diff --git a/intl/locale.alias b/intl/locale.alias
new file mode 100644 (file)
index 0000000..cf1f6ee
--- /dev/null
@@ -0,0 +1,52 @@
+# Locale name alias data base
+# Copyright (C) 1996 Free Software Foundation, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+# The format of this file is the same as for the corresponding file of
+# the X Window System, which normally can be found in
+#      /usr/lib/X11/locale/locale.alias
+# A single line contains two fields: an alias and a substitution value.
+# All entries are case independent.
+
+# Note: This file is far from being complete.  If you have a value for
+# your own site which you think might be useful for others too, share it
+# with the rest of us.  Send it to bug-gnu-utils@prep.ai.mit.edu.
+
+czech          cz_CZ.ISO-8859-2
+danish          da_DK.ISO-8859-1
+dansk          da_DK.ISO-8859-1
+deutsch                de_DE.ISO-8859-1
+dutch          nl_NL.ISO-8859-1
+finnish         fi_FI.ISO-8859-1
+français       fr_FR.ISO-8859-1
+french         fr_FR.ISO-8859-1
+german         de_DE.ISO-8859-1
+greek           el_GR.ISO-8859-7
+hebrew          iw_IL.ISO-8859-8
+hungarian       hu_HU.ISO-8859-2
+icelandic       is_IS.ISO-8859-1
+italian         it_CH.ISO-8859-1
+japanese       ja_JP.EUC
+norwegian       no_NO.ISO-8859-1
+polish          pl_PL.ISO-8859-2
+portuguese      pt_PT.ISO-8859-1
+rumanian        ro_RO.ISO-8859-2
+russian         ru_SU.ISO-8859-5
+slovak          sk_SK.ISO-8859-2
+slovene         sl_CS.ISO-8859-2
+spanish         es_ES.ISO-8859-1
+swedish         sv_SE.ISO-8859-1
+turkish         tr_TR.ISO-8859-9
index 893e7bf3fe7b07f0d6826c332572b0f5623833ce..e68b6ceeffdce392b945917fc0f52863addd5428 100644 (file)
@@ -1,6 +1,6 @@
 /* This is part of the iostream/stdio library, providing -*- C -*- I/O.
    Define ANSI C stdio on top of C++ iostreams.
-   Copyright (C) 1991, 1994, 1995 Free Software Foundation, Inc.
+   Copyright (C) 1991, 1994, 1995, 1996 Free Software Foundation, Inc.
 
 This library is free software; you can redistribute it and/or
 modify it under the terms of the GNU Library General Public
@@ -166,6 +166,9 @@ extern int snprintf __P ((char *, size_t, __const char *, ...));
 extern int __snprintf __P ((char *, size_t, __const char *, ...));
 extern int vsnprintf __P ((char *, size_t, __const char *, _G_va_list));
 
+extern int asprintf __P ((char **, const char *, ...));
+extern int vasprintf __P ((char **, const char *, _G_va_list));
+
 /* Open a stream that writes into a malloc'd buffer that is expanded as
    necessary.  *BUFLOC and *SIZELOC are updated with the buffer's location
    and the number of characters written on fflush or fclose.  */
index ec467fc8aa10f1c3e1d134efc6679b05a8eee683..3b89e4fbe83cf1bb5b7c2094c6244c57113733bf 100644 (file)
@@ -21,6 +21,7 @@ Boston, MA 02111-1307, USA.  */
 
 const struct locale_data _nl_C_LC_COLLATE =
 {
+  _nl_C_name,
   NULL, 0, /* no file mapped */
   0,
 };
index 95ac31157060ed137897cc7b4a2919cb457e8b54..ea990da8affaa754f0517643eb14895c8ae5bc86 100644 (file)
@@ -896,6 +896,7 @@ const char _nl_C_LC_CTYPE_width[256] =
 
 const struct locale_data _nl_C_LC_CTYPE =
 {
+  _nl_C_name,
   NULL, 0, /* no file mapped */
   13,
   {
index b118c13f928fca8495bc975f2b5b2a994609beeb..c6ce5b758d60dd84399398aaa42b367afd977be2 100644 (file)
@@ -21,6 +21,7 @@ Boston, MA 02111-1307, USA.  */
 
 const struct locale_data _nl_C_LC_MESSAGES =
 {
+  _nl_C_name,
   NULL, 0, /* no file mapped */
   4,
   {
index befb42910667ef4657c639db366595fe2ddb693c..b661a57493b6ebf367b7e69adf0e9d2f63fe6e39 100644 (file)
@@ -21,6 +21,7 @@ Boston, MA 02111-1307, USA.  */
 
 const struct locale_data _nl_C_LC_MONETARY =
 {
+  _nl_C_name,
   NULL, 0, /* no file mapped */
   15,
   {
index feb20c81ceb9780c5d4f49d90abe78e813703ddd..6298f7000f362d4783ebdaa7275e4a598231860b 100644 (file)
@@ -21,6 +21,7 @@ Boston, MA 02111-1307, USA.  */
 
 const struct locale_data _nl_C_LC_NUMERIC =
 {
+  _nl_C_name,
   NULL, 0, /* no file mapped */
   3,
   {
index 4bab361cc235f3eacc285779ae876148b18ccec0..a595e6b251398af48aa9aaed8d43e5b021447081 100644 (file)
@@ -21,6 +21,7 @@ Boston, MA 02111-1307, USA.  */
 
 const struct locale_data _nl_C_LC_TIME =
 {
+  _nl_C_name,
   NULL, 0, /* no file mapped */
   45,
   {
index 7399eda735e14126b1cd30659eb66e41f828660f..6b208b71a6480cf7bee1b289c82e087c830e2ef7 100644 (file)
@@ -28,7 +28,7 @@ distribute    = localeinfo.h categories.def \
                  charmap-kw.gperf charmap-kw.h locfile-token.h \
                  locfile-kw.gperf locfile-kw.h linereader.h \
                  locales.h locfile.h stringtrans.h
-routines       = setlocale loadlocale localeconv nl_langinfo
+routines       = setlocale findlocale loadlocale localeconv nl_langinfo
 categories     = ctype messages monetary numeric time collate
 aux            = $(categories:%=lc-%) $(categories:%=C-%) SYS_libc
 others         = localedef locale
diff --git a/locale/findlocale.c b/locale/findlocale.c
new file mode 100644 (file)
index 0000000..35b1971
--- /dev/null
@@ -0,0 +1,192 @@
+/* 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.  */
+
+#include <locale.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "localeinfo.h"
+
+
+/* Constant data defined in setlocale.c.  */
+extern const struct locale_data *const _nl_C[];
+
+
+static inline char *
+copy (const char *string)
+{
+  size_t len;
+  char *new;
+  len = strlen (string) + 1;
+  new = (char *) malloc (len);
+  return new != NULL ? memcpy (new, string, len) : NULL;
+}
+
+
+/* For each category we keep a list of records for the locale files
+   which are somehow addressed.  */
+static struct loaded_l10nfile *locale_file_list[LC_ALL];
+
+
+const struct locale_data *
+_nl_find_locale (const char *locale_path, size_t locale_path_len,
+                int category, char **name)
+{
+  int mask;
+  /* Name of the locale for this category.  */
+  char *loc_name;
+  const char *language;
+  const char *modifier;
+  const char *territory;
+  const char *codeset;
+  const char *normalized_codeset;
+  const char *special;
+  const char *sponsor;
+  const char *revision;
+  struct loaded_l10nfile *locale_file;
+
+  if ((*name)[0] == '\0')
+    {
+      /* The user decides which locale to use by setting environment
+        variables.  */
+      *name = getenv ("LC_ALL");
+      if (*name == NULL || (*name)[0] == '\0')
+       *name = getenv (_nl_category_names[category]);
+      if (*name == NULL || (*name)[0] == '\0')
+       *name = getenv ("LANG");
+      if (*name == NULL || (*name)[0] == '\0')
+       *name = (char *) _nl_C_name;
+    }
+
+  if (strcmp (*name, _nl_C_name) == 0 || strcmp (*name, "POSIX") == 0)
+    {
+      /* We need not load anything.  The needed data is contained in
+        the library itself.  */
+      *name = (char *) _nl_C_name;
+      return _nl_C[category];
+    }
+
+  /* We really have to load some data.  First see whether the name is
+     an alias.  Please note that this makes it impossible to have "C"
+     or "POSIX" as aliases.  */
+  loc_name = _nl_expand_alias (*name);
+  if (loc_name == NULL)
+    /* It is no alias.  */
+    loc_name = *name;
+
+  /* Make a writable copy of the locale name.  */
+  loc_name = copy (loc_name);
+
+  /* LOCALE can consist of up to four recognized parts for the XPG syntax:
+
+               language[_territory[.codeset]][@modifier]
+
+     and six parts for the CEN syntax:
+
+       language[_territory][+audience][+special][,sponsor][_revision]
+
+     Beside the first all of them are allowed to be missing.  If the
+     full specified locale is not found, the less specific one are
+     looked for.  The various part will be stripped of according to
+     the following order:
+               (1) revision
+               (2) sponsor
+               (3) special
+               (4) codeset
+               (5) normalized codeset
+               (6) territory
+               (7) audience/modifier
+   */
+  mask = _nl_explode_name (loc_name, &language, &modifier, &territory,
+                          &codeset, &normalized_codeset, &special,
+                          &sponsor, &revision);
+
+  /* If exactly this locale was already asked for we have an entry with
+     the complete name.  */
+  locale_file = _nl_make_l10nflist (&locale_file_list[category],
+                                   locale_path, locale_path_len, mask,
+                                   language, territory, codeset,
+                                   normalized_codeset, modifier, special,
+                                   sponsor, revision,
+                                   _nl_category_names[category], 0);
+
+  if (locale_file == NULL)
+    {
+      /* Find status record for addressed locale file.  We have to search
+        through all directories in the locale path.  */
+      locale_file = _nl_make_l10nflist (&locale_file_list[category],
+                                       locale_path, locale_path_len, mask,
+                                       language, territory, codeset,
+                                       normalized_codeset, modifier, special,
+                                       sponsor, revision,
+                                       _nl_category_names[category], 1);
+      if (locale_file == NULL)
+       /* This means we are out of core.  */
+       return NULL;
+    }
+  else
+    /* If the addressed locale is already available it should be freed.
+       If we would not do this switching back and force between two
+       locales would slowly eat up all memory.*/
+    free (loc_name);
+
+  if (locale_file->decided == 0)
+    _nl_load_locale (locale_file, category);
+
+  if (locale_file->data == NULL)
+    {
+      int cnt;
+      for (cnt = 0; locale_file->successor[cnt] != NULL; ++cnt)
+       {
+         if (locale_file->successor[cnt]->decided == 0)
+           _nl_load_locale (locale_file->successor[cnt], category);
+         if (locale_file->successor[cnt]->data != NULL)
+           break;
+       }
+      /* Move the entry we found (or NULL) to the first place of
+        successors.  */
+      locale_file->successor[0] = locale_file->successor[cnt];
+      locale_file = locale_file->successor[cnt];
+    }
+
+  if (locale_file == NULL)
+    return NULL;
+
+  /* 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.  */
+  if (((struct locale_data *) locale_file->data)->name == NULL)
+    {
+      char *newp, *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;
+    }
+  *name = (char *) ((struct locale_data *) locale_file->data)->name;
+
+  return (struct locale_data *) locale_file->data;
+}
index 911477b6bd47c4366864e61e7f9eef830423e79f..23643b29c82c4446b928cc33b82a2ee892f876d3 100644 (file)
@@ -22,8 +22,8 @@ Boston, MA 02111-1307, USA.  */
 
 _NL_CURRENT_DEFINE (LC_COLLATE);
 
-const u32_t *__collate_table;
-const u32_t *__collate_extra;
+const u_int32_t *__collate_table;
+const u_int32_t *__collate_extra;
 
 
 void
index 68f9c7a48dfa63bde5f20689f92766f666ded24d..93b9e955931284a787ba3552d6c91595304ae61b 100644 (file)
@@ -1,6 +1,6 @@
-/* Functions to read locale data files.
-Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+/* 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
@@ -14,20 +14,21 @@ 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.  */
 
 #include <errno.h>
 #include <fcntl.h>
-#include <unistd.h>
 #include <stdlib.h>
 #include <string.h>
-#include <stdio.h>
-#include <sys/stat.h>
+#include <unistd.h>
 #include <sys/mman.h>
+#include <sys/stat.h>
+
 #include "localeinfo.h"
 
-const size_t _nl_category_num_items[] =
+
+static const size_t _nl_category_num_items[] =
 {
 #define DEFINE_CATEGORY(category, category_name, items, a, b, c, d) \
   [category] = _NL_ITEM_INDEX (_NL_NUM_##category),
@@ -54,8 +55,8 @@ static const enum value_type *_nl_value_types[] =
 };
 
 
-struct locale_data *
-_nl_load_locale (int category, char **name)
+void
+_nl_load_locale (struct loaded_l10nfile *file, int category)
 {
   int fd;
   struct
@@ -66,7 +67,9 @@ _nl_load_locale (int category, char **name)
     } *filedata;
   struct stat st;
   struct locale_data *newdata;
+  int save_err;
   int swap = 0;
+  size_t cnt;
   inline unsigned int SWAP (const unsigned int *inw)
     {
       const unsigned char *inc = (const unsigned char *) inw;
@@ -74,98 +77,86 @@ _nl_load_locale (int category, char **name)
        return *inw;
       return (inc[3] << 24) | (inc[2] << 16) | (inc[1] << 8) | inc[0];
     }
-  unsigned int i;
 
-  if ((*name)[0] == '\0')
+  file->decided = 1;
+  file->data = NULL;
+
+  fd = __open (file->filename, O_RDONLY);
+  if (fd < 0)
+    /* Cannot open the file.  */
+    return;
+
+  if (__fstat (fd, &st) < 0)
+    goto puntfd;
+  if (S_ISDIR (st.st_mode))
     {
-      *name = getenv ("LC_ALL");
-      if (! *name || (*name)[0] == '\0')
-       *name = getenv (_nl_category_names[category]);
-      if (! *name || (*name)[0] == '\0')
-       *name = getenv ("LANG");
-      if (! *name || (*name)[0] == '\0')
-       *name = (char *) "local";
+      /* LOCALE/LC_foo is a directory; open LOCALE/LC_foo/SYS_LC_foo
+           instead.  */
+      char *newp;
+      
+      __close (fd);
+
+      newp = (char *) alloca (strlen (file->filename)
+                             + 5 + _nl_category_name_sizes[category] + 1);
+      __stpcpy (__stpcpy (__stpcpy (newp, file->filename), "/SYS_"),
+               _nl_category_names[category]);
+
+      fd = __open (newp, O_RDONLY);
+      if (fd < 0)
+       return;
+
+      if (__fstat (fd, &st) < 0)
+       goto puntfd;
     }
 
-  {
-    const char *catname = _nl_category_names[category];
-    size_t namelen = strlen (*name);
-    size_t catlen = strlen (catname);
-    char file[sizeof LOCALE_PATH + 1 + namelen + catlen * 2 + 4];
-    if (strchr (*name, '/') != NULL)
-      sprintf (file, "%s/%s", *name, catname);
-    else
-      sprintf (file, "%s/%s/%s", LOCALE_PATH, *name, catname);
-    fd = __open (file, O_RDONLY);
-    if (fd < 0)
-      return NULL;
-    if (__fstat (fd, &st) < 0)
-      goto puntfd;
-    if (S_ISDIR (st.st_mode))
-      {
-       /* LOCALE/LC_foo is a directory; open LOCALE/LC_foo/SYS_LC_foo
-           instead.  */
-       __close (fd);
-       memcpy (stpcpy (strchr (file, '\0'), "SYS_"), catname, catlen);
-       fd = __open (file, O_RDONLY);
-       if (fd < 0)
-         return NULL;
-       if (__fstat (fd, &st) < 0)
-         goto puntfd;
-      }
-  }
-
-  {
-    /* Map in the file's data.  */
-    int save = errno;
+  /* Map in the file's data.  */
+  save_err = errno;
 #ifndef MAP_COPY
-    /* Linux seems to lack read-only copy-on-write.  */
+  /* Linux seems to lack read-only copy-on-write.  */
 #define MAP_COPY MAP_PRIVATE
 #endif
 #ifndef        MAP_FILE
-    /* Some systems do not have this flag; it is superfluous.  */
+  /* Some systems do not have this flag; it is superfluous.  */
 #define        MAP_FILE 0
 #endif
 #ifndef MAP_INHERIT
-    /* Some systems might lack this; they lose.  */
+  /* Some systems might lack this; they lose.  */
 #define MAP_INHERIT 0
 #endif
-    filedata = (void *) __mmap ((caddr_t) 0, st.st_size,
-                               PROT_READ, MAP_FILE|MAP_COPY|MAP_INHERIT,
-                               fd, 0);
-    if (filedata == (void *) -1)
-      {
-       if (errno == ENOSYS)
-         {
-           /* No mmap; allocate a buffer and read from the file.  */
-           filedata = malloc (st.st_size);
-           if (filedata)
-             {
-               off_t to_read = st.st_size;
-               ssize_t nread;
-               char *p = (char *) filedata;
-               while (to_read > 0)
-                 {
-                   nread = __read (fd, p, to_read);
-                   if (nread <= 0)
-                     {
-                       free (filedata);
-                       if (nread == 0)
-                         errno = EINVAL; /* Bizarreness going on.  */
-                       goto puntfd;
-                     }
-                   p += nread;
-                   to_read -= nread;
-                 }
-             }
-           else
-             goto puntfd;
-           errno = save;
-         }
-       else
-         goto puntfd;
-      }
-  }
+  filedata = (void *) __mmap ((caddr_t) 0, st.st_size, PROT_READ,
+                             MAP_FILE|MAP_COPY|MAP_INHERIT, fd, 0);
+  if (filedata == (void *) -1)
+    {
+      if (errno == ENOSYS)
+       {
+         /* No mmap; allocate a buffer and read from the file.  */
+         filedata = malloc (st.st_size);
+         if (filedata != NULL)
+           {
+             off_t to_read = st.st_size;
+             ssize_t nread;
+             char *p = (char *) filedata;
+             while (to_read > 0)
+               {
+                 nread = __read (fd, p, to_read);
+                 if (nread <= 0)
+                   {
+                     free (filedata);
+                     if (nread == 0)
+                       errno = EINVAL; /* Bizarreness going on.  */
+                     goto puntfd;
+                   }
+                 p += nread;
+                 to_read -= nread;
+               }
+           }
+         else
+           goto puntfd;
+         errno = save_err;
+       }
+      else
+       goto puntfd;
+    }
 
   if (filedata->magic == LIMAGIC (category))
     /* Good data file in our byte order.  */
@@ -181,7 +172,7 @@ _nl_load_locale (int category, char **name)
          __munmap ((caddr_t) filedata, st.st_size);
        puntfd:
          __close (fd);
-         return NULL;
+         return;
        }
     }
 
@@ -201,41 +192,46 @@ _nl_load_locale (int category, char **name)
   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);
-  for (i = 0; i < newdata->nstrings; ++i)
+  for (cnt = 0; cnt < newdata->nstrings; ++cnt)
     {
-      unsigned int idx = W (filedata->strindex[i]);
+      off_t idx = W (filedata->strindex[cnt]);
       if (idx >= newdata->filesize)
        {
          free (newdata);
          errno = EINVAL;
          goto puntmap;
        }
-      if (_nl_value_types[category][i] == word)
-       newdata->values[i].word = W (*((u32_t *) (newdata->filedata + idx)));
+      if (_nl_value_types[category][cnt] == word)
+       newdata->values[cnt].word = W (*((u_int32_t *) (newdata->filedata
+                                                       + idx)));
       else
-       newdata->values[i].string = newdata->filedata + idx;
+       newdata->values[cnt].string = newdata->filedata + idx;
     }
 
   __close (fd);
-  return newdata;
+  file->data = newdata;
 }
 \f
 void
-_nl_free_locale (struct locale_data *data)
+_nl_free_locale (const struct locale_data *data)
 {
   int save = errno;
-  if (! data)
+  if (data == NULL)
     /* Ignore a null pointer, like free does.  */
     return;
+  if (data->name != NULL)
+    free ((void *) data->name);
   if (__munmap ((caddr_t) data->filedata, data->filesize) < 0)
     {
       if (errno == ENOSYS)
        free ((void *) data->filedata);
       errno = save;
     }
-  free (data);
+  free ((void *) data);
 }
 
+
index a3049a51dd817f96ffb8c059c292da211146f97b..ac14626dc0f3badef974e8e0a331282a733b34bc 100644 (file)
@@ -24,17 +24,20 @@ Cambridge, MA 02139, USA.  */
 #include <langinfo.h>
 #include <sys/types.h>
 
+#include "../intl/loadinfo.h"  /* For loaded_l10nfile definition.  */
+
 /* Magic number at the beginning of a locale data file for CATEGORY.  */
 #define        LIMAGIC(category)       (0x960316de ^ (category))
 
 /* Two special weight constants for the collation data.  */
-#define FORWARD_CHAR 0xfffffffd
-#define ELLIPSIS_CHAR 0xfffffffe
-#define IGNORE_CHAR 0xffffffff
+#define FORWARD_CHAR ((wchar_t) 0xfffffffd)
+#define ELLIPSIS_CHAR ((wchar_t) 0xfffffffe)
+#define IGNORE_CHAR ((wchar_t) 0xffffffff)
 
 /* Structure describing locale data in core for a category.  */
 struct locale_data
 {
+  const char *name;
   const char *filedata;                /* Region mapping the file data.  */
   off_t filesize;              /* Size of the file (and the region).  */
 
@@ -78,9 +81,13 @@ extern const struct locale_data *_nl_current_##category;
 #include "categories.def"
 #undef DEFINE_CATEGORY
 
-extern const char *const _nl_category_names[LC_ALL];
+extern const char *const _nl_category_names[LC_ALL + 1];
+extern const size_t _nl_category_name_sizes[LC_ALL + 1];
 extern const struct locale_data * *const _nl_current[LC_ALL];
 
+/* Name of the standard locale.  */
+extern const char _nl_C_name[];
+
 /* Extract the current CATEGORY locale's string for ITEM.  */
 #define _NL_CURRENT(category, item) \
   (_nl_current_##category->values[_NL_ITEM_INDEX (item)].string)
@@ -96,18 +103,21 @@ extern const struct locale_data * *const _nl_current[LC_ALL];
 
 /* Load the locale data for CATEGORY from the file specified by *NAME.
    If *NAME is "", use environment variables as specified by POSIX,
-   and fill in *NAME with the actual name used.  */
-extern struct locale_data *_nl_load_locale (int category, char **name);
+   and fill in *NAME with the actual name used.  The directories
+   listed in LOCALE_PATH are searched for the locale files.  */
+extern const struct locale_data *_nl_find_locale (const char *locale_path,
+                                                 size_t locale_path_len,
+                                                 int category, char **name);
 
-/* Free the locale data read in by a `_nl_load_locale' call.  */
-extern void _nl_free_locale (struct locale_data *);
+/* Try to load the file described by FILE.  */
+extern void _nl_load_locale (struct loaded_l10nfile *file, int category);
 
+/* Free the locale data read in by a `_nl_load_locale' call.  */
+extern void _nl_free_locale (const struct locale_data *);
 
-/* XXX For now.  */
-typedef unsigned int u32_t;
 
 /* Global variables for LC_COLLATE category data.  */
-extern const u32_t *__collate_table;
-extern const u32_t *__collate_extra;
+extern const u_int32_t *__collate_table;
+extern const u_int32_t *__collate_extra;
 
 #endif /* localeinfo.h */
index 1e8819c66203834fa68e3a2f8612da4ebea511f6..2885bf1d1a62b84580d3c6876de439bc5572057e 100644 (file)
@@ -53,7 +53,7 @@ struct charset_t
 /* We need one value to mark the error case.  Let's use 0xffffffff.
    I.e., it is placed in the last page of ISO 10646.  For now only the
    first is used and we have plenty of room.  */
-#define ILLEGAL_CHAR_VALUE 0xffffffffu
+#define ILLEGAL_CHAR_VALUE ((wchar_t) 0xffffffffu)
 
 
 /* Prototypes for charmap handling functions.  */
index 4aa406d755e771f2124146222b47bd630f814d47..6c67813f93a6030c3271d9577e0d84ed44f0000c 100644 (file)
@@ -24,7 +24,6 @@
 
 
 typedef int wint_t;
-typedef unsigned short int u16_t;
 
 
 #include_next <config.h>
index 598b963fc0e57d3e6793bc982e109f12f68925b0..6643ae85c85467480e8ccf90a09c40d9a787d8c0 100644 (file)
@@ -253,7 +253,7 @@ collate_finish (struct localedef_t *locale, struct charset_t *charset)
       |* XXX We should test whether really an unspecified character *|
       |* exists before giving the message.                         *|
       \**************************************************************/
-      u32_t weight;
+      u_int32_t weight;
 
       error (0, 0, _("no definition of `UNDEFINED'"));
 
@@ -262,7 +262,7 @@ collate_finish (struct localedef_t *locale, struct charset_t *charset)
 
       for (cnt = 0; cnt < collate->nrules; ++cnt)
        {
-         u32_t one = 1;
+         u_int32_t one = 1;
          obstack_grow (&collate->element_mem, &one, sizeof (one));
        }
 
@@ -286,7 +286,7 @@ void
 collate_output (struct localedef_t *locale, const char *output_path)
 {
   struct locale_collate_t *collate = locale->categories[LC_COLLATE].collate;
-  u32_t table_size, table_best, level_best, sum_best;
+  u_int32_t table_size, table_best, level_best, sum_best;
   void *last;
   element_t *pelem;
   wchar_t *name;
@@ -294,11 +294,11 @@ collate_output (struct localedef_t *locale, const char *output_path)
   const size_t nelems = _NL_ITEM_INDEX (_NL_NUM_LC_COLLATE);
   struct iovec iov[2 + nelems];
   struct locale_file data;
-  u32_t idx[nelems];
+  u_int32_t idx[nelems];
   struct obstack non_simple;
   size_t cnt, entry_size;
-  u32_t undefined_offset = UINT_MAX;
-  u32_t *table, *extra, *table2, *extra2;
+  u_int32_t undefined_offset = UINT_MAX;
+  u_int32_t *table, *extra, *table2, *extra2;
   size_t extra_len;
 
   sum_best = UINT_MAX;
@@ -352,12 +352,12 @@ Computing table size for collation information might take a while..."),
   iov[1].iov_len = sizeof (idx);
 
   iov[2 + _NL_ITEM_INDEX (_NL_COLLATE_NRULES)].iov_base = &collate->nrules;
-  iov[2 + _NL_ITEM_INDEX (_NL_COLLATE_NRULES)].iov_len = sizeof (u32_t);
+  iov[2 + _NL_ITEM_INDEX (_NL_COLLATE_NRULES)].iov_len = sizeof (u_int32_t);
 
-  table = (u32_t *) alloca (collate->nrules * sizeof (u32_t));
+  table = (u_int32_t *) alloca (collate->nrules * sizeof (u_int32_t));
   iov[2 + _NL_ITEM_INDEX (_NL_COLLATE_RULES)].iov_base = table;
   iov[2 + _NL_ITEM_INDEX (_NL_COLLATE_RULES)].iov_len
-    = collate->nrules * sizeof (u32_t);
+    = collate->nrules * sizeof (u_int32_t);
   /* Another trick here.  Describing the collation method needs only a
      few bits (3, to be exact).  But the binary file should be
      accessible by maschines with both endianesses and so we store both
@@ -366,15 +366,16 @@ Computing table size for collation information might take a while..."),
     table[cnt] = collate->rules[cnt] | SWAPU32 (collate->rules[cnt]);
 
   iov[2 + _NL_ITEM_INDEX (_NL_COLLATE_HASH_SIZE)].iov_base = &table_best;
-  iov[2 + _NL_ITEM_INDEX (_NL_COLLATE_HASH_SIZE)].iov_len = sizeof (u32_t);
+  iov[2 + _NL_ITEM_INDEX (_NL_COLLATE_HASH_SIZE)].iov_len = sizeof (u_int32_t);
 
   iov[2 + _NL_ITEM_INDEX (_NL_COLLATE_HASH_LAYERS)].iov_base = &level_best;
-  iov[2 + _NL_ITEM_INDEX (_NL_COLLATE_HASH_LAYERS)].iov_len = sizeof (u32_t);
+  iov[2 + _NL_ITEM_INDEX (_NL_COLLATE_HASH_LAYERS)].iov_len
+    = sizeof (u_int32_t);
 
   entry_size = 1 + MAX (collate->nrules, 2);
 
-  table = (u32_t *) alloca (table_best * level_best * entry_size
-                           * sizeof (table[0]));
+  table = (u_int32_t *) alloca (table_best * level_best * entry_size
+                               * sizeof (table[0]));
   memset (table, '\0', table_best * level_best * entry_size
          * sizeof (table[0]));
 
@@ -382,7 +383,7 @@ Computing table size for collation information might take a while..."),
   /* Macros for inserting in output table.  */
 #define ADD_VALUE(expr)                                                              \
   do {                                                                       \
-    u32_t to_write = (u32_t) expr;                                           \
+    u_int32_t to_write = (u_int32_t) expr;                                   \
     obstack_grow (&non_simple, &to_write, sizeof (to_write));                \
   } while (0)
 
@@ -393,7 +394,7 @@ Computing table size for collation information might take a while..."),
     ADD_VALUE (len);                                                         \
                                                                              \
     wlen = wcslen (pelem->name);                                             \
-    obstack_grow (&non_simple, pelem->name, (wlen + 1) * sizeof (u32_t));     \
+    obstack_grow (&non_simple, pelem->name, (wlen + 1) * sizeof (u_int32_t)); \
                                                                              \
     idx = collate->nrules;                                                   \
     for (cnt = 0; cnt < collate->nrules; ++cnt)                                      \
@@ -417,14 +418,14 @@ Computing table size for collation information might take a while..."),
     table[(level * table_best + slot) * entry_size + 1]                              \
       = FORWARD_CHAR;                                                        \
     table[(level * table_best + slot) * entry_size + 2]                              \
-      = obstack_object_size (&non_simple) / sizeof (u32_t);                  \
+      = obstack_object_size (&non_simple) / sizeof (u_int32_t);                      \
                                                                              \
     /* Here we have to construct the non-simple table entry.  First          \
        compute the total length of this entry.  */                           \
     for (runp = (pelem); runp != NULL; runp = runp->next)                    \
       if (runp->ordering != NULL)                                            \
        {                                                                     \
-         u32_t value;                                                        \
+         u_int32_t value;                                                    \
          size_t cnt;                                                         \
                                                                              \
          value = 1 + wcslen (runp->name) + 1;                                \
@@ -513,7 +514,7 @@ Computing table size for collation information might take a while..."),
       {
        /* We have to fill in the information from the UNDEFINED
           entry.  */
-       table[cnt * entry_size] = (u32_t) cnt;
+       table[cnt * entry_size] = (u_int32_t) cnt;
 
        if (collate->undefined.ordering_len == collate->nrules)
          {
@@ -593,18 +594,18 @@ Computing table size for collation information might take a while..."),
 
   /* Finish the extra block.  */
   extra_len = obstack_object_size (&non_simple);
-  extra = (u32_t *) obstack_finish (&non_simple);
-  assert ((extra_len % sizeof (u32_t)) == 0);
+  extra = (u_int32_t *) obstack_finish (&non_simple);
+  assert ((extra_len % sizeof (u_int32_t)) == 0);
 
   /* Now we have to build the two array for the other byte ordering.  */
-  table2 = (u32_t *) alloca (table_best * level_best * entry_size
-                            * sizeof (table[0]));
-  extra2 = (u32_t *) alloca (extra_len);
+  table2 = (u_int32_t *) alloca (table_best * level_best * entry_size
+                                * sizeof (table[0]));
+  extra2 = (u_int32_t *) alloca (extra_len);
 
   for (cnt = 0; cnt < table_best * level_best * entry_size; ++cnt)
     table2[cnt] = SWAPU32 (table[cnt]);
 
-  for (cnt = 0; cnt < extra_len / sizeof (u32_t); ++cnt)
+  for (cnt = 0; cnt < extra_len / sizeof (u_int32_t); ++cnt)
     extra2[cnt] = SWAPU32 (extra2[cnt]);
 
   /* Store table adresses and lengths.   */
@@ -639,7 +640,7 @@ Computing table size for collation information might take a while..."),
 #endif
 
   iov[2 + _NL_ITEM_INDEX (_NL_COLLATE_UNDEFINED)].iov_base = &undefined_offset;
-  iov[2 + _NL_ITEM_INDEX (_NL_COLLATE_UNDEFINED)].iov_len = sizeof (u32_t);
+  iov[2 + _NL_ITEM_INDEX (_NL_COLLATE_UNDEFINED)].iov_len = sizeof (u_int32_t);
 
   /* Update idx array.  */
   idx[0] = iov[0].iov_len + iov[1].iov_len;
index 99e9ebe3fa4f781ef17a4cc44b9c268aeb672a51..79e01ba69b768808a8823070795a5cebe13dfe8a 100644 (file)
@@ -59,9 +59,9 @@ void *xrealloc (void *__ptr, size_t __n);
 /* To be compatible with former implementations we for now restrict
    the number of bits for character classes to 16.  When compatibility
    is not necessary anymore increase the number to 32.  */
-#define char_class_t u16_t
+#define char_class_t u_int16_t
 #define CHAR_CLASS_TRANS SWAPU16
-#define char_class32_t u32_t
+#define char_class32_t u_int32_t
 #define CHAR_CLASS32_TRANS SWAPU32
 
 
@@ -72,13 +72,13 @@ struct locale_ctype_t
   size_t charnames_max;
   size_t charnames_act;
 
-  /* We will allow up to 8 * sizeof(u32_t) - 1 character classes.  */
-#define MAX_NR_CHARCLASS (8 * sizeof (u32_t) - 1)
+  /* We will allow up to 8 * sizeof(u_int32_t) - 1 character classes.  */
+#define MAX_NR_CHARCLASS (8 * sizeof (u_int32_t) - 1)
   int nr_charclass;
   const char *classnames[MAX_NR_CHARCLASS];
   unsigned long int current_class_mask;
   unsigned int last_class_char;
-  u32_t *class_collection;
+  u_int32_t *class_collection;
   size_t class_collection_max;
   size_t class_collection_act;
   unsigned long int class_done;
@@ -87,7 +87,7 @@ struct locale_ctype_t
      increase it.  But I doubt it will.  --drepper@gnu */
 #define MAX_NR_CHARMAP 16
   const char *mapnames[MAX_NR_CHARMAP];
-  u32_t *map_collection[MAX_NR_CHARMAP];
+  u_int32_t *map_collection[MAX_NR_CHARMAP];
   unsigned int map_collection_max[MAX_NR_CHARMAP];
   unsigned int map_collection_act[MAX_NR_CHARMAP];
   size_t map_collection_nr;
@@ -97,16 +97,16 @@ struct locale_ctype_t
   int tolower_done;
 
   /* The arrays for the binary representation.  */
-  u32_t plane_size;
-  u32_t plane_cnt;
+  u_int32_t plane_size;
+  u_int32_t plane_cnt;
   char_class_t *ctype_b;
   char_class32_t *ctype32_b;
-  u32_t *names_el;
-  u32_t *names_eb;
-  u32_t **map_eb;
-  u32_t **map_el;
-  u32_t *class_name_ptr;
-  u32_t *map_name_ptr;
+  u_int32_t *names_el;
+  u_int32_t *names_eb;
+  u_int32_t **map_eb;
+  u_int32_t **map_el;
+  u_int32_t *class_name_ptr;
+  u_int32_t *map_name_ptr;
   unsigned char *width;
 };
 
@@ -117,8 +117,8 @@ static void ctype_class_newP (struct linereader *lr,
 static void ctype_map_newP (struct linereader *lr,
                            struct locale_ctype_t *ctype,
                            const char *name, struct charset_t *charset);
-static u32_t *find_idx (struct locale_ctype_t *ctype, u32_t **table,
-                       size_t *max, size_t *act, unsigned int idx);
+static u_int32_t *find_idx (struct locale_ctype_t *ctype, u_int32_t **table,
+                           size_t *max, size_t *act, unsigned int idx);
 static void set_class_defaults (struct locale_ctype_t *ctype,
                                struct charset_t *charset);
 static void allocate_arrays (struct locale_ctype_t *ctype,
@@ -167,8 +167,9 @@ ctype_startup (struct linereader *lr, struct localedef_t *locale,
   ctype_class_newP (lr, ctype, "alnum");
 
   ctype->class_collection_max = charset->mb_cur_max == 1 ? 256 : 512;
-  ctype->class_collection = (u32_t *) xmalloc (sizeof (unsigned long int)
-                                              * ctype->class_collection_max);
+  ctype->class_collection
+    = (u_int32_t *) xmalloc (sizeof (unsigned long int)
+                            * ctype->class_collection_max);
   memset (ctype->class_collection, '\0',
          sizeof (unsigned long int) * ctype->class_collection_max);
   ctype->class_collection_act = 256;
@@ -348,7 +349,7 @@ ctype_output (struct localedef_t *locale, struct charset_t *charset,
   struct iovec iov[2 + nelems + ctype->nr_charclass
                  + ctype->map_collection_nr];
   struct locale_file data;
-  u32_t idx[nelems];
+  u_int32_t idx[nelems];
   size_t elem, cnt, offset, total;
 
 
@@ -397,20 +398,20 @@ ctype_output (struct localedef_t *locale, struct charset_t *charset,
          CTYPE_DATA (_NL_CTYPE_TOUPPER_EB,
                      ctype->map_eb[0],
                      (ctype->plane_size * ctype->plane_cnt + 128)
-                     * sizeof (u32_t));
+                     * sizeof (u_int32_t));
          CTYPE_DATA (_NL_CTYPE_TOLOWER_EB,
                      ctype->map_eb[1],
                      (ctype->plane_size * ctype->plane_cnt + 128)
-                     * sizeof (u32_t));
+                     * sizeof (u_int32_t));
 
          CTYPE_DATA (_NL_CTYPE_TOUPPER_EL,
                      ctype->map_el[0],
                      (ctype->plane_size * ctype->plane_cnt + 128)
-                     * sizeof (u32_t));
+                     * sizeof (u_int32_t));
          CTYPE_DATA (_NL_CTYPE_TOLOWER_EL,
                      ctype->map_el[1],
                      (ctype->plane_size * ctype->plane_cnt + 128)
-                     * sizeof (u32_t));
+                     * sizeof (u_int32_t));
 
          CTYPE_DATA (_NL_CTYPE_CLASS32,
                      ctype->ctype32_b,
@@ -418,16 +419,16 @@ ctype_output (struct localedef_t *locale, struct charset_t *charset,
                       * sizeof (char_class32_t)));
 
          CTYPE_DATA (_NL_CTYPE_NAMES_EB,
-                     ctype->names_eb,
-                     ctype->plane_size * ctype->plane_cnt * sizeof (u32_t));
+                     ctype->names_eb, (ctype->plane_size * ctype->plane_cnt
+                                       * sizeof (u_int32_t)));
          CTYPE_DATA (_NL_CTYPE_NAMES_EL,
-                     ctype->names_el,
-                     ctype->plane_size * ctype->plane_cnt * sizeof (u32_t));
+                     ctype->names_el, (ctype->plane_size * ctype->plane_cnt
+                                       * sizeof (u_int32_t)));
 
          CTYPE_DATA (_NL_CTYPE_HASH_SIZE,
-                     &ctype->plane_size, sizeof (u32_t));
+                     &ctype->plane_size, sizeof (u_int32_t));
          CTYPE_DATA (_NL_CTYPE_HASH_LAYERS,
-                     &ctype->plane_cnt, sizeof (u32_t));
+                     &ctype->plane_cnt, sizeof (u_int32_t));
 
          case _NL_ITEM_INDEX (_NL_CTYPE_CLASS_NAMES):
            /* The class name array.  */
@@ -485,7 +486,7 @@ ctype_output (struct localedef_t *locale, struct charset_t *charset,
 
          iov[2 + elem + offset].iov_len = ((ctype->plane_size
                                             * ctype->plane_cnt + 128)
-                                           * sizeof (u32_t));
+                                           * sizeof (u_int32_t));
 
          if (elem + 1 < nelems)
            idx[elem + 1] = idx[elem] + iov[2 + elem + offset].iov_len;
@@ -825,10 +826,10 @@ implementation limit: no more than %d character maps allowed"),
   else
     ctype->map_collection_max[cnt] = max_chars;
 
-  ctype->map_collection[cnt] =
-    (u32_t *) xmalloc (sizeof (u32_t) * ctype->map_collection_max[cnt]);
+  ctype->map_collection[cnt] = (u_int32_t *)
+    xmalloc (sizeof (u_int32_t) * ctype->map_collection_max[cnt]);
   memset (ctype->map_collection[cnt], '\0',
-         sizeof (u32_t) * ctype->map_collection_max[cnt]);
+         sizeof (u_int32_t) * ctype->map_collection_max[cnt]);
   ctype->map_collection_act[cnt] = 256;
 
   ++ctype->map_collection_nr;
@@ -837,8 +838,8 @@ implementation limit: no more than %d character maps allowed"),
 
 /* We have to be prepared that TABLE, MAX, and ACT can be NULL.  This
    is possible if we only want ot extend the name array.  */
-static u32_t *
-find_idx (struct locale_ctype_t *ctype, u32_t **table, size_t *max,
+static u_int32_t *
+find_idx (struct locale_ctype_t *ctype, u_int32_t **table, size_t *max,
          size_t *act, unsigned int idx)
 {
   size_t cnt;
@@ -878,8 +879,9 @@ find_idx (struct locale_ctype_t *ctype, u32_t **table, size_t *max,
          while (*max <= cnt);
 
          *table =
-           (u32_t *) xrealloc (*table, *max * sizeof (unsigned long int));
-         memset (&(*table)[old_max], '\0', (*max - old_max) * sizeof (u32_t));
+           (u_int32_t *) xrealloc (*table, *max * sizeof (unsigned long int));
+         memset (&(*table)[old_max], '\0',
+                 (*max - old_max) * sizeof (u_int32_t));
        }
 
       (*table)[cnt] = 0;
@@ -1219,10 +1221,12 @@ Computing table size for character classes might take a while..."),
 # define NAMES_B2 ctype->names_el
 #endif
 
-  ctype->names_eb = (u32_t *) xcalloc (ctype->plane_size * ctype->plane_cnt,
-                                      sizeof (u32_t));
-  ctype->names_el = (u32_t *) xcalloc (ctype->plane_size * ctype->plane_cnt,
-                                      sizeof (u32_t));
+  ctype->names_eb = (u_int32_t *) xcalloc (ctype->plane_size
+                                          * ctype->plane_cnt,
+                                          sizeof (u_int32_t));
+  ctype->names_el = (u_int32_t *) xcalloc (ctype->plane_size
+                                          * ctype->plane_cnt,
+                                          sizeof (u_int32_t));
 
   for (idx = 1; idx < 256; ++idx)
     NAMES_B1[idx] = idx;
@@ -1286,10 +1290,10 @@ Computing table size for character classes might take a while..."),
       = TRANS32 (ctype->class_collection[idx]);
 
   /* Room for table of mappings.  */
-  ctype->map_eb = (u32_t **) xmalloc (ctype->map_collection_nr
-                                     * sizeof (u32_t *));
-  ctype->map_el = (u32_t **) xmalloc (ctype->map_collection_nr
-                                     * sizeof (u32_t *));
+  ctype->map_eb = (u_int32_t **) xmalloc (ctype->map_collection_nr
+                                         * sizeof (u_int32_t *));
+  ctype->map_el = (u_int32_t **) xmalloc (ctype->map_collection_nr
+                                         * sizeof (u_int32_t *));
 
   /* Fill in all mappings.  */
   for (idx = 0; idx < ctype->map_collection_nr; ++idx)
@@ -1297,12 +1301,12 @@ Computing table size for character classes might take a while..."),
       unsigned int idx2;
 
       /* Allocate table.  */
-      ctype->map_eb[idx] = (u32_t *) xmalloc ((ctype->plane_size
-                                              * ctype->plane_cnt + 128)
-                                             * sizeof (u32_t));
-      ctype->map_el[idx] = (u32_t *) xmalloc ((ctype->plane_size
-                                              * ctype->plane_cnt + 128)
-                                             * sizeof (u32_t));
+      ctype->map_eb[idx] = (u_int32_t *) xmalloc ((ctype->plane_size
+                                                  * ctype->plane_cnt + 128)
+                                                 * sizeof (u_int32_t));
+      ctype->map_el[idx] = (u_int32_t *) xmalloc ((ctype->plane_size
+                                                  * ctype->plane_cnt + 128)
+                                                 * sizeof (u_int32_t));
 
 #if __BYTE_ORDER == __LITTLE_ENDIAN
 # define MAP_B1 ctype->map_el
@@ -1314,7 +1318,7 @@ Computing table size for character classes might take a while..."),
 
       /* Copy default value (identity mapping).  */
       memcpy (&MAP_B1[idx][128], NAMES_B1,
-             ctype->plane_size * ctype->plane_cnt * sizeof (u32_t));
+             ctype->plane_size * ctype->plane_cnt * sizeof (u_int32_t));
 
       /* Copy values from collection.  */
       for (idx2 = 0; idx2 < ctype->map_collection_act[idx]; ++idx2)
@@ -1336,10 +1340,10 @@ Computing table size for character classes might take a while..."),
     }
 
   /* Extra array for class and map names.  */
-  ctype->class_name_ptr = (u32_t *) xmalloc (ctype->nr_charclass
-                                            * sizeof (u32_t));
-  ctype->map_name_ptr = (u32_t *) xmalloc (ctype->map_collection_nr
-                                          * sizeof (u32_t));
+  ctype->class_name_ptr = (u_int32_t *) xmalloc (ctype->nr_charclass
+                                                * sizeof (u_int32_t));
+  ctype->map_name_ptr = (u_int32_t *) xmalloc (ctype->map_collection_nr
+                                              * sizeof (u_int32_t));
 
   /* Array for width information.  Because the expected width are very
      small we use only one single byte.  This save space and we need
index ebd5054b0248bc5a064ff4e247570b3cbfa434fb..ede616768dcc54a150de02616c8342676930a918 100644 (file)
@@ -128,7 +128,7 @@ messages_output (struct localedef_t *locale, const char *output_path)
     = locale->categories[LC_MESSAGES].messages;
   struct iovec iov[2 + _NL_ITEM_INDEX (_NL_NUM_LC_MESSAGES)];
   struct locale_file data;
-  u32_t idx[_NL_ITEM_INDEX (_NL_NUM_LC_MESSAGES)];
+  u_int32_t idx[_NL_ITEM_INDEX (_NL_NUM_LC_MESSAGES)];
   size_t cnt = 0;
 
   if ((locale->binary & (1 << LC_MESSAGES)) != 0)
index 18e27866fb8e10c33dff79827b898330a58ca9c5..a717377a8b430714f829f8147b663780e6424131 100644 (file)
@@ -182,7 +182,7 @@ monetary_output (struct localedef_t *locale, const char *output_path)
     = locale->categories[LC_MONETARY].monetary;
   struct iovec iov[2 + _NL_ITEM_INDEX (_NL_NUM_LC_MONETARY)];
   struct locale_file data;
-  u32_t idx[_NL_ITEM_INDEX (_NL_NUM_LC_MONETARY)];
+  u_int32_t idx[_NL_ITEM_INDEX (_NL_NUM_LC_MONETARY)];
   size_t cnt = 0;
 
   if ((locale->binary & (1 << LC_MONETARY)) != 0)
index 0b5fe2afe5ef263e615a8a8a49c707f6fc22e021..dcee7bdb4e045766d0ad0e3ad4aca2f593317090 100644 (file)
@@ -102,7 +102,7 @@ numeric_output (struct localedef_t *locale, const char *output_path)
   struct locale_numeric_t *numeric = locale->categories[LC_NUMERIC].numeric;
   struct iovec iov[2 + _NL_ITEM_INDEX (_NL_NUM_LC_NUMERIC)];
   struct locale_file data;
-  u32_t idx[_NL_ITEM_INDEX (_NL_NUM_LC_NUMERIC)];
+  u_int32_t idx[_NL_ITEM_INDEX (_NL_NUM_LC_NUMERIC)];
   size_t cnt = 0;
 
   if ((locale->binary & (1 << LC_NUMERIC)) != 0)
index 2587faccdc8a9d154621b4a288063784fda5772d..e031b24edc1c8714523ce3d2285f2fe3f6cbe87b 100644 (file)
@@ -117,7 +117,7 @@ time_output (struct localedef_t *locale, const char *output_path)
   struct iovec iov[2 + _NL_ITEM_INDEX (_NL_NUM_LC_TIME)
                  + time->cur_num_alt_digits];
   struct locale_file data;
-  u32_t idx[_NL_ITEM_INDEX (_NL_NUM_LC_TIME)];
+  u_int32_t idx[_NL_ITEM_INDEX (_NL_NUM_LC_TIME)];
   size_t cnt, last_idx, num;
 
   if ((locale->binary & (1 << LC_TIME)) != 0)
index 72eb2d36e292b01d005a9ab97a63f951650dba6e..e9fb6d57a6a52b21a60070be06e366c88c91242c 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 */
@@ -95,7 +96,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
@@ -424,25 +425,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;
+
+         if (endp > startp)
+           normal = _nl_normalize_codeset (startp, endp - startp);
+       }
 
-      snprintf (result, path_max_len, "%s/%s", LOCALE_PATH, path);
+      /* 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;
index 70ec6eba6ee8e92fef2ece47226bcdc1b15b47f5..c0d6fcdc4e50811155009320aedde92ee3ca50c8 100644 (file)
@@ -13,14 +13,17 @@ 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.  */
 
+#include <alloca.h>
+#include <argz.h>
 #include <errno.h>
-#include <string.h>
-#include <stdlib.h>
 #include <locale.h>
-#include <langinfo.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
 #include "localeinfo.h"
 
 /* For each category declare two external variables (with weak references):
@@ -33,20 +36,19 @@ Cambridge, MA 02139, USA.  */
 #define DEFINE_CATEGORY(category, category_name, items, a, b, c, d) \
 extern const struct locale_data *_nl_current_##category;                     \
 extern const struct locale_data _nl_C_##category;                            \
-/* XXX The linker is broken so we cannot do the weak symbols right just now. */
-/* weak_symbol (_nl_current_##category) weak_symbol (_nl_C_##category) */
+weak_symbol (_nl_current_##category) weak_symbol (_nl_C_##category)
 #include "categories.def"
 #undef DEFINE_CATEGORY
 
 /* Array indexed by category of pointers to _nl_current_CATEGORY slots.
    Elements are zero for categories whose data is never used.  */
-const struct locale_data * *const _nl_current[] =
-{
+static const struct locale_data * *const _nl_current[] =
+  {
 #define DEFINE_CATEGORY(category, category_name, items, a, b, c, d) \
-  [category] = &_nl_current_##category,
+    [category] = &_nl_current_##category,
 #include "categories.def"
 #undef DEFINE_CATEGORY
-};
+  };
 
 /* Array indexed by category of pointers to _nl_C_CATEGORY slots.
    Elements are zero for categories whose data is never used.  */
@@ -67,6 +69,7 @@ const char *const _nl_category_names[] =
     [category] = category_name,
 #include "categories.def"
 #undef DEFINE_CATEGORY
+    [LC_ALL] = "LC_ALL"
   };
 /* An array of their lengths, for convenience.  */
 const size_t _nl_category_name_sizes[] =
@@ -75,6 +78,7 @@ const size_t _nl_category_name_sizes[] =
     [category] = sizeof (category_name) - 1,
 #include "categories.def"
 #undef DEFINE_CATEGORY
+    [LC_ALL] = sizeof ("LC_ALL") - 1
   };
 
 
@@ -98,256 +102,257 @@ void (*const _nl_category_postload[]) (void) =
   };
 
 
+/* Name of our standard locale.  */
 const char _nl_C_name[] = "C";
 
 /* Name of current locale for each individual category.
    Each is malloc'd unless it is nl_C_name.  */
-const char *_nl_current_names[] =
+static const char *_nl_current_names[] =
   {
 #define DEFINE_CATEGORY(category, category_name, items, a, b, c, d) \
-    _nl_C_name,
+    [category] = _nl_C_name,
 #include "categories.def"
 #undef DEFINE_CATEGORY
+    [LC_ALL] = _nl_C_name              /* For LC_ALL.  */
   };
 
-/* Composite LC_ALL name for current locale.
-   This is malloc'd unless it's _nl_C_name.  */
-char *_nl_current_composite_name = (char *) _nl_C_name;
 
 
-/* Switch to the locale called NAME in CATEGORY.  Return a string
-   describing the locale.  This string can be used as the NAME argument in
-   a later call.  If NAME is NULL, don't switch locales, but return the
-   current one.  If NAME is "", switch to a locale based on the environment
-   variables, as per POSIX.  Return NULL on error.  */
+/* Use this when we come along an error.  */
+#define ERROR_RETURN                                                         \
+  do {                                                                       \
+    errno = EINVAL;                                                          \
+    return NULL;                                                             \
+  } while (0)
 
-char *
-setlocale (int category, const char *name)
+
+static inline char *
+clever_copy (const char *string)
 {
-  /* Return a malloc'd copy of STRING.  */
-  char *copy (const char *string)
-    {
-      size_t len = strlen (string) + 1;
-      char *new = malloc (len);
-      return new ? memcpy (new, string, len) : NULL;
-    }
+  size_t len;
+  char *new;
+
+  if (strcmp (string, "C") == 0 || strcmp (string, "POSIX") == 0)
+    /* This return is dangerous because the returned string might be
+       placed in read-only memory.  But everything should be set up to
+       handle this case.  */
+    return (char *) _nl_C_name;
+
+  len = strlen (string) + 1;
+  new = (char *) malloc (len);
+  return new != NULL ? memcpy (new, string, len) : NULL;
+}
 
-  /* Construct a new composite name.  */
-  char *new_composite_name (int category, char *newnames[LC_ALL])
-  {
-    size_t lens[LC_ALL], cumlen = 0;
-    int i;
-    char *new, *p;
-    int same = 1;
-
-    for (i = 0; i < LC_ALL; ++i)
-      {
-       char *name = (category == LC_ALL ? newnames[i] :
-                     category == i ? newnames[0] :
-                     (char *) _nl_current_names[i]);
-       lens[i] = strlen (name);
-       cumlen += _nl_category_name_sizes[i] + 1 + lens[i] + 1;
-       if (i > 0 && same && strcmp (name, newnames[0]))
-         same = 0;
-      }
-
-    if (same)
-      {
-       /* All the categories use the same name.  */
-       new = malloc (lens[0] + 1);
-       if (! new)
-         {
-           if (!strcmp (newnames[0], "C") || !strcmp (newnames[0], "POSIX"))
-             return (char *) _nl_C_name;
-           return NULL;
-         }
-       memcpy (new, newnames[0], lens[0] + 1);
-       return new;
-      }
 
-    new = malloc (cumlen);
-    if (! new)
-      return NULL;
-    p = new;
-    for (i = 0; i < LC_ALL; ++i)
-      {
-       /* Add "CATEGORY=NAME;" to the string.  */
-       char *name = (category == LC_ALL ? newnames[i] :
-                     category == i ? newnames[0] :
-                     (char *) _nl_current_names[i]);
-       memcpy (p, _nl_category_names[i], _nl_category_name_sizes[i]);
-       p += _nl_category_name_sizes[i];
-       *p++ = '=';
-       memcpy (p, name, lens[i]);
-       p += lens[i];
-       *p++ = ';';
-      }
-    p[-1] = '\0';              /* Clobber the last ';'.  */
-    return new;
-  }
-  /* Put COMPOSITE in _nl_current_composite_name and free the old value.  */
-  void setcomposite (char *composite)
+/* Construct a new composite name.  */
+static inline char *
+new_composite_name (int category, char *newnames[LC_ALL])
+{
+  size_t last_len;
+  size_t cumlen = 0;
+  int i;
+  char *new, *p;
+  int same = 1;
+
+  for (i = 0; i < LC_ALL; ++i)
     {
-      char *old = _nl_current_composite_name;
-      _nl_current_composite_name = composite;
-      if (old != _nl_C_name)
-       free (old);
+      char *name = (category == LC_ALL ? newnames[i] :
+                   category == i ? newnames[0] :
+                   (char *) _nl_current_names[i]);
+      last_len = strlen (name);
+      cumlen += _nl_category_name_sizes[i] + 1 + last_len + 1;
+      if (i > 0 && same && strcmp (name, newnames[0]) != 0)
+       same = 0;
     }
-  /* Put NAME in _nl_current_names and free the old value.  */
-  void setname (int category, const char *name)
+
+  if (same)
     {
-      const char *oldname = _nl_current_names[category];
-      _nl_current_names[category] = name;
-      if (oldname != _nl_C_name)
-       free ((char *) oldname);
+      /* All the categories use the same name.  */
+      if (strcmp (newnames[0], "C") == 0 || strcmp (newnames[0], "POSIX") == 0)
+       return (char *) _nl_C_name;
+
+      new = malloc (last_len + 1);
+      if (new == NULL)
+       return NULL;
+
+      memcpy (new, newnames[0], last_len + 1);
+      return new;
     }
-  /* Put DATA in *_nl_current[CATEGORY] and free the old value.  */
-  void setdata (int category, struct locale_data *data)
+
+  new = malloc (cumlen);
+  if (new == NULL)
+    return NULL;
+  p = new;
+  for (i = 0; i < LC_ALL; ++i)
     {
-      if (_nl_current[category])
-       {
-         const struct locale_data *olddata = *_nl_current[category];
-         *_nl_current[category] = data;
-         if (_nl_category_postload[category])
-           (*_nl_category_postload[category]) ();
-         if (olddata != _nl_C[category])
-           _nl_free_locale ((struct locale_data *) olddata);
-       }
+      /* Add "CATEGORY=NAME;" to the string.  */
+      char *name = (category == LC_ALL ? newnames[i] :
+                   category == i ? newnames[0] :
+                   (char *) _nl_current_names[i]);
+      p = __stpcpy (p, _nl_category_names[i]);
+      *p++ = '=';
+      p = __stpcpy (p, name);
+      *p++ = ';';
     }
+  p[-1] = '\0';                /* Clobber the last ';'.  */
+  return new;
+}
 
-  const char *current_name;
-  char *composite;
 
-  if (category < 0 || category > LC_ALL)
+/* Put NAME in _nl_current_names.  */
+static inline void
+setname (int category, const char *name)
+{
+  if (_nl_current[category] == NULL
+      && _nl_current_names[category] != _nl_C_name)
+    free ((void *) _nl_current_names[category]);
+
+  _nl_current_names[category] = name;
+}
+
+
+/* Put DATA in *_nl_current[CATEGORY].  */
+static inline void
+setdata (int category, const struct locale_data *data)
+{
+  if (_nl_current[category] != NULL)
     {
-      errno = EINVAL;
-      return NULL;
+      *_nl_current[category] = data;
+      if (_nl_category_postload[category])
+       (*_nl_category_postload[category]) ();
     }
+}
 
-  if (category == LC_ALL)
-    current_name = _nl_current_composite_name;
-  else
-    current_name = _nl_current_names[category];
 
-  if (name == NULL)
-    /* Return the name of the current locale.  */
-    return (char *) current_name;
+char *
+setlocale (int category, const char *locale)
+{
+  char *locpath_var;
+  char *locale_path;
+  size_t locale_path_len;
+  char *composite;
 
-  if (name == current_name)
+  /* Sanity check for CATEGORY argument.  */
+  if (category < 0 || category > LC_ALL)
+    ERROR_RETURN;
+
+  /* Does user want name of current locale?  */
+  if (locale == NULL)
+    return (char *) _nl_current_names[category];
+
+  if (strcmp (locale, _nl_current_names[category]) == 0)
     /* Changing to the same thing.  */
-    return (char *) current_name;
+    return (char *) _nl_current_names[category];
+
+  /* We perhaps really have to load some data.  So we determine the
+     path in which to look for the data now.  But this environment
+     variable must only be used when the binary has no SUID or SGID
+     bit set.  */
+  locale_path = NULL;
+  locale_path_len = 0;
+
+  locpath_var = getenv ("LOCPATH");
+  if (locpath_var != NULL && locpath_var[0] != '\0'
+      && __getuid () == __geteuid () && __getgid () == __getegid ())
+    if (__argz_create_sep (locpath_var, ':',
+                          &locale_path, &locale_path_len) != 0)
+      return NULL;
 
+  if (__argz_append (&locale_path, &locale_path_len,
+                    LOCALE_PATH, sizeof (LOCALE_PATH)) != 0)
+    return NULL;
+  
   if (category == LC_ALL)
     {
-      const size_t len = strlen (name) + 1;
+      /* The user wants to set all categories.  The desired locales
+        for the individual categories can be selected by using a
+        composite locale name.  This is a semi-colon separated list
+        of entries of the form `CATEGORY=VALUE'.  */
       char *newnames[LC_ALL];
-      char *p;
-      struct locale_data *newdata[LC_ALL];
+      const struct locale_data *newdata[LC_ALL];
 
       /* Set all name pointers to the argument name.  */
       for (category = 0; category < LC_ALL; ++category)
-       newnames[category] = (char *) name;
-
-      p = strchr (name, ';');
-      if (p)
+       newnames[category] = (char *) locale;
+      
+      if (strchr (locale, ';') != NULL)
        {
-         /* This is a composite name.  Make a local copy and split it up.  */
-         int i;
-         char *n = alloca (len);
-         memcpy (n, name, len);
+         /* This is a composite name.  Make a copy and split it up.  */
+         char *np = strdupa (locale);
+         char *cp;
+         int cnt;
 
-         while ((p = strchr (n, '=')) != NULL)
+         while ((cp = strchr (np, '=')) != NULL)
            {
-             for (i = 0; i < LC_ALL; ++i)
-               if (_nl_category_name_sizes[i] == p - n &&
-                   !memcmp (_nl_category_names[i], n, p - n))
+             for (cnt = 0; cnt < LC_ALL; ++cnt)
+               if (cp - np == _nl_category_name_sizes[cnt]
+                   && memcmp (np, _nl_category_names[cnt], cp - np) == 0)
                  break;
-             if (i == LC_ALL)
-               {
-                 /* Bogus category name.  */
-                 errno = EINVAL;
-                 return NULL;
-               }
-             if (i < LC_ALL)
+
+             if (cnt == LC_ALL)
+               /* Bogus category name.  */
+               ERROR_RETURN;
+
+             /* Found the category this clause sets.  */
+             newnames[cnt] = ++cp;
+             cp = strchr (cp, ';');
+             if (cp != NULL)
                {
-                 /* Found the category this clause sets.  */
-                 char *end = strchr (++p, ';');
-                 newnames[i] = p;
-                 if (end)
-                   {
-                     /* Examine the next clause.  */
-                     *end = '\0';
-                     n = end + 1;
-                   }
-                 else
-                   /* This was the last clause.  We are done.  */
-                   break;
+                 /* Examine the next clause.  */
+                 *cp = '\0';
+                 np = cp + 1;
                }
+             else
+               /* This was the last clause.  We are done.  */
+               break;
            }
 
-         for (i = 0; i < LC_ALL; ++i)
-           if (newnames[i] == name)
+         for (cnt = 0; cnt < LC_ALL; ++cnt)
+           if (newnames[cnt] == locale)
              /* The composite name did not specify all categories.  */
-             return NULL;
+             ERROR_RETURN;
        }
 
       /* Load the new data for each category.  */
       while (category-- > 0)
        /* Only actually load the data if anything will use it.  */
-       if (_nl_current[category])
+       if (_nl_current[category] != NULL)
          {
-           newdata[category] = _nl_load_locale (category,
+           newdata[category] = _nl_find_locale (locale_path, locale_path_len,
+                                                category,
                                                 &newnames[category]);
-           if (newdata[category])
-             newnames[category] = copy (newnames[category]);
-           if (! newdata[category] || ! newnames[category])
+
+           if (newdata[category] == NULL)
              {
-               if (!strcmp (newnames[category], "C") ||
-                   !strcmp (newnames[category], "POSIX"))
-                 {
-                   /* Loading from a file failed, but this is a request
-                      for the default locale.  Use the built-in data.  */
-                   if (! newdata[category])
-                     newdata[category]
-                       = (struct locale_data *) _nl_C[category];
-                   newnames[category] = (char *) _nl_C_name;
-                 }
-               else
-                 {
-                   /* Loading this part of the locale failed.
-                      Abort the composite load.  */
-                 abort_composite:
-                   while (++category < LC_ALL)
-                     {
-                       if (_nl_current[category])
-                         _nl_free_locale (newdata[category]);
-                       if (newnames[category] != _nl_C_name)
-                         free (newnames[category]);
-                     }
-                   return NULL;
-                 }
+               /* Loading this part of the locale failed.  Abort the
+                  composite load.  */
+               int save_errno;
+             abort_composite:
+               save_errno = errno;
+               
+               while (++category < LC_ALL)
+                 if (_nl_current[category] != NULL)
+                   _nl_free_locale (newdata[category]);
+                 else
+                   if (_nl_current[category] == NULL
+                       && newnames[category] != _nl_C_name)
+                     free (newnames[category]);
+
+               errno = save_errno;
+               return NULL;
              }
          }
        else
          {
            /* The data is never used; just change the name.  */
-           newnames[category] = copy (newnames[category]);
-           if (! newnames[category])
-             {
-               if (!strcmp (newnames[category], "C") ||
-                   !strcmp (newnames[category], "POSIX"))
-                 newnames[category] = (char *) _nl_C_name;
-               else
-                 {
-                   while (++category < LC_ALL)
-                     if (newnames[category] != _nl_C_name)
-                       free (newnames[category]);
-                 }
-             }
+           newnames[category] = clever_copy (newnames[category]);
+           if (newnames[category] == NULL)
+             goto abort_composite;
          }
 
+      /* Create new composite name.  */
       composite = new_composite_name (LC_ALL, newnames);
-      if (! composite)
+      if (composite == NULL)
        {
          category = -1;
          goto abort_composite;
@@ -359,46 +364,45 @@ setlocale (int category, const char *name)
          setdata (category, newdata[category]);
          setname (category, newnames[category]);
        }
-      setcomposite (composite);
+      setname (LC_ALL, composite);
 
       return composite;
     }
   else
     {
-      char *newname = copy (name);
-      if (! newname)
+      const struct locale_data *newdata;
+      char *newname;
+
+      if (_nl_current[category] != NULL)
        {
-         if (!strcmp (name, "C") || !strcmp (name, "POSIX"))
-           newname = (char *) _nl_C_name;
-         else
+         /* Only actually load the data if anything will use it.  */
+         newname = (char *) locale;
+         newdata = _nl_find_locale (locale_path, locale_path_len, category,
+                                    (char **) &newname);
+         if (newdata == NULL)
            return NULL;
        }
 
+      /* Create new composite name.  */
       composite = new_composite_name (category, &newname);
-      if (! composite)
+      if (composite == NULL)
        {
-         if (newname != _nl_C_name)
-           free (newname);
+         /* If anything went wrong free what we managed to allocate
+            so far.  */
+         int save_errno = errno;
+
+         if (_nl_current[category] != NULL)
+           _nl_free_locale (newdata);
+
+         errno = save_errno;
          return NULL;
        }
 
-      /* Only actually load the data if anything will use it.  */
-      if (_nl_current[category])
-       {
-         struct locale_data *newdata = _nl_load_locale (category,
-                                                        (char **) &name);
-         if (! newdata)
-           {
-             if (!strcmp (name, "C") || !strcmp (name, "POSIX"))
-               newdata = (struct locale_data *) _nl_C[category];
-             else
-               return NULL;
-           }
-         setdata (category, newdata);
-       }
+      if (_nl_current[category] != NULL)
+       setdata (category, newdata);
 
       setname (category, newname);
-      setcomposite (composite);
+      setname (LC_ALL, composite);
 
       return newname;
     }
index 128b63168d9ab437b2bbf13ea1b6f726c4d3d1b0..904a154f82c077ff1b3c703444a6c820d7ec68d9 100644 (file)
@@ -35,7 +35,7 @@ typedef struct weight_t
   struct weight_t *next;
   struct data_pair
     {
-      size_t number;
+      int number;
       const u_int32_t *value;
     } data[0];
 } weight_t;
@@ -115,7 +115,7 @@ get_weight (const STRING_TYPE **str, weight_t *result)
     {
       size_t idx;
 
-      /* This is a comparison between a u32_t array (aka wchar_t) and
+      /* This is a comparison between a u_int32_t array (aka wchar_t) and
         an 8-bit string.  */
       for (idx = 0; __collate_extra[slot + 2 + idx] != 0; ++idx)
        if (__collate_extra[slot + 2 + idx] != (u_int32_t) str[idx])
index d90bf6f857338a4000b72842b35a404efb67f133..af371ed689a0f12ab2e623dbbf333905302a845e 100644 (file)
@@ -33,11 +33,11 @@ routines    := strcat strchr strcmp strcoll strcpy strcspn strdup   \
                   strcasecmp strncase                                  \
                   memccpy memcpy wordcopy strsep                       \
                   swab strfry memfrob memmem                           \
-                  $(addprefix argz-,append count create                \
+                  $(addprefix argz-,append count create ctsep next     \
                                     delete extract insert stringify)   \
                   envz
 
-tests          := tester testcopy test-ffs
+tests          := tester testcopy test-ffs tst-strlen
 distribute     := memcopy.h pagecopy.h
 
 
diff --git a/string/argz-ctsep.c b/string/argz-ctsep.c
new file mode 100644 (file)
index 0000000..9560591
--- /dev/null
@@ -0,0 +1,60 @@
+/* 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.  */
+
+#include <argz.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+error_t
+__argz_create_sep (const char *string, int delim, char **argz, size_t *len)
+{
+  size_t nlen = strlen (string) + 1;
+
+  if (nlen != 0)
+    {
+      const char *rp;
+      char *wp;
+      
+      *argz = (char *) malloc (nlen);
+      if (*argz == NULL)
+       return ENOMEM;
+
+      rp = string;
+      wp = *argz;
+      do
+       if (*rp == delim)
+         {
+           if (wp > *argz && wp[-1] != '\0')
+             *wp++ = '\0';
+           else
+             --nlen;
+         }
+       else
+         *wp++ = *rp;
+      while (*rp++ != '\0');
+    }
+  if (nlen == 0)
+    *argz = NULL;
+  *len = nlen;
+
+  return 0;
+}
+weak_alias (__argz_create_sep, argz_create_sep)
diff --git a/string/argz-next.c b/string/argz-next.c
new file mode 100644 (file)
index 0000000..6149c7e
--- /dev/null
@@ -0,0 +1,39 @@
+/* Iterate through the elements of an argz block.
+   Copyright (C) 1995, 1996 Free Software Foundation, Inc.
+
+   Written by Miles Bader <miles@gnu.ai.mit.edu>
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   This program 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
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+
+#include <argz.h>
+#include <string.h>
+
+char *
+__argz_next (char *argz, size_t argz_len, const char *entry)
+{
+  if (entry)
+    {
+      if (entry < argz + argz_len)
+       entry = strchr (entry, '\0') + 1;
+
+      return entry >= argz + argz_len ? NULL : entry;
+    }
+  else
+    if (argz_len > 0)
+      return argz;
+    else
+      return NULL;
+}
+weak_alias (__argz_next, argz_next)
index 9c03815915bf5bc6b41d300c58f5e1be8ac1a4b1..733d06cca84ad3fe6984917f110e139da048f43a 100644 (file)
 
 #ifndef __ARGZ_H__
 #define __ARGZ_H__     1
+
+#include <features.h>
+
 #include <errno.h>             /* Define error_t.  */
 #include <string.h>            /* Need size_t, and strchr is called below.  */
 
+
+__BEGIN_DECLS
+
 /* Make a '\0' separated arg vector from a unix argv vector, returning it in
    ARGZ, and the total length in LEN.  If a memory allocation error occurs,
    ENOMEM is returned, otherwise 0.  The result can be destroyed using free. */
-error_t __argz_create (char **argv, char **argz, size_t *len);
-error_t argz_create (char **argv, char **argz, size_t *len);
+error_t __argz_create __P ((char **__argv, char **__argz, size_t *__len));
+error_t argz_create __P ((char **__argv, char **__argz, size_t *__len));
+
+/* Make a '\0' separated arg vector from a SEP separated list in
+   STRING, returning it in ARGZ, and the total length in LEN.  If a
+   memory allocation error occurs, ENOMEM is returned, otherwise 0.
+   The result can be destroyed using free.  */
+error_t __argz_create_sep __P ((__const char *__string, int __sep,
+                               char **__argz, size_t *__len));
+error_t argz_create_sep __P ((__const char *__string, int __sep,
+                             char **__argz, size_t *__len));
 
 /* Returns the number of strings in ARGZ.  */
-size_t __argz_count (const char *argz, size_t len);
-size_t argz_count (const char *argz, size_t len);
+size_t __argz_count __P ((__const char *__argz, size_t __len));
+size_t argz_count __P ((__const char *__argz, size_t __len));
 
 /* Puts pointers to each string in ARGZ into ARGV, which must be large enough
    to hold them all.  */
-void __argz_extract (const char *argz, size_t len, char **argv);
-void argz_extract (const char *argz, size_t len, char **argv);
+void __argz_extract __P ((__const char *__argz, size_t __len, char **__argv));
+void argz_extract __P ((__const char *__argz, size_t __len, char **__argv));
 
 /* Make '\0' separated arg vector ARGZ printable by converting all the '\0's
    except the last into the character SEP.  */
-void __argz_stringify (char *argz, size_t len, int sep);
-void argz_stringify (char *argz, size_t len, int sep);
+void __argz_stringify __P ((char *__argz, size_t __len, int __sep));
+void argz_stringify __P ((char *__argz, size_t __len, int __sep));
 
 /* Append BUF, of length BUF_LEN to the argz vector in ARGZ & ARGZ_LEN.  */
-error_t __argz_append (char **argz, size_t *argz_len,
-                      const char *buf, size_t buf_len);
-error_t argz_append (char **argz, size_t *argz_len,
-                    const char *buf, size_t buf_len);
+error_t __argz_append __P ((char **__argz, size_t *__argz_len,
+                           __const char *__buf, size_t __buf_len));
+error_t argz_append __P ((char **__argz, size_t *__argz_len,
+                         __const char *__buf, size_t __buf_len));
 
 /* Append STR to the argz vector in ARGZ & ARGZ_LEN.  */
-error_t __argz_add (char **argz, size_t *argz_len, const char *str);
-error_t argz_add (char **argz, size_t *argz_len, const char *str);
+error_t __argz_add __P ((char **__argz, size_t *__argz_len,
+                        __const char *__str));
+error_t argz_add __P ((char **__argz, size_t *__argz_len,
+                      __const char *__str));
 
 /* Delete ENTRY from ARGZ & ARGZ_LEN, if it appears there.  */
-void __argz_delete (char **argz, size_t *argz_len, char *entry);
-void argz_delete (char **argz, size_t *argz_len, char *entry);
+void __argz_delete __P ((char **__argz, size_t *__argz_len, char *__entry));
+void argz_delete __P ((char **__argz, size_t *__argz_len, char *__entry));
 
 /* Insert ENTRY into ARGZ & ARGZ_LEN before BEFORE, which should be an
    existing entry in ARGZ; if BEFORE is NULL, ENTRY is appended to the end.
@@ -63,17 +80,17 @@ void argz_delete (char **argz, size_t *argz_len, char *entry);
    ARGZ, ENTRY) will insert ENTRY at the beginning of ARGZ.  If BEFORE is not
    in ARGZ, EINVAL is returned, else if memory can't be allocated for the new
    ARGZ, ENOMEM is returned, else 0.  */
-error_t __argz_insert (char **argz, size_t *argz_len,
-                      char *before, const char *entry);
-error_t argz_insert (char **argz, size_t *argz_len,
-                    char *before, const char *entry);
+error_t __argz_insert __P ((char **__argz, size_t *__argz_len,
+                           char *__before, __const char *__entry));
+error_t argz_insert __P ((char **__argz, size_t *__argz_len,
+                         char *__before, __const char *__entry));
 \f
 /* Returns the next entry in ARGZ & ARGZ_LEN after ENTRY, or NULL if there
    are no more.  If entry is NULL, then the first entry is returned.  This
    behavior allows two convenient iteration styles:
 
     char *entry = 0;
-    while (entry = argz_next (argz, argz_len, entry))
+    while ((entry = argz_next (argz, argz_len, entry)))
       ...;
 
    or
@@ -82,19 +99,33 @@ error_t argz_insert (char **argz, size_t *argz_len,
     for (entry = argz; entry; entry = argz_next (argz, argz_len, entry))
       ...;
 */
+extern char *__argz_next __P ((char *__argz, size_t __argz_len,
+                              __const char *__entry));
+extern char *argz_next __P ((char *__argz, size_t __argz_len,
+                            __const char *__entry));
+
+#if defined (__OPTIMIZE__) && __GNUC__ >= 2
 extern inline char *
-argz_next (char *argz, size_t argz_len, const char *entry)
+__argz_next (char *argz, size_t argz_len, const char *entry)
 {
   if (entry)
-    if (entry >= argz + argz_len)
-      return 0;
-    else
-      return strchr (entry, '\0') + 1;
+    {
+      if (entry < argz + argz_len)
+       entry = strchr (entry, '\0') + 1;
+
+      return entry >= argz + argz_len ? NULL : entry;
+    }
   else
     if (argz_len > 0)
       return argz;
     else
       return 0;
 }
+extern inline char *
+argz_next (char *argz, size_t argz_len, const char *entry)
+{
+  return __argz_next (argz, argz_len, entry);
+}
+#endif /* optimizing GCC2 */
 
 #endif /* __ARGZ_H__ */
index 4d0816e4e17e9417179821e2d837b16ab2f0dd21..e751eccb8fca82bdb517db84e59c9a2600276c15 100644 (file)
@@ -29,8 +29,8 @@
 /* Returns a pointer to the entry in ENVZ for NAME, or 0 if there is none.
    If NAME contains the separator character, only the portion before it is
    used in the comparison.  */
-char *
-envz_entry (char *envz, unsigned envz_len, char *name)
+const char *
+envz_entry (const char *envz, size_t envz_len, const char *name)
 {
   while (envz_len)
     {
@@ -57,8 +57,8 @@ envz_entry (char *envz, unsigned envz_len, char *name)
 
 /* Returns a pointer to the value portion of the entry in ENVZ for NAME, or 0
    if there is none.  */
-char *
-envz_get (char *envz, unsigned envz_len, char *name)
+const char *
+envz_get (const char *envz, size_t envz_len, const char *name)
 {
   char *entry = envz_entry (envz, envz_len, name);
   if (entry)
@@ -75,7 +75,7 @@ envz_get (char *envz, unsigned envz_len, char *name)
 \f
 /* Remove the entry for NAME from ENVZ & ENVZ_LEN, if any.  */
 void
-envz_remove (char **envz, unsigned *envz_len, char *name)
+envz_remove (char **envz, size_t *envz_len, char *name)
 {
   char *entry = envz_entry (*envz, *envz_len, name);
   if (entry)
@@ -89,7 +89,7 @@ envz_remove (char **envz, unsigned *envz_len, char *name)
    because when merging with another envz, the null entry can override an
    entry in the other one.  Null entries can be removed with envz_strip ().  */
 error_t
-envz_add (char **envz, unsigned *envz_len, char *name, char *value)
+envz_add (char **envz, unsigned *envz_len, const char *name, const char *value)
 {
   envz_remove (envz, envz_len, name);
 
@@ -126,8 +126,8 @@ envz_add (char **envz, unsigned *envz_len, char *name, char *value)
    OVERRIDE is true, then values in ENVZ2 will supercede those with the same
    name in ENV, otherwise not.  */
 error_t
-envz_merge (char **envz, unsigned *envz_len, char *envz2, unsigned envz2_len,
-           int override)
+envz_merge (char **envz, unsigned *envz_len, const char *envz2,
+           size_t envz2_len, int override)
 {
   error_t err = 0;
 
index c39c497e7e3d0675c73ffeae9d1b2746b6d8d97c..dad2d281f44486103df437795fc4105c11ffdfe3 100644 (file)
 #include <argz.h>
 
 /* Returns a pointer to the entry in ENVZ for NAME, or 0 if there is none.  */
-char *envz_entry (const char *envz, size_t envz_len, const char *name);
+const char *envz_entry __P ((__const char *__envz, size_t __envz_len,
+                            __const char *__name));
 
 /* Returns a pointer to the value portion of the entry in ENVZ for NAME, or 0
    if there is none.  */
-char *envz_get (const char *envz, size_t envz_len, const char *name);
+const char *envz_get __P ((__const char *__envz, size_t __envz_len,
+                          __const char *__name));
 
 /* Adds an entry for NAME with value VALUE to ENVZ & ENVZ_LEN.  If an entry
    with the same name already exists in ENVZ, it is removed.  If VALUE is
@@ -40,17 +42,17 @@ char *envz_get (const char *envz, size_t envz_len, const char *name);
    return NULL, although envz_entry will still return an entry; this is handy
    because when merging with another envz, the null entry can override an
    entry in the other one.  Null entries can be removed with envz_strip ().  */
-error_t envz_add (char **envz, size_t *envz_len,
-                 const char *name, const char *value);
+error_t envz_add __P ((char **__envz, size_t *__envz_len,
+                      __const char *__name, __const char *__value));
 
 /* Adds each entry in ENVZ2 to ENVZ & ENVZ_LEN, as if with envz_add().  If
    OVERRIDE is true, then values in ENVZ2 will supercede those with the same
    name in ENV, otherwise not.  */
-error_t envz_merge (char **envz, size_t *envz_len,
-                   const char *envz2, size_t envz2_len,
-                   int override);
+error_t envz_merge __P ((char **__envz, size_t *__envz_len,
+                        __const char *__envz2, size_t __envz2_len,
+                        int __override));
 
 /* Remove null entries.  */
-void envz_strip (char **envz, size_t *envz_len);
+void envz_strip __P ((char **__envz, size_t *__envz_len));
 
 #endif /* __ENVZ_H__ */
index dc1bb2aaaaa7bbce4065e8b18a2d2c6032d86799..a4bbabc2acefed6acad1e79ffe5b5c6f26311aa7 100644 (file)
@@ -71,7 +71,7 @@ STRCOLL (s1, s2)
        {
          int s1ignore = 0;
          int s2ignore = 0;
-         u32_t w1, w2;
+         u_int32_t w1, w2;
 
          /* Here we have to check for IGNORE entries.  If these are
             found we count them and go on witht he next value.  */
diff --git a/string/tst-strlen.c b/string/tst-strlen.c
new file mode 100644 (file)
index 0000000..a58f878
--- /dev/null
@@ -0,0 +1,32 @@
+#include <stdio.h>
+#include <string.h>
+
+int
+main()
+{
+  static const lens[16] = { 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, 4 };
+  char buf[24];
+  int words;
+
+  for (words = 0; words < 4; ++words)
+    {
+      int last;
+      memset (buf, 'a', words * 4);
+
+      for (last = 0; last < 16; ++last)
+        {
+         buf[words * 4 + 0] = (last & 1) != 0 ? 'b' : '\0';
+         buf[words * 4 + 1] = (last & 2) != 0 ? 'c' : '\0';
+         buf[words * 4 + 2] = (last & 4) != 0 ? 'd' : '\0';
+         buf[words * 4 + 3] = (last & 8) != 0 ? 'e' : '\0';
+         buf[words * 4 + 4] = '\0';
+
+         if (strlen (buf) != words * 4 + lens[last])
+           {
+             printf ("failed for words=%d and last=%d\n", words, last);
+             return 1;
+           }
+        }
+    }
+  return 0;
+}
index a18c8bce976317ea44984a801a51c6c58b29f092..0a30c45b425de177f622ccf242147804eb01f28d 100644 (file)
@@ -52,12 +52,12 @@ static struct proglst {
 } *proglst;
 static void universal();
 static SVCXPRT *transp;
-struct proglst *pl;
 
 registerrpc(prognum, versnum, procnum, progname, inproc, outproc)
        char *(*progname)();
        xdrproc_t inproc, outproc;
 {
+       struct proglst *pl;
 
        if (procnum == NULLPROC) {
                (void) fprintf(stderr,
index b807ed4b4f4ca71ad6eb06b189d621d38bea6331..15d01947d4aee76cbf6193bcd10c78ba48ee7742 100644 (file)
@@ -1,6 +1,6 @@
 /* strlen -- Compute length og NUL terminated string.
 Highly optimized version for ix86, x>=5.
-Copyright (C) 1995 Free Software Foundation, Inc.
+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>.
 
@@ -102,7 +102,6 @@ L1:
        jnc L3                  /* previous addl caused overflow? */
 
        xorl %ecx, %edx         /* (word+magic)^word */
-       subl $magic, %ecx       /* undo previous addl to restore word */
 
        andl $~magic, %edx      /* any of the carry flags set? */
 
@@ -119,7 +118,6 @@ L1:
        jnc L3                  /* previous addl caused overflow? */
 
        xorl %ecx, %edx         /* (word+magic)^word */
-       subl $magic, %ecx       /* undo previous addl to restore word */
 
        andl $~magic, %edx      /* any of the carry flags set? */
 
@@ -136,7 +134,6 @@ L1:
        jnc L3                  /* previous addl caused overflow? */
 
        xorl %ecx, %edx         /* (word+magic)^word */
-       subl $magic, %ecx       /* undo previous addl to restore word */
 
        andl $~magic, %edx      /* any of the carry flags set? */
 
@@ -149,11 +146,10 @@ L1:
        subl %ecx, %edx         /* first step to negate word */
        addl $magic, %ecx       /* add magic word */
 
-       decl %edx               /* wcomplete negation of ord */
+       decl %edx               /* complete negation of word */
        jnc L3                  /* previous addl caused overflow? */
 
        xorl %ecx, %edx         /* (word+magic)^word */
-       subl $magic, %ecx       /* undo previous addl to restore word */
 
        andl $~magic, %edx      /* any of the carry flags set? */
 
@@ -161,8 +157,9 @@ L1:
 
 
 L3:    subl $4, %eax           /* correct too early pointer increment */
-       testb %cl, %cl          /* lowest byte NUL? */
+       subl $magic, %ecx
 
+       cmpb $0, %cl            /* lowest byte NUL? */
        jz L2                   /* yes => return */
 
        inc %eax                /* increment pointer */
index b4e97a2c6bc788d9cb6d60037ead45cb7a2149c0..eed171cc90a2af4eec76f346fe821c4d720dad17 100644 (file)
@@ -79,7 +79,7 @@ static float zero = 0.0;
         * j0(x) = 1/sqrt(pi) * (P(0,x)*cc - Q(0,x)*ss) / sqrt(x)
         * y0(x) = 1/sqrt(pi) * (P(0,x)*ss + Q(0,x)*cc) / sqrt(x)
         */
-               if(ix>0x80000000) z = (invsqrtpi*cc)/__sqrtf(x);
+               if(ix>0x48000000) z = (invsqrtpi*cc)/__sqrtf(x);
                else {
                    u = pzerof(x); v = qzerof(x);
                    z = invsqrtpi*(u*cc-v*ss)/__sqrtf(x);
@@ -161,7 +161,7 @@ v04  =  4.4111031494e-10; /* 0x2ff280c2 */
                     if ((s*c)<zero) cc = z/ss;
                     else            ss = z/cc;
                 }
-                if(ix>0x80000000) z = (invsqrtpi*ss)/__sqrtf(x);
+                if(ix>0x48000000) z = (invsqrtpi*ss)/__sqrtf(x);
                 else {
                     u = pzerof(x); v = qzerof(x);
                     z = invsqrtpi*(u*ss+v*cc)/__sqrtf(x);
index 06384bd68df002e2a2c691544dbdbc85a351f384..e6f14a16ac1b49f3507d92e3b0afbfd12c7eb7ca 100644 (file)
@@ -80,7 +80,7 @@ static float zero    = 0.0;
         * j1(x) = 1/sqrt(pi) * (P(1,x)*cc - Q(1,x)*ss) / sqrt(x)
         * y1(x) = 1/sqrt(pi) * (P(1,x)*ss + Q(1,x)*cc) / sqrt(x)
         */
-               if(ix>0x80000000) z = (invsqrtpi*cc)/__sqrtf(y);
+               if(ix>0x48000000) z = (invsqrtpi*cc)/__sqrtf(y);
                else {
                    u = ponef(y); v = qonef(y);
                    z = invsqrtpi*(u*cc-v*ss)/__sqrtf(y);
index 1a292229970f832ed70a0dcbafce2227a8e82588..34dfc82cff1db47ea61a415e3613482582bc6777 100644 (file)
@@ -17,7 +17,6 @@ not, write to the Free Software Foundation, Inc., 675 Mass Ave,
 Cambridge, MA 02139, USA.  */
 
 #include <ansidecl.h>
-#define        __NO_MATH_INLINES
 #include <math.h>
 
 #ifndef        FUNC
index 51968156f5479e1dca9045e61b16bece6700b9f4..34da7ee1636a7390f77ea0bb08c7f4a92e84d6dc 100644 (file)
@@ -17,7 +17,6 @@ not, write to the Free Software Foundation, Inc., 675 Mass Ave,
 Cambridge, MA 02139, USA.  */
 
 #include <ansidecl.h>
-#define        __NO_MATH_INLINES
 #include <math.h>
 
 #ifndef        FUNC
index 310b1c41fa1df52230b08c0211893d522cd3eb91..578fa3ce535161ccae822c7065775e1e785e007c 100644 (file)
@@ -17,7 +17,6 @@ not, write to the Free Software Foundation, Inc., 675 Mass Ave,
 Cambridge, MA 02139, USA.  */
 
 #include <ansidecl.h>
-#define        __NO_MATH_INLINES
 #include <math.h>
 
 #ifndef FUNC
index 1a74c3611b888f3345abe16ad76ce8aa50112828..b3c3eadddf57a96e51717d6f95e2fb914f46ddbc 100644 (file)
@@ -17,7 +17,6 @@ not, write to the Free Software Foundation, Inc., 675 Mass Ave,
 Cambridge, MA 02139, USA.  */
 
 #include <ansidecl.h>
-#define        __NO_MATH_INLINES
 #include <math.h>
 
 #ifndef FUNC
index 77fd75918280189c7c9a763c71b558041007e23a..97b5983d0f67484ae37bbf9bab545523de7b3e57 100644 (file)
@@ -17,7 +17,6 @@ not, write to the Free Software Foundation, Inc., 675 Mass Ave,
 Cambridge, MA 02139, USA.  */
 
 #include <ansidecl.h>
-#define        __NO_MATH_INLINES
 #include <math.h>
 
 int
index 1e58ea4ebd20cd05f833dc2a57a1737f25a45d85..e5e3db2171d1fee02cb730257da861eaaa5189aa 100644 (file)
@@ -17,7 +17,6 @@ not, write to the Free Software Foundation, Inc., 675 Mass Ave,
 Cambridge, MA 02139, USA.  */
 
 #include <ansidecl.h>
-#define        __NO_MATH_INLINES
 #include <math.h>
 
 int
index f1cc9757b5563fcb60263d6696f87a652efe107f..51916e12ffd9d2f8afb2f558f025f85642930099 100644 (file)
@@ -17,7 +17,6 @@ not, write to the Free Software Foundation, Inc., 675 Mass Ave,
 Cambridge, MA 02139, USA.  */
 
 #include <ansidecl.h>
-#define        __NO_MATH_INLINES
 #include <math.h>
 
 #ifndef FUNC
index 5d1f337beef332f58a405b54c2006640863afa2d..d26f83875b69e7ce7c5a58a977fc4eb4d357ed4b 100644 (file)
@@ -17,7 +17,6 @@ not, write to the Free Software Foundation, Inc., 675 Mass Ave,
 Cambridge, MA 02139, USA.  */
 
 #include <ansidecl.h>
-#define        __NO_MATH_INLINES
 #include <math.h>
 
 #ifndef FUNC
index b24af7495654d5f7070400b01c749ffb47eeb350..45c054016d363c14f7ccc297ee31ecf39fabc52c 100644 (file)
@@ -17,7 +17,6 @@ not, write to the Free Software Foundation, Inc., 675 Mass Ave,
 Cambridge, MA 02139, USA.  */
 
 #include <ansidecl.h>
-#define        __NO_MATH_INLINES
 #include <math.h>
 
 double
index c7cd98a68472f6e099e1a1c6f9e8a987d340c0fc..dd30f6c39cc948f52f6cac0ce6d844fc6c1b5567 100644 (file)
@@ -17,7 +17,6 @@ not, write to the Free Software Foundation, Inc., 675 Mass Ave,
 Cambridge, MA 02139, USA.  */
 
 #include <ansidecl.h>
-#define        __NO_MATH_INLINES
 #include <math.h>
 
 float
index 2df00a656a03d0472dfb56a7f3fc103a720ad008..4119df968ae279ae8d0b184a4c547de07f532de2 100644 (file)
@@ -17,7 +17,6 @@ not, write to the Free Software Foundation, Inc., 675 Mass Ave,
 Cambridge, MA 02139, USA.  */
 
 #include <ansidecl.h>
-#define        __NO_MATH_INLINES
 #include <math.h>
 
 int
index 05f1546a96610c7bee6321c39da7f7af2c35143f..8d9a027f224644bcc24840b12095ae26f4482d3f 100644 (file)
@@ -17,7 +17,6 @@ not, write to the Free Software Foundation, Inc., 675 Mass Ave,
 Cambridge, MA 02139, USA.  */
 
 #include <ansidecl.h>
-#define        __NO_MATH_INLINES
 #include <math.h>
 
 int
index 96745337c9471e6339acdee1cfad0ee08808c5e7..eec07c7d3a5e192d37d3ff89e5e8fae1289c062c 100644 (file)
@@ -17,7 +17,6 @@ not, write to the Free Software Foundation, Inc., 675 Mass Ave,
 Cambridge, MA 02139, USA.  */
 
 #include <ansidecl.h>
-#define        __NO_MATH_INLINES
 #include <math.h>
 
 #ifndef FUNC
index d9101a9fd99a608903deefcd76b650cf9bd08d1d..8f18db5b088475bba5ee779363a0e1547f162ee1 100644 (file)
@@ -17,7 +17,6 @@ not, write to the Free Software Foundation, Inc., 675 Mass Ave,
 Cambridge, MA 02139, USA.  */
 
 #include <ansidecl.h>
-#define        __NO_MATH_INLINES
 #include <math.h>
 
 #ifndef FUNC
index ee7662e7d273fe7f2d762faaaef45b7bf10f3efc..67513d4875efc2b35169a0c20e83965d0b208c0d 100644 (file)
@@ -17,7 +17,6 @@ not, write to the Free Software Foundation, Inc., 675 Mass Ave,
 Cambridge, MA 02139, USA.  */
 
 #include <ansidecl.h>
-#define        __NO_MATH_INLINES
 #include <math.h>
 
 #ifndef FUNC
index a9741732a6c74f67ab157b54c74ccbcc2a5107ad..94abf25ac1ea954ec01e154a0f69e3e7920fc732 100644 (file)
@@ -17,7 +17,6 @@ not, write to the Free Software Foundation, Inc., 675 Mass Ave,
 Cambridge, MA 02139, USA.  */
 
 #include <ansidecl.h>
-#define        __NO_MATH_INLINES
 #include <math.h>
 
 #ifndef FUNC
index 355df2fb19d103791003fbc950f1fcd9376e7c89..ce70be8168bb2171212dd16b586bf498a51b6dec 100644 (file)
@@ -17,7 +17,6 @@ not, write to the Free Software Foundation, Inc., 675 Mass Ave,
 Cambridge, MA 02139, USA.  */
 
 #include <ansidecl.h>
-#define        __NO_MATH_INLINES
 #include <math.h>
 
 double
index f56bcb45ef18ce1df3161c948f552ed996521403..04b51d5be19ec3421b8aec7941a1c08cf8593a09 100644 (file)
@@ -17,7 +17,6 @@ not, write to the Free Software Foundation, Inc., 675 Mass Ave,
 Cambridge, MA 02139, USA.  */
 
 #include <ansidecl.h>
-#define        __NO_MATH_INLINES
 #include <math.h>
 
 float
diff --git a/sysdeps/unix/sysv/linux/getpriority.c b/sysdeps/unix/sysv/linux/getpriority.c
new file mode 100644 (file)
index 0000000..6dd56cc
--- /dev/null
@@ -0,0 +1,42 @@
+/* getpriority for Linux.
+Copyright (C) 1996 Free Software Foundation, Inc.
+
+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.  */
+
+#include <errno.h>
+#include <sys/resource.h>
+
+extern int __syscall_getpriority (int, int);
+
+/* The return value of __syscall_getpriority is biased by this value
+   to avoid returning negative values.  */
+#define PZERO 20
+
+/* Return the highest priority of any process specified by WHICH and WHO
+   (see above); if WHO is zero, the current process, process group, or user
+   (as specified by WHO) is used.  A lower priority number means higher
+   priority.  Priorities range from PRIO_MIN to PRIO_MAX.  */
+
+int
+getpriority (enum __priority_which which, int who)
+{
+  int res;
+
+  res = __syscall_getpriority ((int) which, who);
+  if (res >= 0)
+    res = PZERO - res;
+  return res;
+}
index 0b3623d9a3fe6756fb9bbe3a4b5c3093bde590d9..97bde853bc13453b8fc174849fd79bf002b0422c 100644 (file)
@@ -80,11 +80,9 @@ Cambridge, MA 02139, USA.  */
 
 /* Now two recommended fpucr */
 
-/* Linux default:
-     - extended precision
-     - rounding to nearest
-     - exceptions on overflow, zero divide and NaN */
-#define _FPU_DEFAULT  0x00005400
+/* The fdlibm code requires no interrupts for exceptions.  Don't
+   change the rounding mode, it would break long double I/O!  */
+#define _FPU_DEFAULT  0x00000000
 
 /* IEEE:  same as above, but exceptions.  We must make it non-zero so
    that __setfpucw works.  This bit will be ignored.  */
index b3e8fe85e9510fe97b788e8ebd67ce9ffb8e18ae..cd6c58bd32bd4685dfdea9ee0c72e004833d5cac 100644 (file)
@@ -1,2 +1 @@
 #include <linux/socket.h>
-#include <linux/socket.h>
index 6deee5950f9c7b890cfc918ce136641ba1c473c4..d78a1f7e89165991af807bc7a2eb52d5d1ddd950 100644 (file)
@@ -20,6 +20,7 @@ nanosleep     -       nanosleep       2       nanosleep
 personality    init-first personality  1       __personality   personality
 pipe           -       pipe            1       __pipe  pipe
 reboot         -       reboot          3       reboot
+s_getpriority  getpriority getpriority 2       __syscall_getpriority
 s_ptrace       ptrace  ptrace          4       __syscall_ptrace
 s_sigsuspend   sigsuspend sigsuspend   3       __syscall_sigsuspend
 sched_setp     -       sched_setparam  2       __sched_setparam        sched_setparam
index bf3de172df998faaa44de6c658819fde37fc219f..bc2c7e9d18557b138a8af774d1dfcfc08fbca15b 100644 (file)
@@ -48,7 +48,7 @@ main (int argc, char *argv[])
     {
 #define TEST(test)                                                           \
       do                                                                     \
-       if (is##test (ch) != iswctype ((wchar_t) ch, bit_##test))             \
+       if ((is##test (ch) == 0) != (iswctype (ch, bit_##test)) == 0)         \
          {                                                                   \
            printf ("class `%s' test for character \\%o failed\n",            \
                    #test, ch);                                               \