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