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