about summary refs log tree commit diff
path: root/intl/finddomain.c
diff options
context:
space:
mode:
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