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