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

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

Add actual test for using range in scanf.

  • Property mode set to 100644
File size: 26.4 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
[f4aa1c8]52/** Empty format string */
[ed18e14]53PCUT_TEST(empty_fmt)
54{
55 int rc;
56
[5a6c28d1]57 rc = sscanf("42", "");
[ed18e14]58 PCUT_ASSERT_INT_EQUALS(0, rc);
59}
60
[f4aa1c8]61/** Decimal integer */
[ed18e14]62PCUT_TEST(dec_int)
63{
64 int rc;
65 int i;
66
[5a6c28d1]67 rc = sscanf("42", "%d", &i);
[ed18e14]68 PCUT_ASSERT_INT_EQUALS(1, rc);
69 PCUT_ASSERT_TRUE(i == 42);
70}
71
[f4aa1c8]72/** Two integers */
[ed18e14]73PCUT_TEST(int_int)
74{
75 int rc;
76 int i, j;
77
[5a6c28d1]78 rc = sscanf("42 43", "%d%d", &i, &j);
[ed18e14]79 PCUT_ASSERT_INT_EQUALS(2, rc);
80 PCUT_ASSERT_TRUE(i == 42);
81 PCUT_ASSERT_TRUE(j == 43);
82}
83
[f4aa1c8]84/** Decimal signed char */
[ed18e14]85PCUT_TEST(dec_sign_char)
86{
87 int rc;
88 signed char sc;
89
[5a6c28d1]90 rc = sscanf("42", "%hhd", &sc);
[ed18e14]91 PCUT_ASSERT_INT_EQUALS(1, rc);
92 PCUT_ASSERT_TRUE(sc == 42);
93}
94
[f4aa1c8]95/** Decimal short */
[ed18e14]96PCUT_TEST(dec_short)
97{
98 int rc;
99 short si;
100
[5a6c28d1]101 rc = sscanf("42", "%hd", &si);
[ed18e14]102 PCUT_ASSERT_INT_EQUALS(1, rc);
103 PCUT_ASSERT_TRUE(si == 42);
104}
105
[f4aa1c8]106/** Decimal long */
[ed18e14]107PCUT_TEST(dec_long)
108{
109 int rc;
110 long li;
111
[5a6c28d1]112 rc = sscanf("42", "%ld", &li);
[ed18e14]113 PCUT_ASSERT_INT_EQUALS(1, rc);
114 PCUT_ASSERT_TRUE(li == 42);
115}
116
[f4aa1c8]117/** Decimal long long */
[ed18e14]118PCUT_TEST(dec_long_long)
119{
120 int rc;
121 long long lli;
122
[5a6c28d1]123 rc = sscanf("42", "%lld", &lli);
[ed18e14]124 PCUT_ASSERT_INT_EQUALS(1, rc);
125 PCUT_ASSERT_TRUE(lli == 42);
126}
127
[f4aa1c8]128/** Decimal intmax_t */
[ed18e14]129PCUT_TEST(dec_intmax)
130{
131 int rc;
132 intmax_t imax;
133
[5a6c28d1]134 rc = sscanf("42", "%jd", &imax);
[ed18e14]135 PCUT_ASSERT_INT_EQUALS(1, rc);
136 PCUT_ASSERT_TRUE(imax == 42);
137}
138
[f4aa1c8]139/** Decimal size_t-sized */
[ed18e14]140PCUT_TEST(dec_size_t_size)
141{
142 int rc;
143 size_t szi;
144
[5a6c28d1]145 rc = sscanf("42", "%zd", &szi);
[ed18e14]146 PCUT_ASSERT_INT_EQUALS(1, rc);
147 PCUT_ASSERT_TRUE(szi == 42);
148}
149
[f4aa1c8]150/** Decimal ptrdiff_t-sized */
[ed18e14]151PCUT_TEST(dec_ptrdiff_t_size)
152{
153 int rc;
154 ptrdiff_t pdi;
155
[5a6c28d1]156 rc = sscanf("42", "%td", &pdi);
[ed18e14]157 PCUT_ASSERT_INT_EQUALS(1, rc);
158 PCUT_ASSERT_TRUE(pdi == 42);
159}
160
[f4aa1c8]161/** Decimal integer followed by hexadecimal digit */
[ed18e14]162PCUT_TEST(dec_int_hexdigit)
163{
164 int rc;
165 int i;
166
[5a6c28d1]167 rc = sscanf("42a", "%d", &i);
[ed18e14]168 PCUT_ASSERT_INT_EQUALS(1, rc);
169 PCUT_ASSERT_TRUE(i == 42);
170}
171
[f4aa1c8]172/** Decimal integer - detect no prefix */
[ed18e14]173PCUT_TEST(int_noprefix)
174{
175 int rc;
176 int i;
177
[5a6c28d1]178 rc = sscanf("42", "%i", &i);
[ed18e14]179 PCUT_ASSERT_INT_EQUALS(1, rc);
180 PCUT_ASSERT_TRUE(i == 42);
181}
182
[f4aa1c8]183/** Prefixed octal integer followed by decimal digit */
[ed18e14]184PCUT_TEST(octal_decimal_digit)
185{
186 int rc;
187 int i;
188
[5a6c28d1]189 rc = sscanf("019", "%i", &i);
[ed18e14]190 PCUT_ASSERT_INT_EQUALS(1, rc);
191 PCUT_ASSERT_TRUE(i == 1);
192}
193
[f4aa1c8]194/** Prefixed hexadecimal integer followed by other character */
[ed18e14]195PCUT_TEST(hex_other_char)
196{
197 int rc;
198 int i;
199
[5a6c28d1]200 rc = sscanf("0xag", "%i", &i);
[ed18e14]201 PCUT_ASSERT_INT_EQUALS(1, rc);
202 PCUT_ASSERT_TRUE(i == 10);
203}
204
[f4aa1c8]205/** Decimal integer with '+' sign */
[ed18e14]206PCUT_TEST(positive_dec)
207{
208 int rc;
209 int i;
210
[5a6c28d1]211 rc = sscanf("+42", "%d", &i);
[ed18e14]212 PCUT_ASSERT_INT_EQUALS(1, rc);
213 PCUT_ASSERT_TRUE(i == 42);
214}
215
[f4aa1c8]216/** Decimal integer with '-' sign */
[ed18e14]217PCUT_TEST(negative_dec)
218{
219 int rc;
220 int i;
221
[5a6c28d1]222 rc = sscanf("-42", "%d", &i);
[ed18e14]223 PCUT_ASSERT_INT_EQUALS(1, rc);
224 PCUT_ASSERT_TRUE(i == -42);
225}
226
[f4aa1c8]227/** Hexadecimal integer with prefix and '-' sign */
[ed18e14]228PCUT_TEST(negative_hex)
229{
230 int rc;
231 int i;
232
[5a6c28d1]233 rc = sscanf("-0xa", "%i", &i);
[ed18e14]234 PCUT_ASSERT_INT_EQUALS(1, rc);
235 PCUT_ASSERT_TRUE(i == -10);
236}
237
[f4aa1c8]238/** Decimal unsigned integer */
[ed18e14]239PCUT_TEST(dec_unsigned)
240{
241 int rc;
242 unsigned u;
243
[5a6c28d1]244 rc = sscanf("42", "%u", &u);
[ed18e14]245 PCUT_ASSERT_INT_EQUALS(1, rc);
246 PCUT_ASSERT_TRUE(u == 42);
247}
248
[f4aa1c8]249/** Decimal unsigned char */
[ed18e14]250PCUT_TEST(dec_unsigned_char)
251{
252 int rc;
253 unsigned char uc;
254
[5a6c28d1]255 rc = sscanf("42", "%hhu", &uc);
[ed18e14]256 PCUT_ASSERT_INT_EQUALS(1, rc);
257 PCUT_ASSERT_TRUE(uc == 42);
258}
259
[f4aa1c8]260/** Decimal unsigned short */
[ed18e14]261PCUT_TEST(dec_unsigned_short)
262{
263 int rc;
264 unsigned short su;
265
[5a6c28d1]266 rc = sscanf("42", "%hu", &su);
[ed18e14]267 PCUT_ASSERT_INT_EQUALS(1, rc);
268 PCUT_ASSERT_TRUE(su == 42);
269}
270
[f4aa1c8]271/** Decimal unsigned long */
[ed18e14]272PCUT_TEST(dec_unsigned_long)
273{
274 int rc;
275 unsigned long lu;
276
[5a6c28d1]277 rc = sscanf("42", "%lu", &lu);
[ed18e14]278 PCUT_ASSERT_INT_EQUALS(1, rc);
279 PCUT_ASSERT_TRUE(lu == 42);
280}
281
[f4aa1c8]282/** Decimal unsigned long long */
[ed18e14]283PCUT_TEST(dec_unsigned_long_long)
284{
285 int rc;
286 unsigned long long llu;
287
[5a6c28d1]288 rc = sscanf("42", "%llu", &llu);
[ed18e14]289 PCUT_ASSERT_INT_EQUALS(1, rc);
290 PCUT_ASSERT_TRUE(llu == 42);
291}
292
[f4aa1c8]293/** Decimal uintmax_t */
[ed18e14]294PCUT_TEST(dec_unitmax)
295{
296 int rc;
297 uintmax_t umax;
298
[5a6c28d1]299 rc = sscanf("42", "%ju", &umax);
[ed18e14]300 PCUT_ASSERT_INT_EQUALS(1, rc);
301 PCUT_ASSERT_TRUE(umax == 42);
302}
303
[f4aa1c8]304/** Decimal size_t */
[ed18e14]305PCUT_TEST(dec_unsigned_size)
306{
307 int rc;
308 size_t szu;
309
[5a6c28d1]310 rc = sscanf("42", "%zu", &szu);
[ed18e14]311 PCUT_ASSERT_INT_EQUALS(1, rc);
312 PCUT_ASSERT_TRUE(szu == 42);
313}
314
[f4aa1c8]315/** Decimal ptrdiff_t-sized unsigned int*/
[ed18e14]316PCUT_TEST(dec_unsigned_ptrdiff)
317{
318 int rc;
319 ptrdiff_t pdu;
320
[5a6c28d1]321 rc = sscanf("42", "%tu", &pdu);
[ed18e14]322 PCUT_ASSERT_INT_EQUALS(1, rc);
323 PCUT_ASSERT_TRUE(pdu == 42);
324}
325
[f4aa1c8]326/** Octal unsigned integer */
[ed18e14]327PCUT_TEST(octal_unsigned)
328{
329 int rc;
330 unsigned u;
331
[5a6c28d1]332 rc = sscanf("52", "%o", &u);
[ed18e14]333 PCUT_ASSERT_INT_EQUALS(1, rc);
334 PCUT_ASSERT_TRUE(u == 052);
335}
336
[f4aa1c8]337/** Hexadecimal unsigned integer */
[ed18e14]338PCUT_TEST(hex_unsigned)
339{
340 int rc;
341 unsigned u;
342
[5a6c28d1]343 rc = sscanf("2a", "%x", &u);
[ed18e14]344 PCUT_ASSERT_INT_EQUALS(1, rc);
345 PCUT_ASSERT_TRUE(u == 0x2a);
346}
347
[f4aa1c8]348/** Hexadecimal unsigned integer unsing alternate specifier */
[ed18e14]349PCUT_TEST(hex_unsigned_cap_x)
350{
351 int rc;
352 unsigned u;
353
[5a6c28d1]354 rc = sscanf("2a", "%X", &u);
[ed18e14]355 PCUT_ASSERT_INT_EQUALS(1, rc);
356 PCUT_ASSERT_TRUE(u == 0x2a);
357}
358
[f4aa1c8]359/** Uppercase hexadecimal unsigned integer */
[ed18e14]360PCUT_TEST(uppercase_hex_unsigned)
361{
362 int rc;
363 unsigned u;
364
[5a6c28d1]365 rc = sscanf("2A", "%x", &u);
[ed18e14]366 PCUT_ASSERT_INT_EQUALS(1, rc);
367 PCUT_ASSERT_TRUE(u == 0x2a);
368}
369
[f4aa1c8]370/** Make sure %x does not match 0x prefix */
[5a6c28d1]371PCUT_TEST(hex_not_match_0x)
372{
373 int rc;
374 unsigned u;
375
376 rc = sscanf("0x1", "%x", &u);
377
378 PCUT_ASSERT_INT_EQUALS(1, rc);
379 PCUT_ASSERT_TRUE(u == 0);
380}
381
[f4aa1c8]382/** Skipping whitespace */
[ed18e14]383PCUT_TEST(skipws)
384{
385 int rc;
386 int i;
387
[5a6c28d1]388 rc = sscanf(" \t\n42", "%d", &i);
[ed18e14]389 PCUT_ASSERT_INT_EQUALS(1, rc);
390 PCUT_ASSERT_TRUE(i == 42);
391}
392
[f4aa1c8]393/** Percentile conversion */
[ed18e14]394PCUT_TEST(percentile)
395{
396 int rc;
397 int i;
398
[5a6c28d1]399 rc = sscanf(" \t\n%42", "%%%d", &i);
[ed18e14]400 PCUT_ASSERT_INT_EQUALS(1, rc);
401 PCUT_ASSERT_TRUE(i == 42);
402}
403
[f4aa1c8]404/** Matching specific character */
[ed18e14]405PCUT_TEST(match_spec_char)
406{
407 int rc;
408 int i;
409
[5a6c28d1]410 rc = sscanf("x42", "x%d", &i);
[ed18e14]411 PCUT_ASSERT_INT_EQUALS(1, rc);
412 PCUT_ASSERT_TRUE(i == 42);
413}
414
[f4aa1c8]415/** Matching specific character should not skip whitespace */
[ed18e14]416PCUT_TEST(match_char_noskipws)
417{
418 int rc;
419 int i;
420
[5a6c28d1]421 rc = sscanf(" x42", "x%d", &i);
[ed18e14]422 PCUT_ASSERT_INT_EQUALS(0, rc);
423}
424
[f4aa1c8]425/** Skipping whitespace + match specific character */
[ed18e14]426PCUT_TEST(skipws_match_char)
427{
428 int rc;
429 int i;
430
[5a6c28d1]431 rc = sscanf(" x42", "\t\nx%d", &i);
[ed18e14]432 PCUT_ASSERT_INT_EQUALS(1, rc);
433 PCUT_ASSERT_TRUE(i == 42);
434}
435
[f4aa1c8]436/** Decimal with limited, but sufficient width */
[ed18e14]437PCUT_TEST(dec_sufficient_lim_width)
438{
439 int rc;
440 int i;
441
[5a6c28d1]442 rc = sscanf("42", "%2d", &i);
[ed18e14]443 PCUT_ASSERT_INT_EQUALS(1, rc);
444 PCUT_ASSERT_TRUE(i == 42);
445}
446
[f4aa1c8]447/** Decimal with limited, smaller width */
[ed18e14]448PCUT_TEST(dec_smaller_width)
449{
450 int rc;
451 int i;
452
[5a6c28d1]453 rc = sscanf("42", "%1d", &i);
[ed18e14]454 PCUT_ASSERT_INT_EQUALS(1, rc);
455 PCUT_ASSERT_TRUE(i == 4);
456}
457
[f4aa1c8]458/** Integer with hex prefix, format with limited, sufficient width */
[ed18e14]459PCUT_TEST(int_hex_limited_width)
460{
461 int rc;
462 int i;
463
[5a6c28d1]464 rc = sscanf("0x1", "%3i", &i);
[ed18e14]465 PCUT_ASSERT_INT_EQUALS(1, rc);
466 PCUT_ASSERT_TRUE(i == 1);
467}
468
[f4aa1c8]469/** Integer with hex prefix, format with limited, smaller width */
[ed18e14]470PCUT_TEST(int_hex_small_width)
471{
472 int rc;
473 int i;
474
[5a6c28d1]475 rc = sscanf("0x1", "%2i", &i);
[ed18e14]476 PCUT_ASSERT_INT_EQUALS(1, rc);
477 PCUT_ASSERT_TRUE(i == 0);
478}
479
[f4aa1c8]480/** Integer with octal prefix, format with limited, sufficient width */
[ed18e14]481PCUT_TEST(int_oct_limited_width)
482{
483 int rc;
484 int i;
485
[5a6c28d1]486 rc = sscanf("012", "%3i", &i);
[ed18e14]487 PCUT_ASSERT_INT_EQUALS(1, rc);
488 PCUT_ASSERT_TRUE(i == 012);
489}
490
[f4aa1c8]491/** Integer with octal prefix, format with limited, smaller width */
[ed18e14]492PCUT_TEST(int_oct_smaller_width)
493{
494 int rc;
495 int i;
496
[5a6c28d1]497 rc = sscanf("012", "%2i", &i);
[ed18e14]498 PCUT_ASSERT_INT_EQUALS(1, rc);
499 PCUT_ASSERT_TRUE(i == 01);
500}
501
[f4aa1c8]502/** Integer with octal prefix, format with width allowing just for 0 */
[ed18e14]503PCUT_TEST(int_oct_tiny_width)
504{
505 int rc;
506 int i;
507
[5a6c28d1]508 rc = sscanf("012", "%1i", &i);
[ed18e14]509 PCUT_ASSERT_INT_EQUALS(1, rc);
510 PCUT_ASSERT_TRUE(i == 0);
511}
512
[f4aa1c8]513/** Pointer */
[ed18e14]514PCUT_TEST(pointer)
515{
516 int rc;
517 void *ptr;
518
[5a6c28d1]519 rc = sscanf("0xABCDEF88", "%p", &ptr);
[ed18e14]520 PCUT_ASSERT_INT_EQUALS(1, rc);
[5a6c28d1]521 PCUT_ASSERT_TRUE(ptr == (void *)0xABCDEF88);
[ed18e14]522}
523
[f4aa1c8]524/** Single character */
[ed18e14]525PCUT_TEST(single_char)
526{
527 int rc;
528 char c;
529
[5a6c28d1]530 rc = sscanf("x", "%c", &c);
[ed18e14]531 PCUT_ASSERT_INT_EQUALS(1, rc);
532 PCUT_ASSERT_TRUE(c == 'x');
533}
534
[f4aa1c8]535/** Single whitespace character */
[ed18e14]536PCUT_TEST(single_ws_char)
537{
538 int rc;
539 char c;
540
[5a6c28d1]541 rc = sscanf("\t", "%c", &c);
[ed18e14]542 PCUT_ASSERT_INT_EQUALS(1, rc);
543 PCUT_ASSERT_TRUE(c == '\t');
544}
545
[f4aa1c8]546/** Multiple characters */
[ed18e14]547PCUT_TEST(chars)
548{
549 int rc;
550 char chars[chars_size];
551
552 memset(chars, 'X', chars_size);
[5a6c28d1]553 rc = sscanf("abc", "%3c", chars);
[ed18e14]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
[f4aa1c8]561/** Fewer characters than requested */
[ed18e14]562PCUT_TEST(fewer_chars)
563{
564 int rc;
565 char chars[chars_size];
566
567 memset(chars, 'X', chars_size);
[5a6c28d1]568 rc = sscanf("abc", "%5c", chars);
[ed18e14]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
[f4aa1c8]576/** Reading characters but no found */
[ed18e14]577PCUT_TEST(chars_not_found)
578{
579 int rc;
580 char chars[chars_size];
581
582 memset(chars, 'X', chars_size);
[5a6c28d1]583 rc = sscanf("", "%5c", chars);
[ed18e14]584 PCUT_ASSERT_INT_EQUALS(EOF, rc);
585 PCUT_ASSERT_TRUE(chars[0] == 'X');
586}
587
[f4aa1c8]588/** Multiple characters with suppressed assignment */
[ed18e14]589PCUT_TEST(chars_noassign)
590{
591 int rc;
592 int n;
593
[5a6c28d1]594 rc = sscanf("abc", "%*3c%n", &n);
[ed18e14]595 PCUT_ASSERT_INT_EQUALS(0, rc);
596 PCUT_ASSERT_INT_EQUALS(3, n);
597}
598
[f4aa1c8]599/** Multiple characters with memory allocation */
[ed18e14]600PCUT_TEST(chars_malloc)
601{
602 int rc;
603 char *cp;
604
605 cp = NULL;
[5a6c28d1]606 rc = sscanf("abc", "%m3c", &cp);
[ed18e14]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
[f4aa1c8]615/** String of non-whitespace characters, unlimited width */
[ed18e14]616PCUT_TEST(str)
617{
618 int rc;
619 char chars[chars_size];
620
621 memset(chars, 'X', chars_size);
[5a6c28d1]622 rc = sscanf(" abc d", "%s", chars);
[ed18e14]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
[f4aa1c8]631/** String of non-whitespace characters, until the end */
[ed18e14]632PCUT_TEST(str_till_end)
633{
634 int rc;
635 char chars[chars_size];
636
637 memset(chars, 'X', chars_size);
[5a6c28d1]638 rc = sscanf(" abc", "%s", chars);
[ed18e14]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
[f4aa1c8]647/** String of non-whitespace characters, large enough width */
[ed18e14]648PCUT_TEST(str_large_width)
649{
650 int rc;
651 char chars[chars_size];
652
653 memset(chars, 'X', chars_size);
[5a6c28d1]654 rc = sscanf(" abc d", "%5s", chars);
[ed18e14]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
[f4aa1c8]663/** Want string of non-whitespace, but got only whitespace */
[ed18e14]664PCUT_TEST(str_not_found)
665{
666 int rc;
667 char chars[chars_size];
668
669 memset(chars, 'X', chars_size);
[5a6c28d1]670 rc = sscanf(" ", "%s", chars);
[ed18e14]671 PCUT_ASSERT_INT_EQUALS(EOF, rc);
672 PCUT_ASSERT_TRUE(chars[0] == 'X');
673}
674
[f4aa1c8]675/** String of non-whitespace characters, small width */
[ed18e14]676PCUT_TEST(str_small_width)
677{
678 int rc;
679 char chars[chars_size];
680
681 memset(chars, 'X', chars_size);
[5a6c28d1]682 rc = sscanf(" abc", "%2s", chars);
[ed18e14]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
[f4aa1c8]690/** String of non-whitespace characters, assignment suppression */
[ed18e14]691PCUT_TEST(str_noassign)
692{
693 int rc;
694 int n;
695
[5a6c28d1]696 rc = sscanf(" abc d", "%*s%n", &n);
[ed18e14]697 PCUT_ASSERT_INT_EQUALS(0, rc);
698 PCUT_ASSERT_INT_EQUALS(4, n);
699}
700
[f4aa1c8]701/** String of non-whitespace characters, memory allocation */
[ed18e14]702PCUT_TEST(str_malloc)
703{
704 int rc;
705 char *cp;
706
[5a6c28d1]707 rc = sscanf(" abc d", "%ms", &cp);
[ed18e14]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
[f4aa1c8]717/** Set conversion without width specified terminating before the end */
[ed18e14]718PCUT_TEST(set_convert)
719{
720 int rc;
721 char chars[chars_size];
722 int i;
723
724 memset(chars, 'X', chars_size);
[5a6c28d1]725 rc = sscanf("abcd42", "%[abc]d%d", chars, &i);
[ed18e14]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
[f4aa1c8]735/** Set conversion without width specified, until the end */
[ed18e14]736PCUT_TEST(set_till_end)
737{
738 int rc;
739 char chars[chars_size];
740
741 memset(chars, 'X', chars_size);
[5a6c28d1]742 rc = sscanf("abc", "%[abc]", chars);
[ed18e14]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
[f4aa1c8]751/** Set conversion with larger width */
[ed18e14]752PCUT_TEST(set_large_width)
753{
754 int rc;
755 char chars[chars_size];
756
757 memset(chars, 'X', chars_size);
[5a6c28d1]758 rc = sscanf("abcd", "%5[abc]", chars);
[ed18e14]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
[f4aa1c8]767/** Set conversion with smaller width */
[ed18e14]768PCUT_TEST(set_small_width)
769{
770 int rc;
771 char chars[chars_size];
772
773 memset(chars, 'X', chars_size);
[5a6c28d1]774 rc = sscanf("abcd", "%3[abcd]", chars);
[ed18e14]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
[f4aa1c8]783/** Set conversion with negated scanset */
[39f84ce4]784PCUT_TEST(set_inverted)
[ed18e14]785{
786 int rc;
787 char chars[chars_size];
788
789 memset(chars, 'X', chars_size);
[5a6c28d1]790 rc = sscanf("abcd", "%[^d]", chars);
[ed18e14]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
[f4aa1c8]799/** Set conversion with ']' in scanset */
[ed18e14]800PCUT_TEST(set_with_rbr)
801{
802 int rc;
803 char chars[chars_size];
804
805 memset(chars, 'X', chars_size);
[5a6c28d1]806 rc = sscanf("]bcd", "%[]bc]", chars);
[ed18e14]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
[f4aa1c8]815/** Set conversion with ']' in inverted scanset */
[ed18e14]816PCUT_TEST(set_inverted_with_rbr)
817{
818 int rc;
819 char chars[chars_size];
820
821 memset(chars, 'X', chars_size);
[5a6c28d1]822 rc = sscanf("abc]", "%[^]def]", chars);
[ed18e14]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
[f4aa1c8]831/** Set conversion with leading '-' in scanset */
[39f84ce4]832PCUT_TEST(set_with_leading_dash)
833{
834 int rc;
835 char chars[chars_size];
836
837 memset(chars, 'X', chars_size);
838 rc = sscanf("a-bc[", "%[-abc]", chars);
839 PCUT_ASSERT_INT_EQUALS(1, rc);
840 PCUT_ASSERT_TRUE(chars[0] == 'a');
841 PCUT_ASSERT_TRUE(chars[1] == '-');
842 PCUT_ASSERT_TRUE(chars[2] == 'b');
843 PCUT_ASSERT_TRUE(chars[3] == 'c');
844 PCUT_ASSERT_TRUE(chars[4] == '\0');
845 PCUT_ASSERT_TRUE(chars[5] == 'X');
846}
847
[f4aa1c8]848/** Set conversion with trailing '-' in scanset */
[39f84ce4]849PCUT_TEST(set_with_trailing_dash)
850{
851 int rc;
852 char chars[chars_size];
853
854 memset(chars, 'X', chars_size);
855 rc = sscanf("a-bc]", "%[abc-]", chars);
856 PCUT_ASSERT_INT_EQUALS(1, rc);
857 PCUT_ASSERT_TRUE(chars[0] == 'a');
858 PCUT_ASSERT_TRUE(chars[1] == '-');
859 PCUT_ASSERT_TRUE(chars[2] == 'b');
860 PCUT_ASSERT_TRUE(chars[3] == 'c');
861 PCUT_ASSERT_TRUE(chars[4] == '\0');
862 PCUT_ASSERT_TRUE(chars[5] == 'X');
863}
864
[f4aa1c8]865/** Set conversion with leading '-' in inverted scanset */
[39f84ce4]866PCUT_TEST(set_inverted_with_leading_dash)
867{
868 int rc;
869 char chars[chars_size];
870
871 memset(chars, 'X', chars_size);
872 rc = sscanf("def-", "%[^-abc]", chars);
873 PCUT_ASSERT_INT_EQUALS(1, rc);
874 PCUT_ASSERT_TRUE(chars[0] == 'd');
875 PCUT_ASSERT_TRUE(chars[1] == 'e');
876 PCUT_ASSERT_TRUE(chars[2] == 'f');
877 PCUT_ASSERT_TRUE(chars[3] == '\0');
878 PCUT_ASSERT_TRUE(chars[4] == 'X');
879}
880
[f4aa1c8]881/** ']' after '^' in scanset does not lose meaning of scanset delimiter */
[39f84ce4]882PCUT_TEST(set_inverted_with_only_dash)
883{
884 int rc;
885 char chars[chars_size];
886
887 memset(chars, 'X', chars_size);
888 rc = sscanf("abc-", "%[^-]", chars);
889 PCUT_ASSERT_INT_EQUALS(1, rc);
890 PCUT_ASSERT_TRUE(chars[0] == 'a');
891 PCUT_ASSERT_TRUE(chars[1] == 'b');
892 PCUT_ASSERT_TRUE(chars[2] == 'c');
893 PCUT_ASSERT_TRUE(chars[3] == '\0');
894 PCUT_ASSERT_TRUE(chars[4] == 'X');
895}
896
[f4aa1c8]897/** '^' after '-' in scanset does not have special meaning */
[39f84ce4]898PCUT_TEST(set_inverted_with_dash_caret)
899{
900 int rc;
901 char chars[chars_size];
902
903 memset(chars, 'X', chars_size);
904 rc = sscanf("-^a", "%[-^a]", chars);
905 PCUT_ASSERT_INT_EQUALS(1, rc);
906 PCUT_ASSERT_TRUE(chars[0] == '-');
907 PCUT_ASSERT_TRUE(chars[1] == '^');
908 PCUT_ASSERT_TRUE(chars[2] == 'a');
909 PCUT_ASSERT_TRUE(chars[3] == '\0');
910 PCUT_ASSERT_TRUE(chars[4] == 'X');
911}
912
[f4aa1c8]913/** Set conversion with range (GNU extension) */
914PCUT_TEST(set_with_range)
915{
916 int rc;
917 char chars[chars_size];
918
919 memset(chars, 'X', chars_size);
920 rc = sscanf("abc]", "%[a-c]", chars);
921 PCUT_ASSERT_INT_EQUALS(1, rc);
922 PCUT_ASSERT_TRUE(chars[0] == 'a');
923 PCUT_ASSERT_TRUE(chars[1] == 'b');
924 PCUT_ASSERT_TRUE(chars[2] == 'c');
925 PCUT_ASSERT_TRUE(chars[3] == '\0');
926 PCUT_ASSERT_TRUE(chars[4] == 'X');
927}
928
929/** Set conversion with range (GNU extension) in inverted scanset */
930PCUT_TEST(set_inverted_with_range)
931{
932 int rc;
933 char chars[chars_size];
934
935 memset(chars, 'X', chars_size);
936 rc = sscanf("defb", "%[^a-c]", chars);
937 PCUT_ASSERT_INT_EQUALS(1, rc);
938 PCUT_ASSERT_TRUE(chars[0] == 'd');
939 PCUT_ASSERT_TRUE(chars[1] == 'e');
940 PCUT_ASSERT_TRUE(chars[2] == 'f');
941 PCUT_ASSERT_TRUE(chars[3] == '\0');
942 PCUT_ASSERT_TRUE(chars[4] == 'X');
943}
944
945/** Set conversion with assignment suppression */
[ed18e14]946PCUT_TEST(set_noassign)
947{
948 int rc;
949 int n;
950
[5a6c28d1]951 rc = sscanf("abcd42", "%*[abc]%n", &n);
[ed18e14]952 PCUT_ASSERT_INT_EQUALS(0, rc);
953 PCUT_ASSERT_INT_EQUALS(3, n);
954}
955
[f4aa1c8]956/** Set conversion with memory allocation */
[ed18e14]957PCUT_TEST(set_malloc)
958{
959 int rc;
960 char *cp;
961
962 cp = NULL;
[5a6c28d1]963 rc = sscanf("abcd42", "%m[abcd]", &cp);
[ed18e14]964 PCUT_ASSERT_INT_EQUALS(1, rc);
965 PCUT_ASSERT_NOT_NULL(cp);
966 PCUT_ASSERT_TRUE(cp[0] == 'a');
967 PCUT_ASSERT_TRUE(cp[1] == 'b');
968 PCUT_ASSERT_TRUE(cp[2] == 'c');
969 PCUT_ASSERT_TRUE(cp[3] == 'd');
970 PCUT_ASSERT_TRUE(cp[4] == '\0');
971 free(cp);
972}
973
[f4aa1c8]974/** Decimal integer with suppressed assignment */
[ed18e14]975PCUT_TEST(dec_int_noassign)
976{
977 int rc;
978 int n;
979
[5a6c28d1]980 rc = sscanf("42", "%*d%n", &n);
[ed18e14]981 PCUT_ASSERT_INT_EQUALS(0, rc);
982 PCUT_ASSERT_INT_EQUALS(2, n);
983}
984
[f4aa1c8]985/** Count of characters read */
[ed18e14]986PCUT_TEST(count_chars)
987{
988 int rc;
989 char chars[chars_size];
990 int n;
991
992 memset(chars, 'X', chars_size);
[5a6c28d1]993 rc = sscanf("abcd", "%3c%n", chars, &n);
[ed18e14]994 PCUT_ASSERT_INT_EQUALS(1, rc);
995 PCUT_ASSERT_TRUE(chars[0] == 'a');
996 PCUT_ASSERT_TRUE(chars[1] == 'b');
997 PCUT_ASSERT_TRUE(chars[2] == 'c');
998 PCUT_ASSERT_TRUE(chars[3] == 'X');
999 PCUT_ASSERT_INT_EQUALS(3, n);
1000}
1001
[f4aa1c8]1002/** Float with just integer part */
[ed18e14]1003PCUT_TEST(float_intpart_only)
1004{
1005 int rc;
1006 float f;
1007
[5a6c28d1]1008 rc = sscanf("42", "%f", &f);
[ed18e14]1009 PCUT_ASSERT_INT_EQUALS(1, rc);
1010 PCUT_ASSERT_TRUE(f == 42.0);
1011}
1012
[f4aa1c8]1013/** Double with just integer part */
[ed18e14]1014PCUT_TEST(double_intpart_only)
1015{
1016 int rc;
1017 double d;
1018
[5a6c28d1]1019 rc = sscanf("42", "%lf", &d);
[ed18e14]1020 PCUT_ASSERT_INT_EQUALS(1, rc);
1021 PCUT_ASSERT_TRUE(d == 42.0);
1022}
1023
[f4aa1c8]1024/** Long double with just integer part */
[ed18e14]1025PCUT_TEST(ldouble_intpart_only)
1026{
1027 int rc;
1028 long double ld;
1029
[5a6c28d1]1030 rc = sscanf("42", "%Lf", &ld);
[ed18e14]1031 PCUT_ASSERT_INT_EQUALS(1, rc);
1032 PCUT_ASSERT_TRUE(ld == 42.0);
1033}
1034
[f4aa1c8]1035/** Float with just hexadecimal integer part */
[ed18e14]1036PCUT_TEST(float_hex_intpart_only)
1037{
1038 int rc;
1039 float f;
1040
[5a6c28d1]1041 rc = sscanf("0x2a", "%f", &f);
[ed18e14]1042 PCUT_ASSERT_INT_EQUALS(1, rc);
1043 PCUT_ASSERT_TRUE(f == 0x2a.0p0);
1044}
1045
[f4aa1c8]1046/** Float with sign and integer part */
[ed18e14]1047PCUT_TEST(float_sign_intpart)
1048{
1049 int rc;
1050 float f;
1051
[5a6c28d1]1052 rc = sscanf("-42", "%f", &f);
[ed18e14]1053 PCUT_ASSERT_INT_EQUALS(1, rc);
1054 PCUT_ASSERT_TRUE(f == -42.0);
1055}
1056
[f4aa1c8]1057/** Float with integer and fractional part */
[ed18e14]1058PCUT_TEST(float_intpart_fract)
1059{
1060 int rc;
1061 float f;
1062
[5a6c28d1]1063 rc = sscanf("4.2", "%f", &f);
[ed18e14]1064 PCUT_ASSERT_INT_EQUALS(1, rc);
1065 /* 1/10 is not exactly representable in binary floating point */
1066 PCUT_ASSERT_TRUE(f > 4.199);
1067 PCUT_ASSERT_TRUE(f < 4.201);
1068}
1069
[f4aa1c8]1070/** Float with integer part and unsigned exponent */
[ed18e14]1071PCUT_TEST(float_intpart_exp)
1072{
1073 int rc;
1074 float f;
1075
[5a6c28d1]1076 rc = sscanf("42e1", "%f", &f);
[ed18e14]1077 PCUT_ASSERT_INT_EQUALS(1, rc);
1078 PCUT_ASSERT_TRUE(f == 420.0);
1079}
1080
[f4aa1c8]1081
1082/** Float with integer part and positive exponent */
[ed18e14]1083PCUT_TEST(float_intpart_posexp)
1084{
1085 int rc;
1086 float f;
[5a6c28d1]1087 rc = sscanf("42e+1", "%f", &f);
[ed18e14]1088 PCUT_ASSERT_INT_EQUALS(1, rc);
1089 PCUT_ASSERT_TRUE(f == 420.0);
1090}
1091
[f4aa1c8]1092/** Float with integer part and negative exponent */
[ed18e14]1093PCUT_TEST(float_intpart_negexp)
1094{
1095 int rc;
1096 float f;
1097
[5a6c28d1]1098 rc = sscanf("42e-1", "%f", &f);
[ed18e14]1099 PCUT_ASSERT_INT_EQUALS(1, rc);
1100 /* 1/10 is not exactly representable in binary floating point */
1101 PCUT_ASSERT_TRUE(f > 4.199);
1102 PCUT_ASSERT_TRUE(f < 4.201);
1103}
1104
[f4aa1c8]1105/** Float with integer, fractional parts and unsigned exponent */
[ed18e14]1106PCUT_TEST(float_intpart_fract_exp)
1107{
1108 int rc;
1109 float f;
1110
[5a6c28d1]1111 rc = sscanf("4.2e1", "%f", &f);
[ed18e14]1112 PCUT_ASSERT_INT_EQUALS(1, rc);
1113 PCUT_ASSERT_TRUE(f == 42.0);
1114}
1115
[f4aa1c8]1116/** Hexadecimal float with integer and fractional part */
[ed18e14]1117PCUT_TEST(hexfloat_intpart_fract)
1118{
1119 int rc;
1120 float f;
1121
[5a6c28d1]1122 rc = sscanf("0x2.a", "%f", &f);
[ed18e14]1123 PCUT_ASSERT_INT_EQUALS(1, rc);
1124 PCUT_ASSERT_TRUE(f == 0x2.ap0);
1125}
1126
[f4aa1c8]1127/** Hexadecimal float with integer part and unsigned exponent */
[ed18e14]1128PCUT_TEST(hexfloat_intpart_exp)
1129{
1130 int rc;
1131 float f;
1132
[5a6c28d1]1133 rc = sscanf("0x2ap1", "%f", &f);
[ed18e14]1134 PCUT_ASSERT_INT_EQUALS(1, rc);
1135 PCUT_ASSERT_TRUE(f == 0x2ap1);
1136}
1137
[f4aa1c8]1138/** Hexadecimal float with integer part and negative exponent */
[ed18e14]1139PCUT_TEST(hexfloat_intpart_negexp)
1140{
1141 int rc;
1142 float f;
1143
[5a6c28d1]1144 rc = sscanf("0x2ap-1", "%f", &f);
[ed18e14]1145 PCUT_ASSERT_INT_EQUALS(1, rc);
1146 PCUT_ASSERT_TRUE(f == 0x2ap-1);
1147}
1148
[f4aa1c8]1149/** Hexadecimal float with integer, fractional parts and unsigned exponent */
[ed18e14]1150PCUT_TEST(hexfloat_intpart_fract_exp)
1151{
1152 int rc;
1153 float f;
1154
[5a6c28d1]1155 rc = sscanf("0x2.ap4", "%f", &f);
[ed18e14]1156 PCUT_ASSERT_INT_EQUALS(1, rc);
1157 PCUT_ASSERT_TRUE(f == 0x2.ap4);
1158}
1159
[f4aa1c8]1160/** Float with just integer part and limited width */
[ed18e14]1161PCUT_TEST(float_intpart_limwidth)
1162{
1163 int rc;
1164 float f;
1165
[5a6c28d1]1166 rc = sscanf("1234", "%3f", &f);
[ed18e14]1167 PCUT_ASSERT_INT_EQUALS(1, rc);
1168 PCUT_ASSERT_TRUE(f == 123.0);
1169}
1170
[f4aa1c8]1171/** Float with integer, fractional part and limited width */
[ed18e14]1172PCUT_TEST(float_intpart_fract_limwidth)
1173{
1174 int rc;
1175 float f;
1176
[5a6c28d1]1177 rc = sscanf("12.34", "%4f", &f);
[ed18e14]1178 PCUT_ASSERT_INT_EQUALS(1, rc);
1179 /* 1/10 is not exactly representable in binary floating point */
1180 PCUT_ASSERT_TRUE(f > 12.29);
1181 PCUT_ASSERT_TRUE(f < 12.31);
1182}
1183
[f4aa1c8]1184/** Float with width only enough to cover an integral part */
[ed18e14]1185PCUT_TEST(float_width_for_only_intpart)
1186{
1187 int rc;
1188 float f;
1189
[5a6c28d1]1190 rc = sscanf("12.34", "%3f", &f);
[ed18e14]1191 PCUT_ASSERT_INT_EQUALS(1, rc);
1192 PCUT_ASSERT_TRUE(f == 12.0);
1193}
1194
[f4aa1c8]1195/** Float with width too small to cover the exponent number */
[ed18e14]1196PCUT_TEST(float_width_small_for_expnum)
1197{
1198 int rc;
1199 float f;
1200
[5a6c28d1]1201 rc = sscanf("12.34e+2", "%7f", &f);
[ed18e14]1202 PCUT_ASSERT_INT_EQUALS(1, rc);
1203 /* 1/10 is not exactly representable in binary floating point */
1204 PCUT_ASSERT_TRUE(f > 12.339);
1205 PCUT_ASSERT_TRUE(f < 12.341);
1206}
1207
[f4aa1c8]1208/** Float with width too small to cover the exponent sign and number */
[ed18e14]1209PCUT_TEST(float_width_small_for_expsignum)
1210{
1211 int rc;
1212 float f;
1213
[5a6c28d1]1214 rc = sscanf("12.34e+2", "%6f", &f);
[ed18e14]1215 PCUT_ASSERT_INT_EQUALS(1, rc);
1216 /* 1/10 is not exactly representable in binary floating point */
1217 PCUT_ASSERT_TRUE(f > 12.339);
1218 PCUT_ASSERT_TRUE(f < 12.341);
1219}
1220
[f4aa1c8]1221/** Float with width too small to cover the exponent part */
[ed18e14]1222PCUT_TEST(float_width_small_for_exp)
1223{
1224 int rc;
1225 float f;
1226
[5a6c28d1]1227 rc = sscanf("12.34e+2", "%5f", &f);
[ed18e14]1228 PCUT_ASSERT_INT_EQUALS(1, rc);
1229 /* 1/10 is not exactly representable in binary floating point */
1230 PCUT_ASSERT_TRUE(f > 12.339);
1231 PCUT_ASSERT_TRUE(f < 12.341);
1232}
1233
[f4aa1c8]1234/** Float using alternate form 'F' */
[ed18e14]1235PCUT_TEST(float_cap_f)
1236{
1237 int rc;
1238 float f;
1239
[5a6c28d1]1240 rc = sscanf("42e1", "%F", &f);
[ed18e14]1241 PCUT_ASSERT_INT_EQUALS(1, rc);
1242 PCUT_ASSERT_TRUE(f == 420.0);
1243}
1244
[f4aa1c8]1245/** Float using alternate form 'a' */
[ed18e14]1246PCUT_TEST(float_a)
1247{
1248 int rc;
1249 float f;
1250
[5a6c28d1]1251 rc = sscanf("42e1", "%a", &f);
[ed18e14]1252 PCUT_ASSERT_INT_EQUALS(1, rc);
1253 PCUT_ASSERT_TRUE(f == 420.0);
1254}
1255
[f4aa1c8]1256/** Float using alternate form 'e' */
[ed18e14]1257PCUT_TEST(float_e)
1258{
1259 int rc;
1260 float f;
1261
[5a6c28d1]1262 rc = sscanf("42e1", "%e", &f);
[ed18e14]1263 PCUT_ASSERT_INT_EQUALS(1, rc);
1264 PCUT_ASSERT_TRUE(f == 420.0);
1265}
1266
[f4aa1c8]1267/** Float using alternate form 'g' */
[ed18e14]1268PCUT_TEST(float_g)
1269{
1270 int rc;
1271 float f;
1272
[5a6c28d1]1273 rc = sscanf("42e1", "%g", &f);
[ed18e14]1274 PCUT_ASSERT_INT_EQUALS(1, rc);
1275 PCUT_ASSERT_TRUE(f == 420.0);
1276}
1277
[f4aa1c8]1278/** Float using alternate form 'A' */
[ed18e14]1279PCUT_TEST(float_cap_a)
1280{
1281 int rc;
1282 float f;
1283
[5a6c28d1]1284 rc = sscanf("42e1", "%A", &f);
[ed18e14]1285 PCUT_ASSERT_INT_EQUALS(1, rc);
1286 PCUT_ASSERT_TRUE(f == 420.0);
1287}
1288
[f4aa1c8]1289/** Float using alternate form 'E' */
[ed18e14]1290PCUT_TEST(float_cap_e)
1291{
1292 int rc;
1293 float f;
1294
[5a6c28d1]1295 rc = sscanf("42e1", "%E", &f);
[ed18e14]1296 PCUT_ASSERT_INT_EQUALS(1, rc);
1297 PCUT_ASSERT_TRUE(f == 420.0);
1298}
1299
[f4aa1c8]1300/** Float using alternate form 'G' */
[ed18e14]1301PCUT_TEST(float_cap_g)
1302{
1303 int rc;
1304 float f;
1305
[5a6c28d1]1306 rc = sscanf("42e1", "%G", &f);
[ed18e14]1307 PCUT_ASSERT_INT_EQUALS(1, rc);
1308 PCUT_ASSERT_TRUE(f == 420.0);
1309}
1310
1311PCUT_EXPORT(scanf);
Note: See TracBrowser for help on using the repository browser.