xref: /netbsd-src/external/gpl2/grep/dist/intl/finddomain.c (revision a8fa202a6440953be7b92a8960a811bff58203f4)
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