Home | History | Annotate | Line # | Download | only in intl
      1  1.1  mrg /* Handle list of needed message catalogs
      2  1.1  mrg    Copyright (C) 1995-1999, 2000, 2001 Free Software Foundation, Inc.
      3  1.1  mrg    Written by Ulrich Drepper <drepper (at) gnu.org>, 1995.
      4  1.1  mrg 
      5  1.1  mrg    This program is free software; you can redistribute it and/or modify it
      6  1.1  mrg    under the terms of the GNU Library General Public License as published
      7  1.1  mrg    by the Free Software Foundation; either version 2, or (at your option)
      8  1.1  mrg    any later version.
      9  1.1  mrg 
     10  1.1  mrg    This program is distributed in the hope that it will be useful,
     11  1.1  mrg    but WITHOUT ANY WARRANTY; without even the implied warranty of
     12  1.1  mrg    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     13  1.1  mrg    Library General Public License for more details.
     14  1.1  mrg 
     15  1.1  mrg    You should have received a copy of the GNU Library General Public
     16  1.1  mrg    License along with this program; if not, write to the Free Software
     17  1.1  mrg    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301,
     18  1.1  mrg    USA.  */
     19  1.1  mrg 
     20  1.1  mrg #ifdef HAVE_CONFIG_H
     21  1.1  mrg # include <config.h>
     22  1.1  mrg #endif
     23  1.1  mrg 
     24  1.1  mrg #include <stdio.h>
     25  1.1  mrg #include <sys/types.h>
     26  1.1  mrg #include <stdlib.h>
     27  1.1  mrg #include <string.h>
     28  1.1  mrg 
     29  1.1  mrg #if defined HAVE_UNISTD_H || defined _LIBC
     30  1.1  mrg # include <unistd.h>
     31  1.1  mrg #endif
     32  1.1  mrg 
     33  1.1  mrg #include "gettextP.h"
     34  1.1  mrg #ifdef _LIBC
     35  1.1  mrg # include <libintl.h>
     36  1.1  mrg #else
     37  1.1  mrg # include "libgnuintl.h"
     38  1.1  mrg #endif
     39  1.1  mrg 
     40  1.1  mrg /* @@ end of prolog @@ */
     41  1.1  mrg /* List of already loaded domains.  */
     42  1.1  mrg static struct loaded_l10nfile *_nl_loaded_domains;
     43  1.1  mrg 
     44  1.1  mrg 
     45  1.1  mrg /* Return a data structure describing the message catalog described by
     46  1.1  mrg    the DOMAINNAME and CATEGORY parameters with respect to the currently
     47  1.1  mrg    established bindings.  */
     48  1.1  mrg struct loaded_l10nfile *
     49  1.1  mrg internal_function
     50  1.1  mrg _nl_find_domain (dirname, locale, domainname, domainbinding)
     51  1.1  mrg      const char *dirname;
     52  1.1  mrg      char *locale;
     53  1.1  mrg      const char *domainname;
     54  1.1  mrg      struct binding *domainbinding;
     55  1.1  mrg {
     56  1.1  mrg   struct loaded_l10nfile *retval;
     57  1.1  mrg   const char *language;
     58  1.1  mrg   const char *modifier;
     59  1.1  mrg   const char *territory;
     60  1.1  mrg   const char *codeset;
     61  1.1  mrg   const char *normalized_codeset;
     62  1.1  mrg   const char *special;
     63  1.1  mrg   const char *sponsor;
     64  1.1  mrg   const char *revision;
     65  1.1  mrg   const char *alias_value;
     66  1.1  mrg   int mask;
     67  1.1  mrg 
     68  1.1  mrg   /* LOCALE can consist of up to four recognized parts for the XPG syntax:
     69  1.1  mrg 
     70  1.1  mrg 		language[_territory[.codeset]][@modifier]
     71  1.1  mrg 
     72  1.1  mrg      and six parts for the CEN syntax:
     73  1.1  mrg 
     74  1.1  mrg 	language[_territory][+audience][+special][,[sponsor][_revision]]
     75  1.1  mrg 
     76  1.1  mrg      Beside the first part all of them are allowed to be missing.  If
     77  1.1  mrg      the full specified locale is not found, the less specific one are
     78  1.1  mrg      looked for.  The various parts will be stripped off according to
     79  1.1  mrg      the following order:
     80  1.1  mrg 		(1) revision
     81  1.1  mrg 		(2) sponsor
     82  1.1  mrg 		(3) special
     83  1.1  mrg 		(4) codeset
     84  1.1  mrg 		(5) normalized codeset
     85  1.1  mrg 		(6) territory
     86  1.1  mrg 		(7) audience/modifier
     87  1.1  mrg    */
     88  1.1  mrg 
     89  1.1  mrg   /* If we have already tested for this locale entry there has to
     90  1.1  mrg      be one data set in the list of loaded domains.  */
     91  1.1  mrg   retval = _nl_make_l10nflist (&_nl_loaded_domains, dirname,
     92  1.1  mrg 			       strlen (dirname) + 1, 0, locale, NULL, NULL,
     93  1.1  mrg 			       NULL, NULL, NULL, NULL, NULL, domainname, 0);
     94  1.1  mrg   if (retval != NULL)
     95  1.1  mrg     {
     96  1.1  mrg       /* We know something about this locale.  */
     97  1.1  mrg       int cnt;
     98  1.1  mrg 
     99  1.1  mrg       if (retval->decided == 0)
    100  1.1  mrg 	_nl_load_domain (retval, domainbinding);
    101  1.1  mrg 
    102  1.1  mrg       if (retval->data != NULL)
    103  1.1  mrg 	return retval;
    104  1.1  mrg 
    105  1.1  mrg       for (cnt = 0; retval->successor[cnt] != NULL; ++cnt)
    106  1.1  mrg 	{
    107  1.1  mrg 	  if (retval->successor[cnt]->decided == 0)
    108  1.1  mrg 	    _nl_load_domain (retval->successor[cnt], domainbinding);
    109  1.1  mrg 
    110  1.1  mrg 	  if (retval->successor[cnt]->data != NULL)
    111  1.1  mrg 	    break;
    112  1.1  mrg 	}
    113  1.1  mrg       return cnt >= 0 ? retval : NULL;
    114  1.1  mrg       /* NOTREACHED */
    115  1.1  mrg     }
    116  1.1  mrg 
    117  1.1  mrg   /* See whether the locale value is an alias.  If yes its value
    118  1.1  mrg      *overwrites* the alias name.  No test for the original value is
    119  1.1  mrg      done.  */
    120  1.1  mrg   alias_value = _nl_expand_alias (locale);
    121  1.1  mrg   if (alias_value != NULL)
    122  1.1  mrg     {
    123  1.1  mrg #if defined _LIBC || defined HAVE_STRDUP
    124  1.1  mrg       locale = strdup (alias_value);
    125  1.1  mrg       if (locale == NULL)
    126  1.1  mrg 	return NULL;
    127  1.1  mrg #else
    128  1.1  mrg       size_t len = strlen (alias_value) + 1;
    129  1.1  mrg       locale = (char *) malloc (len);
    130  1.1  mrg       if (locale == NULL)
    131  1.1  mrg 	return NULL;
    132  1.1  mrg 
    133  1.1  mrg       memcpy (locale, alias_value, len);
    134  1.1  mrg #endif
    135  1.1  mrg     }
    136  1.1  mrg 
    137  1.1  mrg   /* Now we determine the single parts of the locale name.  First
    138  1.1  mrg      look for the language.  Termination symbols are `_' and `@' if
    139  1.1  mrg      we use XPG4 style, and `_', `+', and `,' if we use CEN syntax.  */
    140  1.1  mrg   mask = _nl_explode_name (locale, &language, &modifier, &territory,
    141  1.1  mrg 			   &codeset, &normalized_codeset, &special,
    142  1.1  mrg 			   &sponsor, &revision);
    143  1.1  mrg 
    144  1.1  mrg   /* Create all possible locale entries which might be interested in
    145  1.1  mrg      generalization.  */
    146  1.1  mrg   retval = _nl_make_l10nflist (&_nl_loaded_domains, dirname,
    147  1.1  mrg 			       strlen (dirname) + 1, mask, language, territory,
    148  1.1  mrg 			       codeset, normalized_codeset, modifier, special,
    149  1.1  mrg 			       sponsor, revision, domainname, 1);
    150  1.1  mrg   if (retval == NULL)
    151  1.1  mrg     /* This means we are out of core.  */
    152  1.1  mrg     return NULL;
    153  1.1  mrg 
    154  1.1  mrg   if (retval->decided == 0)
    155  1.1  mrg     _nl_load_domain (retval, domainbinding);
    156  1.1  mrg   if (retval->data == NULL)
    157  1.1  mrg     {
    158  1.1  mrg       int cnt;
    159  1.1  mrg       for (cnt = 0; retval->successor[cnt] != NULL; ++cnt)
    160  1.1  mrg 	{
    161  1.1  mrg 	  if (retval->successor[cnt]->decided == 0)
    162  1.1  mrg 	    _nl_load_domain (retval->successor[cnt], domainbinding);
    163  1.1  mrg 	  if (retval->successor[cnt]->data != NULL)
    164  1.1  mrg 	    break;
    165  1.1  mrg 	}
    166  1.1  mrg     }
    167  1.1  mrg 
    168  1.1  mrg   /* The room for an alias was dynamically allocated.  Free it now.  */
    169  1.1  mrg   if (alias_value != NULL)
    170  1.1  mrg     free (locale);
    171  1.1  mrg 
    172  1.1  mrg   /* The space for normalized_codeset is dynamically allocated.  Free it.  */
    173  1.1  mrg   if (mask & XPG_NORM_CODESET)
    174  1.1  mrg     free ((void *) normalized_codeset);
    175  1.1  mrg 
    176  1.1  mrg   return retval;
    177  1.1  mrg }
    178  1.1  mrg 
    179  1.1  mrg 
    180  1.1  mrg #ifdef _LIBC
    181  1.1  mrg libc_freeres_fn (free_mem)
    182  1.1  mrg {
    183  1.1  mrg   struct loaded_l10nfile *runp = _nl_loaded_domains;
    184  1.1  mrg 
    185  1.1  mrg   while (runp != NULL)
    186  1.1  mrg     {
    187  1.1  mrg       struct loaded_l10nfile *here = runp;
    188  1.1  mrg       if (runp->data != NULL)
    189  1.1  mrg 	_nl_unload_domain ((struct loaded_domain *) runp->data);
    190  1.1  mrg       runp = runp->next;
    191  1.1  mrg       free ((char *) here->filename);
    192  1.1  mrg       free (here);
    193  1.1  mrg     }
    194  1.1  mrg }
    195  1.1  mrg #endif
    196