1 | /* Copyright (C) 1991-2024 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 | if (fscanf (stream: in, format: "%2d%f%*d %[0123456789]" , &i, &x, name) < 3) |
124 | { |
125 | fputs ("test failed!\n" , stdout); |
126 | result = 1; |
127 | } |
128 | |
129 | fprintf (out, "i = %d, x = %f, name = \"%.50s\"\n" , i, x, name); |
130 | if (i != 56 || x != 789.0F || strcmp (name, "56" )) |
131 | { |
132 | fputs ("test failed!\n" , stdout); |
133 | result = 1; |
134 | } |
135 | } |
136 | fprintf (out, "Residual: \"%s\"\n" , fgets (s: buf, n: sizeof (buf), stream: in)); |
137 | if (strcmp (buf, "a72\n" )) |
138 | { |
139 | fputs ("test failed!\n" , stdout); |
140 | result = 1; |
141 | } |
142 | fputs ("Test 3:\n" , out); |
143 | { |
144 | static struct { |
145 | int count; |
146 | float quant; |
147 | const char *units; |
148 | const char *item; |
149 | } ok[] = { |
150 | { 3, 2.0F, "quarts" , "oil" }, |
151 | { 2, -12.8F, "degrees" , "" }, |
152 | { 0, 0.0F, "" , "" }, |
153 | { 3, 10.0F, "LBS" , "fertilizer" }, |
154 | { 3, 100.0F, "rgs" , "energy" }, |
155 | { -1, 0.0F, "" , "" }}; |
156 | size_t rounds = 0; |
157 | float quant; |
158 | char units[21], item[21]; |
159 | while (!feof (stream: in) && !ferror (stream: in)) |
160 | { |
161 | int count; |
162 | |
163 | if (rounds++ >= array_length (ok)) |
164 | { |
165 | fputs ("test failed!\n" , stdout); |
166 | result = 1; |
167 | } |
168 | |
169 | quant = 0.0; |
170 | units[0] = item[0] = '\0'; |
171 | count = fscanf (stream: in, format: "%f%20s of %20s" , &quant, units, item); |
172 | if (fscanf (stream: in, format: "%*[^\n]" ) < 0 && ferror (stream: in)) |
173 | { |
174 | fputs ("test failed!\n" , stdout); |
175 | result = 1; |
176 | } |
177 | |
178 | fprintf (out, "count = %d, quant = %f, item = %.21s, units = %.21s\n" , |
179 | count, quant, item, units); |
180 | if (count != ok[rounds-1].count || quant != ok[rounds-1].quant |
181 | || strcmp (item, ok[rounds-1].item) |
182 | || strcmp (units, ok[rounds-1].units)) |
183 | { |
184 | fputs ("test failed!\n" , stdout); |
185 | result = 1; |
186 | } |
187 | } |
188 | } |
189 | buf[0] = '\0'; |
190 | fprintf (out, "Residual: \"%s\"\n" , fgets (s: buf, n: sizeof (buf), stream: in)); |
191 | if (strcmp (buf, "" )) |
192 | { |
193 | fputs ("test failed!\n" , stdout); |
194 | result = 1; |
195 | } |
196 | |
197 | if (out != stdout) |
198 | pclose (stream: out); |
199 | |
200 | fputs ("Test 4:\n" , out); |
201 | { |
202 | int res, val, n; |
203 | |
204 | res = sscanf ("-242" , "%3o%n" , &val, &n); |
205 | printf (format: "res = %d, val = %d, n = %d\n" , res, val, n); |
206 | if (res != 1 || val != -20 || n != 3) |
207 | { |
208 | fputs ("test failed!\n" , stdout); |
209 | result = 1; |
210 | } |
211 | } |
212 | |
213 | fputs ("Test 5:\n" , out); |
214 | { |
215 | double a = 0, b = 0; |
216 | int res, n; |
217 | |
218 | res = sscanf ("1234567" , "%3lg%3lg%n" , &a, &b, &n); |
219 | printf (format: "res = %d, a = %g, b = %g, n = %d\n" , res, a, b, n); |
220 | |
221 | if (res != 2 || a != 123 || b != 456 || n != 6) |
222 | { |
223 | fputs ("test failed!\n" , stdout); |
224 | result = 1; |
225 | } |
226 | |
227 | res = sscanf ("0" , "%lg" , &a); |
228 | printf (format: "res = %d, a = %g\n" , res, a); |
229 | |
230 | if (res != 1 || a != 0) |
231 | { |
232 | fputs ("test failed!\n" , stdout); |
233 | result = 1; |
234 | } |
235 | |
236 | res = sscanf ("1e3" , "%lg%n" , &a, &n); |
237 | printf (format: "res = %d, a = %g, n = %d\n" , res, a, n); |
238 | |
239 | if (res != 1 || a != 1000 || n != 3) |
240 | { |
241 | fputs ("test failed!\n" , stdout); |
242 | result = 1; |
243 | } |
244 | } |
245 | |
246 | fputs ("Test 6:\n" , stdout); |
247 | { |
248 | char *p = (char *) -1; |
249 | int res; |
250 | |
251 | sprintf (buf, "%p" , NULL); |
252 | res = sscanf (buf, "%p" , &p); |
253 | printf (format: "sscanf (\"%s\", \"%%p\", &p) = %d, p == %p\n" , buf, res, p); |
254 | |
255 | if (res != 1 || p != NULL) |
256 | { |
257 | fputs ("test failed!\n" , stdout); |
258 | result = 1; |
259 | } |
260 | } |
261 | |
262 | fputs ("Test 7:\n" , stdout); |
263 | { |
264 | short a[2] = { -1, -1 }; |
265 | int res; |
266 | |
267 | res = sscanf ("32767 1234" , "%hd %hd" , &a[0], &a[1]); |
268 | printf (format: "res = %d, a[0] = %d, a[1] = %d\n" , res, a[0], a[1]); |
269 | |
270 | if (res != 2 || a[0] != 32767 || a[1] != 1234) |
271 | { |
272 | fputs ("test failed!\n" , stdout); |
273 | result = 1; |
274 | } |
275 | } |
276 | |
277 | fputs ("Test 8:\n" , stdout); |
278 | { |
279 | double d = 123456.789; |
280 | int res; |
281 | |
282 | res = sscanf ("0x1234" , "%lf" , &d); |
283 | printf (format: "res = %d, d = %f\n" , res, d); |
284 | |
285 | if (res != 1 || d != 4660) |
286 | { |
287 | fputs ("test failed!\n" , stdout); |
288 | result = 1; |
289 | } |
290 | } |
291 | |
292 | fputs ("Test 9:\n" , stdout); |
293 | { |
294 | /* From PR libc/1313 reported by Ben Caradoc-Davies <bmcd@physics.otago.ac.nz>. */ |
295 | float value; |
296 | int res; |
297 | |
298 | res = sscanf ("0123" , "%2f" , &value); |
299 | if (res != 1 || value != 1.0) |
300 | { |
301 | fputs ("test failed!\n" , stdout); |
302 | result = 1; |
303 | } |
304 | } |
305 | |
306 | fputs ("Test 10:\n" , stdout); |
307 | { |
308 | float value; |
309 | int res; |
310 | |
311 | res = sscanf ("--" , "%f" , &value); |
312 | if (res != 0) |
313 | { |
314 | fputs ("test failed!\n" , stdout); |
315 | result = 1; |
316 | } |
317 | } |
318 | |
319 | fputs ("Test 11:\n" , stdout); |
320 | { |
321 | char uart[50]; |
322 | int res; |
323 | |
324 | res = sscanf ("uart:16550A tx:0" , "uart:%31s tx:%*u" , uart); |
325 | if (res != 1) |
326 | { |
327 | fputs ("test failed!\n" , stdout); |
328 | result = 1; |
329 | } |
330 | } |
331 | |
332 | fputs ("Test 12:\n" , stdout); |
333 | { |
334 | char uart[50]; |
335 | int res; |
336 | |
337 | res = sscanf ("uart:16550A" , "uart:%31s tx:%*u" , uart); |
338 | if (res != 1) |
339 | { |
340 | fputs ("test failed!\n" , stdout); |
341 | result = 1; |
342 | } |
343 | } |
344 | |
345 | fputs ("Test 13:\n" , stdout); |
346 | { |
347 | float value; |
348 | int res; |
349 | |
350 | res = sscanf ("-InF" , "%f" , &value); |
351 | if (res != 1 || isinf (value) != -1) |
352 | { |
353 | fputs ("test failed!\n" , stdout); |
354 | result = 1; |
355 | } |
356 | |
357 | res = sscanf ("+InfiNiTY" , "%f" , &value); |
358 | if (res != 1 || isinf (value) != 1) |
359 | { |
360 | fputs ("test failed!\n" , stdout); |
361 | result = 1; |
362 | } |
363 | } |
364 | |
365 | return result; |
366 | } |
367 | |