1*946379e7Schristos /* Copyright (C) 1995-1998, 2000-2001, 2003, 2005 Free Software Foundation, Inc.
2*946379e7Schristos Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
3*946379e7Schristos
4*946379e7Schristos This program is free software; you can redistribute it and/or modify it
5*946379e7Schristos under the terms of the GNU Library General Public License as published
6*946379e7Schristos by the Free Software Foundation; either version 2, or (at your option)
7*946379e7Schristos any later version.
8*946379e7Schristos
9*946379e7Schristos This program is distributed in the hope that it will be useful,
10*946379e7Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of
11*946379e7Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12*946379e7Schristos Library General Public License for more details.
13*946379e7Schristos
14*946379e7Schristos You should have received a copy of the GNU Library General Public
15*946379e7Schristos License along with this program; if not, write to the Free Software
16*946379e7Schristos Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
17*946379e7Schristos USA. */
18*946379e7Schristos
19*946379e7Schristos #ifdef HAVE_CONFIG_H
20*946379e7Schristos # include <config.h>
21*946379e7Schristos #endif
22*946379e7Schristos
23*946379e7Schristos #include <stdlib.h>
24*946379e7Schristos #include <string.h>
25*946379e7Schristos #include <sys/types.h>
26*946379e7Schristos
27*946379e7Schristos #include "loadinfo.h"
28*946379e7Schristos
29*946379e7Schristos /* On some strange systems still no definition of NULL is found. Sigh! */
30*946379e7Schristos #ifndef NULL
31*946379e7Schristos # if defined __STDC__ && __STDC__
32*946379e7Schristos # define NULL ((void *) 0)
33*946379e7Schristos # else
34*946379e7Schristos # define NULL 0
35*946379e7Schristos # endif
36*946379e7Schristos #endif
37*946379e7Schristos
38*946379e7Schristos /* @@ end of prolog @@ */
39*946379e7Schristos
40*946379e7Schristos /* Split a locale name NAME into a leading language part and all the
41*946379e7Schristos rest. Return a pointer to the first character after the language,
42*946379e7Schristos i.e. to the first byte of the rest. */
43*946379e7Schristos static char *_nl_find_language (const char *name);
44*946379e7Schristos
45*946379e7Schristos static char *
_nl_find_language(const char * name)46*946379e7Schristos _nl_find_language (const char *name)
47*946379e7Schristos {
48*946379e7Schristos while (name[0] != '\0' && name[0] != '_' && name[0] != '@' && name[0] != '.')
49*946379e7Schristos ++name;
50*946379e7Schristos
51*946379e7Schristos return (char *) name;
52*946379e7Schristos }
53*946379e7Schristos
54*946379e7Schristos
55*946379e7Schristos int
_nl_explode_name(char * name,const char ** language,const char ** modifier,const char ** territory,const char ** codeset,const char ** normalized_codeset)56*946379e7Schristos _nl_explode_name (char *name,
57*946379e7Schristos const char **language, const char **modifier,
58*946379e7Schristos const char **territory, const char **codeset,
59*946379e7Schristos const char **normalized_codeset)
60*946379e7Schristos {
61*946379e7Schristos char *cp;
62*946379e7Schristos int mask;
63*946379e7Schristos
64*946379e7Schristos *modifier = NULL;
65*946379e7Schristos *territory = NULL;
66*946379e7Schristos *codeset = NULL;
67*946379e7Schristos *normalized_codeset = NULL;
68*946379e7Schristos
69*946379e7Schristos /* Now we determine the single parts of the locale name. First
70*946379e7Schristos look for the language. Termination symbols are `_', '.', and `@'. */
71*946379e7Schristos mask = 0;
72*946379e7Schristos *language = cp = name;
73*946379e7Schristos cp = _nl_find_language (*language);
74*946379e7Schristos
75*946379e7Schristos if (*language == cp)
76*946379e7Schristos /* This does not make sense: language has to be specified. Use
77*946379e7Schristos this entry as it is without exploding. Perhaps it is an alias. */
78*946379e7Schristos cp = strchr (*language, '\0');
79*946379e7Schristos else
80*946379e7Schristos {
81*946379e7Schristos if (cp[0] == '_')
82*946379e7Schristos {
83*946379e7Schristos /* Next is the territory. */
84*946379e7Schristos cp[0] = '\0';
85*946379e7Schristos *territory = ++cp;
86*946379e7Schristos
87*946379e7Schristos while (cp[0] != '\0' && cp[0] != '.' && cp[0] != '@')
88*946379e7Schristos ++cp;
89*946379e7Schristos
90*946379e7Schristos mask |= XPG_TERRITORY;
91*946379e7Schristos }
92*946379e7Schristos
93*946379e7Schristos if (cp[0] == '.')
94*946379e7Schristos {
95*946379e7Schristos /* Next is the codeset. */
96*946379e7Schristos cp[0] = '\0';
97*946379e7Schristos *codeset = ++cp;
98*946379e7Schristos
99*946379e7Schristos while (cp[0] != '\0' && cp[0] != '@')
100*946379e7Schristos ++cp;
101*946379e7Schristos
102*946379e7Schristos mask |= XPG_CODESET;
103*946379e7Schristos
104*946379e7Schristos if (*codeset != cp && (*codeset)[0] != '\0')
105*946379e7Schristos {
106*946379e7Schristos *normalized_codeset = _nl_normalize_codeset (*codeset,
107*946379e7Schristos cp - *codeset);
108*946379e7Schristos if (strcmp (*codeset, *normalized_codeset) == 0)
109*946379e7Schristos free ((char *) *normalized_codeset);
110*946379e7Schristos else
111*946379e7Schristos mask |= XPG_NORM_CODESET;
112*946379e7Schristos }
113*946379e7Schristos }
114*946379e7Schristos }
115*946379e7Schristos
116*946379e7Schristos if (cp[0] == '@')
117*946379e7Schristos {
118*946379e7Schristos /* Next is the modifier. */
119*946379e7Schristos cp[0] = '\0';
120*946379e7Schristos *modifier = ++cp;
121*946379e7Schristos
122*946379e7Schristos if (cp[0] != '\0')
123*946379e7Schristos mask |= XPG_MODIFIER;
124*946379e7Schristos }
125*946379e7Schristos
126*946379e7Schristos if (*territory != NULL && (*territory)[0] == '\0')
127*946379e7Schristos mask &= ~XPG_TERRITORY;
128*946379e7Schristos
129*946379e7Schristos if (*codeset != NULL && (*codeset)[0] == '\0')
130*946379e7Schristos mask &= ~XPG_CODESET;
131*946379e7Schristos
132*946379e7Schristos return mask;
133*946379e7Schristos }
134