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