Back to index

tetex-bin  3.0
finddomain.c
Go to the documentation of this file.
00001 /* Handle list of needed message catalogs
00002    Copyright (C) 1995-1999, 2000-2001, 2003 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
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 (const char *dirname, char *locale,
00051                const char *domainname, struct binding *domainbinding)
00052 {
00053   struct loaded_l10nfile *retval;
00054   const char *language;
00055   const char *modifier;
00056   const char *territory;
00057   const char *codeset;
00058   const char *normalized_codeset;
00059   const char *special;
00060   const char *sponsor;
00061   const char *revision;
00062   const char *alias_value;
00063   int mask;
00064 
00065   /* LOCALE can consist of up to four recognized parts for the XPG syntax:
00066 
00067               language[_territory[.codeset]][@modifier]
00068 
00069      and six parts for the CEN syntax:
00070 
00071        language[_territory][+audience][+special][,[sponsor][_revision]]
00072 
00073      Beside the first part all of them are allowed to be missing.  If
00074      the full specified locale is not found, the less specific one are
00075      looked for.  The various parts will be stripped off according to
00076      the following order:
00077               (1) revision
00078               (2) sponsor
00079               (3) special
00080               (4) codeset
00081               (5) normalized codeset
00082               (6) territory
00083               (7) audience/modifier
00084    */
00085 
00086   /* If we have already tested for this locale entry there has to
00087      be one data set in the list of loaded domains.  */
00088   retval = _nl_make_l10nflist (&_nl_loaded_domains, dirname,
00089                             strlen (dirname) + 1, 0, locale, NULL, NULL,
00090                             NULL, NULL, NULL, NULL, NULL, domainname, 0);
00091   if (retval != NULL)
00092     {
00093       /* We know something about this locale.  */
00094       int cnt;
00095 
00096       if (retval->decided == 0)
00097        _nl_load_domain (retval, domainbinding);
00098 
00099       if (retval->data != NULL)
00100        return retval;
00101 
00102       for (cnt = 0; retval->successor[cnt] != NULL; ++cnt)
00103        {
00104          if (retval->successor[cnt]->decided == 0)
00105            _nl_load_domain (retval->successor[cnt], domainbinding);
00106 
00107          if (retval->successor[cnt]->data != NULL)
00108            break;
00109        }
00110       return cnt >= 0 ? retval : NULL;
00111       /* NOTREACHED */
00112     }
00113 
00114   /* See whether the locale value is an alias.  If yes its value
00115      *overwrites* the alias name.  No test for the original value is
00116      done.  */
00117   alias_value = _nl_expand_alias (locale);
00118   if (alias_value != NULL)
00119     {
00120 #if defined _LIBC || defined HAVE_STRDUP
00121       locale = strdup (alias_value);
00122       if (locale == NULL)
00123        return NULL;
00124 #else
00125       size_t len = strlen (alias_value) + 1;
00126       locale = (char *) malloc (len);
00127       if (locale == NULL)
00128        return NULL;
00129 
00130       memcpy (locale, alias_value, len);
00131 #endif
00132     }
00133 
00134   /* Now we determine the single parts of the locale name.  First
00135      look for the language.  Termination symbols are `_' and `@' if
00136      we use XPG4 style, and `_', `+', and `,' if we use CEN syntax.  */
00137   mask = _nl_explode_name (locale, &language, &modifier, &territory,
00138                         &codeset, &normalized_codeset, &special,
00139                         &sponsor, &revision);
00140 
00141   /* Create all possible locale entries which might be interested in
00142      generalization.  */
00143   retval = _nl_make_l10nflist (&_nl_loaded_domains, dirname,
00144                             strlen (dirname) + 1, mask, language, territory,
00145                             codeset, normalized_codeset, modifier, special,
00146                             sponsor, revision, domainname, 1);
00147   if (retval == NULL)
00148     /* This means we are out of core.  */
00149     return NULL;
00150 
00151   if (retval->decided == 0)
00152     _nl_load_domain (retval, domainbinding);
00153   if (retval->data == NULL)
00154     {
00155       int cnt;
00156       for (cnt = 0; retval->successor[cnt] != NULL; ++cnt)
00157        {
00158          if (retval->successor[cnt]->decided == 0)
00159            _nl_load_domain (retval->successor[cnt], domainbinding);
00160          if (retval->successor[cnt]->data != NULL)
00161            break;
00162        }
00163     }
00164 
00165   /* The room for an alias was dynamically allocated.  Free it now.  */
00166   if (alias_value != NULL)
00167     free (locale);
00168 
00169   /* The space for normalized_codeset is dynamically allocated.  Free it.  */
00170   if (mask & XPG_NORM_CODESET)
00171     free ((void *) normalized_codeset);
00172 
00173   return retval;
00174 }
00175 
00176 
00177 #ifdef _LIBC
00178 libc_freeres_fn (free_mem)
00179 {
00180   struct loaded_l10nfile *runp = _nl_loaded_domains;
00181 
00182   while (runp != NULL)
00183     {
00184       struct loaded_l10nfile *here = runp;
00185       if (runp->data != NULL)
00186        _nl_unload_domain ((struct loaded_domain *) runp->data);
00187       runp = runp->next;
00188       free ((char *) here->filename);
00189       free (here);
00190     }
00191 }
00192 #endif