]> git.ipfire.org Git - thirdparty/glibc.git/blame - intl/finddomain.c
dcigettext.c: Add missing bracket
[thirdparty/glibc.git] / intl / finddomain.c
CommitLineData
8f2ece69 1/* Handle list of needed message catalogs
1c298d08 2 Copyright (C) 1995-1999, 2000, 2001, 2002, 2004, 2006, 2007
9e365fe7 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>
f6b90f42 38# include <bits/libc-lock.h>
24906b43 39#else
4a4d50f3 40# include "libgnuintl.h"
24906b43
RM
41#endif
42
43/* @@ end of prolog @@ */
24906b43 44/* List of already loaded domains. */
7a12c6bb 45static struct loaded_l10nfile *_nl_loaded_domains;
857fa1b8 46
24906b43
RM
47
48/* Return a data structure describing the message catalog described by
49 the DOMAINNAME and CATEGORY parameters with respect to the currently
50 established bindings. */
7a12c6bb 51struct loaded_l10nfile *
d0fc4041 52internal_function
17c389fc 53_nl_find_domain (dirname, locale, domainname, domainbinding)
24906b43
RM
54 const char *dirname;
55 char *locale;
56 const char *domainname;
17c389fc 57 struct binding *domainbinding;
24906b43 58{
7a12c6bb 59 struct loaded_l10nfile *retval;
24906b43 60 const char *language;
7a12c6bb
RM
61 const char *modifier;
62 const char *territory;
63 const char *codeset;
64 const char *normalized_codeset;
7a12c6bb 65 const char *alias_value;
24906b43
RM
66 int mask;
67
7a12c6bb 68 /* LOCALE can consist of up to four recognized parts for the XPG syntax:
24906b43
RM
69
70 language[_territory[.codeset]][@modifier]
71
f41c8091
UD
72 Beside the first part all of them are allowed to be missing. If
73 the full specified locale is not found, the less specific one are
74 looked for. The various parts will be stripped off according to
24906b43 75 the following order:
e155c801
UD
76 (1) codeset
77 (2) normalized codeset
78 (3) territory
79 (4) modifier
24906b43
RM
80 */
81
f6b90f42 82 /* We need to protect modifying the _NL_LOADED_DOMAINS data. */
ce7265c7
UD
83 __libc_rwlock_define_initialized (static, lock);
84 __libc_rwlock_rdlock (lock);
f6b90f42 85
24906b43
RM
86 /* If we have already tested for this locale entry there has to
87 be one data set in the list of loaded domains. */
7a12c6bb
RM
88 retval = _nl_make_l10nflist (&_nl_loaded_domains, dirname,
89 strlen (dirname) + 1, 0, locale, NULL, NULL,
e155c801 90 NULL, NULL, domainname, 0);
ce7265c7 91 __libc_rwlock_unlock (lock);
f6b90f42 92
24906b43
RM
93 if (retval != NULL)
94 {
95 /* We know something about this locale. */
96 int cnt;
97
ce7265c7 98 if (retval->decided <= 0)
c44a663d 99 _nl_load_domain (retval, domainbinding);
24906b43
RM
100
101 if (retval->data != NULL)
102 return retval;
103
75914335 104 for (cnt = 0; retval->successor[cnt] != NULL; ++cnt)
24906b43 105 {
ce7265c7 106 if (retval->successor[cnt]->decided <= 0)
c44a663d 107 _nl_load_domain (retval->successor[cnt], domainbinding);
24906b43
RM
108
109 if (retval->successor[cnt]->data != NULL)
110 break;
111 }
f6b90f42 112
0292b0dd 113 return retval;
24906b43
RM
114 /* NOTREACHED */
115 }
116
117 /* See whether the locale value is an alias. If yes its value
118 *overwrites* the alias name. No test for the original value is
119 done. */
120 alias_value = _nl_expand_alias (locale);
121 if (alias_value != NULL)
0292b0dd 122 locale = strdupa (alias_value);
24906b43
RM
123
124 /* Now we determine the single parts of the locale name. First
125 look for the language. Termination symbols are `_' and `@' if
126 we use XPG4 style, and `_', `+', and `,' if we use CEN syntax. */
7a12c6bb 127 mask = _nl_explode_name (locale, &language, &modifier, &territory,
e155c801 128 &codeset, &normalized_codeset);
1c298d08
UD
129 if (mask == -1)
130 /* This means we are out of core. */
131 return NULL;
24906b43 132
f6b90f42 133 /* We need to protect modifying the _NL_LOADED_DOMAINS data. */
ce7265c7 134 __libc_rwlock_wrlock (lock);
f6b90f42 135
24906b43 136 /* Create all possible locale entries which might be interested in
6d52618b 137 generalization. */
7a12c6bb
RM
138 retval = _nl_make_l10nflist (&_nl_loaded_domains, dirname,
139 strlen (dirname) + 1, mask, language, territory,
e155c801
UD
140 codeset, normalized_codeset, modifier,
141 domainname, 1);
ce7265c7 142 __libc_rwlock_unlock (lock);
f6b90f42 143
24906b43
RM
144 if (retval == NULL)
145 /* This means we are out of core. */
ce31a3b1 146 goto out;
24906b43 147
ce7265c7 148 if (retval->decided <= 0)
c44a663d 149 _nl_load_domain (retval, domainbinding);
24906b43
RM
150 if (retval->data == NULL)
151 {
152 int cnt;
153 for (cnt = 0; retval->successor[cnt] != NULL; ++cnt)
154 {
ce7265c7 155 if (retval->successor[cnt]->decided <= 0)
c44a663d 156 _nl_load_domain (retval->successor[cnt], domainbinding);
24906b43
RM
157 if (retval->successor[cnt]->data != NULL)
158 break;
24906b43 159 }
24906b43
RM
160 }
161
ce31a3b1 162out:
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