1 | /* Test driver for nl_langinfo[_l] functions. |
2 | Copyright (C) 2000-2022 Free Software Foundation, Inc. |
3 | This file is part of the GNU C Library. |
4 | |
5 | The GNU C Library is free software; you can redistribute it and/or |
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. |
9 | |
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 |
13 | Lesser General Public License for more details. |
14 | |
15 | You should have received a copy of the GNU Lesser General Public |
16 | License along with the GNU C Library; if not, see |
17 | <https://www.gnu.org/licenses/>. */ |
18 | |
19 | #include <langinfo.h> |
20 | #include <locale.h> |
21 | #include <stdio.h> |
22 | #include <string.h> |
23 | |
24 | |
25 | struct map |
26 | { |
27 | const char *str; |
28 | int val; |
29 | } map[] = |
30 | { |
31 | #define VAL(name) { #name, name } |
32 | VAL (ABDAY_1), |
33 | VAL (ABDAY_2), |
34 | VAL (ABDAY_3), |
35 | VAL (ABDAY_4), |
36 | VAL (ABDAY_5), |
37 | VAL (ABDAY_6), |
38 | VAL (ABDAY_7), |
39 | VAL (ABMON_1), |
40 | VAL (ABMON_10), |
41 | VAL (ABMON_11), |
42 | VAL (ABMON_12), |
43 | VAL (ABMON_2), |
44 | VAL (ABMON_3), |
45 | VAL (ABMON_4), |
46 | VAL (ABMON_5), |
47 | VAL (ABMON_6), |
48 | VAL (ABMON_7), |
49 | VAL (ABMON_8), |
50 | VAL (ABMON_9), |
51 | VAL (ALT_DIGITS), |
52 | VAL (ALTMON_1), |
53 | VAL (ALTMON_10), |
54 | VAL (ALTMON_11), |
55 | VAL (ALTMON_12), |
56 | VAL (ALTMON_2), |
57 | VAL (ALTMON_3), |
58 | VAL (ALTMON_4), |
59 | VAL (ALTMON_5), |
60 | VAL (ALTMON_6), |
61 | VAL (ALTMON_7), |
62 | VAL (ALTMON_8), |
63 | VAL (ALTMON_9), |
64 | VAL (AM_STR), |
65 | VAL (CRNCYSTR), |
66 | VAL (CURRENCY_SYMBOL), |
67 | VAL (DAY_1), |
68 | VAL (DAY_2), |
69 | VAL (DAY_3), |
70 | VAL (DAY_4), |
71 | VAL (DAY_5), |
72 | VAL (DAY_6), |
73 | VAL (DAY_7), |
74 | VAL (DECIMAL_POINT), |
75 | VAL (D_FMT), |
76 | VAL (D_T_FMT), |
77 | VAL (ERA), |
78 | VAL (ERA_D_FMT), |
79 | VAL (ERA_D_T_FMT), |
80 | VAL (ERA_T_FMT), |
81 | VAL (ERA_YEAR), |
82 | VAL (FRAC_DIGITS), |
83 | VAL (GROUPING), |
84 | VAL (INT_CURR_SYMBOL), |
85 | VAL (INT_FRAC_DIGITS), |
86 | VAL (MON_1), |
87 | VAL (MON_10), |
88 | VAL (MON_11), |
89 | VAL (MON_12), |
90 | VAL (MON_2), |
91 | VAL (MON_3), |
92 | VAL (MON_4), |
93 | VAL (MON_5), |
94 | VAL (MON_6), |
95 | VAL (MON_7), |
96 | VAL (MON_8), |
97 | VAL (MON_9), |
98 | VAL (MON_DECIMAL_POINT), |
99 | VAL (MON_GROUPING), |
100 | VAL (MON_THOUSANDS_SEP), |
101 | VAL (NEGATIVE_SIGN), |
102 | VAL (NOEXPR), |
103 | VAL (NOSTR), |
104 | VAL (N_CS_PRECEDES), |
105 | VAL (N_SEP_BY_SPACE), |
106 | VAL (N_SIGN_POSN), |
107 | VAL (PM_STR), |
108 | VAL (POSITIVE_SIGN), |
109 | VAL (P_CS_PRECEDES), |
110 | VAL (P_SEP_BY_SPACE), |
111 | VAL (P_SIGN_POSN), |
112 | VAL (RADIXCHAR), |
113 | VAL (THOUSANDS_SEP), |
114 | VAL (THOUSEP), |
115 | VAL (T_FMT), |
116 | VAL (T_FMT_AMPM), |
117 | VAL (YESEXPR), |
118 | VAL (YESSTR) |
119 | }; |
120 | |
121 | |
122 | static int |
123 | map_paramstr (const char *str) |
124 | { |
125 | int low = 0; |
126 | int high = sizeof (map) / sizeof (map[0]); |
127 | |
128 | while (low < high) |
129 | { |
130 | int med = (low + high) / 2; |
131 | int cmpres; |
132 | |
133 | cmpres = strcmp (str, map[med].str); |
134 | if (cmpres == 0) |
135 | return map[med].val; |
136 | else if (cmpres > 0) |
137 | low = med + 1; |
138 | else |
139 | high = med; |
140 | } |
141 | |
142 | return -1; |
143 | } |
144 | |
145 | |
146 | #ifdef DEBUG |
147 | # define REASON(str) printf ("\"%s\" ignored: %s\n", buf, str) |
148 | #else |
149 | # define REASON(str) |
150 | #endif |
151 | |
152 | static int |
153 | do_test (void) |
154 | { |
155 | int result = 0; |
156 | |
157 | while (! feof (stdin)) |
158 | { |
159 | char buf[1000]; |
160 | char *rp; |
161 | char *locale; |
162 | char *paramstr; |
163 | char *expected; |
164 | int param; |
165 | |
166 | if (fgets (s: buf, n: sizeof (buf), stdin) == NULL) |
167 | break; |
168 | |
169 | /* Split the fields. There are three is them: |
170 | 1. locale |
171 | 2. langinfo() parameter |
172 | 3. expected result; this can be a string with white space etc. |
173 | */ |
174 | rp = buf; |
175 | while (*rp == ' ' || *rp == '\t') |
176 | ++rp; |
177 | |
178 | if (*rp == '#') |
179 | { |
180 | /* It's a comment line. Ignore it. */ |
181 | REASON ("comment" ); |
182 | continue; |
183 | } |
184 | locale = rp; |
185 | |
186 | while (*rp != '\0' && *rp != ' ' && *rp != '\t' && *rp != '\n') |
187 | ++rp; |
188 | if (*rp == '\0' || *rp == '\n') |
189 | { |
190 | /* Incomplete line. */ |
191 | REASON ("incomplete line" ); |
192 | continue; |
193 | } |
194 | *rp++ = '\0'; |
195 | |
196 | while (*rp == ' ' || *rp == '\t') |
197 | ++rp; |
198 | paramstr = rp; |
199 | |
200 | while (*rp != '\0' && *rp != ' ' && *rp != '\t' && *rp != '\n') |
201 | ++rp; |
202 | if (*rp == '\0' || *rp == '\n') |
203 | { |
204 | /* Incomplete line. */ |
205 | REASON ("incomplete line" ); |
206 | continue; |
207 | } |
208 | *rp++ = '\0'; |
209 | |
210 | while (*rp == ' ' || *rp == '\t') |
211 | ++rp; |
212 | |
213 | if (*rp == '"') |
214 | { |
215 | char *wp; |
216 | |
217 | expected = wp = ++rp; |
218 | while (*rp != '"' && *rp != '\n' && *rp != '\0') |
219 | { |
220 | if (*rp == '\\') |
221 | { |
222 | ++rp; |
223 | if (*rp == '\0') |
224 | break; |
225 | if (*rp >= '0' && *rp <= '9') |
226 | { |
227 | int val = *rp - '0'; |
228 | if (rp[1] >= '0' && rp[1] <= '9') |
229 | { |
230 | ++rp; |
231 | val *= 10; |
232 | val += *rp - '0'; |
233 | if (rp[1] >= '0' && rp[1] <= '9') |
234 | { |
235 | ++rp; |
236 | val *= 10; |
237 | val += *rp - '0'; |
238 | } |
239 | } |
240 | *rp = val; |
241 | } |
242 | } |
243 | *wp++ = *rp++; |
244 | } |
245 | |
246 | if (*rp != '"') |
247 | { |
248 | REASON ("missing '\"'" ); |
249 | continue; |
250 | } |
251 | |
252 | *wp = '\0'; |
253 | } |
254 | else |
255 | { |
256 | expected = rp; |
257 | while (*rp != '\0' && *rp != '\n') |
258 | ++rp; |
259 | *rp = '\0'; |
260 | } |
261 | |
262 | param = map_paramstr (str: paramstr); |
263 | if (param == -1) |
264 | { |
265 | /* Invalid parameter. */ |
266 | REASON ("invalid parameter" ); |
267 | continue; |
268 | } |
269 | |
270 | result = test_locale (locale, paramstr, param, expected); |
271 | } |
272 | |
273 | return result; |
274 | } |
275 | |
276 | #define TEST_FUNCTION do_test () |
277 | #include "../test-skeleton.c" |
278 | |