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
map_paramstr(const char * str)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
do_test(void)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 (buf, 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 (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