Back to index

cell-binutils  2.17cvs20070401
finddomain.c
Go to the documentation of this file.
00001 /* Handle list of needed message catalogs
00002    Copyright (C) 1995-1999, 2000, 2001 Free Software Foundation, Inc.
00003    Written by Ulrich Drepper <drepper@gnu.org>, 1995.
00004 
00005    This program is free software; you can redistribute it and/or modify it
00006    under the terms of the GNU Library General Public License as published
00007    by the Free Software Foundation; either version 2, or (at your option)
00008    any later version.
00009 
00010    This program is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Library General Public License for more details.
00014 
00015    You should have received a copy of the GNU Library General Public
00016    License along with this program; if not, write to the Free Software
00017    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301,
00018    USA.  */
00019 
00020 #ifdef HAVE_CONFIG_H
00021 # include <config.h>
00022 #endif
00023 
00024 #include <stdio.h>
00025 #include <sys/types.h>
00026 #include <stdlib.h>
00027 #include <string.h>
00028 
00029 #if defined HAVE_UNISTD_H || defined _LIBC
00030 # include <unistd.h>
00031 #endif
00032 
00033 #include "gettextP.h"
00034 #ifdef _LIBC
00035 # include <libintl.h>
00036 #else
00037 # include "libgnuintl.h"
00038 #endif
00039 
00040 /* @@ end of prolog @@ */
00041 /* List of already loaded domains.  */
00042 static struct loaded_l10nfile *_nl_loaded_domains;
00043 
00044 
00045 /* Return a data structure describing the message catalog described by
00046    the DOMAINNAME and CATEGORY parameters with respect to the currently
00047    established bindings.  */
00048 struct loaded_l10nfile *
00049 internal_function
00050 _nl_find_domain (dirname, locale, domainname, domainbinding)
00051      const char *dirname;
00052      char *locale;
00053      const char *domainname;
00054      struct binding *domainbinding;
00055 {
00056   struct loaded_l10nfile *retval;
00057   const char *language;
00058   const char *modifier;
00059   const char *territory;
00060   const char *codeset;
00061   const char *normalized_codeset;
00062   const char *special;
00063   const char *sponsor;
00064   const char *revision;
00065   const char *alias_value;
00066   int mask;
00067 
00068   /* LOCALE can consist of up to four recognized parts for the XPG syntax:
00069 
00070               language[_territory[.codeset]][@modifier]
00071 
00072      and six parts for the CEN syntax:
00073 
00074        language[_territory][+audience][+special][,[sponsor][_revision]]
00075 
00076      Beside the first part all of them are allowed to be missing.  If
00077      the full specified locale is not found, the less specific one are
00078      looked for.  The various parts will be stripped off according to
00079      the following order:
00080               (1) revision
00081               (2) sponsor
00082               (3) special
00083               (4) codeset
00084               (5) normalized codeset
00085               (6) territory
00086               (7) audience/modifier
00087    */
00088 
00089   /* If we have already tested for this locale entry there has to
00090      be one data set in the list of loaded domains.  */
00091   retval = _nl_make_l10nflist (&_nl_loaded_domains, dirname,
00092                             strlen (dirname) + 1, 0, locale, NULL, NULL,
00093                             NULL, NULL, NULL, NULL, NULL, domainname, 0);
00094   if (retval != NULL)
00095     {
00096       /* We know something about this locale.  */
00097       int cnt;
00098 
00099       if (retval->decided == 0)
00100        _nl_load_domain (retval, domainbinding);
00101 
00102       if (retval->data != NULL)
00103        return retval;
00104 
00105       for (cnt = 0; retval->successor[cnt] != NULL; ++cnt)
00106        {
00107          if (retval->successor[cnt]->decided == 0)
00108            _nl_load_domain (retval->successor[cnt], domainbinding);
00109 
00110          if (retval->successor[cnt]->data != NULL)
00111            break;
00112        }
00113       return cnt >= 0 ? retval : NULL;
00114       /* NOTREACHED */
00115     }
00116 
00117   /* See whether the locale value is an alias.  If yes its value
00118      *overwrites* the alias name.  No test for the original value is
00119      done.  */
00120   alias_value = _nl_expand_alias (locale);
00121   if (alias_value != NULL)
00122     {
00123 #if defined _LIBC || defined HAVE_STRDUP
00124       locale = strdup (alias_value);
00125       if (locale == NULL)
00126        return NULL;
00127 #else
00128       size_t len = strlen (alias_value) + 1;
00129       locale = (char *) malloc (len);
00130       if (locale == NULL)
00131        return NULL;
00132 
00133       memcpy (locale, alias_value, len);
00134 #endif
00135     }
00136 
00137   /* Now we determine the single parts of the locale name.  First
00138      look for the language.  Termination symbols are `_' and `@' if
00139      we use XPG4 style, and `_', `+', and `,' if we use CEN syntax.  */
00140   mask = _nl_explode_name (locale, &language, &modifier, &territory,
00141                         &codeset, &normalized_codeset, &special,
00142                         &sponsor, &revision);
00143 
00144   /* Create all possible locale entries which might be interested in
00145      generalization.  */
00146   retval = _nl_make_l10nflist (&_nl_loaded_domains, dirname,
00147                             strlen (dirname) + 1, mask, language, territory,
00148                             codeset, normalized_codeset, modifier, special,
00149                             sponsor, revision, domainname, 1);
00150   if (retval == NULL)
00151     /* This means we are out of core.  */
00152     return NULL;
00153 
00154   if (retval->decided == 0)
00155     _nl_load_domain (retval, domainbinding);
00156   if (retval->data == NULL)
00157     {
00158       int cnt;
00159       for (cnt = 0; retval->successor[cnt] != NULL; ++cnt)
00160        {
00161          if (retval->successor[cnt]->decided == 0)
00162            _nl_load_domain (retval->successor[cnt], domainbinding);
00163          if (retval->successor[cnt]->data != NULL)
00164            break;
00165        }
00166     }
00167 
00168   /* The room for an alias was dynamically allocated.  Free it now.  */
00169   if (alias_value != NULL)
00170     free (locale);
00171 
00172   /* The space for normalized_codeset is dynamically allocated.  Free it.  */
00173   if (mask & XPG_NORM_CODESET)
00174     free ((void *) normalized_codeset);
00175 
00176   return retval;
00177 }
00178 
00179 
00180 #ifdef _LIBC
00181 libc_freeres_fn (free_mem)
00182 {
00183   struct loaded_l10nfile *runp = _nl_loaded_domains;
00184 
00185   while (runp != NULL)
00186     {
00187       struct loaded_l10nfile *here = runp;
00188       if (runp->data != NULL)
00189        _nl_unload_domain ((struct loaded_domain *) runp->data);
00190       runp = runp->next;
00191       free ((char *) here->filename);
00192       free (here);
00193     }
00194 }
00195 #endif