]>
Commit | Line | Data |
---|---|---|
616d9133 | 1 | /* Copyright (C) 1995-2002, 2003, 2006 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 AJ |
15 | You should have received a copy of the GNU Lesser General Public |
16 | License along with the GNU C Library; if not, write to the Free | |
17 | Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | |
18 | 02111-1307 USA. */ | |
842907c6 RM |
19 | |
20 | #ifdef HAVE_CONFIG_H | |
21 | # include <config.h> | |
22 | #endif | |
7a12c6bb | 23 | |
0555fcce UD |
24 | #include <stdlib.h> |
25 | #include <string.h> | |
0c5ecdc4 | 26 | #include <sys/types.h> |
7a12c6bb RM |
27 | |
28 | #include "loadinfo.h" | |
29 | ||
842907c6 RM |
30 | /* On some strange systems still no definition of NULL is found. Sigh! */ |
31 | #ifndef NULL | |
32 | # if defined __STDC__ && __STDC__ | |
33 | # define NULL ((void *) 0) | |
34 | # else | |
35 | # define NULL 0 | |
36 | # endif | |
37 | #endif | |
38 | ||
39 | /* @@ end of prolog @@ */ | |
40 | ||
f5bf21a7 UD |
41 | static char *_nl_find_language PARAMS ((const char *name)); |
42 | ||
43 | static char * | |
4a4d50f3 UD |
44 | _nl_find_language (name) |
45 | const char *name; | |
3081378b | 46 | { |
e155c801 | 47 | while (name[0] != '\0' && name[0] != '_' && name[0] != '@' && name[0] != '.') |
3081378b UD |
48 | ++name; |
49 | ||
50 | return (char *) name; | |
51 | } | |
52 | ||
53 | ||
7a12c6bb RM |
54 | int |
55 | _nl_explode_name (name, language, modifier, territory, codeset, | |
e155c801 | 56 | normalized_codeset) |
7a12c6bb RM |
57 | char *name; |
58 | const char **language; | |
59 | const char **modifier; | |
60 | const char **territory; | |
61 | const char **codeset; | |
62 | const char **normalized_codeset; | |
7a12c6bb | 63 | { |
7a12c6bb RM |
64 | char *cp; |
65 | int mask; | |
842907c6 | 66 | |
7a12c6bb RM |
67 | *modifier = NULL; |
68 | *territory = NULL; | |
69 | *codeset = NULL; | |
70 | *normalized_codeset = NULL; | |
7a12c6bb RM |
71 | |
72 | /* Now we determine the single parts of the locale name. First | |
e155c801 | 73 | look for the language. Termination symbols are `_', '.', and `@'. */ |
7a12c6bb | 74 | mask = 0; |
7a12c6bb | 75 | *language = cp = name; |
3081378b | 76 | cp = _nl_find_language (*language); |
7a12c6bb RM |
77 | |
78 | if (*language == cp) | |
79 | /* This does not make sense: language has to be specified. Use | |
80 | this entry as it is without exploding. Perhaps it is an alias. */ | |
616d9133 | 81 | cp = __rawmemchr (*language, '\0'); |
e155c801 | 82 | else if (cp[0] != '@') |
7a12c6bb | 83 | { |
e155c801 UD |
84 | if (cp[0] == '_') |
85 | { | |
86 | /* Next is the territory. */ | |
87 | cp[0] = '\0'; | |
88 | *territory = ++cp; | |
7a12c6bb | 89 | |
e155c801 UD |
90 | while (cp[0] != '\0' && cp[0] != '.' && cp[0] != '@') |
91 | ++cp; | |
7a12c6bb | 92 | |
e155c801 UD |
93 | mask |= XPG_TERRITORY; |
94 | } | |
7a12c6bb RM |
95 | |
96 | if (cp[0] == '.') | |
97 | { | |
98 | /* Next is the codeset. */ | |
7a12c6bb RM |
99 | cp[0] = '\0'; |
100 | *codeset = ++cp; | |
101 | ||
102 | while (cp[0] != '\0' && cp[0] != '@') | |
103 | ++cp; | |
104 | ||
105 | mask |= XPG_CODESET; | |
106 | ||
107 | if (*codeset != cp && (*codeset)[0] != '\0') | |
108 | { | |
109 | *normalized_codeset = _nl_normalize_codeset (*codeset, | |
110 | cp - *codeset); | |
111 | if (strcmp (*codeset, *normalized_codeset) == 0) | |
112 | free ((char *) *normalized_codeset); | |
113 | else | |
114 | mask |= XPG_NORM_CODESET; | |
115 | } | |
116 | } | |
117 | } | |
118 | ||
e155c801 | 119 | if (cp[0] == '@') |
7a12c6bb RM |
120 | { |
121 | /* Next is the modifier. */ | |
7a12c6bb RM |
122 | cp[0] = '\0'; |
123 | *modifier = ++cp; | |
124 | ||
e155c801 UD |
125 | if (cp[0] != '\0') |
126 | mask |= XPG_MODIFIER; | |
7a12c6bb RM |
127 | } |
128 | ||
e155c801 UD |
129 | if (*territory != NULL && (*territory)[0] == '\0') |
130 | mask &= ~XPG_TERRITORY; | |
7a12c6bb | 131 | |
e155c801 UD |
132 | if (*codeset != NULL && (*codeset)[0] == '\0') |
133 | mask &= ~XPG_CODESET; | |
7a12c6bb RM |
134 | |
135 | return mask; | |
136 | } |