source: mainline/uspace/lib/c/test/stdio/scanf.c@ 5a6c28d1

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 5a6c28d1 was 5a6c28d1, checked in by Jiri Svoboda <jiri@…>, 7 years ago

Replace libposix scanf with libc scanf.

  • Property mode set to 100644
File size: 23.5 KB
Line 
1/*
2 * Copyright (c) 2018 Jiri Svoboda
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup libc
30 * @{
31 */
32/**
33 * @file
34 * @brief Test formatted input (scanf family)
35 */
36
37#include <mem.h>
38#include <pcut/pcut.h>
39#include <stddef.h>
40#include <stdint.h>
41#include <stdio.h>
42#include <stdlib.h>
43
44PCUT_INIT;
45
46PCUT_TEST_SUITE(scanf);
47
48enum {
49 chars_size = 10
50};
51
52PCUT_TEST(empty_fmt)
53{
54 int rc;
55
56 /* Empty format string */
57 rc = sscanf("42", "");
58 PCUT_ASSERT_INT_EQUALS(0, rc);
59}
60
61PCUT_TEST(dec_int)
62{
63 int rc;
64 int i;
65
66 /* Decimal integer */
67 rc = sscanf("42", "%d", &i);
68 PCUT_ASSERT_INT_EQUALS(1, rc);
69 PCUT_ASSERT_TRUE(i == 42);
70}
71
72PCUT_TEST(int_int)
73{
74 int rc;
75 int i, j;
76
77 /* Two integers */
78 rc = sscanf("42 43", "%d%d", &i, &j);
79 PCUT_ASSERT_INT_EQUALS(2, rc);
80 PCUT_ASSERT_TRUE(i == 42);
81 PCUT_ASSERT_TRUE(j == 43);
82}
83
84PCUT_TEST(dec_sign_char)
85{
86 int rc;
87 signed char sc;
88
89 /* Decimal signed char */
90 rc = sscanf("42", "%hhd", &sc);
91 PCUT_ASSERT_INT_EQUALS(1, rc);
92 PCUT_ASSERT_TRUE(sc == 42);
93}
94
95PCUT_TEST(dec_short)
96{
97 int rc;
98 short si;
99
100 /* Decimal short */
101 rc = sscanf("42", "%hd", &si);
102 PCUT_ASSERT_INT_EQUALS(1, rc);
103 PCUT_ASSERT_TRUE(si == 42);
104}
105
106PCUT_TEST(dec_long)
107{
108 int rc;
109 long li;
110
111 /* Decimal long */
112 rc = sscanf("42", "%ld", &li);
113 PCUT_ASSERT_INT_EQUALS(1, rc);
114 PCUT_ASSERT_TRUE(li == 42);
115}
116
117PCUT_TEST(dec_long_long)
118{
119 int rc;
120 long long lli;
121
122 /* Decimal long long */
123 rc = sscanf("42", "%lld", &lli);
124 PCUT_ASSERT_INT_EQUALS(1, rc);
125 PCUT_ASSERT_TRUE(lli == 42);
126}
127
128PCUT_TEST(dec_intmax)
129{
130 int rc;
131 intmax_t imax;
132
133 /* Decimal intmax_t */
134 rc = sscanf("42", "%jd", &imax);
135 PCUT_ASSERT_INT_EQUALS(1, rc);
136 PCUT_ASSERT_TRUE(imax == 42);
137}
138
139PCUT_TEST(dec_size_t_size)
140{
141 int rc;
142 size_t szi;
143
144 /* Decimal size_t-sized */
145 rc = sscanf("42", "%zd", &szi);
146 PCUT_ASSERT_INT_EQUALS(1, rc);
147 PCUT_ASSERT_TRUE(szi == 42);
148}
149
150PCUT_TEST(dec_ptrdiff_t_size)
151{
152 int rc;
153 ptrdiff_t pdi;
154
155 /* Decimal ptrdiff_t-sized */
156 rc = sscanf("42", "%td", &pdi);
157 PCUT_ASSERT_INT_EQUALS(1, rc);
158 PCUT_ASSERT_TRUE(pdi == 42);
159}
160
161PCUT_TEST(dec_int_hexdigit)
162{
163 int rc;
164 int i;
165
166 /* Decimal integer followed by hexadecimal digit */
167 rc = sscanf("42a", "%d", &i);
168 PCUT_ASSERT_INT_EQUALS(1, rc);
169 PCUT_ASSERT_TRUE(i == 42);
170}
171
172PCUT_TEST(int_noprefix)
173{
174 int rc;
175 int i;
176
177 /* Decimal integer - detect no prefix */
178 rc = sscanf("42", "%i", &i);
179 PCUT_ASSERT_INT_EQUALS(1, rc);
180 PCUT_ASSERT_TRUE(i == 42);
181}
182
183PCUT_TEST(octal_decimal_digit)
184{
185 int rc;
186 int i;
187
188 /* Prefixed octal integer followed by decimal digit */
189 rc = sscanf("019", "%i", &i);
190 PCUT_ASSERT_INT_EQUALS(1, rc);
191 PCUT_ASSERT_TRUE(i == 1);
192}
193
194PCUT_TEST(hex_other_char)
195{
196 int rc;
197 int i;
198
199 /* Prefixed hexadecimal integer followed by other character */
200 rc = sscanf("0xag", "%i", &i);
201 PCUT_ASSERT_INT_EQUALS(1, rc);
202 PCUT_ASSERT_TRUE(i == 10);
203}
204
205PCUT_TEST(positive_dec)
206{
207 int rc;
208 int i;
209
210 /* Decimal integer with '+' sign */
211 rc = sscanf("+42", "%d", &i);
212 PCUT_ASSERT_INT_EQUALS(1, rc);
213 PCUT_ASSERT_TRUE(i == 42);
214}
215
216PCUT_TEST(negative_dec)
217{
218 int rc;
219 int i;
220
221 /* Decimal integer with '-' sign */
222 rc = sscanf("-42", "%d", &i);
223 PCUT_ASSERT_INT_EQUALS(1, rc);
224 PCUT_ASSERT_TRUE(i == -42);
225}
226
227PCUT_TEST(negative_hex)
228{
229 int rc;
230 int i;
231
232 /* Hexadecimal integer with prefix and '-' sign */
233 rc = sscanf("-0xa", "%i", &i);
234 PCUT_ASSERT_INT_EQUALS(1, rc);
235 PCUT_ASSERT_TRUE(i == -10);
236}
237
238PCUT_TEST(dec_unsigned)
239{
240 int rc;
241 unsigned u;
242
243 /* Decimal unsigned integer */
244 rc = sscanf("42", "%u", &u);
245 PCUT_ASSERT_INT_EQUALS(1, rc);
246 PCUT_ASSERT_TRUE(u == 42);
247}
248
249PCUT_TEST(dec_unsigned_char)
250{
251 int rc;
252 unsigned char uc;
253
254 /* Decimal unsigned char */
255 rc = sscanf("42", "%hhu", &uc);
256 PCUT_ASSERT_INT_EQUALS(1, rc);
257 PCUT_ASSERT_TRUE(uc == 42);
258}
259
260PCUT_TEST(dec_unsigned_short)
261{
262 int rc;
263 unsigned short su;
264
265 /* Decimal unsigned short */
266 rc = sscanf("42", "%hu", &su);
267 PCUT_ASSERT_INT_EQUALS(1, rc);
268 PCUT_ASSERT_TRUE(su == 42);
269}
270
271PCUT_TEST(dec_unsigned_long)
272{
273 int rc;
274 unsigned long lu;
275
276 /* Decimal unsigned long */
277 rc = sscanf("42", "%lu", &lu);
278 PCUT_ASSERT_INT_EQUALS(1, rc);
279 PCUT_ASSERT_TRUE(lu == 42);
280}
281
282PCUT_TEST(dec_unsigned_long_long)
283{
284 int rc;
285 unsigned long long llu;
286
287 /* Decimal unsigned long long */
288 rc = sscanf("42", "%llu", &llu);
289 PCUT_ASSERT_INT_EQUALS(1, rc);
290 PCUT_ASSERT_TRUE(llu == 42);
291}
292
293PCUT_TEST(dec_unitmax)
294{
295 int rc;
296 uintmax_t umax;
297
298 /* Decimal uintmax_t */
299 rc = sscanf("42", "%ju", &umax);
300 PCUT_ASSERT_INT_EQUALS(1, rc);
301 PCUT_ASSERT_TRUE(umax == 42);
302}
303
304PCUT_TEST(dec_unsigned_size)
305{
306 int rc;
307 size_t szu;
308
309 /* Decimal size_t */
310 rc = sscanf("42", "%zu", &szu);
311 PCUT_ASSERT_INT_EQUALS(1, rc);
312 PCUT_ASSERT_TRUE(szu == 42);
313}
314
315PCUT_TEST(dec_unsigned_ptrdiff)
316{
317 int rc;
318 ptrdiff_t pdu;
319
320 /* Decimal ptrdiff_t-sized unsigned int*/
321 rc = sscanf("42", "%tu", &pdu);
322 PCUT_ASSERT_INT_EQUALS(1, rc);
323 PCUT_ASSERT_TRUE(pdu == 42);
324}
325
326PCUT_TEST(octal_unsigned)
327{
328 int rc;
329 unsigned u;
330
331 /* Octal unsigned integer */
332 rc = sscanf("52", "%o", &u);
333 PCUT_ASSERT_INT_EQUALS(1, rc);
334 PCUT_ASSERT_TRUE(u == 052);
335}
336
337PCUT_TEST(hex_unsigned)
338{
339 int rc;
340 unsigned u;
341
342 /* Hexadecimal unsigned integer */
343 rc = sscanf("2a", "%x", &u);
344 PCUT_ASSERT_INT_EQUALS(1, rc);
345 PCUT_ASSERT_TRUE(u == 0x2a);
346}
347
348PCUT_TEST(hex_unsigned_cap_x)
349{
350 int rc;
351 unsigned u;
352
353 /* Hexadecimal unsigned integer unsing alternate specifier */
354 rc = sscanf("2a", "%X", &u);
355 PCUT_ASSERT_INT_EQUALS(1, rc);
356 PCUT_ASSERT_TRUE(u == 0x2a);
357}
358
359PCUT_TEST(uppercase_hex_unsigned)
360{
361 int rc;
362 unsigned u;
363
364 /* Uppercase hexadecimal unsigned integer */
365 rc = sscanf("2A", "%x", &u);
366 PCUT_ASSERT_INT_EQUALS(1, rc);
367 PCUT_ASSERT_TRUE(u == 0x2a);
368}
369
370PCUT_TEST(hex_not_match_0x)
371{
372 int rc;
373 unsigned u;
374
375 /* Make sure %x does not match 0x prefix */
376 rc = sscanf("0x1", "%x", &u);
377
378 PCUT_ASSERT_INT_EQUALS(1, rc);
379 PCUT_ASSERT_TRUE(u == 0);
380}
381
382PCUT_TEST(skipws)
383{
384 int rc;
385 int i;
386
387 /* Skipping whitespace */
388 rc = sscanf(" \t\n42", "%d", &i);
389 PCUT_ASSERT_INT_EQUALS(1, rc);
390 PCUT_ASSERT_TRUE(i == 42);
391}
392
393PCUT_TEST(percentile)
394{
395 int rc;
396 int i;
397
398 /* Percentile conversion */
399 rc = sscanf(" \t\n%42", "%%%d", &i);
400 PCUT_ASSERT_INT_EQUALS(1, rc);
401 PCUT_ASSERT_TRUE(i == 42);
402}
403
404PCUT_TEST(match_spec_char)
405{
406 int rc;
407 int i;
408
409 /* Matching specific character */
410 rc = sscanf("x42", "x%d", &i);
411 PCUT_ASSERT_INT_EQUALS(1, rc);
412 PCUT_ASSERT_TRUE(i == 42);
413}
414
415PCUT_TEST(match_char_noskipws)
416{
417 int rc;
418 int i;
419
420 /* Matching specific character should not skip whitespace */
421 rc = sscanf(" x42", "x%d", &i);
422 PCUT_ASSERT_INT_EQUALS(0, rc);
423}
424
425PCUT_TEST(skipws_match_char)
426{
427 int rc;
428 int i;
429
430 /* Skipping whitespace + match specific character */
431 rc = sscanf(" x42", "\t\nx%d", &i);
432 PCUT_ASSERT_INT_EQUALS(1, rc);
433 PCUT_ASSERT_TRUE(i == 42);
434}
435
436PCUT_TEST(dec_sufficient_lim_width)
437{
438 int rc;
439 int i;
440
441 /* Decimal with limited, but sufficient width */
442 rc = sscanf("42", "%2d", &i);
443 PCUT_ASSERT_INT_EQUALS(1, rc);
444 PCUT_ASSERT_TRUE(i == 42);
445}
446
447PCUT_TEST(dec_smaller_width)
448{
449 int rc;
450 int i;
451
452 /* Decimal with limited, smaller width */
453 rc = sscanf("42", "%1d", &i);
454 PCUT_ASSERT_INT_EQUALS(1, rc);
455 PCUT_ASSERT_TRUE(i == 4);
456}
457
458PCUT_TEST(int_hex_limited_width)
459{
460 int rc;
461 int i;
462
463 /* Integer with hex prefix, format with limited, sufficient width */
464 rc = sscanf("0x1", "%3i", &i);
465 PCUT_ASSERT_INT_EQUALS(1, rc);
466 PCUT_ASSERT_TRUE(i == 1);
467}
468
469PCUT_TEST(int_hex_small_width)
470{
471 int rc;
472 int i;
473
474 /* Integer with hex prefix, format with limited, smaller width */
475 rc = sscanf("0x1", "%2i", &i);
476 PCUT_ASSERT_INT_EQUALS(1, rc);
477 PCUT_ASSERT_TRUE(i == 0);
478}
479
480PCUT_TEST(int_oct_limited_width)
481{
482 int rc;
483 int i;
484
485 /* Integer with octal prefix, format with limited, sufficient width */
486 rc = sscanf("012", "%3i", &i);
487 PCUT_ASSERT_INT_EQUALS(1, rc);
488 PCUT_ASSERT_TRUE(i == 012);
489}
490
491PCUT_TEST(int_oct_smaller_width)
492{
493 int rc;
494 int i;
495
496 /* Integer with octal prefix, format with limited, smaller width */
497 rc = sscanf("012", "%2i", &i);
498 PCUT_ASSERT_INT_EQUALS(1, rc);
499 PCUT_ASSERT_TRUE(i == 01);
500}
501
502PCUT_TEST(int_oct_tiny_width)
503{
504 int rc;
505 int i;
506
507 /* Integer with octal prefix, format with width allowing just for 0 */
508 rc = sscanf("012", "%1i", &i);
509 PCUT_ASSERT_INT_EQUALS(1, rc);
510 PCUT_ASSERT_TRUE(i == 0);
511}
512
513PCUT_TEST(pointer)
514{
515 int rc;
516 void *ptr;
517
518 /* Pointer */
519 rc = sscanf("0xABCDEF88", "%p", &ptr);
520 PCUT_ASSERT_INT_EQUALS(1, rc);
521 PCUT_ASSERT_TRUE(ptr == (void *)0xABCDEF88);
522}
523
524PCUT_TEST(single_char)
525{
526 int rc;
527 char c;
528
529 /* Single character */
530 rc = sscanf("x", "%c", &c);
531 PCUT_ASSERT_INT_EQUALS(1, rc);
532 PCUT_ASSERT_TRUE(c == 'x');
533}
534
535PCUT_TEST(single_ws_char)
536{
537 int rc;
538 char c;
539
540 /* Single whitespace character */
541 rc = sscanf("\t", "%c", &c);
542 PCUT_ASSERT_INT_EQUALS(1, rc);
543 PCUT_ASSERT_TRUE(c == '\t');
544}
545
546PCUT_TEST(chars)
547{
548 int rc;
549 char chars[chars_size];
550
551 /* Multiple characters */
552 memset(chars, 'X', chars_size);
553 rc = sscanf("abc", "%3c", chars);
554 PCUT_ASSERT_INT_EQUALS(1, rc);
555 PCUT_ASSERT_TRUE(chars[0] == 'a');
556 PCUT_ASSERT_TRUE(chars[1] == 'b');
557 PCUT_ASSERT_TRUE(chars[2] == 'c');
558 PCUT_ASSERT_TRUE(chars[3] == 'X');
559}
560
561PCUT_TEST(fewer_chars)
562{
563 int rc;
564 char chars[chars_size];
565
566 /* Fewer characters than requested */
567 memset(chars, 'X', chars_size);
568 rc = sscanf("abc", "%5c", chars);
569 PCUT_ASSERT_INT_EQUALS(1, rc);
570 PCUT_ASSERT_TRUE(chars[0] == 'a');
571 PCUT_ASSERT_TRUE(chars[1] == 'b');
572 PCUT_ASSERT_TRUE(chars[2] == 'c');
573 PCUT_ASSERT_TRUE(chars[3] == 'X');
574}
575
576PCUT_TEST(chars_not_found)
577{
578 int rc;
579 char chars[chars_size];
580
581 /* Reading characters but no found */
582 memset(chars, 'X', chars_size);
583 rc = sscanf("", "%5c", chars);
584 PCUT_ASSERT_INT_EQUALS(EOF, rc);
585 PCUT_ASSERT_TRUE(chars[0] == 'X');
586}
587
588PCUT_TEST(chars_noassign)
589{
590 int rc;
591 int n;
592
593 /* Multiple characters with suppressed assignment */
594 rc = sscanf("abc", "%*3c%n", &n);
595 PCUT_ASSERT_INT_EQUALS(0, rc);
596 PCUT_ASSERT_INT_EQUALS(3, n);
597}
598
599PCUT_TEST(chars_malloc)
600{
601 int rc;
602 char *cp;
603
604 /* Multiple characters with memory allocation */
605 cp = NULL;
606 rc = sscanf("abc", "%m3c", &cp);
607 PCUT_ASSERT_INT_EQUALS(1, rc);
608 PCUT_ASSERT_NOT_NULL(cp);
609 PCUT_ASSERT_TRUE(cp[0] == 'a');
610 PCUT_ASSERT_TRUE(cp[1] == 'b');
611 PCUT_ASSERT_TRUE(cp[2] == 'c');
612 free(cp);
613}
614
615PCUT_TEST(str)
616{
617 int rc;
618 char chars[chars_size];
619
620 /* String of non-whitespace characters, unlimited width */
621 memset(chars, 'X', chars_size);
622 rc = sscanf(" abc d", "%s", chars);
623 PCUT_ASSERT_INT_EQUALS(1, rc);
624 PCUT_ASSERT_TRUE(chars[0] == 'a');
625 PCUT_ASSERT_TRUE(chars[1] == 'b');
626 PCUT_ASSERT_TRUE(chars[2] == 'c');
627 PCUT_ASSERT_TRUE(chars[3] == '\0');
628 PCUT_ASSERT_TRUE(chars[4] == 'X');
629}
630
631PCUT_TEST(str_till_end)
632{
633 int rc;
634 char chars[chars_size];
635
636 /* String of non-whitespace characters, until the end */
637 memset(chars, 'X', chars_size);
638 rc = sscanf(" abc", "%s", chars);
639 PCUT_ASSERT_INT_EQUALS(1, rc);
640 PCUT_ASSERT_TRUE(chars[0] == 'a');
641 PCUT_ASSERT_TRUE(chars[1] == 'b');
642 PCUT_ASSERT_TRUE(chars[2] == 'c');
643 PCUT_ASSERT_TRUE(chars[3] == '\0');
644 PCUT_ASSERT_TRUE(chars[4] == 'X');
645}
646
647PCUT_TEST(str_large_width)
648{
649 int rc;
650 char chars[chars_size];
651
652 /* String of non-whitespace characters, large enough width */
653 memset(chars, 'X', chars_size);
654 rc = sscanf(" abc d", "%5s", chars);
655 PCUT_ASSERT_INT_EQUALS(1, rc);
656 PCUT_ASSERT_TRUE(chars[0] == 'a');
657 PCUT_ASSERT_TRUE(chars[1] == 'b');
658 PCUT_ASSERT_TRUE(chars[2] == 'c');
659 PCUT_ASSERT_TRUE(chars[3] == '\0');
660 PCUT_ASSERT_TRUE(chars[4] == 'X');
661}
662
663PCUT_TEST(str_not_found)
664{
665 int rc;
666 char chars[chars_size];
667
668 /* Want string of non-whitespace, but got only whitespace */
669 memset(chars, 'X', chars_size);
670 rc = sscanf(" ", "%s", chars);
671 PCUT_ASSERT_INT_EQUALS(EOF, rc);
672 PCUT_ASSERT_TRUE(chars[0] == 'X');
673}
674
675PCUT_TEST(str_small_width)
676{
677 int rc;
678 char chars[chars_size];
679
680 /* String of non-whitespace characters, small width */
681 memset(chars, 'X', chars_size);
682 rc = sscanf(" abc", "%2s", chars);
683 PCUT_ASSERT_INT_EQUALS(1, rc);
684 PCUT_ASSERT_TRUE(chars[0] == 'a');
685 PCUT_ASSERT_TRUE(chars[1] == 'b');
686 PCUT_ASSERT_TRUE(chars[2] == '\0');
687 PCUT_ASSERT_TRUE(chars[3] == 'X');
688}
689
690PCUT_TEST(str_noassign)
691{
692 int rc;
693 int n;
694
695 /* String of non-whitespace characters, assignment suppression */
696 rc = sscanf(" abc d", "%*s%n", &n);
697 PCUT_ASSERT_INT_EQUALS(0, rc);
698 PCUT_ASSERT_INT_EQUALS(4, n);
699}
700
701PCUT_TEST(str_malloc)
702{
703 int rc;
704 char *cp;
705
706 /* String of non-whitespace characters, memory allocation */
707 rc = sscanf(" abc d", "%ms", &cp);
708 PCUT_ASSERT_INT_EQUALS(1, rc);
709 PCUT_ASSERT_NOT_NULL(cp);
710 PCUT_ASSERT_TRUE(cp[0] == 'a');
711 PCUT_ASSERT_TRUE(cp[1] == 'b');
712 PCUT_ASSERT_TRUE(cp[2] == 'c');
713 PCUT_ASSERT_TRUE(cp[3] == '\0');
714 free(cp);
715}
716
717PCUT_TEST(set_convert)
718{
719 int rc;
720 char chars[chars_size];
721 int i;
722
723 /* Set conversion without width specified terminating before the end */
724 memset(chars, 'X', chars_size);
725 rc = sscanf("abcd42", "%[abc]d%d", chars, &i);
726 PCUT_ASSERT_INT_EQUALS(2, rc);
727 PCUT_ASSERT_TRUE(chars[0] == 'a');
728 PCUT_ASSERT_TRUE(chars[1] == 'b');
729 PCUT_ASSERT_TRUE(chars[2] == 'c');
730 PCUT_ASSERT_TRUE(chars[3] == '\0');
731 PCUT_ASSERT_TRUE(chars[4] == 'X');
732 PCUT_ASSERT_TRUE(i == 42);
733}
734
735PCUT_TEST(set_till_end)
736{
737 int rc;
738 char chars[chars_size];
739
740 /* Set conversion without width specified, until the end */
741 memset(chars, 'X', chars_size);
742 rc = sscanf("abc", "%[abc]", chars);
743 PCUT_ASSERT_INT_EQUALS(1, rc);
744 PCUT_ASSERT_TRUE(chars[0] == 'a');
745 PCUT_ASSERT_TRUE(chars[1] == 'b');
746 PCUT_ASSERT_TRUE(chars[2] == 'c');
747 PCUT_ASSERT_TRUE(chars[3] == '\0');
748 PCUT_ASSERT_TRUE(chars[4] == 'X');
749}
750
751PCUT_TEST(set_large_width)
752{
753 int rc;
754 char chars[chars_size];
755
756 /* Set conversion with larger width */
757 memset(chars, 'X', chars_size);
758 rc = sscanf("abcd", "%5[abc]", chars);
759 PCUT_ASSERT_INT_EQUALS(1, rc);
760 PCUT_ASSERT_TRUE(chars[0] == 'a');
761 PCUT_ASSERT_TRUE(chars[1] == 'b');
762 PCUT_ASSERT_TRUE(chars[2] == 'c');
763 PCUT_ASSERT_TRUE(chars[3] == '\0');
764 PCUT_ASSERT_TRUE(chars[4] == 'X');
765}
766
767PCUT_TEST(set_small_width)
768{
769 int rc;
770 char chars[chars_size];
771
772 /* Set conversion with smaller width */
773 memset(chars, 'X', chars_size);
774 rc = sscanf("abcd", "%3[abcd]", chars);
775 PCUT_ASSERT_INT_EQUALS(1, rc);
776 PCUT_ASSERT_TRUE(chars[0] == 'a');
777 PCUT_ASSERT_TRUE(chars[1] == 'b');
778 PCUT_ASSERT_TRUE(chars[2] == 'c');
779 PCUT_ASSERT_TRUE(chars[3] == '\0');
780 PCUT_ASSERT_TRUE(chars[4] == 'X');
781}
782
783PCUT_TEST(set_negated)
784{
785 int rc;
786 char chars[chars_size];
787
788 /* Set conversion with negated scanset */
789 memset(chars, 'X', chars_size);
790 rc = sscanf("abcd", "%[^d]", chars);
791 PCUT_ASSERT_INT_EQUALS(1, rc);
792 PCUT_ASSERT_TRUE(chars[0] == 'a');
793 PCUT_ASSERT_TRUE(chars[1] == 'b');
794 PCUT_ASSERT_TRUE(chars[2] == 'c');
795 PCUT_ASSERT_TRUE(chars[3] == '\0');
796 PCUT_ASSERT_TRUE(chars[4] == 'X');
797}
798
799PCUT_TEST(set_with_rbr)
800{
801 int rc;
802 char chars[chars_size];
803
804 /* Set conversion with ']' in scanset */
805 memset(chars, 'X', chars_size);
806 rc = sscanf("]bcd", "%[]bc]", chars);
807 PCUT_ASSERT_INT_EQUALS(1, rc);
808 PCUT_ASSERT_TRUE(chars[0] == ']');
809 PCUT_ASSERT_TRUE(chars[1] == 'b');
810 PCUT_ASSERT_TRUE(chars[2] == 'c');
811 PCUT_ASSERT_TRUE(chars[3] == '\0');
812 PCUT_ASSERT_TRUE(chars[4] == 'X');
813}
814
815PCUT_TEST(set_inverted_with_rbr)
816{
817 int rc;
818 char chars[chars_size];
819
820 /* Set conversion with ']' in inverted scanset */
821 memset(chars, 'X', chars_size);
822 rc = sscanf("abc]", "%[^]def]", chars);
823 PCUT_ASSERT_INT_EQUALS(1, rc);
824 PCUT_ASSERT_TRUE(chars[0] == 'a');
825 PCUT_ASSERT_TRUE(chars[1] == 'b');
826 PCUT_ASSERT_TRUE(chars[2] == 'c');
827 PCUT_ASSERT_TRUE(chars[3] == '\0');
828 PCUT_ASSERT_TRUE(chars[4] == 'X');
829}
830
831PCUT_TEST(set_noassign)
832{
833 int rc;
834 int n;
835
836 /* Set conversion with assignment suppression */
837 rc = sscanf("abcd42", "%*[abc]%n", &n);
838 PCUT_ASSERT_INT_EQUALS(0, rc);
839 PCUT_ASSERT_INT_EQUALS(3, n);
840}
841
842PCUT_TEST(set_malloc)
843{
844 int rc;
845 char *cp;
846
847 /* Set conversion with memory allocation */
848 cp = NULL;
849 rc = sscanf("abcd42", "%m[abcd]", &cp);
850 PCUT_ASSERT_INT_EQUALS(1, rc);
851 PCUT_ASSERT_NOT_NULL(cp);
852 PCUT_ASSERT_TRUE(cp[0] == 'a');
853 PCUT_ASSERT_TRUE(cp[1] == 'b');
854 PCUT_ASSERT_TRUE(cp[2] == 'c');
855 PCUT_ASSERT_TRUE(cp[3] == 'd');
856 PCUT_ASSERT_TRUE(cp[4] == '\0');
857 free(cp);
858}
859
860PCUT_TEST(dec_int_noassign)
861{
862 int rc;
863 int n;
864
865 /* Decimal integer with suppressed assignment */
866 rc = sscanf("42", "%*d%n", &n);
867 PCUT_ASSERT_INT_EQUALS(0, rc);
868 PCUT_ASSERT_INT_EQUALS(2, n);
869}
870
871PCUT_TEST(count_chars)
872{
873 int rc;
874 char chars[chars_size];
875 int n;
876
877 /* Count of characters read */
878 memset(chars, 'X', chars_size);
879 rc = sscanf("abcd", "%3c%n", chars, &n);
880 PCUT_ASSERT_INT_EQUALS(1, rc);
881 PCUT_ASSERT_TRUE(chars[0] == 'a');
882 PCUT_ASSERT_TRUE(chars[1] == 'b');
883 PCUT_ASSERT_TRUE(chars[2] == 'c');
884 PCUT_ASSERT_TRUE(chars[3] == 'X');
885 PCUT_ASSERT_INT_EQUALS(3, n);
886}
887
888PCUT_TEST(float_intpart_only)
889{
890 int rc;
891 float f;
892
893 /* Float with just integer part */
894 rc = sscanf("42", "%f", &f);
895 PCUT_ASSERT_INT_EQUALS(1, rc);
896 PCUT_ASSERT_TRUE(f == 42.0);
897}
898
899PCUT_TEST(double_intpart_only)
900{
901 int rc;
902 double d;
903
904 /* Double with just integer part */
905 rc = sscanf("42", "%lf", &d);
906 PCUT_ASSERT_INT_EQUALS(1, rc);
907 PCUT_ASSERT_TRUE(d == 42.0);
908}
909
910PCUT_TEST(ldouble_intpart_only)
911{
912 int rc;
913 long double ld;
914
915 /* Long double with just integer part */
916 rc = sscanf("42", "%Lf", &ld);
917 PCUT_ASSERT_INT_EQUALS(1, rc);
918 PCUT_ASSERT_TRUE(ld == 42.0);
919}
920
921PCUT_TEST(float_hex_intpart_only)
922{
923 int rc;
924 float f;
925
926 /* Float with just hexadecimal integer part */
927 rc = sscanf("0x2a", "%f", &f);
928 PCUT_ASSERT_INT_EQUALS(1, rc);
929 PCUT_ASSERT_TRUE(f == 0x2a.0p0);
930}
931
932PCUT_TEST(float_sign_intpart)
933{
934 int rc;
935 float f;
936
937 /* Float with sign and integer part */
938 rc = sscanf("-42", "%f", &f);
939 PCUT_ASSERT_INT_EQUALS(1, rc);
940 PCUT_ASSERT_TRUE(f == -42.0);
941}
942
943PCUT_TEST(float_intpart_fract)
944{
945 int rc;
946 float f;
947
948 /* Float with integer and fractional part */
949 rc = sscanf("4.2", "%f", &f);
950 PCUT_ASSERT_INT_EQUALS(1, rc);
951 /* 1/10 is not exactly representable in binary floating point */
952 PCUT_ASSERT_TRUE(f > 4.199);
953 PCUT_ASSERT_TRUE(f < 4.201);
954}
955
956PCUT_TEST(float_intpart_exp)
957{
958 int rc;
959 float f;
960
961 /* Float with integer part and unsigned exponent */
962 rc = sscanf("42e1", "%f", &f);
963 PCUT_ASSERT_INT_EQUALS(1, rc);
964 PCUT_ASSERT_TRUE(f == 420.0);
965}
966
967PCUT_TEST(float_intpart_posexp)
968{
969 int rc;
970 float f;
971
972 /* Float with integer part and positive exponent */
973 rc = sscanf("42e+1", "%f", &f);
974 PCUT_ASSERT_INT_EQUALS(1, rc);
975 PCUT_ASSERT_TRUE(f == 420.0);
976}
977
978PCUT_TEST(float_intpart_negexp)
979{
980 int rc;
981 float f;
982
983 /* Float with integer part and negative exponent */
984 rc = sscanf("42e-1", "%f", &f);
985 PCUT_ASSERT_INT_EQUALS(1, rc);
986 /* 1/10 is not exactly representable in binary floating point */
987 PCUT_ASSERT_TRUE(f > 4.199);
988 PCUT_ASSERT_TRUE(f < 4.201);
989}
990
991PCUT_TEST(float_intpart_fract_exp)
992{
993 int rc;
994 float f;
995
996 /* Float with integer, fractional parts and unsigned exponent */
997 rc = sscanf("4.2e1", "%f", &f);
998 PCUT_ASSERT_INT_EQUALS(1, rc);
999 PCUT_ASSERT_TRUE(f == 42.0);
1000}
1001
1002PCUT_TEST(hexfloat_intpart_fract)
1003{
1004 int rc;
1005 float f;
1006
1007 /* Hexadecimal float with integer and fractional part */
1008 rc = sscanf("0x2.a", "%f", &f);
1009 PCUT_ASSERT_INT_EQUALS(1, rc);
1010 PCUT_ASSERT_TRUE(f == 0x2.ap0);
1011}
1012
1013PCUT_TEST(hexfloat_intpart_exp)
1014{
1015 int rc;
1016 float f;
1017
1018 /*
1019 * Hexadecimal float with integer part and unsigned exponent
1020 */
1021 rc = sscanf("0x2ap1", "%f", &f);
1022 PCUT_ASSERT_INT_EQUALS(1, rc);
1023 PCUT_ASSERT_TRUE(f == 0x2ap1);
1024}
1025
1026PCUT_TEST(hexfloat_intpart_negexp)
1027{
1028 int rc;
1029 float f;
1030
1031 /*
1032 * Hexadecimal float with integer part and negative exponent
1033 */
1034 rc = sscanf("0x2ap-1", "%f", &f);
1035 PCUT_ASSERT_INT_EQUALS(1, rc);
1036 PCUT_ASSERT_TRUE(f == 0x2ap-1);
1037}
1038
1039PCUT_TEST(hexfloat_intpart_fract_exp)
1040{
1041 int rc;
1042 float f;
1043
1044 /*
1045 * Hexadecimal float with integer, fractional parts and unsigned
1046 * exponent
1047 */
1048 rc = sscanf("0x2.ap4", "%f", &f);
1049 PCUT_ASSERT_INT_EQUALS(1, rc);
1050 PCUT_ASSERT_TRUE(f == 0x2.ap4);
1051}
1052
1053PCUT_TEST(float_intpart_limwidth)
1054{
1055 int rc;
1056 float f;
1057
1058 /* Float with just integer part and limited width */
1059 rc = sscanf("1234", "%3f", &f);
1060 PCUT_ASSERT_INT_EQUALS(1, rc);
1061 PCUT_ASSERT_TRUE(f == 123.0);
1062}
1063
1064PCUT_TEST(float_intpart_fract_limwidth)
1065{
1066 int rc;
1067 float f;
1068
1069 /* Float with integer, fractional part and limited width */
1070 rc = sscanf("12.34", "%4f", &f);
1071 PCUT_ASSERT_INT_EQUALS(1, rc);
1072 /* 1/10 is not exactly representable in binary floating point */
1073 PCUT_ASSERT_TRUE(f > 12.29);
1074 PCUT_ASSERT_TRUE(f < 12.31);
1075}
1076
1077PCUT_TEST(float_width_for_only_intpart)
1078{
1079 int rc;
1080 float f;
1081
1082 /* Float with width only enough to cover an integral part */
1083 rc = sscanf("12.34", "%3f", &f);
1084 PCUT_ASSERT_INT_EQUALS(1, rc);
1085 PCUT_ASSERT_TRUE(f == 12.0);
1086}
1087
1088PCUT_TEST(float_width_small_for_expnum)
1089{
1090 int rc;
1091 float f;
1092
1093 /* Float with width too small to cover the exponent number */
1094 rc = sscanf("12.34e+2", "%7f", &f);
1095 PCUT_ASSERT_INT_EQUALS(1, rc);
1096 /* 1/10 is not exactly representable in binary floating point */
1097 PCUT_ASSERT_TRUE(f > 12.339);
1098 PCUT_ASSERT_TRUE(f < 12.341);
1099}
1100
1101PCUT_TEST(float_width_small_for_expsignum)
1102{
1103 int rc;
1104 float f;
1105
1106 /* Float with width too small to cover the exponent sign and number */
1107 rc = sscanf("12.34e+2", "%6f", &f);
1108 PCUT_ASSERT_INT_EQUALS(1, rc);
1109 /* 1/10 is not exactly representable in binary floating point */
1110 PCUT_ASSERT_TRUE(f > 12.339);
1111 PCUT_ASSERT_TRUE(f < 12.341);
1112}
1113
1114PCUT_TEST(float_width_small_for_exp)
1115{
1116 int rc;
1117 float f;
1118
1119 /* Float with width too small to cover the exponent part */
1120 rc = sscanf("12.34e+2", "%5f", &f);
1121 PCUT_ASSERT_INT_EQUALS(1, rc);
1122 /* 1/10 is not exactly representable in binary floating point */
1123 PCUT_ASSERT_TRUE(f > 12.339);
1124 PCUT_ASSERT_TRUE(f < 12.341);
1125}
1126
1127PCUT_TEST(float_cap_f)
1128{
1129 int rc;
1130 float f;
1131
1132 /* Float using alternate form 'F' */
1133 rc = sscanf("42e1", "%F", &f);
1134 PCUT_ASSERT_INT_EQUALS(1, rc);
1135 PCUT_ASSERT_TRUE(f == 420.0);
1136}
1137
1138PCUT_TEST(float_a)
1139{
1140 int rc;
1141 float f;
1142
1143 /* Float using alternate form 'a' */
1144 rc = sscanf("42e1", "%a", &f);
1145 PCUT_ASSERT_INT_EQUALS(1, rc);
1146 PCUT_ASSERT_TRUE(f == 420.0);
1147}
1148
1149PCUT_TEST(float_e)
1150{
1151 int rc;
1152 float f;
1153
1154 /* Float using alternate form 'e' */
1155 rc = sscanf("42e1", "%e", &f);
1156 PCUT_ASSERT_INT_EQUALS(1, rc);
1157 PCUT_ASSERT_TRUE(f == 420.0);
1158}
1159
1160PCUT_TEST(float_g)
1161{
1162 int rc;
1163 float f;
1164
1165 /* Float using alternate form 'g' */
1166 rc = sscanf("42e1", "%g", &f);
1167 PCUT_ASSERT_INT_EQUALS(1, rc);
1168 PCUT_ASSERT_TRUE(f == 420.0);
1169}
1170
1171PCUT_TEST(float_cap_a)
1172{
1173 int rc;
1174 float f;
1175
1176 /* Float using alternate form 'A' */
1177 rc = sscanf("42e1", "%A", &f);
1178 PCUT_ASSERT_INT_EQUALS(1, rc);
1179 PCUT_ASSERT_TRUE(f == 420.0);
1180}
1181
1182PCUT_TEST(float_cap_e)
1183{
1184 int rc;
1185 float f;
1186
1187 /* Float using alternate form 'E' */
1188 rc = sscanf("42e1", "%E", &f);
1189 PCUT_ASSERT_INT_EQUALS(1, rc);
1190 PCUT_ASSERT_TRUE(f == 420.0);
1191}
1192
1193PCUT_TEST(float_cap_g)
1194{
1195 int rc;
1196 float f;
1197
1198 /* Float using alternate form 'G' */
1199 rc = sscanf("42e1", "%G", &f);
1200 PCUT_ASSERT_INT_EQUALS(1, rc);
1201 PCUT_ASSERT_TRUE(f == 420.0);
1202}
1203
1204PCUT_EXPORT(scanf);
Note: See TracBrowser for help on using the repository browser.