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

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

vfscanf with tests.

  • Property mode set to 100644
File size: 23.5 KB
RevLine 
[ed18e14]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 = xxsscanf("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 = xxsscanf("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 = xxsscanf("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 = xxsscanf("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 = xxsscanf("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 = xxsscanf("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 = xxsscanf("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 = xxsscanf("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 = xxsscanf("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 = xxsscanf("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 = xxsscanf("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 = xxsscanf("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 = xxsscanf("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 = xxsscanf("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 = xxsscanf("+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 = xxsscanf("-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 = xxsscanf("-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 = xxsscanf("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 = xxsscanf("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 = xxsscanf("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 = xxsscanf("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 = xxsscanf("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 = xxsscanf("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 = xxsscanf("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 = xxsscanf("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 = xxsscanf("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 = xxsscanf("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 = xxsscanf("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 = xxsscanf("2A", "%x", &u);
366 PCUT_ASSERT_INT_EQUALS(1, rc);
367 PCUT_ASSERT_TRUE(u == 0x2a);
368}
369
370PCUT_TEST(skipws)
371{
372 int rc;
373 int i;
374
375 /* Skipping whitespace */
376 rc = xxsscanf(" \t\n42", "%d", &i);
377 PCUT_ASSERT_INT_EQUALS(1, rc);
378 PCUT_ASSERT_TRUE(i == 42);
379}
380
381PCUT_TEST(percentile)
382{
383 int rc;
384 int i;
385
386 /* Percentile conversion */
387 rc = xxsscanf(" \t\n%42", "%%%d", &i);
388 PCUT_ASSERT_INT_EQUALS(1, rc);
389 PCUT_ASSERT_TRUE(i == 42);
390}
391
392PCUT_TEST(match_spec_char)
393{
394 int rc;
395 int i;
396
397 /* Matching specific character */
398 rc = xxsscanf("x42", "x%d", &i);
399 PCUT_ASSERT_INT_EQUALS(1, rc);
400 PCUT_ASSERT_TRUE(i == 42);
401}
402
403PCUT_TEST(match_char_noskipws)
404{
405 int rc;
406 int i;
407
408 /* Matching specific character should not skip whitespace */
409 rc = xxsscanf(" x42", "x%d", &i);
410 PCUT_ASSERT_INT_EQUALS(0, rc);
411}
412
413PCUT_TEST(skipws_match_char)
414{
415 int rc;
416 int i;
417
418 /* Skipping whitespace + match specific character */
419 rc = xxsscanf(" x42", "\t\nx%d", &i);
420 PCUT_ASSERT_INT_EQUALS(1, rc);
421 PCUT_ASSERT_TRUE(i == 42);
422}
423
424PCUT_TEST(dec_sufficient_lim_width)
425{
426 int rc;
427 int i;
428
429 /* Decimal with limited, but sufficient width */
430 rc = xxsscanf("42", "%2d", &i);
431 PCUT_ASSERT_INT_EQUALS(1, rc);
432 PCUT_ASSERT_TRUE(i == 42);
433}
434
435PCUT_TEST(dec_smaller_width)
436{
437 int rc;
438 int i;
439
440 /* Decimal with limited, smaller width */
441 rc = xxsscanf("42", "%1d", &i);
442 PCUT_ASSERT_INT_EQUALS(1, rc);
443 PCUT_ASSERT_TRUE(i == 4);
444}
445
446PCUT_TEST(int_hex_limited_width)
447{
448 int rc;
449 int i;
450
451 /* Integer with hex prefix, format with limited, sufficient width */
452 rc = xxsscanf("0x1", "%3i", &i);
453 PCUT_ASSERT_INT_EQUALS(1, rc);
454 PCUT_ASSERT_TRUE(i == 1);
455}
456
457PCUT_TEST(int_hex_small_width)
458{
459 int rc;
460 int i;
461
462 /* Integer with hex prefix, format with limited, smaller width */
463 rc = xxsscanf("0x1", "%2i", &i);
464 PCUT_ASSERT_INT_EQUALS(1, rc);
465 PCUT_ASSERT_TRUE(i == 0);
466}
467
468PCUT_TEST(int_oct_limited_width)
469{
470 int rc;
471 int i;
472
473 /* Integer with octal prefix, format with limited, sufficient width */
474 rc = xxsscanf("012", "%3i", &i);
475 PCUT_ASSERT_INT_EQUALS(1, rc);
476 PCUT_ASSERT_TRUE(i == 012);
477}
478
479PCUT_TEST(int_oct_smaller_width)
480{
481 int rc;
482 int i;
483
484 /* Integer with octal prefix, format with limited, smaller width */
485 rc = xxsscanf("012", "%2i", &i);
486 PCUT_ASSERT_INT_EQUALS(1, rc);
487 PCUT_ASSERT_TRUE(i == 01);
488}
489
490PCUT_TEST(int_oct_tiny_width)
491{
492 int rc;
493 int i;
494
495 /* Integer with octal prefix, format with width allowing just for 0 */
496 rc = xxsscanf("012", "%1i", &i);
497 PCUT_ASSERT_INT_EQUALS(1, rc);
498 PCUT_ASSERT_TRUE(i == 0);
499}
500
501PCUT_TEST(pointer)
502{
503 int rc;
504 void *ptr;
505
506 /* Pointer */
507 rc = xxsscanf("0x12341234", "%p", &ptr);
508 PCUT_ASSERT_INT_EQUALS(1, rc);
509 PCUT_ASSERT_TRUE(ptr == (void *)0x12341234);
510}
511
512PCUT_TEST(single_char)
513{
514 int rc;
515 char c;
516
517 /* Single character */
518 rc = xxsscanf("x", "%c", &c);
519 PCUT_ASSERT_INT_EQUALS(1, rc);
520 PCUT_ASSERT_TRUE(c == 'x');
521}
522
523PCUT_TEST(single_ws_char)
524{
525 int rc;
526 char c;
527
528 /* Single whitespace character */
529 rc = xxsscanf("\t", "%c", &c);
530 PCUT_ASSERT_INT_EQUALS(1, rc);
531 PCUT_ASSERT_TRUE(c == '\t');
532}
533
534PCUT_TEST(chars)
535{
536 int rc;
537 char chars[chars_size];
538
539 /* Multiple characters */
540 memset(chars, 'X', chars_size);
541 rc = xxsscanf("abc", "%3c", chars);
542 PCUT_ASSERT_INT_EQUALS(1, rc);
543 PCUT_ASSERT_TRUE(chars[0] == 'a');
544 PCUT_ASSERT_TRUE(chars[1] == 'b');
545 PCUT_ASSERT_TRUE(chars[2] == 'c');
546 PCUT_ASSERT_TRUE(chars[3] == 'X');
547}
548
549PCUT_TEST(fewer_chars)
550{
551 int rc;
552 char chars[chars_size];
553
554 /* Fewer characters than requested */
555 memset(chars, 'X', chars_size);
556 rc = xxsscanf("abc", "%5c", chars);
557 PCUT_ASSERT_INT_EQUALS(1, rc);
558 PCUT_ASSERT_TRUE(chars[0] == 'a');
559 PCUT_ASSERT_TRUE(chars[1] == 'b');
560 PCUT_ASSERT_TRUE(chars[2] == 'c');
561 PCUT_ASSERT_TRUE(chars[3] == 'X');
562}
563
564PCUT_TEST(chars_not_found)
565{
566 int rc;
567 char chars[chars_size];
568
569 /* Reading characters but no found */
570 memset(chars, 'X', chars_size);
571 rc = xxsscanf("", "%5c", chars);
572 PCUT_ASSERT_INT_EQUALS(EOF, rc);
573 PCUT_ASSERT_TRUE(chars[0] == 'X');
574}
575
576PCUT_TEST(chars_noassign)
577{
578 int rc;
579 int n;
580
581 /* Multiple characters with suppressed assignment */
582 rc = xxsscanf("abc", "%*3c%n", &n);
583 PCUT_ASSERT_INT_EQUALS(0, rc);
584 PCUT_ASSERT_INT_EQUALS(3, n);
585}
586
587PCUT_TEST(chars_malloc)
588{
589 int rc;
590 char *cp;
591
592 /* Multiple characters with memory allocation */
593 cp = NULL;
594 rc = xxsscanf("abc", "%m3c", &cp);
595 PCUT_ASSERT_INT_EQUALS(1, rc);
596 PCUT_ASSERT_NOT_NULL(cp);
597 PCUT_ASSERT_TRUE(cp[0] == 'a');
598 PCUT_ASSERT_TRUE(cp[1] == 'b');
599 PCUT_ASSERT_TRUE(cp[2] == 'c');
600 free(cp);
601}
602
603PCUT_TEST(str)
604{
605 int rc;
606 char chars[chars_size];
607
608 /* String of non-whitespace characters, unlimited width */
609 memset(chars, 'X', chars_size);
610 rc = xxsscanf(" abc d", "%s", chars);
611 PCUT_ASSERT_INT_EQUALS(1, rc);
612 PCUT_ASSERT_TRUE(chars[0] == 'a');
613 PCUT_ASSERT_TRUE(chars[1] == 'b');
614 PCUT_ASSERT_TRUE(chars[2] == 'c');
615 PCUT_ASSERT_TRUE(chars[3] == '\0');
616 PCUT_ASSERT_TRUE(chars[4] == 'X');
617}
618
619PCUT_TEST(str_till_end)
620{
621 int rc;
622 char chars[chars_size];
623
624 /* String of non-whitespace characters, until the end */
625 memset(chars, 'X', chars_size);
626 rc = xxsscanf(" abc", "%s", chars);
627 PCUT_ASSERT_INT_EQUALS(1, rc);
628 PCUT_ASSERT_TRUE(chars[0] == 'a');
629 PCUT_ASSERT_TRUE(chars[1] == 'b');
630 PCUT_ASSERT_TRUE(chars[2] == 'c');
631 PCUT_ASSERT_TRUE(chars[3] == '\0');
632 PCUT_ASSERT_TRUE(chars[4] == 'X');
633}
634
635PCUT_TEST(str_large_width)
636{
637 int rc;
638 char chars[chars_size];
639
640 /* String of non-whitespace characters, large enough width */
641 memset(chars, 'X', chars_size);
642 rc = xxsscanf(" abc d", "%5s", chars);
643 PCUT_ASSERT_INT_EQUALS(1, rc);
644 PCUT_ASSERT_TRUE(chars[0] == 'a');
645 PCUT_ASSERT_TRUE(chars[1] == 'b');
646 PCUT_ASSERT_TRUE(chars[2] == 'c');
647 PCUT_ASSERT_TRUE(chars[3] == '\0');
648 PCUT_ASSERT_TRUE(chars[4] == 'X');
649}
650
651PCUT_TEST(str_not_found)
652{
653 int rc;
654 char chars[chars_size];
655
656 /* Want string of non-whitespace, but got only whitespace */
657 memset(chars, 'X', chars_size);
658 rc = xxsscanf(" ", "%s", chars);
659 PCUT_ASSERT_INT_EQUALS(EOF, rc);
660 PCUT_ASSERT_TRUE(chars[0] == 'X');
661}
662
663PCUT_TEST(str_small_width)
664{
665 int rc;
666 char chars[chars_size];
667
668 /* String of non-whitespace characters, small width */
669 memset(chars, 'X', chars_size);
670 rc = xxsscanf(" abc", "%2s", chars);
671 PCUT_ASSERT_INT_EQUALS(1, rc);
672 PCUT_ASSERT_TRUE(chars[0] == 'a');
673 PCUT_ASSERT_TRUE(chars[1] == 'b');
674 PCUT_ASSERT_TRUE(chars[2] == '\0');
675 PCUT_ASSERT_TRUE(chars[3] == 'X');
676}
677
678PCUT_TEST(str_noassign)
679{
680 int rc;
681 int n;
682
683 /* String of non-whitespace characters, assignment suppression */
684 rc = xxsscanf(" abc d", "%*s%n", &n);
685 PCUT_ASSERT_INT_EQUALS(0, rc);
686 PCUT_ASSERT_INT_EQUALS(4, n);
687}
688
689PCUT_TEST(str_malloc)
690{
691 int rc;
692 char *cp;
693
694 /* String of non-whitespace characters, memory allocation */
695 rc = xxsscanf(" abc d", "%ms", &cp);
696 PCUT_ASSERT_INT_EQUALS(1, rc);
697 PCUT_ASSERT_NOT_NULL(cp);
698 PCUT_ASSERT_TRUE(cp[0] == 'a');
699 PCUT_ASSERT_TRUE(cp[1] == 'b');
700 PCUT_ASSERT_TRUE(cp[2] == 'c');
701 PCUT_ASSERT_TRUE(cp[3] == '\0');
702 free(cp);
703}
704
705PCUT_TEST(set_convert)
706{
707 int rc;
708 char chars[chars_size];
709 int i;
710
711 /* Set conversion without width specified terminating before the end */
712 memset(chars, 'X', chars_size);
713 rc = xxsscanf("abcd42", "%[abc]d%d", chars, &i);
714 PCUT_ASSERT_INT_EQUALS(2, rc);
715 PCUT_ASSERT_TRUE(chars[0] == 'a');
716 PCUT_ASSERT_TRUE(chars[1] == 'b');
717 PCUT_ASSERT_TRUE(chars[2] == 'c');
718 PCUT_ASSERT_TRUE(chars[3] == '\0');
719 PCUT_ASSERT_TRUE(chars[4] == 'X');
720 PCUT_ASSERT_TRUE(i == 42);
721}
722
723PCUT_TEST(set_till_end)
724{
725 int rc;
726 char chars[chars_size];
727
728 /* Set conversion without width specified, until the end */
729 memset(chars, 'X', chars_size);
730 rc = xxsscanf("abc", "%[abc]", chars);
731 PCUT_ASSERT_INT_EQUALS(1, rc);
732 PCUT_ASSERT_TRUE(chars[0] == 'a');
733 PCUT_ASSERT_TRUE(chars[1] == 'b');
734 PCUT_ASSERT_TRUE(chars[2] == 'c');
735 PCUT_ASSERT_TRUE(chars[3] == '\0');
736 PCUT_ASSERT_TRUE(chars[4] == 'X');
737}
738
739PCUT_TEST(set_large_width)
740{
741 int rc;
742 char chars[chars_size];
743
744 /* Set conversion with larger width */
745 memset(chars, 'X', chars_size);
746 rc = xxsscanf("abcd", "%5[abc]", chars);
747 PCUT_ASSERT_INT_EQUALS(1, rc);
748 PCUT_ASSERT_TRUE(chars[0] == 'a');
749 PCUT_ASSERT_TRUE(chars[1] == 'b');
750 PCUT_ASSERT_TRUE(chars[2] == 'c');
751 PCUT_ASSERT_TRUE(chars[3] == '\0');
752 PCUT_ASSERT_TRUE(chars[4] == 'X');
753}
754
755PCUT_TEST(set_small_width)
756{
757 int rc;
758 char chars[chars_size];
759
760 /* Set conversion with smaller width */
761 memset(chars, 'X', chars_size);
762 rc = xxsscanf("abcd", "%3[abcd]", chars);
763 PCUT_ASSERT_INT_EQUALS(1, rc);
764 PCUT_ASSERT_TRUE(chars[0] == 'a');
765 PCUT_ASSERT_TRUE(chars[1] == 'b');
766 PCUT_ASSERT_TRUE(chars[2] == 'c');
767 PCUT_ASSERT_TRUE(chars[3] == '\0');
768 PCUT_ASSERT_TRUE(chars[4] == 'X');
769}
770
771PCUT_TEST(set_negated)
772{
773 int rc;
774 char chars[chars_size];
775
776 /* Set conversion with negated scanset */
777 memset(chars, 'X', chars_size);
778 rc = xxsscanf("abcd", "%[^d]", chars);
779 PCUT_ASSERT_INT_EQUALS(1, rc);
780 PCUT_ASSERT_TRUE(chars[0] == 'a');
781 PCUT_ASSERT_TRUE(chars[1] == 'b');
782 PCUT_ASSERT_TRUE(chars[2] == 'c');
783 PCUT_ASSERT_TRUE(chars[3] == '\0');
784 PCUT_ASSERT_TRUE(chars[4] == 'X');
785}
786
787PCUT_TEST(set_with_rbr)
788{
789 int rc;
790 char chars[chars_size];
791
792 /* Set conversion with ']' in scanset */
793 memset(chars, 'X', chars_size);
794 rc = xxsscanf("]bcd", "%[]bc]", chars);
795 PCUT_ASSERT_INT_EQUALS(1, rc);
796 PCUT_ASSERT_TRUE(chars[0] == ']');
797 PCUT_ASSERT_TRUE(chars[1] == 'b');
798 PCUT_ASSERT_TRUE(chars[2] == 'c');
799 PCUT_ASSERT_TRUE(chars[3] == '\0');
800 PCUT_ASSERT_TRUE(chars[4] == 'X');
801}
802
803PCUT_TEST(set_inverted_with_rbr)
804{
805 int rc;
806 char chars[chars_size];
807
808 /* Set conversion with ']' in inverted scanset */
809 memset(chars, 'X', chars_size);
810 rc = xxsscanf("abc]", "%[^]def]", chars);
811 PCUT_ASSERT_INT_EQUALS(1, rc);
812 PCUT_ASSERT_TRUE(chars[0] == 'a');
813 PCUT_ASSERT_TRUE(chars[1] == 'b');
814 PCUT_ASSERT_TRUE(chars[2] == 'c');
815 PCUT_ASSERT_TRUE(chars[3] == '\0');
816 PCUT_ASSERT_TRUE(chars[4] == 'X');
817}
818
819PCUT_TEST(set_noassign)
820{
821 int rc;
822 int n;
823
824 /* Set conversion with assignment suppression */
825 rc = xxsscanf("abcd42", "%*[abc]%n", &n);
826 PCUT_ASSERT_INT_EQUALS(0, rc);
827 PCUT_ASSERT_INT_EQUALS(3, n);
828}
829
830PCUT_TEST(set_malloc)
831{
832 int rc;
833 char *cp;
834
835 /* Set conversion with memory allocation */
836 cp = NULL;
837 rc = xxsscanf("abcd42", "%m[abcd]", &cp);
838 PCUT_ASSERT_INT_EQUALS(1, rc);
839 PCUT_ASSERT_NOT_NULL(cp);
840 PCUT_ASSERT_TRUE(cp[0] == 'a');
841 PCUT_ASSERT_TRUE(cp[1] == 'b');
842 PCUT_ASSERT_TRUE(cp[2] == 'c');
843 PCUT_ASSERT_TRUE(cp[3] == 'd');
844 PCUT_ASSERT_TRUE(cp[4] == '\0');
845 free(cp);
846}
847
848PCUT_TEST(dec_int_noassign)
849{
850 int rc;
851 int n;
852
853 /* Decimal integer with suppressed assignment */
854 rc = xxsscanf("42", "%*d%n", &n);
855 PCUT_ASSERT_INT_EQUALS(0, rc);
856 PCUT_ASSERT_INT_EQUALS(2, n);
857}
858
859PCUT_TEST(count_chars)
860{
861 int rc;
862 char chars[chars_size];
863 int n;
864
865 /* Count of characters read */
866 memset(chars, 'X', chars_size);
867 rc = xxsscanf("abcd", "%3c%n", chars, &n);
868 PCUT_ASSERT_INT_EQUALS(1, rc);
869 PCUT_ASSERT_TRUE(chars[0] == 'a');
870 PCUT_ASSERT_TRUE(chars[1] == 'b');
871 PCUT_ASSERT_TRUE(chars[2] == 'c');
872 PCUT_ASSERT_TRUE(chars[3] == 'X');
873 PCUT_ASSERT_INT_EQUALS(3, n);
874}
875
876PCUT_TEST(float_intpart_only)
877{
878 int rc;
879 float f;
880
881 /* Float with just integer part */
882 rc = xxsscanf("42", "%f", &f);
883 PCUT_ASSERT_INT_EQUALS(1, rc);
884 PCUT_ASSERT_TRUE(f == 42.0);
885}
886
887PCUT_TEST(double_intpart_only)
888{
889 int rc;
890 double d;
891
892 /* Double with just integer part */
893 rc = xxsscanf("42", "%lf", &d);
894 PCUT_ASSERT_INT_EQUALS(1, rc);
895 PCUT_ASSERT_TRUE(d == 42.0);
896}
897
898PCUT_TEST(ldouble_intpart_only)
899{
900 int rc;
901 long double ld;
902
903 /* Long double with just integer part */
904 rc = xxsscanf("42", "%Lf", &ld);
905 PCUT_ASSERT_INT_EQUALS(1, rc);
906 PCUT_ASSERT_TRUE(ld == 42.0);
907}
908
909PCUT_TEST(float_hex_intpart_only)
910{
911 int rc;
912 float f;
913
914 /* Float with just hexadecimal integer part */
915 rc = xxsscanf("0x2a", "%f", &f);
916 PCUT_ASSERT_INT_EQUALS(1, rc);
917 PCUT_ASSERT_TRUE(f == 0x2a.0p0);
918}
919
920PCUT_TEST(float_sign_intpart)
921{
922 int rc;
923 float f;
924
925 /* Float with sign and integer part */
926 rc = xxsscanf("-42", "%f", &f);
927 PCUT_ASSERT_INT_EQUALS(1, rc);
928 PCUT_ASSERT_TRUE(f == -42.0);
929}
930
931PCUT_TEST(float_intpart_fract)
932{
933 int rc;
934 float f;
935
936 /* Float with integer and fractional part */
937 rc = xxsscanf("4.2", "%f", &f);
938 PCUT_ASSERT_INT_EQUALS(1, rc);
939 /* 1/10 is not exactly representable in binary floating point */
940 PCUT_ASSERT_TRUE(f > 4.199);
941 PCUT_ASSERT_TRUE(f < 4.201);
942}
943
944PCUT_TEST(float_intpart_exp)
945{
946 int rc;
947 float f;
948
949 /* Float with integer part and unsigned exponent */
950 rc = xxsscanf("42e1", "%f", &f);
951 PCUT_ASSERT_INT_EQUALS(1, rc);
952 PCUT_ASSERT_TRUE(f == 420.0);
953}
954
955PCUT_TEST(float_intpart_posexp)
956{
957 int rc;
958 float f;
959
960 /* Float with integer part and positive exponent */
961 rc = xxsscanf("42e+1", "%f", &f);
962 PCUT_ASSERT_INT_EQUALS(1, rc);
963 PCUT_ASSERT_TRUE(f == 420.0);
964}
965
966PCUT_TEST(float_intpart_negexp)
967{
968 int rc;
969 float f;
970
971 /* Float with integer part and negative exponent */
972 rc = xxsscanf("42e-1", "%f", &f);
973 PCUT_ASSERT_INT_EQUALS(1, rc);
974 /* 1/10 is not exactly representable in binary floating point */
975 PCUT_ASSERT_TRUE(f > 4.199);
976 PCUT_ASSERT_TRUE(f < 4.201);
977}
978
979PCUT_TEST(float_intpart_fract_exp)
980{
981 int rc;
982 float f;
983
984 /* Float with integer, fractional parts and unsigned exponent */
985 rc = xxsscanf("4.2e1", "%f", &f);
986 PCUT_ASSERT_INT_EQUALS(1, rc);
987 PCUT_ASSERT_TRUE(f == 42.0);
988}
989
990PCUT_TEST(hexfloat_intpart_fract)
991{
992 int rc;
993 float f;
994
995 /* Hexadecimal float with integer and fractional part */
996 rc = xxsscanf("0x2.a", "%f", &f);
997 PCUT_ASSERT_INT_EQUALS(1, rc);
998 PCUT_ASSERT_TRUE(f == 0x2.ap0);
999}
1000
1001PCUT_TEST(hexfloat_intpart_exp)
1002{
1003 int rc;
1004 float f;
1005
1006 /*
1007 * Hexadecimal float with integer part and unsigned exponent
1008 */
1009 rc = xxsscanf("0x2ap1", "%f", &f);
1010 PCUT_ASSERT_INT_EQUALS(1, rc);
1011 PCUT_ASSERT_TRUE(f == 0x2ap1);
1012}
1013
1014PCUT_TEST(hexfloat_intpart_negexp)
1015{
1016 int rc;
1017 float f;
1018
1019 /*
1020 * Hexadecimal float with integer part and negative exponent
1021 */
1022 rc = xxsscanf("0x2ap-1", "%f", &f);
1023 PCUT_ASSERT_INT_EQUALS(1, rc);
1024 PCUT_ASSERT_TRUE(f == 0x2ap-1);
1025}
1026
1027PCUT_TEST(hexfloat_intpart_fract_exp)
1028{
1029 int rc;
1030 float f;
1031
1032 /*
1033 * Hexadecimal float with integer, fractional parts and unsigned
1034 * exponent
1035 */
1036 rc = xxsscanf("0x2.ap4", "%f", &f);
1037 PCUT_ASSERT_INT_EQUALS(1, rc);
1038 PCUT_ASSERT_TRUE(f == 0x2.ap4);
1039}
1040
1041PCUT_TEST(float_intpart_limwidth)
1042{
1043 int rc;
1044 float f;
1045
1046 /* Float with just integer part and limited width */
1047 rc = xxsscanf("1234", "%3f", &f);
1048 PCUT_ASSERT_INT_EQUALS(1, rc);
1049 PCUT_ASSERT_TRUE(f == 123.0);
1050}
1051
1052PCUT_TEST(float_intpart_fract_limwidth)
1053{
1054 int rc;
1055 float f;
1056
1057 /* Float with integer, fractional part and limited width */
1058 rc = xxsscanf("12.34", "%4f", &f);
1059 PCUT_ASSERT_INT_EQUALS(1, rc);
1060 /* 1/10 is not exactly representable in binary floating point */
1061 PCUT_ASSERT_TRUE(f > 12.29);
1062 PCUT_ASSERT_TRUE(f < 12.31);
1063}
1064
1065PCUT_TEST(float_width_for_only_intpart)
1066{
1067 int rc;
1068 float f;
1069
1070 /* Float with width only enough to cover an integral part */
1071 rc = xxsscanf("12.34", "%3f", &f);
1072 PCUT_ASSERT_INT_EQUALS(1, rc);
1073 PCUT_ASSERT_TRUE(f == 12.0);
1074}
1075
1076PCUT_TEST(float_width_small_for_expnum)
1077{
1078 int rc;
1079 float f;
1080
1081 /* Float with width too small to cover the exponent number */
1082 rc = xxsscanf("12.34e+2", "%7f", &f);
1083 PCUT_ASSERT_INT_EQUALS(1, rc);
1084 /* 1/10 is not exactly representable in binary floating point */
1085 PCUT_ASSERT_TRUE(f > 12.339);
1086 PCUT_ASSERT_TRUE(f < 12.341);
1087}
1088
1089PCUT_TEST(float_width_small_for_expsignum)
1090{
1091 int rc;
1092 float f;
1093
1094 /* Float with width too small to cover the exponent sign and number */
1095 rc = xxsscanf("12.34e+2", "%6f", &f);
1096 PCUT_ASSERT_INT_EQUALS(1, rc);
1097 /* 1/10 is not exactly representable in binary floating point */
1098 PCUT_ASSERT_TRUE(f > 12.339);
1099 PCUT_ASSERT_TRUE(f < 12.341);
1100}
1101
1102PCUT_TEST(float_width_small_for_exp)
1103{
1104 int rc;
1105 float f;
1106
1107 /* Float with width too small to cover the exponent part */
1108 rc = xxsscanf("12.34e+2", "%5f", &f);
1109 PCUT_ASSERT_INT_EQUALS(1, rc);
1110 /* 1/10 is not exactly representable in binary floating point */
1111 PCUT_ASSERT_TRUE(f > 12.339);
1112 PCUT_ASSERT_TRUE(f < 12.341);
1113}
1114
1115PCUT_TEST(float_cap_f)
1116{
1117 int rc;
1118 float f;
1119
1120 /* Float using alternate form 'F' */
1121 rc = xxsscanf("42e1", "%F", &f);
1122 PCUT_ASSERT_INT_EQUALS(1, rc);
1123 PCUT_ASSERT_TRUE(f == 420.0);
1124}
1125
1126PCUT_TEST(float_a)
1127{
1128 int rc;
1129 float f;
1130
1131 /* Float using alternate form 'a' */
1132 rc = xxsscanf("42e1", "%a", &f);
1133 PCUT_ASSERT_INT_EQUALS(1, rc);
1134 PCUT_ASSERT_TRUE(f == 420.0);
1135}
1136
1137PCUT_TEST(float_e)
1138{
1139 int rc;
1140 float f;
1141
1142 /* Float using alternate form 'e' */
1143 rc = xxsscanf("42e1", "%e", &f);
1144 PCUT_ASSERT_INT_EQUALS(1, rc);
1145 PCUT_ASSERT_TRUE(f == 420.0);
1146}
1147
1148PCUT_TEST(float_g)
1149{
1150 int rc;
1151 float f;
1152
1153 /* Float using alternate form 'g' */
1154 rc = xxsscanf("42e1", "%g", &f);
1155 PCUT_ASSERT_INT_EQUALS(1, rc);
1156 PCUT_ASSERT_TRUE(f == 420.0);
1157}
1158
1159PCUT_TEST(float_cap_a)
1160{
1161 int rc;
1162 float f;
1163
1164 /* Float using alternate form 'A' */
1165 rc = xxsscanf("42e1", "%A", &f);
1166 PCUT_ASSERT_INT_EQUALS(1, rc);
1167 PCUT_ASSERT_TRUE(f == 420.0);
1168}
1169
1170PCUT_TEST(float_cap_e)
1171{
1172 int rc;
1173 float f;
1174
1175 /* Float using alternate form 'E' */
1176 rc = xxsscanf("42e1", "%E", &f);
1177 PCUT_ASSERT_INT_EQUALS(1, rc);
1178 PCUT_ASSERT_TRUE(f == 420.0);
1179}
1180
1181PCUT_TEST(float_cap_g)
1182{
1183 int rc;
1184 float f;
1185
1186 /* Float using alternate form 'G' */
1187 rc = xxsscanf("42e1", "%G", &f);
1188 PCUT_ASSERT_INT_EQUALS(1, rc);
1189 PCUT_ASSERT_TRUE(f == 420.0);
1190}
1191
1192PCUT_EXPORT(scanf);
Note: See TracBrowser for help on using the repository browser.