]>
Commit | Line | Data |
---|---|---|
63bda0c1 | 1 | /* Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc. |
0c5ecdc4 | 2 | Contributed by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995. |
7a12c6bb | 3 | |
0c5ecdc4 | 4 | This file is part of the GNU C Library. Its master source is NOT part of |
40a55d20 | 5 | the C library, however. |
842907c6 | 6 | |
0c5ecdc4 UD |
7 | The GNU C Library is free software; you can redistribute it and/or |
8 | modify it under the terms of the GNU Library General Public License as | |
9 | published by the Free Software Foundation; either version 2 of the | |
10 | License, or (at your option) any later version. | |
7a12c6bb | 11 | |
0c5ecdc4 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 | |
15 | Library General Public License for more details. | |
7a12c6bb | 16 | |
0c5ecdc4 UD |
17 | You should have received a copy of the GNU Library General Public |
18 | License along with the GNU C Library; see the file COPYING.LIB. If not, | |
19 | write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
20 | Boston, MA 02111-1307, USA. */ | |
842907c6 RM |
21 | |
22 | #ifdef HAVE_CONFIG_H | |
23 | # include <config.h> | |
24 | #endif | |
7a12c6bb | 25 | |
63bda0c1 UD |
26 | #if defined STDC_HEADERS || defined _LIBC |
27 | # include <stdlib.h> | |
28 | #endif | |
29 | ||
30 | #if defined HAVE_STRING_H || defined _LIBC | |
31 | # include <string.h> | |
32 | #else | |
33 | # include <strings.h> | |
34 | #endif | |
0c5ecdc4 | 35 | #include <sys/types.h> |
7a12c6bb RM |
36 | |
37 | #include "loadinfo.h" | |
38 | ||
842907c6 RM |
39 | /* On some strange systems still no definition of NULL is found. Sigh! */ |
40 | #ifndef NULL | |
41 | # if defined __STDC__ && __STDC__ | |
42 | # define NULL ((void *) 0) | |
43 | # else | |
44 | # define NULL 0 | |
45 | # endif | |
46 | #endif | |
47 | ||
48 | /* @@ end of prolog @@ */ | |
49 | ||
3081378b UD |
50 | char * |
51 | _nl_find_language (const char *name) | |
52 | { | |
53 | while (name[0] != '\0' && name[0] != '_' && name[0] != '@' | |
54 | && name[0] != '+' && name[0] != ',') | |
55 | ++name; | |
56 | ||
57 | return (char *) name; | |
58 | } | |
59 | ||
60 | ||
7a12c6bb RM |
61 | int |
62 | _nl_explode_name (name, language, modifier, territory, codeset, | |
63 | normalized_codeset, special, sponsor, revision) | |
64 | char *name; | |
65 | const char **language; | |
66 | const char **modifier; | |
67 | const char **territory; | |
68 | const char **codeset; | |
69 | const char **normalized_codeset; | |
70 | const char **special; | |
71 | const char **sponsor; | |
72 | const char **revision; | |
73 | { | |
74 | enum { undecided, xpg, cen } syntax; | |
75 | char *cp; | |
76 | int mask; | |
842907c6 | 77 | |
7a12c6bb RM |
78 | *modifier = NULL; |
79 | *territory = NULL; | |
80 | *codeset = NULL; | |
81 | *normalized_codeset = NULL; | |
82 | *special = NULL; | |
83 | *sponsor = NULL; | |
84 | *revision = NULL; | |
85 | ||
86 | /* Now we determine the single parts of the locale name. First | |
87 | look for the language. Termination symbols are `_' and `@' if | |
88 | we use XPG4 style, and `_', `+', and `,' if we use CEN syntax. */ | |
89 | mask = 0; | |
90 | syntax = undecided; | |
91 | *language = cp = name; | |
3081378b | 92 | cp = _nl_find_language (*language); |
7a12c6bb RM |
93 | |
94 | if (*language == cp) | |
95 | /* This does not make sense: language has to be specified. Use | |
96 | this entry as it is without exploding. Perhaps it is an alias. */ | |
97 | cp = strchr (*language, '\0'); | |
98 | else if (cp[0] == '_') | |
99 | { | |
100 | /* Next is the territory. */ | |
101 | cp[0] = '\0'; | |
102 | *territory = ++cp; | |
103 | ||
104 | while (cp[0] != '\0' && cp[0] != '.' && cp[0] != '@' | |
105 | && cp[0] != '+' && cp[0] != ',' && cp[0] != '_') | |
106 | ++cp; | |
107 | ||
108 | mask |= TERRITORY; | |
109 | ||
110 | if (cp[0] == '.') | |
111 | { | |
112 | /* Next is the codeset. */ | |
113 | syntax = xpg; | |
114 | cp[0] = '\0'; | |
115 | *codeset = ++cp; | |
116 | ||
117 | while (cp[0] != '\0' && cp[0] != '@') | |
118 | ++cp; | |
119 | ||
120 | mask |= XPG_CODESET; | |
121 | ||
122 | if (*codeset != cp && (*codeset)[0] != '\0') | |
123 | { | |
124 | *normalized_codeset = _nl_normalize_codeset (*codeset, | |
125 | cp - *codeset); | |
126 | if (strcmp (*codeset, *normalized_codeset) == 0) | |
127 | free ((char *) *normalized_codeset); | |
128 | else | |
129 | mask |= XPG_NORM_CODESET; | |
130 | } | |
131 | } | |
132 | } | |
133 | ||
134 | if (cp[0] == '@' || (syntax != xpg && cp[0] == '+')) | |
135 | { | |
136 | /* Next is the modifier. */ | |
137 | syntax = cp[0] == '@' ? xpg : cen; | |
138 | cp[0] = '\0'; | |
139 | *modifier = ++cp; | |
140 | ||
141 | while (syntax == cen && cp[0] != '\0' && cp[0] != '+' | |
142 | && cp[0] != ',' && cp[0] != '_') | |
143 | ++cp; | |
144 | ||
145 | mask |= XPG_MODIFIER | CEN_AUDIENCE; | |
146 | } | |
147 | ||
148 | if (syntax != xpg && (cp[0] == '+' || cp[0] == ',' || cp[0] == '_')) | |
149 | { | |
150 | syntax = cen; | |
151 | ||
152 | if (cp[0] == '+') | |
153 | { | |
154 | /* Next is special application (CEN syntax). */ | |
155 | cp[0] = '\0'; | |
156 | *special = ++cp; | |
157 | ||
158 | while (cp[0] != '\0' && cp[0] != ',' && cp[0] != '_') | |
159 | ++cp; | |
160 | ||
161 | mask |= CEN_SPECIAL; | |
162 | } | |
163 | ||
164 | if (cp[0] == ',') | |
165 | { | |
166 | /* Next is sponsor (CEN syntax). */ | |
167 | cp[0] = '\0'; | |
168 | *sponsor = ++cp; | |
169 | ||
170 | while (cp[0] != '\0' && cp[0] != '_') | |
171 | ++cp; | |
172 | ||
173 | mask |= CEN_SPONSOR; | |
174 | } | |
175 | ||
176 | if (cp[0] == '_') | |
177 | { | |
178 | /* Next is revision (CEN syntax). */ | |
179 | cp[0] = '\0'; | |
180 | *revision = ++cp; | |
181 | ||
182 | mask |= CEN_REVISION; | |
183 | } | |
184 | } | |
185 | ||
6d52618b | 186 | /* For CEN syntax values it might be important to have the |
7a12c6bb RM |
187 | separator character in the file name, not for XPG syntax. */ |
188 | if (syntax == xpg) | |
189 | { | |
190 | if (*territory != NULL && (*territory)[0] == '\0') | |
191 | mask &= ~TERRITORY; | |
192 | ||
193 | if (*codeset != NULL && (*codeset)[0] == '\0') | |
194 | mask &= ~XPG_CODESET; | |
195 | ||
196 | if (*modifier != NULL && (*modifier)[0] == '\0') | |
197 | mask &= ~XPG_MODIFIER; | |
198 | } | |
199 | ||
200 | return mask; | |
201 | } |