3 /* sscanf( const char *, const char *, ... )
5 This file is part of the Public Domain C Library (PDCLib).
6 Permission is granted to use, modify, and / or redistribute at will.
14 int sscanf( const char * _PDCLIB_restrict s, const char * _PDCLIB_restrict format, ... )
18 va_start( ap, format );
19 rc = vsscanf( s, format, ap );
27 #include <_PDCLIB_test.h>
32 #define CHECK_TRUE( a ) TESTCASE( a != 0 )
33 #define CHECK_FALSE( a ) TESTCASE( a == 0 )
34 #define CHECK_EQUAL( a, b ) do { int x = a; int y = b; TESTCASE( x == y ); } while ( 0 )
35 #define CHECK_FEQUAL( a, b, T, F ) do { T x = a; T y = b; TESTCASE( x == y ); } while ( 0 )
37 // literal matches, character matches, and basic integer matches
38 void suite_one( void );
39 // decimal integer matches
40 void suite_two( void );
41 // hexadecimal integer matches
42 void suite_three( void );
43 // octal integer matches
44 void suite_four( void );
46 void suite_five( void );
48 void suite_six( void );
58 // This test driver fails for many common libraries, so it's disabled for
59 // regression testing. See the function for explanation.
64 // literal matches, character matches, and basic integer matches
67 char const * string = "12345678901\0003-5+7\0009\3772 4 6 8 0\3771 \011 5%% 0";
68 CHECK_EQUAL( string[39], '0' );
70 // -----------------------------------------------------------------------
72 // -----------------------------------------------------------------------
74 // matching six characters literally
76 // should report six characters read
78 CHECK_EQUAL( sscanf( string + 0, "123456%n", &n ), 0 );
82 // matching a character, three whitespace chars, and another character
84 // should report five characters read
86 CHECK_EQUAL( sscanf( string + 30, "1 5%n", &n ), 0 );
90 // matching three characters, not matching whitespaces, and matching another three characters
92 // should report six characters matched
94 CHECK_EQUAL( sscanf( string + 0, "123 456%n", &n ), 0 );
98 // matching a character, two '%' characters, and two whitespaces
100 // should report five characters matched
102 CHECK_EQUAL( sscanf( string + 34, "5%%%% %n", &n ), 0 );
106 // seeking to last character in file, trying to match that char and a whitespace
108 // should report one character matched and EOF
110 CHECK_EQUAL( sscanf( string + 39, "0 %n", &n ), 0 );
114 // seeking to end of file, trying to match a -1
116 // should report error, not executing %n
118 CHECK_EQUAL( sscanf( string + 0, "\377%n", &n ), 0 );
119 CHECK_EQUAL( n, -1 );
122 // -----------------------------------------------------------------------
123 // Character matching ('%c')
124 // -----------------------------------------------------------------------
126 // reading a char array of specified width, including zero bytes
127 // should report the characters read up to first zero
129 memset( buffer, '\177', 8 );
130 CHECK_EQUAL( sscanf( string + 10, "%7c", buffer ), 1 );
131 CHECK_FALSE( memcmp( buffer, "1\177\177", 3 ) );
134 // reading a char array of unspecified width when positioned at -1 value
135 // should default to width one, read the -1 value, no zero termination of the array
137 memset( buffer, '\177', 2 );
138 CHECK_EQUAL( sscanf( string + 19, "%c", buffer ), 1 );
139 CHECK_FALSE( memcmp( buffer, "\377\177", 2 ) );
142 // reading a char array of specified width 1 when positioned at (non-space) whitespace
143 // should read the whitespace (literally), no zero termination of the array
145 memset( buffer, '\177', 2 );
146 CHECK_EQUAL( sscanf( string + 32, "%1c", buffer ), 1 );
147 CHECK_FALSE( memcmp( buffer, "\011\177", 2 ) );
150 // reading a char array of specified width 2 when positioned at last char of file
151 // should read the character, and report EOF
153 memset( buffer, '\177', 2 );
154 CHECK_EQUAL( sscanf( string + 39, "%2c", buffer ), 1 );
155 CHECK_FALSE( memcmp( buffer, "0\177", 2 ) );
158 // reading a char array of specified width 1 when positioned at last char of file
159 // should read the character, and NOT report EOF
161 memset( buffer, '\177', 2 );
162 CHECK_EQUAL( sscanf( string + 39, "%1c", buffer ), 1 );
163 CHECK_FALSE( memcmp( buffer, "0\177", 2 ) );
166 // reading a char array of specified width 1 when positioned at EOF
167 // should report input error before any conversion (-1)
169 memset( buffer, '\177', 2 );
170 CHECK_EQUAL( sscanf( string + 40, "%1c", buffer ), -1 );
171 CHECK_FALSE( memcmp( buffer, "\177\177", 2 ) );
174 // -----------------------------------------------------------------------
175 // Integer matching ('%d')
176 // -----------------------------------------------------------------------
178 // reading a whitespace-terminated integer
181 CHECK_EQUAL( sscanf( string + 20, "%d%n", &i, &n ), 1 );
186 // reading a -1 terminated integer
189 CHECK_EQUAL( sscanf( string + 18, "%d%n", &i, &n ), 1 );
194 // reading a EOF terminated integer
197 CHECK_EQUAL( sscanf( string + 39, "%d%n", &i, &n ), 1 );
202 // trying to read an integer when positioned at whitespace
203 // should skip whitespaces
206 CHECK_EQUAL( sscanf( string + 32, "%d%n", &i, &n ), 1 );
211 // trying to read an integer when positioned at -1 value
212 // should report matching failure
215 CHECK_EQUAL( sscanf( string + 19, "%d%n", &i, &n ), 0 );
217 CHECK_EQUAL( n, -1 );
220 // trying to read an integer when positioned at EOF
221 // should report reading failure
224 CHECK_EQUAL( sscanf( string + 40, "%d%n", &i, &n ), -1 );
226 CHECK_EQUAL( n, -1 );
229 // reading a '-'-prefixed integer
232 CHECK_EQUAL( sscanf( string + 13, "%d%n", &i, &n ), 1 );
233 CHECK_EQUAL( i, -5 );
237 // reading a '+'-prefixed integer
240 CHECK_EQUAL( sscanf( string + 15, "%d%n", &i, &n ), 1 );
246 // decimal integer matches
249 char const * string = "-0 +0 -128 +127 +255 -32768 +32767 +65535\n"
250 "-2147483648 +2147483647 +4294967295\n"
251 "-9223372036854775808 +9223372036854775807\n"
252 "+18446744073709551615\n";
253 CHECK_EQUAL( string[141], '\n' );
258 CHECK_EQUAL( sscanf( string + 1, "%hhd%n", &i, &n ), 1 );
266 CHECK_EQUAL( sscanf( string + 0, "%hhd%n", &i, &n ), 1 );
274 CHECK_EQUAL( sscanf( string + 3, "%hhd%n", &i, &n ), 1 );
282 CHECK_EQUAL( sscanf( string + 6, "%hhd%n", &i, &n ), 1 );
283 CHECK_EQUAL( i, -128 );
290 CHECK_EQUAL( sscanf( string + 12, "%hhd%n", &i, &n ), 1 );
291 CHECK_EQUAL( i, 127 );
298 CHECK_EQUAL( sscanf( string + 11, "%hhd%n", &i, &n ), 1 );
299 CHECK_EQUAL( i, 127 );
304 unsigned char i = -1;
306 CHECK_EQUAL( sscanf( string + 1, "%hhu%n", &i, &n ), 1 );
312 unsigned char i = -1;
314 CHECK_EQUAL( sscanf( string + 0, "%hhu%n", &i, &n ), 1 );
320 unsigned char i = -1;
322 CHECK_EQUAL( sscanf( string + 3, "%hhu%n", &i, &n ), 1 );
328 unsigned char i = -1;
330 CHECK_EQUAL( sscanf( string + 12, "%hhu%n", &i, &n ), 1 );
331 CHECK_EQUAL( i, 127 );
336 unsigned char i = -1;
338 CHECK_EQUAL( sscanf( string + 11, "%hhu%n", &i, &n ), 1 );
339 CHECK_EQUAL( i, 127 );
346 CHECK_EQUAL( sscanf( string + 17, "%hhu%n", &i, &n ), 1 );
347 CHECK_EQUAL( i, 255 );
354 CHECK_EQUAL( sscanf( string + 16, "%hhu%n", &i, &n ), 1 );
355 CHECK_EQUAL( i, 255 );
362 CHECK_EQUAL( sscanf( string + 1, "%hhi%n", &i, &n ), 1 );
370 CHECK_EQUAL( sscanf( string + 0, "%hhi%n", &i, &n ), 1 );
378 CHECK_EQUAL( sscanf( string + 3, "%hhi%n", &i, &n ), 1 );
386 CHECK_EQUAL( sscanf( string + 6, "%hhi%n", &i, &n ), 1 );
387 CHECK_EQUAL( i, -128 );
394 CHECK_EQUAL( sscanf( string + 12, "%hhi%n", &i, &n ), 1 );
395 CHECK_EQUAL( i, 127 );
402 CHECK_EQUAL( sscanf( string + 11, "%hhi%n", &i, &n ), 1 );
403 CHECK_EQUAL( i, 127 );
410 CHECK_EQUAL( sscanf( string + 1, "%hd%n", &i, &n ), 1 );
418 CHECK_EQUAL( sscanf( string + 0, "%hd%n", &i, &n ), 1 );
426 CHECK_EQUAL( sscanf( string + 3, "%hd%n", &i, &n ), 1 );
434 CHECK_EQUAL( sscanf( string + 21, "%hd%n", &i, &n ), 1 );
435 CHECK_EQUAL( i, -32768 );
442 CHECK_EQUAL( sscanf( string + 29, "%hd%n", &i, &n ), 1 );
443 CHECK_EQUAL( i, 32767 );
450 CHECK_EQUAL( sscanf( string + 28, "%hd%n", &i, &n ), 1 );
451 CHECK_EQUAL( i, 32767 );
456 unsigned short i = -1;
458 CHECK_EQUAL( sscanf( string + 1, "%hu%n", &i, &n ), 1 );
464 unsigned short i = -1;
466 CHECK_EQUAL( sscanf( string + 0, "%hu%n", &i, &n ), 1 );
472 unsigned short i = -1;
474 CHECK_EQUAL( sscanf( string + 3, "%hu%n", &i, &n ), 1 );
480 unsigned short i = -1;
482 CHECK_EQUAL( sscanf( string + 29, "%hu%n", &i, &n ), 1 );
483 CHECK_EQUAL( i, 32767 );
488 unsigned short i = -1;
490 CHECK_EQUAL( sscanf( string + 28, "%hu%n", &i, &n ), 1 );
491 CHECK_EQUAL( i, 32767 );
496 unsigned short i = 0;
498 CHECK_EQUAL( sscanf( string + 36, "%hu%n", &i, &n ), 1 );
499 CHECK_EQUAL( i, 65535 );
504 unsigned short i = 0;
506 CHECK_EQUAL( sscanf( string + 35, "%hu%n", &i, &n ), 1 );
507 CHECK_EQUAL( i, 65535 );
514 CHECK_EQUAL( sscanf( string + 1, "%hi%n", &i, &n ), 1 );
522 CHECK_EQUAL( sscanf( string + 0, "%hi%n", &i, &n ), 1 );
530 CHECK_EQUAL( sscanf( string + 3, "%hi%n", &i, &n ), 1 );
538 CHECK_EQUAL( sscanf( string + 21, "%hi%n", &i, &n ), 1 );
539 CHECK_EQUAL( i, -32768 );
546 CHECK_EQUAL( sscanf( string + 29, "%hi%n", &i, &n ), 1 );
547 CHECK_EQUAL( i, 32767 );
554 CHECK_EQUAL( sscanf( string + 28, "%hi%n", &i, &n ), 1 );
555 CHECK_EQUAL( i, 32767 );
562 CHECK_EQUAL( sscanf( string + 1, "%d%n", &i, &n ), 1 );
570 CHECK_EQUAL( sscanf( string + 0, "%d%n", &i, &n ), 1 );
578 CHECK_EQUAL( sscanf( string + 3, "%d%n", &i, &n ), 1 );
583 // reading -2147483648, d
586 CHECK_EQUAL( sscanf( string + 42, "%d%n", &i, &n ), 1 );
587 CHECK_EQUAL( i, -2147483648 );
588 CHECK_EQUAL( n, 11 );
591 // reading 2147483647, d
594 CHECK_EQUAL( sscanf( string + 55, "%d%n", &i, &n ), 1 );
595 CHECK_EQUAL( i, 2147483647 );
596 CHECK_EQUAL( n, 10 );
599 // reading +2147483647, d
602 CHECK_EQUAL( sscanf( string + 54, "%d%n", &i, &n ), 1 );
603 CHECK_EQUAL( i, 2147483647 );
604 CHECK_EQUAL( n, 11 );
610 CHECK_EQUAL( sscanf( string + 1, "%u%n", &i, &n ), 1 );
618 CHECK_EQUAL( sscanf( string + 0, "%u%n", &i, &n ), 1 );
626 CHECK_EQUAL( sscanf( string + 3, "%u%n", &i, &n ), 1 );
631 // reading 2147483647, u
634 CHECK_EQUAL( sscanf( string + 55, "%u%n", &i, &n ), 1 );
635 CHECK_EQUAL( i, 2147483647 );
636 CHECK_EQUAL( n, 10 );
639 // reading +2147483647, u
642 CHECK_EQUAL( sscanf( string + 54, "%u%n", &i, &n ), 1 );
643 CHECK_EQUAL( i, 2147483647 );
644 CHECK_EQUAL( n, 11 );
647 // reading 4294967295, u
650 CHECK_EQUAL( sscanf( string + 67, "%u%n", &i, &n ), 1 );
651 CHECK_FEQUAL( i, 4294967295, unsigned int, "%u" );
652 CHECK_EQUAL( n, 10 );
655 // reading +4294967295, u
658 CHECK_EQUAL( sscanf( string + 66, "%u%n", &i, &n ), 1 );
659 CHECK_FEQUAL( i, 4294967295, unsigned int, "%u" );
660 CHECK_EQUAL( n, 11 );
666 CHECK_EQUAL( sscanf( string + 1, "%i%n", &i, &n ), 1 );
674 CHECK_EQUAL( sscanf( string + 0, "%i%n", &i, &n ), 1 );
682 CHECK_EQUAL( sscanf( string + 3, "%i%n", &i, &n ), 1 );
687 // reading -2147483648, i
690 CHECK_EQUAL( sscanf( string + 42, "%i%n", &i, &n ), 1 );
691 CHECK_EQUAL( i, -2147483648 );
692 CHECK_EQUAL( n, 11 );
695 // reading 2147483647, i
698 CHECK_EQUAL( sscanf( string + 55, "%i%n", &i, &n ), 1 );
699 CHECK_EQUAL( i, 2147483647 );
700 CHECK_EQUAL( n, 10 );
703 // reading +2147483647, i
706 CHECK_EQUAL( sscanf( string + 54, "%i%n", &i, &n ), 1 );
707 CHECK_EQUAL( i, 2147483647 );
708 CHECK_EQUAL( n, 11 );
714 CHECK_EQUAL( sscanf( string + 1, "%ld%n", &i, &n ), 1 );
715 CHECK_EQUAL( i, 0l );
722 CHECK_EQUAL( sscanf( string + 0, "%ld%n", &i, &n ), 1 );
723 CHECK_EQUAL( i, 0l );
730 CHECK_EQUAL( sscanf( string + 3, "%ld%n", &i, &n ), 1 );
731 CHECK_EQUAL( i, 0l );
735 // reading -2147483648, d
738 CHECK_EQUAL( sscanf( string + 42, "%ld%n", &i, &n ), 1 );
739 CHECK_EQUAL( i, -2147483648l );
740 CHECK_EQUAL( n, 11 );
743 // reading 2147483647, d
746 CHECK_EQUAL( sscanf( string + 55, "%ld%n", &i, &n ), 1 );
747 CHECK_EQUAL( i, 2147483647l );
748 CHECK_EQUAL( n, 10 );
751 // reading +2147483647, d
754 CHECK_EQUAL( sscanf( string + 54, "%ld%n", &i, &n ), 1 );
755 CHECK_EQUAL( i, 2147483647l );
756 CHECK_EQUAL( n, 11 );
760 unsigned long i = -1;
762 CHECK_EQUAL( sscanf( string + 1, "%lu%n", &i, &n ), 1 );
763 CHECK_EQUAL( i, 0ul );
768 unsigned long i = -1;
770 CHECK_EQUAL( sscanf( string + 0, "%lu%n", &i, &n ), 1 );
771 CHECK_EQUAL( i, 0ul );
776 unsigned long i = -1;
778 CHECK_EQUAL( sscanf( string + 3, "%lu%n", &i, &n ), 1 );
779 CHECK_EQUAL( i, 0ul );
783 // reading 2147483647, u
784 unsigned long i = -1;
786 CHECK_EQUAL( sscanf( string + 55, "%lu%n", &i, &n ), 1 );
787 CHECK_EQUAL( i, 2147483647ul );
788 CHECK_EQUAL( n, 10 );
791 // reading +2147483647, u
792 unsigned long i = -1;
794 CHECK_EQUAL( sscanf( string + 54, "%lu%n", &i, &n ), 1 );
795 CHECK_EQUAL( i, 2147483647ul );
796 CHECK_EQUAL( n, 11 );
799 // reading 4294967295, u
802 CHECK_EQUAL( sscanf( string + 67, "%lu%n", &i, &n ), 1 );
803 CHECK_FEQUAL( i, 4294967295ul, unsigned long, "%lu" );
804 CHECK_EQUAL( n, 10 );
807 // reading +4294967295, u
810 CHECK_EQUAL( sscanf( string + 66, "%lu%n", &i, &n ), 1 );
811 CHECK_FEQUAL( i, 4294967295ul, unsigned long, "%lu" );
812 CHECK_EQUAL( n, 11 );
818 CHECK_EQUAL( sscanf( string + 1, "%li%n", &i, &n ), 1 );
819 CHECK_EQUAL( i, 0l );
826 CHECK_EQUAL( sscanf( string + 0, "%li%n", &i, &n ), 1 );
827 CHECK_EQUAL( i, 0l );
834 CHECK_EQUAL( sscanf( string + 3, "%li%n", &i, &n ), 1 );
835 CHECK_EQUAL( i, 0l );
839 // reading -2147483648, i
842 CHECK_EQUAL( sscanf( string + 42, "%li%n", &i, &n ), 1 );
843 CHECK_EQUAL( i, -2147483648l );
844 CHECK_EQUAL( n, 11 );
847 // reading 2147483647, i
850 CHECK_EQUAL( sscanf( string + 55, "%li%n", &i, &n ), 1 );
851 CHECK_EQUAL( i, 2147483647l );
852 CHECK_EQUAL( n, 10 );
855 // reading +2147483647, i
858 CHECK_EQUAL( sscanf( string + 54, "%li%n", &i, &n ), 1 );
859 CHECK_EQUAL( i, 2147483647l );
860 CHECK_EQUAL( n, 11 );
864 signed long long i = -1;
866 CHECK_EQUAL( sscanf( string + 1, "%lld%n", &i, &n ), 1 );
867 CHECK_EQUAL( i, 0ll );
872 signed long long i = -1;
874 CHECK_EQUAL( sscanf( string + 0, "%lld%n", &i, &n ), 1 );
875 CHECK_EQUAL( i, 0ll );
880 signed long long i = -1;
882 CHECK_EQUAL( sscanf( string + 3, "%lld%n", &i, &n ), 1 );
883 CHECK_EQUAL( i, 0ll );
887 // reading -9223372036854775808, d
888 signed long long i = -1;
890 CHECK_EQUAL( sscanf( string + 78, "%lld%n", &i, &n ), 1 );
891 CHECK_FEQUAL( i, LLONG_MIN, signed long long, "%lld" ); // should be literal -9223372036854775808ll but GCC balks.
892 CHECK_EQUAL( i < 0ll, 1 );
893 CHECK_EQUAL( n, 20 );
896 // reading 9223372036854775807, d
897 signed long long i = -1;
899 CHECK_EQUAL( sscanf( string + 100, "%lld%n", &i, &n ), 1 );
900 CHECK_FEQUAL( i, 9223372036854775807ll, signed long long, "%lld" );
901 CHECK_EQUAL( n, 19 );
904 // reading +9223372036854775807, d
905 signed long long i = -1;
907 CHECK_EQUAL( sscanf( string + 99, "%lld%n", &i, &n ), 1 );
908 CHECK_FEQUAL( i, 9223372036854775807ll, signed long long, "%lld" );
909 CHECK_EQUAL( n, 20 );
913 unsigned long long i = -1;
915 CHECK_EQUAL( sscanf( string + 1, "%llu%n", &i, &n ), 1 );
916 CHECK_EQUAL( i, 0ull );
921 unsigned long long i = -1;
923 CHECK_EQUAL( sscanf( string + 0, "%llu%n", &i, &n ), 1 );
924 CHECK_EQUAL( i, 0ull );
929 unsigned long long i = -1;
931 CHECK_EQUAL( sscanf( string + 3, "%llu%n", &i, &n ), 1 );
932 CHECK_EQUAL( i, 0ull );
936 // reading 9223372036854775807, u
937 unsigned long long i = -1;
939 CHECK_EQUAL( sscanf( string + 100, "%llu%n", &i, &n ), 1 );
940 CHECK_FEQUAL( i, 9223372036854775807ull, unsigned long long, "%llu" );
941 CHECK_EQUAL( n, 19 );
944 // reading +9223372036854775807, u
945 unsigned long long i = -1;
947 CHECK_EQUAL( sscanf( string + 99, "%llu%n", &i, &n ), 1 );
948 CHECK_FEQUAL( i, 9223372036854775807ull, unsigned long long, "%llu" );
949 CHECK_EQUAL( n, 20 );
952 // reading 18446744073709551615, u
953 unsigned long long i = 0;
955 CHECK_EQUAL( sscanf( string + 121, "%llu%n", &i, &n ), 1 );
956 CHECK_FEQUAL( i, 18446744073709551615ull, unsigned long long, "%llu" );
957 CHECK_EQUAL( n, 20 );
960 // reading +18446744073709551615, u
961 unsigned long long i = 0;
963 CHECK_EQUAL( sscanf( string + 120, "%llu%n", &i, &n ), 1 );
964 CHECK_FEQUAL( i, 18446744073709551615ull, unsigned long long, "%llu" );
965 CHECK_EQUAL( n, 21 );
969 signed long long i = -1;
971 CHECK_EQUAL( sscanf( string + 1, "%lli%n", &i, &n ), 1 );
972 CHECK_EQUAL( i, 0ll );
977 signed long long i = -1;
979 CHECK_EQUAL( sscanf( string + 0, "%lli%n", &i, &n ), 1 );
980 CHECK_EQUAL( i, 0ll );
985 signed long long i = -1;
987 CHECK_EQUAL( sscanf( string + 3, "%lli%n", &i, &n ), 1 );
988 CHECK_EQUAL( i, 0ll );
992 // reading -9223372036854775808, i
993 signed long long i = -1;
995 CHECK_EQUAL( sscanf( string + 78, "%lli%n", &i, &n ), 1 );
996 CHECK_FEQUAL( i, LLONG_MIN, signed long long, "%lli" ); // should be literal -9223372036854775808ll but GCC balks.
997 CHECK_EQUAL( i < 0ll, 1 );
998 CHECK_EQUAL( n, 20 );
1001 // reading 9223372036854775807, i
1002 signed long long i = -1;
1004 CHECK_EQUAL( sscanf( string + 100, "%lli%n", &i, &n ), 1 );
1005 CHECK_FEQUAL( i, 9223372036854775807ll, signed long long, "%lli" );
1006 CHECK_EQUAL( n, 19 );
1009 // reading +9223372036854775807, i
1010 signed long long i = -1;
1012 CHECK_EQUAL( sscanf( string + 99, "%lli%n", &i, &n ), 1 );
1013 CHECK_FEQUAL( i, 9223372036854775807ll, signed long long, "%lli" );
1014 CHECK_EQUAL( n, 20 );
1018 // hexadecimal integer matches
1021 char const * string = "-0x0 -0x000 -0x7f 0x80 0xff -0x7fff 0x8000\n"
1022 "0xffff -0x7fffffff 0x80000000 0xffffffff\n"
1023 "-0x7fffffffffffffff 0x8000000000000000\n"
1024 "0xffffffffffffffff\n";
1025 CHECK_EQUAL( string[141], '\n' );
1028 unsigned char i = -1;
1030 CHECK_EQUAL( sscanf( string + 3, "%hhx%n", &i, &n ), 1 );
1031 CHECK_EQUAL( i, 0 );
1032 CHECK_EQUAL( n, 1 );
1036 unsigned char i = -1;
1038 CHECK_EQUAL( sscanf( string + 0, "%hhx%n", &i, &n ), 1 );
1039 CHECK_EQUAL( i, 0 );
1040 CHECK_EQUAL( n, 4 );
1044 unsigned char i = -1;
1046 CHECK_EQUAL( sscanf( string + 5, "%hhx%n", &i, &n ), 1 );
1047 CHECK_EQUAL( i, 0 );
1048 CHECK_EQUAL( n, 6 );
1054 CHECK_EQUAL( sscanf( string + 0, "%hhi%n", &i, &n ), 1 );
1055 CHECK_EQUAL( i, 0 );
1056 CHECK_EQUAL( n, 4 );
1060 unsigned char i = -1;
1062 CHECK_EQUAL( sscanf( string + 15, "%hhx%n", &i, &n ), 1 );
1063 CHECK_EQUAL( i, 127 );
1064 CHECK_EQUAL( n, 2 );
1068 unsigned char i = -1;
1070 CHECK_EQUAL( sscanf( string + 12, "%hhx%n", &i, &n ), 1 );
1071 CHECK_FEQUAL( i, -127, unsigned char, "%hhu" );
1072 CHECK_EQUAL( n, 5 );
1078 CHECK_EQUAL( sscanf( string + 18, "%hhi%n", &i, &n ), 1 );
1079 CHECK_FEQUAL( i, -128, signed char, "%hhd" );
1080 CHECK_EQUAL( n, 4 );
1084 unsigned char i = -1;
1086 CHECK_EQUAL( sscanf( string + 25, "%hhx%n", &i, &n ), 1 );
1087 CHECK_EQUAL( i, 0xff );
1088 CHECK_EQUAL( n, 2 );
1092 unsigned char i = -1;
1094 CHECK_EQUAL( sscanf( string + 23, "%hhx%n", &i, &n ), 1 );
1095 CHECK_EQUAL( i, 255 );
1096 CHECK_EQUAL( n, 4 );
1102 CHECK_EQUAL( sscanf( string + 23, "%hhi%n", &i, &n ), 1 );
1103 CHECK_EQUAL( i, -1 );
1104 CHECK_EQUAL( n, 4 );
1108 unsigned short i = -1;
1110 CHECK_EQUAL( sscanf( string + 3, "%hx%n", &i, &n ), 1 );
1111 CHECK_EQUAL( i, 0 );
1112 CHECK_EQUAL( n, 1 );
1116 unsigned short i = -1;
1118 CHECK_EQUAL( sscanf( string + 0, "%hx%n", &i, &n ), 1 );
1119 CHECK_EQUAL( i, 0 );
1120 CHECK_EQUAL( n, 4 );
1124 unsigned short i = -1;
1126 CHECK_EQUAL( sscanf( string + 5, "%hx%n", &i, &n ), 1 );
1127 CHECK_EQUAL( i, 0 );
1128 CHECK_EQUAL( n, 6 );
1132 signed short i = -1;
1134 CHECK_EQUAL( sscanf( string + 0, "%hi%n", &i, &n ), 1 );
1135 CHECK_EQUAL( i, 0 );
1136 CHECK_EQUAL( n, 4 );
1140 unsigned short i = -1;
1142 CHECK_EQUAL( sscanf( string + 31, "%hx%n", &i, &n ), 1 );
1143 CHECK_EQUAL( i, 32767 );
1144 CHECK_EQUAL( n, 4 );
1147 // reading -0x7fff, x
1148 unsigned short i = -1;
1150 CHECK_EQUAL( sscanf( string + 28, "%hx%n", &i, &n ), 1 );
1151 CHECK_FEQUAL( i, -32767, unsigned short, "%hu" );
1152 CHECK_EQUAL( n, 7 );
1155 // reading 0x8000, i
1156 signed short i = -1;
1158 CHECK_EQUAL( sscanf( string + 36, "%hi%n", &i, &n ), 1 );
1159 CHECK_FEQUAL( i, -32768, signed short, "%hd" );
1160 CHECK_EQUAL( n, 6 );
1164 unsigned short i = -1;
1166 CHECK_EQUAL( sscanf( string + 45, "%hx%n", &i, &n ), 1 );
1167 CHECK_EQUAL( i, 65535 );
1168 CHECK_EQUAL( n, 4 );
1171 // reading 0xffff, x
1172 unsigned short i = -1;
1174 CHECK_EQUAL( sscanf( string + 43, "%hx%n", &i, &n ), 1 );
1175 CHECK_EQUAL( i, 65535 );
1176 CHECK_EQUAL( n, 6 );
1179 // reading 0xffff, i
1182 CHECK_EQUAL( sscanf( string + 43, "%hi%n", &i, &n ), 1 );
1183 CHECK_FEQUAL( i, -1, signed short, "%hd" );
1184 CHECK_EQUAL( n, 6 );
1188 unsigned int i = -1;
1190 CHECK_EQUAL( sscanf( string + 3, "%x%n", &i, &n ), 1 );
1191 CHECK_EQUAL( i, 0 );
1192 CHECK_EQUAL( n, 1 );
1196 unsigned int i = -1;
1198 CHECK_EQUAL( sscanf( string + 0, "%x%n", &i, &n ), 1 );
1199 CHECK_EQUAL( i, 0 );
1200 CHECK_EQUAL( n, 4 );
1204 unsigned int i = -1;
1206 CHECK_EQUAL( sscanf( string + 5, "%x%n", &i, &n ), 1 );
1207 CHECK_EQUAL( i, 0 );
1208 CHECK_EQUAL( n, 6 );
1214 CHECK_EQUAL( sscanf( string + 0, "%i%n", &i, &n ), 1 );
1215 CHECK_EQUAL( i, 0 );
1216 CHECK_EQUAL( n, 4 );
1219 // reading 7fffffff, x
1220 unsigned int i = -1;
1222 CHECK_EQUAL( sscanf( string + 53, "%x%n", &i, &n ), 1 );
1223 CHECK_EQUAL( i, 2147483647 );
1224 CHECK_EQUAL( n, 8 );
1227 // reading -0x7fffffff, x
1228 unsigned int i = -1;
1230 CHECK_EQUAL( sscanf( string + 50, "%x%n", &i, &n ), 1 );
1231 CHECK_FEQUAL( i, -2147483647, unsigned int, "%u" );
1232 CHECK_EQUAL( n, 11 );
1235 // reading 0x80000000, i
1238 //CHECK_EQUAL( sscanf( string + 62, "%i%n", &i, &n ), 1 );
1239 CHECK_EQUAL( sscanf( "-0x80000000", "%i%n", &i, &n ), 1 );
1240 CHECK_FEQUAL( i, -2147483648, signed int, "%d" );
1241 CHECK_EQUAL( n, 11 );
1244 // reading ffffffff, x
1245 unsigned int i = -1;
1247 CHECK_EQUAL( sscanf( string + 75, "%x%n", &i, &n ), 1 );
1248 CHECK_FEQUAL( i, 4294967295, unsigned int, "%d" );
1249 CHECK_EQUAL( n, 8 );
1252 // reading 0xffffffff, x
1253 unsigned int i = -1;
1255 CHECK_EQUAL( sscanf( string + 73, "%x%n", &i, &n ), 1 );
1256 CHECK_FEQUAL( i, 4294967295, unsigned int, "%d" );
1257 CHECK_EQUAL( n, 10 );
1261 // octal integer matches
1264 char const * string = "+0000 -0000 +0177 +0377 -0377 +077777 +0177777\n"
1265 "-0177777 +017777777777 +037777777777\n"
1266 "-037777777777 +0777777777777777777777\n"
1267 "+01777777777777777777777\n"
1268 "-01777777777777777777777\n";
1269 CHECK_EQUAL( string[171], '\n' );
1272 unsigned char i = -1;
1274 CHECK_EQUAL( sscanf( string + 4, "%hho%n", &i, &n ), 1 );
1275 CHECK_EQUAL( i, 0u );
1276 CHECK_EQUAL( n, 1 );
1280 unsigned char i = -1;
1282 CHECK_EQUAL( sscanf( string + 0, "%hho%n", &i, &n ), 1 );
1283 CHECK_EQUAL( i, 0u );
1284 CHECK_EQUAL( n, 5 );
1288 unsigned char i = -1;
1290 CHECK_EQUAL( sscanf( string + 6, "%hho%n", &i, &n ), 1 );
1291 CHECK_EQUAL( i, 0u );
1292 CHECK_EQUAL( n, 5 );
1296 unsigned char i = -1;
1298 CHECK_EQUAL( sscanf( string + 13, "%hho%n", &i, &n ), 1 );
1299 CHECK_EQUAL( i, 127u );
1300 CHECK_EQUAL( n, 4 );
1304 unsigned char i = -1;
1306 CHECK_EQUAL( sscanf( string + 12, "%hho%n", &i, &n ), 1 );
1307 CHECK_EQUAL( i, 127u );
1308 CHECK_EQUAL( n, 5 );
1312 unsigned char i = -1;
1314 CHECK_EQUAL( sscanf( string + 19, "%hho%n", &i, &n ), 1 );
1315 CHECK_FEQUAL( i, 255u, unsigned char, "%hhu" );
1316 CHECK_EQUAL( n, 4 );
1320 unsigned char i = -1;
1322 CHECK_EQUAL( sscanf( string + 18, "%hho%n", &i, &n ), 1 );
1323 CHECK_FEQUAL( i, 255u, unsigned char, "%hhu" );
1324 CHECK_EQUAL( n, 5 );
1328 unsigned char i = -1;
1330 CHECK_EQUAL( sscanf( string + 24, "%hho%n", &i, &n ), 1 );
1331 CHECK_FEQUAL( i, 1u, unsigned char, "%hhu" );
1332 CHECK_EQUAL( n, 5 );
1335 // reading 077777, o
1336 unsigned short i = -1;
1338 CHECK_EQUAL( sscanf( string + 31, "%ho%n", &i, &n ), 1 );
1339 CHECK_EQUAL( i, 32767u );
1340 CHECK_EQUAL( n, 6 );
1343 // reading +077777, o
1344 unsigned short i = -1;
1346 CHECK_EQUAL( sscanf( string + 30, "%ho%n", &i, &n ), 1 );
1347 CHECK_EQUAL( i, 32767u );
1348 CHECK_EQUAL( n, 7 );
1351 // reading 0177777, o
1352 unsigned short i = -1;
1354 CHECK_EQUAL( sscanf( string + 39, "%ho%n", &i, &n ), 1 );
1355 CHECK_FEQUAL( i, 65535u, unsigned short, "%hu" );
1356 CHECK_EQUAL( n, 7 );
1359 // reading +0177777, o
1360 unsigned short i = -1;
1362 CHECK_EQUAL( sscanf( string + 38, "%ho%n", &i, &n ), 1 );
1363 CHECK_FEQUAL( i, 65535u, unsigned short, "%hu" );
1364 CHECK_EQUAL( n, 8 );
1367 // reading -0177777, o
1368 unsigned short i = -1;
1370 CHECK_EQUAL( sscanf( string + 47, "%ho%n", &i, &n ), 1 );
1371 CHECK_FEQUAL( i, 1u, unsigned short, "%hu" );
1372 CHECK_EQUAL( n, 8 );
1375 // reading 017777777777, o
1376 unsigned int i = -1;
1378 CHECK_EQUAL( sscanf( string + 57, "%o%n", &i, &n ), 1 );
1379 CHECK_EQUAL( i, 2147483647u );
1380 CHECK_EQUAL( n, 12 );
1383 // reading +017777777777, o
1384 unsigned int i = -1;
1386 CHECK_EQUAL( sscanf( string + 56, "%o%n", &i, &n ), 1 );
1387 CHECK_EQUAL( i, 2147483647u );
1388 CHECK_EQUAL( n, 13 );
1391 // reading 037777777777, o
1392 unsigned int i = -1;
1394 CHECK_EQUAL( sscanf( string + 71, "%o%n", &i, &n ), 1 );
1395 CHECK_FEQUAL( i, 4294967295u, unsigned int, "%u" );
1396 CHECK_EQUAL( n, 12 );
1399 // reading +037777777777, o
1400 unsigned int i = -1;
1402 CHECK_EQUAL( sscanf( string + 70, "%o%n", &i, &n ), 1 );
1403 CHECK_FEQUAL( i, 4294967295u, unsigned int, "%u" );
1404 CHECK_EQUAL( n, 13 );
1407 // reading -037777777777, o
1408 unsigned int i = -1;
1410 CHECK_EQUAL( sscanf( string + 84, "%o%n", &i, &n ), 1 );
1411 CHECK_FEQUAL( i, 1u, unsigned int, "%u" );
1412 CHECK_EQUAL( n, 13 );
1415 // reading 017777777777, o
1416 unsigned long i = -1;
1418 CHECK_EQUAL( sscanf( string + 57, "%lo%n", &i, &n ), 1 );
1419 CHECK_EQUAL( i, 2147483647lu );
1420 CHECK_EQUAL( n, 12 );
1423 // reading +017777777777, o
1424 unsigned long i = -1;
1426 CHECK_EQUAL( sscanf( string + 56, "%lo%n", &i, &n ), 1 );
1427 CHECK_EQUAL( i, 2147483647lu );
1428 CHECK_EQUAL( n, 13 );
1431 // reading 037777777777, o
1432 unsigned long i = -1;
1434 CHECK_EQUAL( sscanf( string + 71, "%lo%n", &i, &n ), 1 );
1435 CHECK_FEQUAL( i, 4294967295lu, unsigned long, "%lu" );
1436 CHECK_EQUAL( n, 12 );
1439 // reading +037777777777, o
1440 unsigned long i = -1;
1442 CHECK_EQUAL( sscanf( string + 70, "%lo%n", &i, &n ), 1 );
1443 CHECK_FEQUAL( i, 4294967295lu, unsigned long, "%lu" );
1444 CHECK_EQUAL( n, 13 );
1447 // reading -037777777777, o
1448 unsigned long i = -1;
1450 CHECK_EQUAL( sscanf( string + 84, "%lo%n", &i, &n ), 1 );
1451 CHECK_FEQUAL( i, 1lu, unsigned long, "%lu" );
1452 CHECK_EQUAL( n, 13 );
1455 // reading 0777777777777777777777, o
1456 unsigned long long i = -1;
1458 CHECK_EQUAL( sscanf( string + 99, "%llo%n", &i, &n ), 1 );
1459 CHECK_FEQUAL( i, 9223372036854775807llu, unsigned long long, "%llu" );
1460 CHECK_EQUAL( n, 22 );
1463 // reading +0777777777777777777777, o
1464 unsigned long long i = -1;
1466 CHECK_EQUAL( sscanf( string + 98, "%llo%n", &i, &n ), 1 );
1467 CHECK_FEQUAL( i, 9223372036854775807llu, unsigned long long, "%llu" );
1468 CHECK_EQUAL( n, 23 );
1471 // reading 01777777777777777777777, o
1472 unsigned long long i = -1;
1474 CHECK_EQUAL( sscanf( string + 123, "%llo%n", &i, &n ), 1 );
1475 CHECK_FEQUAL( i, 18446744073709551615llu, unsigned long long, "%llu" );
1476 CHECK_EQUAL( n, 23 );
1479 // reading +01777777777777777777777, o
1480 unsigned long long i = -1;
1482 CHECK_EQUAL( sscanf( string + 122, "%llo%n", &i, &n ), 1 );
1483 CHECK_FEQUAL( i, 18446744073709551615llu, unsigned long long, "%llu" );
1484 CHECK_EQUAL( n, 24 );
1487 // reading -01777777777777777777777, o
1488 unsigned long long i = -1;
1490 CHECK_EQUAL( sscanf( string + 147, "%llo%n", &i, &n ), 1 );
1491 CHECK_FEQUAL( i, 1llu, unsigned long long, "%llu" );
1492 CHECK_EQUAL( n, 24 );
1499 char const * string = "abcdefgh-ijklmnop[qrs%uvw]xyz";
1500 CHECK_EQUAL( string[28], 'z' );
1501 size_t const BUFSIZE = 29;
1502 char buffer[ BUFSIZE ];
1505 memset( buffer, '\0', BUFSIZE );
1507 CHECK_EQUAL( sscanf( string + 0, "%[abc]%n", buffer, &n ), 1 );
1508 CHECK_EQUAL( n, 3 );
1509 CHECK_FALSE( memcmp( buffer, "abc", n + 1 ) );
1513 memset( buffer, '\0', BUFSIZE );
1515 CHECK_EQUAL( sscanf( string + 0, "%[a-c]%n", buffer, &n ), 1 );
1516 CHECK_EQUAL( n, 3 );
1517 CHECK_FALSE( memcmp( buffer, "abc", n + 1 ) );
1521 memset( buffer, '\0', BUFSIZE );
1523 CHECK_EQUAL( sscanf( string + 0, "%[a-h]%n", buffer, &n ), 1 );
1524 CHECK_EQUAL( n, 8 );
1525 CHECK_FALSE( memcmp( buffer, "abcdefgh", n + 1 ) );
1528 // reading o-r, including [, seperate char
1529 memset( buffer, '\0', BUFSIZE );
1531 CHECK_EQUAL( sscanf( string + 15, "%[[o-qr]%n", buffer, &n ), 1 );
1532 CHECK_EQUAL( n, 5 );
1533 CHECK_FALSE( memcmp( buffer, "op[qr", n + 1 ) );
1536 // reading v-y, including ], two groups
1537 memset( buffer, '\0', BUFSIZE );
1539 CHECK_EQUAL( sscanf( string + 23, "%[]v-wx-y]%n", buffer, &n ), 1 );
1540 CHECK_EQUAL( n, 5 );
1541 CHECK_FALSE( memcmp( buffer, "vw]xy", n + 1 ) );
1544 // missing on first character
1545 memset( buffer, '\0', BUFSIZE );
1547 int rc_ = sscanf( string + 0, "%[b]%n", buffer, &n );
1548 CHECK_EQUAL( rc_, 0 );
1549 //CHECK_EQUAL( sscanf( string + 0, "%[b]%n", buffer, &n ), 0 );
1550 CHECK_FALSE( memcmp( buffer, "", 1 ) );
1553 // eof while reading, two groups
1554 memset( buffer, '\0', BUFSIZE );
1556 CHECK_EQUAL( sscanf( string + 27, "%[a-zA-Z]%n", buffer, &n ), 1 );
1557 CHECK_EQUAL( n, 2 );
1558 CHECK_FALSE( memcmp( buffer, "yz", n + 1 ) );
1561 // eof before reading
1562 memset( buffer, '\0', BUFSIZE );
1564 CHECK_EQUAL( sscanf( string + 29, "%[a-z]%n", buffer, &n ), -1 );
1565 CHECK_FALSE( memcmp( buffer, "", 1 ) );
1568 // negation - [^...]
1569 memset( buffer, '\0', BUFSIZE );
1571 CHECK_EQUAL( sscanf( string + 0, "%[^d-f]%n", buffer, &n ), 1 );
1572 CHECK_EQUAL( n, 3 );
1573 CHECK_FALSE( memcmp( buffer, "abc", 4 ) );
1579 char const * string = "-0xz\n";
1580 CHECK_EQUAL( string[4], '\n' );
1583 unsigned char i = 1;
1585 /* Most existing libraries disagree with this test driver, so a little
1586 explanation of why PDCLib chose the implementation it did might be
1587 necessary. All references are from ISO/IEC 9899:1999 "Programming
1588 languages - C". Wording critical to the explanation is in UPPERCASE.
1589 6.4.4.1 Integer constants - states that '0' is a valid (hexa)decimal
1590 constant, whereas '0x' IS NOT.
1591 7.19.6.2 The fscanf function - states...
1592 ...in paragraph 9 that "an INPUT ITEM is defined as the longest
1593 sequence of input characters [...] which is, OR IS A PREFIX OF,
1594 a matching input sequence".
1595 ...in paragraph 10 that "if the INPUT ITEM is not a matching
1596 sequence, the execution of THE DIRECTIVE FAILS; this condition
1597 is a matching failure".
1598 ...in footnote 242) that "fscanf pushes back AT MOST ONE input
1599 character onto the input stream."
1600 ...in paragraph 12 that either of the conversion specifiers d, i,
1601 o, u, or x "matches an [...] integer whose format is the same as
1602 expected for THE SUBJECT SEQUENCE of the [strtol|strtoul]
1604 7.20.1.4 The strtol, strtoll, strtoul, and strtoull functions - states
1605 in paragraph 3 that "the EXPECTED FORM OF THE SUBJECT SEQUENCE is
1606 that of an integer constant AS DESCRIBED IN 6.4.4.1".
1607 These parts of the standard result in the following reasoning:
1608 - The longest sequence of input characters which is a prefix of a
1609 matching input sequence is "-0x" (negative sign, hexadecimal-prefix).
1610 The 'z' is the first character remaining unread as "-0xz" is not a
1611 (prefix of a) matching input sequence. This is according to 7.19.6.2
1613 - "0x", without a valid hexadecimal digit following it, is not a valid
1614 integer constant according to 6.4.4.1.
1615 - "0x" is thus also not of the expected form for a strto[u]l subject
1616 sequence according to 7.20.1.4 paragraph 3. (strto[u]l() would parse
1617 it as zero, but leave the "x" in the final string, i.e. outside the
1619 - "0x" is therefore also not a matching sequence to the i or x
1620 conversion specifier according to 7.19.6.2 paragraph 12.
1621 - The conversion should therefore result in a matching failure
1622 according to 7.19.6.2 paragraph 10.
1624 CHECK_EQUAL( sscanf( string, "%hhx%n", &i, &n ), 0 );
1625 CHECK_EQUAL( i, 1 );
1626 CHECK_EQUAL( n, -1 );
1630 unsigned short i = 1;
1632 CHECK_EQUAL( sscanf( string, "%hx%n", &i, &n ), 0 );
1633 CHECK_EQUAL( i, 1 );
1634 CHECK_EQUAL( n, -1 );
1640 CHECK_EQUAL( sscanf( string, "%x%n", &i, &n ), 0 );
1641 CHECK_EQUAL( i, 1 );
1642 CHECK_EQUAL( n, -1 );