summary refs log tree commit diff
path: root/intl/finddomain.c
diff options
context:
space:
mode:
authorRoland McGrath <roland@gnu.org>1996-05-03 17:44:31 +0000
committerRoland McGrath <roland@gnu.org>1996-05-03 17:44:31 +0000
commit7a12c6bba750ca500009854db3a0fcdfb1ad61a7 (patch)
tree52654097781ee98deb03b41dd4f5a805bb9c9e30 /intl/finddomain.c
parent9e720468715080bd95edadf10fd45a2c8be5e678 (diff)
downloadglibc-7a12c6bba750ca500009854db3a0fcdfb1ad61a7.tar.gz
glibc-7a12c6bba750ca500009854db3a0fcdfb1ad61a7.tar.xz
glibc-7a12c6bba750ca500009854db3a0fcdfb1ad61a7.zip
Fri May 3 13:32:08 1996 Roland McGrath <roland@delasyd.gnu.ai.mit.edu> cvs/libc-960504
	* 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.
Diffstat (limited to 'intl/finddomain.c')
-rw-r--r--intl/finddomain.c414
1 files changed, 27 insertions, 387 deletions
diff --git a/intl/finddomain.c b/intl/finddomain.c
index 3ced26fa4b..bb4609e864 100644
--- a/intl/finddomain.c
+++ b/intl/finddomain.c
@@ -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