Back to Evolution Project page
00001 /* Handle list of needed message catalogs 00002 Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc. 00003 Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995. 00004 00005 This program is free software; you can redistribute it and/or modify 00006 it under the terms of the GNU General Public License as published by 00007 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 00013 GNU General Public License for more details. 00014 00015 You should have received a copy of the GNU General Public License 00016 along with this program; if not, write to the Free Software Foundation, 00017 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 00018 00019 #ifdef HAVE_CONFIG_H 00020 # include <config.h> 00021 #endif 00022 00023 #include <ctype.h> 00024 #include <errno.h> 00025 #include <stdio.h> 00026 #include <sys/types.h> 00027 00028 #if defined STDC_HEADERS || defined _LIBC 00029 # include <stdlib.h> 00030 #else 00031 # ifdef HAVE_MALLOC_H 00032 # include <malloc.h> 00033 # else 00034 void free (); 00035 # endif 00036 #endif 00037 00038 #if defined HAVE_STRING_H || defined _LIBC 00039 # include <string.h> 00040 #else 00041 # include <strings.h> 00042 # ifndef memcpy 00043 # define memcpy(Dst, Src, Num) bcopy (Src, Dst, Num) 00044 # endif 00045 #endif 00046 #if !HAVE_STRCHR && !defined _LIBC 00047 # ifndef strchr 00048 # define strchr index 00049 # endif 00050 #endif 00051 00052 #if defined HAVE_UNISTD_H || defined _LIBC 00053 # include <unistd.h> 00054 #endif 00055 00056 #include "gettext.h" 00057 #include "gettextP.h" 00058 #ifdef _LIBC 00059 # include <libintl.h> 00060 #else 00061 # include "libgettext.h" 00062 #endif 00063 00064 /* @@ end of prolog @@ */ 00065 /* List of already loaded domains. */ 00066 static struct loaded_l10nfile *_nl_loaded_domains; 00067 00068 00069 /* Return a data structure describing the message catalog described by 00070 the DOMAINNAME and CATEGORY parameters with respect to the currently 00071 established bindings. */ 00072 struct loaded_l10nfile * 00073 internal_function 00074 _nl_find_domain (dirname, locale, domainname) 00075 const char *dirname; 00076 char *locale; 00077 const char *domainname; 00078 { 00079 struct loaded_l10nfile *retval; 00080 const char *language; 00081 const char *modifier; 00082 const char *territory; 00083 const char *codeset; 00084 const char *normalized_codeset; 00085 const char *special; 00086 const char *sponsor; 00087 const char *revision; 00088 const char *alias_value; 00089 int mask; 00090 00091 /* LOCALE can consist of up to four recognized parts for the XPG syntax: 00092 00093 language[_territory[.codeset]][@modifier] 00094 00095 and six parts for the CEN syntax: 00096 00097 language[_territory][+audience][+special][,[sponsor][_revision]] 00098 00099 Beside the first part all of them are allowed to be missing. If 00100 the full specified locale is not found, the less specific one are 00101 looked for. The various parts will be stripped off according to 00102 the following order: 00103 (1) revision 00104 (2) sponsor 00105 (3) special 00106 (4) codeset 00107 (5) normalized codeset 00108 (6) territory 00109 (7) audience/modifier 00110 */ 00111 00112 /* If we have already tested for this locale entry there has to 00113 be one data set in the list of loaded domains. */ 00114 retval = _nl_make_l10nflist (&_nl_loaded_domains, dirname, 00115 strlen (dirname) + 1, 0, locale, NULL, NULL, 00116 NULL, NULL, NULL, NULL, NULL, domainname, 0); 00117 if (retval != NULL) 00118 { 00119 /* We know something about this locale. */ 00120 int cnt; 00121 00122 if (retval->decided == 0) 00123 _nl_load_domain (retval); 00124 00125 if (retval->data != NULL) 00126 return retval; 00127 00128 for (cnt = 0; retval->successor[cnt] != NULL; ++cnt) 00129 { 00130 if (retval->successor[cnt]->decided == 0) 00131 _nl_load_domain (retval->successor[cnt]); 00132 00133 if (retval->successor[cnt]->data != NULL) 00134 break; 00135 } 00136 return cnt >= 0 ? retval : NULL; 00137 /* NOTREACHED */ 00138 } 00139 00140 /* See whether the locale value is an alias. If yes its value 00141 *overwrites* the alias name. No test for the original value is 00142 done. */ 00143 alias_value = _nl_expand_alias (locale); 00144 if (alias_value != NULL) 00145 { 00146 #if defined _LIBC || defined HAVE_STRDUP 00147 locale = strdup (alias_value); 00148 if (locale == NULL) 00149 return NULL; 00150 #else 00151 size_t len = strlen (alias_value) + 1; 00152 locale = (char *) malloc (len); 00153 if (locale == NULL) 00154 return NULL; 00155 00156 memcpy (locale, alias_value, len); 00157 #endif 00158 } 00159 00160 /* Now we determine the single parts of the locale name. First 00161 look for the language. Termination symbols are `_' and `@' if 00162 we use XPG4 style, and `_', `+', and `,' if we use CEN syntax. */ 00163 mask = _nl_explode_name (locale, &language, &modifier, &territory, 00164 &codeset, &normalized_codeset, &special, 00165 &sponsor, &revision); 00166 00167 /* Create all possible locale entries which might be interested in 00168 generalization. */ 00169 retval = _nl_make_l10nflist (&_nl_loaded_domains, dirname, 00170 strlen (dirname) + 1, mask, language, territory, 00171 codeset, normalized_codeset, modifier, special, 00172 sponsor, revision, domainname, 1); 00173 if (retval == NULL) 00174 /* This means we are out of core. */ 00175 return NULL; 00176 00177 if (retval->decided == 0) 00178 _nl_load_domain (retval); 00179 if (retval->data == NULL) 00180 { 00181 int cnt; 00182 for (cnt = 0; retval->successor[cnt] != NULL; ++cnt) 00183 { 00184 if (retval->successor[cnt]->decided == 0) 00185 _nl_load_domain (retval->successor[cnt]); 00186 if (retval->successor[cnt]->data != NULL) 00187 break; 00188 } 00189 } 00190 00191 /* The room for an alias was dynamically allocated. Free it now. */ 00192 if (alias_value != NULL) 00193 free (locale); 00194 00195 return retval; 00196 } 00197 00198 00199 #ifdef _LIBC 00200 static void __attribute__ ((unused)) 00201 free_mem (void) 00202 { 00203 struct loaded_l10nfile *runp = _nl_loaded_domains; 00204 00205 while (runp != NULL) 00206 { 00207 struct loaded_l10nfile *here = runp; 00208 if (runp->data != NULL) 00209 _nl_unload_domain ((struct loaded_domain *) runp->data); 00210 runp = runp->next; 00211 free (here); 00212 } 00213 } 00214 00215 text_set_element (__libc_subfreeres, free_mem); 00216 #endif