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