1 | /* Copyright (C) 1991-2022 Free Software Foundation, Inc. |
2 | This file is part of the GNU C Library. |
3 | |
4 | The GNU C Library is free software; you can redistribute it and/or |
5 | modify it under the terms of the GNU Lesser General Public |
6 | License as published by the Free Software Foundation; either |
7 | version 2.1 of the License, or (at your option) any later version. |
8 | |
9 | The GNU C Library is distributed in the hope that it will be useful, |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
12 | Lesser General Public License for more details. |
13 | |
14 | You should have received a copy of the GNU Lesser General Public |
15 | License along with the GNU C Library; if not, see |
16 | <https://www.gnu.org/licenses/>. */ |
17 | |
18 | #include <array_length.h> |
19 | #ifdef BSD |
20 | #include </usr/include/stdio.h> |
21 | #else |
22 | #include <stdio.h> |
23 | #endif |
24 | #include <math.h> |
25 | #include <stdlib.h> |
26 | #include <string.h> |
27 | |
28 | |
29 | int |
30 | main (int argc, char **argv) |
31 | { |
32 | char buf[BUFSIZ]; |
33 | FILE *in = stdin, *out = stdout; |
34 | int x; |
35 | int result = 0; |
36 | |
37 | if (sscanf ("0" , "%d" , &x) != 1) |
38 | { |
39 | fputs ("test failed!\n" , stdout); |
40 | result = 1; |
41 | } |
42 | |
43 | if (sscanf ("08905x" , "%9[0-9]" , buf) != 1 |
44 | || strcmp (buf, "08905" ) != 0) |
45 | { |
46 | fputs ("test failed!\n" , stdout); |
47 | result = 1; |
48 | } |
49 | |
50 | if (sscanf ("" , "%10[a-z]" , buf) != EOF) |
51 | { |
52 | fputs ("test failed!\n" , stdout); |
53 | result = 1; |
54 | } |
55 | |
56 | sscanf ("conversion] Zero flag Ze]ro#\n" , "%*[^]] %[^#]\n" , buf); |
57 | if (strcmp (buf, "] Zero flag Ze]ro" ) != 0) |
58 | { |
59 | fputs ("test failed!\n" , stdout); |
60 | result = 1; |
61 | } |
62 | |
63 | if (argc == 2 && !strcmp (argv[1], "-opipe" )) |
64 | { |
65 | out = popen (command: "/bin/cat" , modes: "w" ); |
66 | if (out == NULL) |
67 | { |
68 | perror ("popen: /bin/cat" ); |
69 | result = 1; |
70 | } |
71 | } |
72 | else if (argc == 3 && !strcmp (argv[1], "-ipipe" )) |
73 | { |
74 | sprintf (buf, "/bin/cat %s" , argv[2]); |
75 | in = popen (command: buf, modes: "r" ); |
76 | if (in == NULL) |
77 | { |
78 | perror ("popen: /bin/cat" ); |
79 | result = 1; |
80 | } |
81 | } |
82 | |
83 | { |
84 | char name[50]; |
85 | fprintf (out, |
86 | "sscanf (\"thompson\", \"%%s\", name) == %d, name == \"%s\"\n" , |
87 | sscanf ("thompson" , "%s" , name), |
88 | name); |
89 | if (strcmp (name, "thompson" ) != 0) |
90 | { |
91 | fputs ("test failed!\n" , stdout); |
92 | result = 1; |
93 | } |
94 | } |
95 | |
96 | fputs ("Testing scanf (vfscanf)\n" , out); |
97 | |
98 | fputs ("Test 1:\n" , out); |
99 | { |
100 | int n, i; |
101 | float x; |
102 | char name[50]; |
103 | n = fscanf (stream: in, format: "%d%f%s" , &i, &x, name); |
104 | fprintf (out, "n = %d, i = %d, x = %f, name = \"%.50s\"\n" , |
105 | n, i, x, name); |
106 | if (n != 3 || i != 25 || x != 5.432F || strcmp (name, "thompson" )) |
107 | { |
108 | fputs ("test failed!\n" , stdout); |
109 | result = 1; |
110 | } |
111 | } |
112 | fprintf (out, "Residual: \"%s\"\n" , fgets (s: buf, n: sizeof (buf), stream: in)); |
113 | if (strcmp (buf, "\n" )) |
114 | { |
115 | fputs ("test failed!\n" , stdout); |
116 | result = 1; |
117 | } |
118 | fputs ("Test 2:\n" , out); |
119 | { |
120 | int i; |
121 | float x; |
122 | char name[50]; |
123 | (void) fscanf (stream: in, format: "%2d%f%*d %[0123456789]" , &i, &x, name); |
124 | fprintf (out, "i = %d, x = %f, name = \"%.50s\"\n" , i, x, name); |
125 | if (i != 56 || x != 789.0F || strcmp (name, "56" )) |
126 | { |
127 | fputs ("test failed!\n" , stdout); |
128 | result = 1; |
129 | } |
130 | } |
131 | fprintf (out, "Residual: \"%s\"\n" , fgets (s: buf, n: sizeof (buf), stream: in)); |
132 | if (strcmp (buf, "a72\n" )) |
133 | { |
134 | fputs ("test failed!\n" , stdout); |
135 | result = 1; |
136 | } |
137 | fputs ("Test 3:\n" , out); |
138 | { |
139 | static struct { |
140 | int count; |
141 | float quant; |
142 | const char *units; |
143 | const char *item; |
144 | } ok[] = { |
145 | { 3, 2.0F, "quarts" , "oil" }, |
146 | { 2, -12.8F, "degrees" , "" }, |
147 | { 0, 0.0F, "" , "" }, |
148 | { 3, 10.0F, "LBS" , "fertilizer" }, |
149 | { 3, 100.0F, "rgs" , "energy" }, |
150 | { -1, 0.0F, "" , "" }}; |
151 | size_t rounds = 0; |
152 | float quant; |
153 | char units[21], item[21]; |
154 | while (!feof (stream: in) && !ferror (stream: in)) |
155 | { |
156 | int count; |
157 | |
158 | if (rounds++ >= array_length (ok)) |
159 | { |
160 | fputs ("test failed!\n" , stdout); |
161 | result = 1; |
162 | } |
163 | |
164 | quant = 0.0; |
165 | units[0] = item[0] = '\0'; |
166 | count = fscanf (stream: in, format: "%f%20s of %20s" , &quant, units, item); |
167 | (void) fscanf (stream: in, format: "%*[^\n]" ); |
168 | fprintf (out, "count = %d, quant = %f, item = %.21s, units = %.21s\n" , |
169 | count, quant, item, units); |
170 | if (count != ok[rounds-1].count || quant != ok[rounds-1].quant |
171 | || strcmp (item, ok[rounds-1].item) |
172 | || strcmp (units, ok[rounds-1].units)) |
173 | { |
174 | fputs ("test failed!\n" , stdout); |
175 | result = 1; |
176 | } |
177 | } |
178 | } |
179 | buf[0] = '\0'; |
180 | fprintf (out, "Residual: \"%s\"\n" , fgets (s: buf, n: sizeof (buf), stream: in)); |
181 | if (strcmp (buf, "" )) |
182 | { |
183 | fputs ("test failed!\n" , stdout); |
184 | result = 1; |
185 | } |
186 | |
187 | if (out != stdout) |
188 | pclose (stream: out); |
189 | |
190 | fputs ("Test 4:\n" , out); |
191 | { |
192 | int res, val, n; |
193 | |
194 | res = sscanf ("-242" , "%3o%n" , &val, &n); |
195 | printf (format: "res = %d, val = %d, n = %d\n" , res, val, n); |
196 | if (res != 1 || val != -20 || n != 3) |
197 | { |
198 | fputs ("test failed!\n" , stdout); |
199 | result = 1; |
200 | } |
201 | } |
202 | |
203 | fputs ("Test 5:\n" , out); |
204 | { |
205 | double a = 0, b = 0; |
206 | int res, n; |
207 | |
208 | res = sscanf ("1234567" , "%3lg%3lg%n" , &a, &b, &n); |
209 | printf (format: "res = %d, a = %g, b = %g, n = %d\n" , res, a, b, n); |
210 | |
211 | if (res != 2 || a != 123 || b != 456 || n != 6) |
212 | { |
213 | fputs ("test failed!\n" , stdout); |
214 | result = 1; |
215 | } |
216 | |
217 | res = sscanf ("0" , "%lg" , &a); |
218 | printf (format: "res = %d, a = %g\n" , res, a); |
219 | |
220 | if (res != 1 || a != 0) |
221 | { |
222 | fputs ("test failed!\n" , stdout); |
223 | result = 1; |
224 | } |
225 | |
226 | res = sscanf ("1e3" , "%lg%n" , &a, &n); |
227 | printf (format: "res = %d, a = %g, n = %d\n" , res, a, n); |
228 | |
229 | if (res != 1 || a != 1000 || n != 3) |
230 | { |
231 | fputs ("test failed!\n" , stdout); |
232 | result = 1; |
233 | } |
234 | } |
235 | |
236 | fputs ("Test 6:\n" , stdout); |
237 | { |
238 | char *p = (char *) -1; |
239 | int res; |
240 | |
241 | sprintf (buf, "%p" , NULL); |
242 | res = sscanf (buf, "%p" , &p); |
243 | printf (format: "sscanf (\"%s\", \"%%p\", &p) = %d, p == %p\n" , buf, res, p); |
244 | |
245 | if (res != 1 || p != NULL) |
246 | { |
247 | fputs ("test failed!\n" , stdout); |
248 | result = 1; |
249 | } |
250 | } |
251 | |
252 | fputs ("Test 7:\n" , stdout); |
253 | { |
254 | short a[2] = { -1, -1 }; |
255 | int res; |
256 | |
257 | res = sscanf ("32767 1234" , "%hd %hd" , &a[0], &a[1]); |
258 | printf (format: "res = %d, a[0] = %d, a[1] = %d\n" , res, a[0], a[1]); |
259 | |
260 | if (res != 2 || a[0] != 32767 || a[1] != 1234) |
261 | { |
262 | fputs ("test failed!\n" , stdout); |
263 | result = 1; |
264 | } |
265 | } |
266 | |
267 | fputs ("Test 8:\n" , stdout); |
268 | { |
269 | double d = 123456.789; |
270 | int res; |
271 | |
272 | res = sscanf ("0x1234" , "%lf" , &d); |
273 | printf (format: "res = %d, d = %f\n" , res, d); |
274 | |
275 | if (res != 1 || d != 4660) |
276 | { |
277 | fputs ("test failed!\n" , stdout); |
278 | result = 1; |
279 | } |
280 | } |
281 | |
282 | fputs ("Test 9:\n" , stdout); |
283 | { |
284 | /* From PR libc/1313 reported by Ben Caradoc-Davies <bmcd@physics.otago.ac.nz>. */ |
285 | float value; |
286 | int res; |
287 | |
288 | res = sscanf ("0123" , "%2f" , &value); |
289 | if (res != 1 || value != 1.0) |
290 | { |
291 | fputs ("test failed!\n" , stdout); |
292 | result = 1; |
293 | } |
294 | } |
295 | |
296 | fputs ("Test 10:\n" , stdout); |
297 | { |
298 | float value; |
299 | int res; |
300 | |
301 | res = sscanf ("--" , "%f" , &value); |
302 | if (res != 0) |
303 | { |
304 | fputs ("test failed!\n" , stdout); |
305 | result = 1; |
306 | } |
307 | } |
308 | |
309 | fputs ("Test 11:\n" , stdout); |
310 | { |
311 | char uart[50]; |
312 | int res; |
313 | |
314 | res = sscanf ("uart:16550A tx:0" , "uart:%31s tx:%*u" , uart); |
315 | if (res != 1) |
316 | { |
317 | fputs ("test failed!\n" , stdout); |
318 | result = 1; |
319 | } |
320 | } |
321 | |
322 | fputs ("Test 12:\n" , stdout); |
323 | { |
324 | char uart[50]; |
325 | int res; |
326 | |
327 | res = sscanf ("uart:16550A" , "uart:%31s tx:%*u" , uart); |
328 | if (res != 1) |
329 | { |
330 | fputs ("test failed!\n" , stdout); |
331 | result = 1; |
332 | } |
333 | } |
334 | |
335 | fputs ("Test 13:\n" , stdout); |
336 | { |
337 | float value; |
338 | int res; |
339 | |
340 | res = sscanf ("-InF" , "%f" , &value); |
341 | if (res != 1 || isinf (value) != -1) |
342 | { |
343 | fputs ("test failed!\n" , stdout); |
344 | result = 1; |
345 | } |
346 | |
347 | res = sscanf ("+InfiNiTY" , "%f" , &value); |
348 | if (res != 1 || isinf (value) != 1) |
349 | { |
350 | fputs ("test failed!\n" , stdout); |
351 | result = 1; |
352 | } |
353 | } |
354 | |
355 | return result; |
356 | } |
357 | |