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