]> pd.if.org Git - pdclib/blob - functions/stdio/sscanf.c
No more errors from _PDCLIB_scan tests. Yay...
[pdclib] / functions / stdio / sscanf.c
1 /* $Id$ */
2
3 /* sscanf( const char *, const char *, ... )
4
5    This file is part of the Public Domain C Library (PDCLib).
6    Permission is granted to use, modify, and / or redistribute at will.
7 */
8
9 #include <stdio.h>
10 #include <stdarg.h>
11
12 #ifndef REGTEST
13
14 int sscanf( const char * _PDCLIB_restrict s, const char * _PDCLIB_restrict format, ... )
15 {
16     int rc;
17     va_list ap;
18     va_start( ap, format );
19     rc = vsscanf( s, format, ap );
20     va_end( ap );
21     return rc;
22 }
23
24 #endif
25
26 #ifdef TEST
27 #include <_PDCLIB_test.h>
28
29 #include <string.h>
30 #include <limits.h>
31
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 )
36
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 );
45 // string matches
46 void suite_five( void );
47 // 0xz special case
48 void suite_six( void );
49
50 int main()
51 {
52     suite_one();
53     suite_two();
54     suite_three();
55     suite_four();
56     suite_five();
57 #ifndef REGTEST
58     // This test driver fails for many common libraries, so it's disabled for
59     // regression testing. See the function for explanation.
60     suite_six();
61 #endif
62 }
63
64 // literal matches, character matches, and basic integer matches
65 void suite_one()
66 {
67     char const * string = "12345678901\0003-5+7\0009\3772 4 6 8 0\3771 \011 5%%  0";
68     CHECK_EQUAL( string[39], '0' );
69
70     // -----------------------------------------------------------------------
71     // Literal matching
72     // -----------------------------------------------------------------------
73     {
74     // matching six characters literally
75     // checking via %n
76     // should report six characters read
77     int n;
78     CHECK_EQUAL( sscanf( string + 0, "123456%n", &n ), 0 );
79     CHECK_EQUAL( n, 6 );
80     }
81     {
82     // matching a character, three whitespace chars, and another character
83     // checking via %n
84     // should report five characters read
85     int n;
86     CHECK_EQUAL( sscanf( string + 30, "1 5%n", &n ), 0 );
87     CHECK_EQUAL( n, 5 );
88     }
89     {
90     // matching three characters, not matching whitespaces, and matching another three characters
91     // checking via %n
92     // should report six characters matched
93     int n;
94     CHECK_EQUAL( sscanf( string + 0, "123  456%n", &n ), 0 );
95     CHECK_EQUAL( n, 6 );
96     }
97     {
98     // matching a character, two '%' characters, and two whitespaces
99     // checking via %n
100     // should report five characters matched
101     int n;
102     CHECK_EQUAL( sscanf( string + 34, "5%%%% %n", &n ), 0 );
103     CHECK_EQUAL( n, 5 );
104     }
105     {
106     // seeking to last character in file, trying to match that char and a whitespace
107     // checking via %n
108     // should report one character matched and EOF
109     int n;
110     CHECK_EQUAL( sscanf( string + 39, "0 %n", &n ), 0 );
111     CHECK_EQUAL( n, 1 );
112     }
113     {
114     // seeking to end of file, trying to match a -1
115     // checking via %n
116     // should report error, not executing %n
117     int n = -1;
118     CHECK_EQUAL( sscanf( string + 0, "\377%n", &n ), 0 );
119     CHECK_EQUAL( n, -1 );
120     }
121
122     // -----------------------------------------------------------------------
123     // Character matching ('%c')
124     // -----------------------------------------------------------------------
125     {
126     // reading a char array of specified width, including zero bytes
127     // should report the characters read up to first zero
128     char buffer[ 8 ];
129     memset( buffer, '\177', 8 );
130     CHECK_EQUAL( sscanf( string + 10, "%7c", buffer ), 1 );
131     CHECK_FALSE( memcmp( buffer, "1\177\177", 3 ) );
132     }
133     {
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
136     char buffer[ 2 ];
137     memset( buffer, '\177', 2 );
138     CHECK_EQUAL( sscanf( string + 19, "%c", buffer ), 1 );
139     CHECK_FALSE( memcmp( buffer, "\377\177", 2 ) );
140     }
141     {
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
144     char buffer[ 2 ];
145     memset( buffer, '\177', 2 );
146     CHECK_EQUAL( sscanf( string + 32, "%1c", buffer ), 1 );
147     CHECK_FALSE( memcmp( buffer, "\011\177", 2 ) );
148     }
149     {
150     // reading a char array of specified width 2 when positioned at last char of file
151     // should read the character, and report EOF
152     char buffer[ 2 ];
153     memset( buffer, '\177', 2 );
154     CHECK_EQUAL( sscanf( string + 39, "%2c", buffer ), 1 );
155     CHECK_FALSE( memcmp( buffer, "0\177", 2 ) );
156     }
157     {
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
160     char buffer[ 2 ];
161     memset( buffer, '\177', 2 );
162     CHECK_EQUAL( sscanf( string + 39, "%1c", buffer ), 1 );
163     CHECK_FALSE( memcmp( buffer, "0\177", 2 ) );
164     }
165     {
166     // reading a char array of specified width 1 when positioned at EOF
167     // should report input error before any conversion (-1)
168     char buffer[ 2 ];
169     memset( buffer, '\177', 2 );
170     CHECK_EQUAL( sscanf( string + 40, "%1c", buffer ), -1 );
171     CHECK_FALSE( memcmp( buffer, "\177\177", 2 ) );
172     }
173
174     // -----------------------------------------------------------------------
175     // Integer matching ('%d')
176     // -----------------------------------------------------------------------
177     {
178     // reading a whitespace-terminated integer
179     int i;
180     int n;
181     CHECK_EQUAL( sscanf( string + 20, "%d%n", &i, &n ), 1 );
182     CHECK_EQUAL( i, 2 );
183     CHECK_EQUAL( n, 1 );
184     }
185     {
186     // reading a -1 terminated integer
187     int i;
188     int n;
189     CHECK_EQUAL( sscanf( string + 18, "%d%n", &i, &n ), 1 );
190     CHECK_EQUAL( i, 9 );
191     CHECK_EQUAL( n, 1 );
192     }
193     {
194     // reading a EOF terminated integer
195     int i = -1;
196     int n;
197     CHECK_EQUAL( sscanf( string + 39, "%d%n", &i, &n ), 1 );
198     CHECK_EQUAL( i, 0 );
199     CHECK_EQUAL( n, 1 );
200     }
201     {
202     // trying to read an integer when positioned at whitespace
203     // should skip whitespaces
204     int i = -1;
205     int n;
206     CHECK_EQUAL( sscanf( string + 32, "%d%n", &i, &n ), 1 );
207     CHECK_EQUAL( i, 5 );
208     CHECK_EQUAL( n, 3 );
209     }
210     {
211     // trying to read an integer when positioned at -1 value
212     // should report matching failure
213     int i = 0;
214     int n = -1;
215     CHECK_EQUAL( sscanf( string + 19, "%d%n", &i, &n ), 0 );
216     CHECK_EQUAL( i, 0 );
217     CHECK_EQUAL( n, -1 );
218     }
219     {
220     // trying to read an integer when positioned at EOF
221     // should report reading failure
222     int i = 0;
223     int n = -1;
224     CHECK_EQUAL( sscanf( string + 40, "%d%n", &i, &n ), -1 );
225     CHECK_EQUAL( i, 0 );
226     CHECK_EQUAL( n, -1 );
227     }
228     {
229     // reading a '-'-prefixed integer
230     int i;
231     int n;
232     CHECK_EQUAL( sscanf( string + 13, "%d%n", &i, &n ), 1 );
233     CHECK_EQUAL( i, -5 );
234     CHECK_EQUAL( n, 2 );
235     }
236     {
237     // reading a '+'-prefixed integer
238     int i;
239     int n;
240     CHECK_EQUAL( sscanf( string + 15, "%d%n", &i, &n ), 1 );
241     CHECK_EQUAL( i, 7 );
242     CHECK_EQUAL( n, 2 );
243     }
244 }
245
246 // decimal integer matches
247 void suite_two()
248 {
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' );
254     {
255     // reading 0, d
256     signed char i = -1;
257     int n;
258     CHECK_EQUAL( sscanf( string + 1, "%hhd%n", &i, &n ), 1 );
259     CHECK_EQUAL( i, 0 );
260     CHECK_EQUAL( n, 1 );
261     }
262     {
263     // reading -0, d
264     signed char i = -1;
265     int n;
266     CHECK_EQUAL( sscanf( string + 0, "%hhd%n", &i, &n ), 1 );
267     CHECK_EQUAL( i, 0 );
268     CHECK_EQUAL( n, 2 );
269     }
270     {
271     // reading +0, d
272     signed char i = -1;
273     int n;
274     CHECK_EQUAL( sscanf( string + 3, "%hhd%n", &i, &n ), 1 );
275     CHECK_EQUAL( i, 0 );
276     CHECK_EQUAL( n, 2 );
277     }
278     {
279     // reading -128, d
280     signed char i = -1;
281     int n;
282     CHECK_EQUAL( sscanf( string + 6, "%hhd%n", &i, &n ), 1 );
283     CHECK_EQUAL( i, -128 );
284     CHECK_EQUAL( n, 4 );
285     }
286     {
287     // reading 127, d
288     signed char i = -1;
289     int n;
290     CHECK_EQUAL( sscanf( string + 12, "%hhd%n", &i, &n ), 1 );
291     CHECK_EQUAL( i, 127 );
292     CHECK_EQUAL( n, 3 );
293     }
294     {
295     // reading +127, d
296     signed char i = -1;
297     int n;
298     CHECK_EQUAL( sscanf( string + 11, "%hhd%n", &i, &n ), 1 );
299     CHECK_EQUAL( i, 127 );
300     CHECK_EQUAL( n, 4 );
301     }
302     {
303     // reading 0, u
304     unsigned char i = -1;
305     int n;
306     CHECK_EQUAL( sscanf( string + 1, "%hhu%n", &i, &n ), 1 );
307     CHECK_EQUAL( i, 0 );
308     CHECK_EQUAL( n, 1 );
309     }
310     {
311     // reading -0, u
312     unsigned char i = -1;
313     int n;
314     CHECK_EQUAL( sscanf( string + 0, "%hhu%n", &i, &n ), 1 );
315     CHECK_EQUAL( i, 0 );
316     CHECK_EQUAL( n, 2 );
317     }
318     {
319     // reading +0, u
320     unsigned char i = -1;
321     int n;
322     CHECK_EQUAL( sscanf( string + 3, "%hhu%n", &i, &n ), 1 );
323     CHECK_EQUAL( i, 0 );
324     CHECK_EQUAL( n, 2 );
325     }
326     {
327     // reading 127, u
328     unsigned char i = -1;
329     int n;
330     CHECK_EQUAL( sscanf( string + 12, "%hhu%n", &i, &n ), 1 );
331     CHECK_EQUAL( i, 127 );
332     CHECK_EQUAL( n, 3 );
333     }
334     {
335     // reading +127, u
336     unsigned char i = -1;
337     int n;
338     CHECK_EQUAL( sscanf( string + 11, "%hhu%n", &i, &n ), 1 );
339     CHECK_EQUAL( i, 127 );
340     CHECK_EQUAL( n, 4 );
341     }
342     {
343     // reading 255, u
344     unsigned char i = 0;
345     int n;
346     CHECK_EQUAL( sscanf( string + 17, "%hhu%n", &i, &n ), 1 );
347     CHECK_EQUAL( i, 255 );
348     CHECK_EQUAL( n, 3 );
349     }
350     {
351     // reading +255, u
352     unsigned char i = 0;
353     int n;
354     CHECK_EQUAL( sscanf( string + 16, "%hhu%n", &i, &n ), 1 );
355     CHECK_EQUAL( i, 255 );
356     CHECK_EQUAL( n, 4 );
357     }
358     {
359     // reading 0, i
360     signed char i = -1;
361     int n;
362     CHECK_EQUAL( sscanf( string + 1, "%hhi%n", &i, &n ), 1 );
363     CHECK_EQUAL( i, 0 );
364     CHECK_EQUAL( n, 1 );
365     }
366     {
367     // reading -0, i
368     signed char i = -1;
369     int n;
370     CHECK_EQUAL( sscanf( string + 0, "%hhi%n", &i, &n ), 1 );
371     CHECK_EQUAL( i, 0 );
372     CHECK_EQUAL( n, 2 );
373     }
374     {
375     // reading +0, i
376     signed char i = -1;
377     int n;
378     CHECK_EQUAL( sscanf( string + 3, "%hhi%n", &i, &n ), 1 );
379     CHECK_EQUAL( i, 0 );
380     CHECK_EQUAL( n, 2 );
381     }
382     {
383     // reading -128, i
384     signed char i = -1;
385     int n;
386     CHECK_EQUAL( sscanf( string + 6, "%hhi%n", &i, &n ), 1 );
387     CHECK_EQUAL( i, -128 );
388     CHECK_EQUAL( n, 4 );
389     }
390     {
391     // reading 127, i
392     signed char i = -1;
393     int n;
394     CHECK_EQUAL( sscanf( string + 12, "%hhi%n", &i, &n ), 1 );
395     CHECK_EQUAL( i, 127 );
396     CHECK_EQUAL( n, 3 );
397     }
398     {
399     // reading +127, i
400     signed char i = -1;
401     int n;
402     CHECK_EQUAL( sscanf( string + 11, "%hhi%n", &i, &n ), 1 );
403     CHECK_EQUAL( i, 127 );
404     CHECK_EQUAL( n, 4 );
405     }
406     {
407     // reading 0, d
408     signed short i = -1;
409     int n;
410     CHECK_EQUAL( sscanf( string + 1, "%hd%n", &i, &n ), 1 );
411     CHECK_EQUAL( i, 0 );
412     CHECK_EQUAL( n, 1 );
413     }
414     {
415     // reading -0, d
416     signed short i = -1;
417     int n;
418     CHECK_EQUAL( sscanf( string + 0, "%hd%n", &i, &n ), 1 );
419     CHECK_EQUAL( i, 0 );
420     CHECK_EQUAL( n, 2 );
421     }
422     {
423     // reading +0, d
424     signed short i = -1;
425     int n;
426     CHECK_EQUAL( sscanf( string + 3, "%hd%n", &i, &n ), 1 );
427     CHECK_EQUAL( i, 0 );
428     CHECK_EQUAL( n, 2 );
429     }
430     {
431     // reading -32768, d
432     signed short i = -1;
433     int n;
434     CHECK_EQUAL( sscanf( string + 21, "%hd%n", &i, &n ), 1 );
435     CHECK_EQUAL( i, -32768 );
436     CHECK_EQUAL( n, 6 );
437     }
438     {
439     // reading 32767, d
440     signed short i = -1;
441     int n;
442     CHECK_EQUAL( sscanf( string + 29, "%hd%n", &i, &n ), 1 );
443     CHECK_EQUAL( i, 32767 );
444     CHECK_EQUAL( n, 5 );
445     }
446     {
447     // reading +32767, d
448     signed short i = -1;
449     int n;
450     CHECK_EQUAL( sscanf( string + 28, "%hd%n", &i, &n ), 1 );
451     CHECK_EQUAL( i, 32767 );
452     CHECK_EQUAL( n, 6 );
453     }
454     {
455     // reading 0, u
456     unsigned short i = -1;
457     int n;
458     CHECK_EQUAL( sscanf( string + 1, "%hu%n", &i, &n ), 1 );
459     CHECK_EQUAL( i, 0 );
460     CHECK_EQUAL( n, 1 );
461     }
462     {
463     // reading -0, u
464     unsigned short i = -1;
465     int n;
466     CHECK_EQUAL( sscanf( string + 0, "%hu%n", &i, &n ), 1 );
467     CHECK_EQUAL( i, 0 );
468     CHECK_EQUAL( n, 2 );
469     }
470     {
471     // reading +0, u
472     unsigned short i = -1;
473     int n;
474     CHECK_EQUAL( sscanf( string + 3, "%hu%n", &i, &n ), 1 );
475     CHECK_EQUAL( i, 0 );
476     CHECK_EQUAL( n, 2 );
477     }
478     {
479     // reading 32767, u
480     unsigned short i = -1;
481     int n;
482     CHECK_EQUAL( sscanf( string + 29, "%hu%n", &i, &n ), 1 );
483     CHECK_EQUAL( i, 32767 );
484     CHECK_EQUAL( n, 5 );
485     }
486     {
487     // reading +32767, u
488     unsigned short i = -1;
489     int n;
490     CHECK_EQUAL( sscanf( string + 28, "%hu%n", &i, &n ), 1 );
491     CHECK_EQUAL( i, 32767 );
492     CHECK_EQUAL( n, 6 );
493     }
494     {
495     // reading 65535, u
496     unsigned short i = 0;
497     int n;
498     CHECK_EQUAL( sscanf( string + 36, "%hu%n", &i, &n ), 1 );
499     CHECK_EQUAL( i, 65535 );
500     CHECK_EQUAL( n, 5 );
501     }
502     {
503     // reading +65535, u
504     unsigned short i = 0;
505     int n;
506     CHECK_EQUAL( sscanf( string + 35, "%hu%n", &i, &n ), 1 );
507     CHECK_EQUAL( i, 65535 );
508     CHECK_EQUAL( n, 6 );
509     }
510     {
511     // reading 0, i
512     signed short i = -1;
513     int n;
514     CHECK_EQUAL( sscanf( string + 1, "%hi%n", &i, &n ), 1 );
515     CHECK_EQUAL( i, 0 );
516     CHECK_EQUAL( n, 1 );
517     }
518     {
519     // reading -0, i
520     signed short i = -1;
521     int n;
522     CHECK_EQUAL( sscanf( string + 0, "%hi%n", &i, &n ), 1 );
523     CHECK_EQUAL( i, 0 );
524     CHECK_EQUAL( n, 2 );
525     }
526     {
527     // reading +0, i
528     signed short i = -1;
529     int n;
530     CHECK_EQUAL( sscanf( string + 3, "%hi%n", &i, &n ), 1 );
531     CHECK_EQUAL( i, 0 );
532     CHECK_EQUAL( n, 2 );
533     }
534     {
535     // reading -32768, i
536     signed short i = -1;
537     int n;
538     CHECK_EQUAL( sscanf( string + 21, "%hi%n", &i, &n ), 1 );
539     CHECK_EQUAL( i, -32768 );
540     CHECK_EQUAL( n, 6 );
541     }
542     {
543     // reading 32767, i
544     signed short i = -1;
545     int n;
546     CHECK_EQUAL( sscanf( string + 29, "%hi%n", &i, &n ), 1 );
547     CHECK_EQUAL( i, 32767 );
548     CHECK_EQUAL( n, 5 );
549     }
550     {
551     // reading +32767, i
552     signed short i = -1;
553     int n;
554     CHECK_EQUAL( sscanf( string + 28, "%hi%n", &i, &n ), 1 );
555     CHECK_EQUAL( i, 32767 );
556     CHECK_EQUAL( n, 6 );
557     }
558     {
559     // reading 0, d
560     signed int i = -1;
561     int n;
562     CHECK_EQUAL( sscanf( string + 1, "%d%n", &i, &n ), 1 );
563     CHECK_EQUAL( i, 0 );
564     CHECK_EQUAL( n, 1 );
565     }
566     {
567     // reading -0, d
568     signed int i = -1;
569     int n;
570     CHECK_EQUAL( sscanf( string + 0, "%d%n", &i, &n ), 1 );
571     CHECK_EQUAL( i, 0 );
572     CHECK_EQUAL( n, 2 );
573     }
574     {
575     // reading +0, d
576     signed int i = -1;
577     int n;
578     CHECK_EQUAL( sscanf( string + 3, "%d%n", &i, &n ), 1 );
579     CHECK_EQUAL( i, 0 );
580     CHECK_EQUAL( n, 2 );
581     }
582     {
583     // reading -2147483648, d
584     signed int i = -1;
585     int n;
586     CHECK_EQUAL( sscanf( string + 42, "%d%n", &i, &n ), 1 );
587     CHECK_EQUAL( i, -2147483648 );
588     CHECK_EQUAL( n, 11 );
589     }
590     {
591     // reading 2147483647, d
592     signed int i = -1;
593     int n;
594     CHECK_EQUAL( sscanf( string + 55, "%d%n", &i, &n ), 1 );
595     CHECK_EQUAL( i, 2147483647 );
596     CHECK_EQUAL( n, 10 );
597     }
598     {
599     // reading +2147483647, d
600     signed int i = -1;
601     int n;
602     CHECK_EQUAL( sscanf( string + 54, "%d%n", &i, &n ), 1 );
603     CHECK_EQUAL( i, 2147483647 );
604     CHECK_EQUAL( n, 11 );
605     }
606     {
607     // reading 0, u
608     unsigned int i = -1;
609     int n;
610     CHECK_EQUAL( sscanf( string + 1, "%u%n", &i, &n ), 1 );
611     CHECK_EQUAL( i, 0 );
612     CHECK_EQUAL( n, 1 );
613     }
614     {
615     // reading -0, u
616     unsigned int i = -1;
617     int n;
618     CHECK_EQUAL( sscanf( string + 0, "%u%n", &i, &n ), 1 );
619     CHECK_EQUAL( i, 0 );
620     CHECK_EQUAL( n, 2 );
621     }
622     {
623     // reading +0, u
624     unsigned int i = -1;
625     int n;
626     CHECK_EQUAL( sscanf( string + 3, "%u%n", &i, &n ), 1 );
627     CHECK_EQUAL( i, 0 );
628     CHECK_EQUAL( n, 2 );
629     }
630     {
631     // reading 2147483647, u
632     unsigned int i = -1;
633     int n;
634     CHECK_EQUAL( sscanf( string + 55, "%u%n", &i, &n ), 1 );
635     CHECK_EQUAL( i, 2147483647 );
636     CHECK_EQUAL( n, 10 );
637     }
638     {
639     // reading +2147483647, u
640     unsigned int i = -1;
641     int n;
642     CHECK_EQUAL( sscanf( string + 54, "%u%n", &i, &n ), 1 );
643     CHECK_EQUAL( i, 2147483647 );
644     CHECK_EQUAL( n, 11 );
645     }
646     {
647     // reading 4294967295, u
648     unsigned int i = 0;
649     int n;
650     CHECK_EQUAL( sscanf( string + 67, "%u%n", &i, &n ), 1 );
651     CHECK_FEQUAL( i, 4294967295, unsigned int, "%u" );
652     CHECK_EQUAL( n, 10 );
653     }
654     {
655     // reading +4294967295, u
656     unsigned int i = 0;
657     int n;
658     CHECK_EQUAL( sscanf( string + 66, "%u%n", &i, &n ), 1 );
659     CHECK_FEQUAL( i, 4294967295, unsigned int, "%u" );
660     CHECK_EQUAL( n, 11 );
661     }
662     {
663     // reading 0, i
664     signed int i = -1;
665     int n;
666     CHECK_EQUAL( sscanf( string + 1, "%i%n", &i, &n ), 1 );
667     CHECK_EQUAL( i, 0 );
668     CHECK_EQUAL( n, 1 );
669     }
670     {
671     // reading -0, i
672     signed int i = -1;
673     int n;
674     CHECK_EQUAL( sscanf( string + 0, "%i%n", &i, &n ), 1 );
675     CHECK_EQUAL( i, 0 );
676     CHECK_EQUAL( n, 2 );
677     }
678     {
679     // reading +0, i
680     signed int i = -1;
681     int n;
682     CHECK_EQUAL( sscanf( string + 3, "%i%n", &i, &n ), 1 );
683     CHECK_EQUAL( i, 0 );
684     CHECK_EQUAL( n, 2 );
685     }
686     {
687     // reading -2147483648, i
688     signed int i = -1;
689     int n;
690     CHECK_EQUAL( sscanf( string + 42, "%i%n", &i, &n ), 1 );
691     CHECK_EQUAL( i, -2147483648 );
692     CHECK_EQUAL( n, 11 );
693     }
694     {
695     // reading 2147483647, i
696     signed int i = -1;
697     int n;
698     CHECK_EQUAL( sscanf( string + 55, "%i%n", &i, &n ), 1 );
699     CHECK_EQUAL( i, 2147483647 );
700     CHECK_EQUAL( n, 10 );
701     }
702     {
703     // reading +2147483647, i
704     signed int i = -1;
705     int n;
706     CHECK_EQUAL( sscanf( string + 54, "%i%n", &i, &n ), 1 );
707     CHECK_EQUAL( i, 2147483647 );
708     CHECK_EQUAL( n, 11 );
709     }
710     {
711     // reading 0, d
712     signed long i = -1;
713     int n;
714     CHECK_EQUAL( sscanf( string + 1, "%ld%n", &i, &n ), 1 );
715     CHECK_EQUAL( i, 0l );
716     CHECK_EQUAL( n, 1 );
717     }
718     {
719     // reading -0, d
720     signed long i = -1;
721     int n;
722     CHECK_EQUAL( sscanf( string + 0, "%ld%n", &i, &n ), 1 );
723     CHECK_EQUAL( i, 0l );
724     CHECK_EQUAL( n, 2 );
725     }
726     {
727     // reading +0, d
728     signed long i = -1;
729     int n;
730     CHECK_EQUAL( sscanf( string + 3, "%ld%n", &i, &n ), 1 );
731     CHECK_EQUAL( i, 0l );
732     CHECK_EQUAL( n, 2 );
733     }
734     {
735     // reading -2147483648, d
736     signed long i = -1;
737     int n;
738     CHECK_EQUAL( sscanf( string + 42, "%ld%n", &i, &n ), 1 );
739     CHECK_EQUAL( i, -2147483648l );
740     CHECK_EQUAL( n, 11 );
741     }
742     {
743     // reading 2147483647, d
744     signed long i = -1;
745     int n;
746     CHECK_EQUAL( sscanf( string + 55, "%ld%n", &i, &n ), 1 );
747     CHECK_EQUAL( i, 2147483647l );
748     CHECK_EQUAL( n, 10 );
749     }
750     {
751     // reading +2147483647, d
752     signed long i = -1;
753     int n;
754     CHECK_EQUAL( sscanf( string + 54, "%ld%n", &i, &n ), 1 );
755     CHECK_EQUAL( i, 2147483647l );
756     CHECK_EQUAL( n, 11 );
757     }
758     {
759     // reading 0, u
760     unsigned long i = -1;
761     int n;
762     CHECK_EQUAL( sscanf( string + 1, "%lu%n", &i, &n ), 1 );
763     CHECK_EQUAL( i, 0ul );
764     CHECK_EQUAL( n, 1 );
765     }
766     {
767     // reading -0, u
768     unsigned long i = -1;
769     int n;
770     CHECK_EQUAL( sscanf( string + 0, "%lu%n", &i, &n ), 1 );
771     CHECK_EQUAL( i, 0ul );
772     CHECK_EQUAL( n, 2 );
773     }
774     {
775     // reading +0, u
776     unsigned long i = -1;
777     int n;
778     CHECK_EQUAL( sscanf( string + 3, "%lu%n", &i, &n ), 1 );
779     CHECK_EQUAL( i, 0ul );
780     CHECK_EQUAL( n, 2 );
781     }
782     {
783     // reading 2147483647, u
784     unsigned long i = -1;
785     int n;
786     CHECK_EQUAL( sscanf( string + 55, "%lu%n", &i, &n ), 1 );
787     CHECK_EQUAL( i, 2147483647ul );
788     CHECK_EQUAL( n, 10 );
789     }
790     {
791     // reading +2147483647, u
792     unsigned long i = -1;
793     int n;
794     CHECK_EQUAL( sscanf( string + 54, "%lu%n", &i, &n ), 1 );
795     CHECK_EQUAL( i, 2147483647ul );
796     CHECK_EQUAL( n, 11 );
797     }
798     {
799     // reading 4294967295, u
800     unsigned long i = 0;
801     int n;
802     CHECK_EQUAL( sscanf( string + 67, "%lu%n", &i, &n ), 1 );
803     CHECK_FEQUAL( i, 4294967295ul, unsigned long, "%lu" );
804     CHECK_EQUAL( n, 10 );
805     }
806     {
807     // reading +4294967295, u
808     unsigned long i = 0;
809     int n;
810     CHECK_EQUAL( sscanf( string + 66, "%lu%n", &i, &n ), 1 );
811     CHECK_FEQUAL( i, 4294967295ul, unsigned long, "%lu" );
812     CHECK_EQUAL( n, 11 );
813     }
814     {
815     // reading 0, i
816     signed long i = -1;
817     int n;
818     CHECK_EQUAL( sscanf( string + 1, "%li%n", &i, &n ), 1 );
819     CHECK_EQUAL( i, 0l );
820     CHECK_EQUAL( n, 1 );
821     }
822     {
823     // reading -0, i
824     signed long i = -1;
825     int n;
826     CHECK_EQUAL( sscanf( string + 0, "%li%n", &i, &n ), 1 );
827     CHECK_EQUAL( i, 0l );
828     CHECK_EQUAL( n, 2 );
829     }
830     {
831     // reading +0, i
832     signed long i = -1;
833     int n;
834     CHECK_EQUAL( sscanf( string + 3, "%li%n", &i, &n ), 1 );
835     CHECK_EQUAL( i, 0l );
836     CHECK_EQUAL( n, 2 );
837     }
838     {
839     // reading -2147483648, i
840     signed long i = -1;
841     int n;
842     CHECK_EQUAL( sscanf( string + 42, "%li%n", &i, &n ), 1 );
843     CHECK_EQUAL( i, -2147483648l );
844     CHECK_EQUAL( n, 11 );
845     }
846     {
847     // reading 2147483647, i
848     signed long i = -1;
849     int n;
850     CHECK_EQUAL( sscanf( string + 55, "%li%n", &i, &n ), 1 );
851     CHECK_EQUAL( i, 2147483647l );
852     CHECK_EQUAL( n, 10 );
853     }
854     {
855     // reading +2147483647, i
856     signed long i = -1;
857     int n;
858     CHECK_EQUAL( sscanf( string + 54, "%li%n", &i, &n ), 1 );
859     CHECK_EQUAL( i, 2147483647l );
860     CHECK_EQUAL( n, 11 );
861     }
862     {
863     // reading 0, d
864     signed long long i = -1;
865     int n;
866     CHECK_EQUAL( sscanf( string + 1, "%lld%n", &i, &n ), 1 );
867     CHECK_EQUAL( i, 0ll );
868     CHECK_EQUAL( n, 1 );
869     }
870     {
871     // reading -0, d
872     signed long long i = -1;
873     int n;
874     CHECK_EQUAL( sscanf( string + 0, "%lld%n", &i, &n ), 1 );
875     CHECK_EQUAL( i, 0ll );
876     CHECK_EQUAL( n, 2 );
877     }
878     {
879     // reading +0, d
880     signed long long i = -1;
881     int n;
882     CHECK_EQUAL( sscanf( string + 3, "%lld%n", &i, &n ), 1 );
883     CHECK_EQUAL( i, 0ll );
884     CHECK_EQUAL( n, 2 );
885     }
886     {
887     // reading -9223372036854775808, d
888     signed long long i = -1;
889     int n;
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 );
894     }
895     {
896     // reading 9223372036854775807, d
897     signed long long i = -1;
898     int n;
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 );
902     }
903     {
904     // reading +9223372036854775807, d
905     signed long long i = -1;
906     int n;
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 );
910     }
911     {
912     // reading 0, u
913     unsigned long long i = -1;
914     int n;
915     CHECK_EQUAL( sscanf( string + 1, "%llu%n", &i, &n ), 1 );
916     CHECK_EQUAL( i, 0ull );
917     CHECK_EQUAL( n, 1 );
918     }
919     {
920     // reading -0, u
921     unsigned long long i = -1;
922     int n;
923     CHECK_EQUAL( sscanf( string + 0, "%llu%n", &i, &n ), 1 );
924     CHECK_EQUAL( i, 0ull );
925     CHECK_EQUAL( n, 2 );
926     }
927     {
928     // reading +0, u
929     unsigned long long i = -1;
930     int n;
931     CHECK_EQUAL( sscanf( string + 3, "%llu%n", &i, &n ), 1 );
932     CHECK_EQUAL( i, 0ull );
933     CHECK_EQUAL( n, 2 );
934     }
935     {
936     // reading 9223372036854775807, u
937     unsigned long long i = -1;
938     int n;
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 );
942     }
943     {
944     // reading +9223372036854775807, u
945     unsigned long long i = -1;
946     int n;
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 );
950     }
951     {
952     // reading 18446744073709551615, u
953     unsigned long long i = 0;
954     int n;
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 );
958     }
959     {
960     // reading +18446744073709551615, u
961     unsigned long long i = 0;
962     int n;
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 );
966     }
967     {
968     // reading 0, i
969     signed long long i = -1;
970     int n;
971     CHECK_EQUAL( sscanf( string + 1, "%lli%n", &i, &n ), 1 );
972     CHECK_EQUAL( i, 0ll );
973     CHECK_EQUAL( n, 1 );
974     }
975     {
976     // reading -0, i
977     signed long long i = -1;
978     int n;
979     CHECK_EQUAL( sscanf( string + 0, "%lli%n", &i, &n ), 1 );
980     CHECK_EQUAL( i, 0ll );
981     CHECK_EQUAL( n, 2 );
982     }
983     {
984     // reading +0, i
985     signed long long i = -1;
986     int n;
987     CHECK_EQUAL( sscanf( string + 3, "%lli%n", &i, &n ), 1 );
988     CHECK_EQUAL( i, 0ll );
989     CHECK_EQUAL( n, 2 );
990     }
991     {
992     // reading -9223372036854775808, i
993     signed long long i = -1;
994     int n;
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 );
999     }
1000     {
1001     // reading 9223372036854775807, i
1002     signed long long i = -1;
1003     int n;
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 );
1007     }
1008     {
1009     // reading +9223372036854775807, i
1010     signed long long i = -1;
1011     int n;
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 );
1015     }
1016 }
1017
1018 // hexadecimal integer matches
1019 void suite_three()
1020 {
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' );
1026     {
1027     // reading 0, x
1028     unsigned char i = -1;
1029     int n;
1030     CHECK_EQUAL( sscanf( string + 3, "%hhx%n", &i, &n ), 1 );
1031     CHECK_EQUAL( i, 0 );
1032     CHECK_EQUAL( n, 1 );
1033     }
1034     {
1035     // reading -0x0, x
1036     unsigned char i = -1;
1037     int n;
1038     CHECK_EQUAL( sscanf( string + 0, "%hhx%n", &i, &n ), 1 );
1039     CHECK_EQUAL( i, 0 );
1040     CHECK_EQUAL( n, 4 );
1041     }
1042     {
1043     // reading 0x000, x
1044     unsigned char i = -1;
1045     int n;
1046     CHECK_EQUAL( sscanf( string + 5, "%hhx%n", &i, &n ), 1 );
1047     CHECK_EQUAL( i, 0 );
1048     CHECK_EQUAL( n, 6 );
1049     }
1050     {
1051     // reading 0x0, i
1052     signed char i = -1;
1053     int n;
1054     CHECK_EQUAL( sscanf( string + 0, "%hhi%n", &i, &n ), 1 );
1055     CHECK_EQUAL( i, 0 );
1056     CHECK_EQUAL( n, 4 );
1057     }
1058     {
1059     // reading 7f, x
1060     unsigned char i = -1;
1061     int n;
1062     CHECK_EQUAL( sscanf( string + 15, "%hhx%n", &i, &n ), 1 );
1063     CHECK_EQUAL( i, 127 );
1064     CHECK_EQUAL( n, 2 );
1065     }
1066     {
1067     // reading -0x7f, x
1068     unsigned char i = -1;
1069     int n;
1070     CHECK_EQUAL( sscanf( string + 12, "%hhx%n", &i, &n ), 1 );
1071     CHECK_FEQUAL( i, -127, unsigned char, "%hhu" );
1072     CHECK_EQUAL( n, 5 );
1073     }
1074     {
1075     // reading 0x80, i
1076     signed char i = -1;
1077     int n;
1078     CHECK_EQUAL( sscanf( string + 18, "%hhi%n", &i, &n ), 1 );
1079     CHECK_FEQUAL( i, -128, signed char, "%hhd" );
1080     CHECK_EQUAL( n, 4 );
1081     }
1082     {
1083     // reading ff, x
1084     unsigned char i = -1;
1085     int n;
1086     CHECK_EQUAL( sscanf( string + 25, "%hhx%n", &i, &n ), 1 );
1087     CHECK_EQUAL( i, 0xff );
1088     CHECK_EQUAL( n, 2 );
1089     }
1090     {
1091     // reading 0xff, x
1092     unsigned char i = -1;
1093     int n;
1094     CHECK_EQUAL( sscanf( string + 23, "%hhx%n", &i, &n ), 1 );
1095     CHECK_EQUAL( i, 255 );
1096     CHECK_EQUAL( n, 4 );
1097     }
1098     {
1099     // reading 0xff, i
1100     signed char i = 0;
1101     int n;
1102     CHECK_EQUAL( sscanf( string + 23, "%hhi%n", &i, &n ), 1 );
1103     CHECK_EQUAL( i, -1 );
1104     CHECK_EQUAL( n, 4 );
1105     }
1106     {
1107     // reading 0, x
1108     unsigned short i = -1;
1109     int n;
1110     CHECK_EQUAL( sscanf( string + 3, "%hx%n", &i, &n ), 1 );
1111     CHECK_EQUAL( i, 0 );
1112     CHECK_EQUAL( n, 1 );
1113     }
1114     {
1115     // reading -0x0, x
1116     unsigned short i = -1;
1117     int n;
1118     CHECK_EQUAL( sscanf( string + 0, "%hx%n", &i, &n ), 1 );
1119     CHECK_EQUAL( i, 0 );
1120     CHECK_EQUAL( n, 4 );
1121     }
1122     {
1123     // reading 0x000, x
1124     unsigned short i = -1;
1125     int n;
1126     CHECK_EQUAL( sscanf( string + 5, "%hx%n", &i, &n ), 1 );
1127     CHECK_EQUAL( i, 0 );
1128     CHECK_EQUAL( n, 6 );
1129     }
1130     {
1131     // reading 0x0, i
1132     signed short i = -1;
1133     int n;
1134     CHECK_EQUAL( sscanf( string + 0, "%hi%n", &i, &n ), 1 );
1135     CHECK_EQUAL( i, 0 );
1136     CHECK_EQUAL( n, 4 );
1137     }
1138     {
1139     // reading 7fff, x
1140     unsigned short i = -1;
1141     int n;
1142     CHECK_EQUAL( sscanf( string + 31, "%hx%n", &i, &n ), 1 );
1143     CHECK_EQUAL( i, 32767 );
1144     CHECK_EQUAL( n, 4 );
1145     }
1146     {
1147     // reading -0x7fff, x
1148     unsigned short i = -1;
1149     int n;
1150     CHECK_EQUAL( sscanf( string + 28, "%hx%n", &i, &n ), 1 );
1151     CHECK_FEQUAL( i, -32767, unsigned short, "%hu" );
1152     CHECK_EQUAL( n, 7 );
1153     }
1154     {
1155     // reading 0x8000, i
1156     signed short i = -1;
1157     int n;
1158     CHECK_EQUAL( sscanf( string + 36, "%hi%n", &i, &n ), 1 );
1159     CHECK_FEQUAL( i, -32768, signed short, "%hd" );
1160     CHECK_EQUAL( n, 6 );
1161     }
1162     {
1163     // reading ffff, x
1164     unsigned short i = -1;
1165     int n;
1166     CHECK_EQUAL( sscanf( string + 45, "%hx%n", &i, &n ), 1 );
1167     CHECK_EQUAL( i, 65535 );
1168     CHECK_EQUAL( n, 4 );
1169     }
1170     {
1171     // reading 0xffff, x
1172     unsigned short i = -1;
1173     int n;
1174     CHECK_EQUAL( sscanf( string + 43, "%hx%n", &i, &n ), 1 );
1175     CHECK_EQUAL( i, 65535 );
1176     CHECK_EQUAL( n, 6 );
1177     }
1178     {
1179     // reading 0xffff, i
1180     signed short i = 0;
1181     int n;
1182     CHECK_EQUAL( sscanf( string + 43, "%hi%n", &i, &n ), 1 );
1183     CHECK_FEQUAL( i, -1, signed short, "%hd" );
1184     CHECK_EQUAL( n, 6 );
1185     }
1186     {
1187     // reading 0, x
1188     unsigned int i = -1;
1189     int n;
1190     CHECK_EQUAL( sscanf( string + 3, "%x%n", &i, &n ), 1 );
1191     CHECK_EQUAL( i, 0 );
1192     CHECK_EQUAL( n, 1 );
1193     }
1194     {
1195     // reading -0x0, x
1196     unsigned int i = -1;
1197     int n;
1198     CHECK_EQUAL( sscanf( string + 0, "%x%n", &i, &n ), 1 );
1199     CHECK_EQUAL( i, 0 );
1200     CHECK_EQUAL( n, 4 );
1201     }
1202     {
1203     // reading 0x000, x
1204     unsigned int i = -1;
1205     int n;
1206     CHECK_EQUAL( sscanf( string + 5, "%x%n", &i, &n ), 1 );
1207     CHECK_EQUAL( i, 0 );
1208     CHECK_EQUAL( n, 6 );
1209     }
1210     {
1211     // reading 0x0, i
1212     signed int i = -1;
1213     int n;
1214     CHECK_EQUAL( sscanf( string + 0, "%i%n", &i, &n ), 1 );
1215     CHECK_EQUAL( i, 0 );
1216     CHECK_EQUAL( n, 4 );
1217     }
1218     {
1219     // reading 7fffffff, x
1220     unsigned int i = -1;
1221     int n;
1222     CHECK_EQUAL( sscanf( string + 53, "%x%n", &i, &n ), 1 );
1223     CHECK_EQUAL( i, 2147483647 );
1224     CHECK_EQUAL( n, 8 );
1225     }
1226     {
1227     // reading -0x7fffffff, x
1228     unsigned int i = -1;
1229     int n;
1230     CHECK_EQUAL( sscanf( string + 50, "%x%n", &i, &n ), 1 );
1231     CHECK_FEQUAL( i, -2147483647, unsigned int, "%u" );
1232     CHECK_EQUAL( n, 11 );
1233     }
1234     {
1235     // reading 0x80000000, i
1236     signed int i = -1;
1237     int n;
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 );
1242     }
1243     {
1244     // reading ffffffff, x
1245     unsigned int i = -1;
1246     int n;
1247     CHECK_EQUAL( sscanf( string + 75, "%x%n", &i, &n ), 1 );
1248     CHECK_FEQUAL( i, 4294967295, unsigned int, "%d" );
1249     CHECK_EQUAL( n, 8 );
1250     }
1251     {
1252     // reading 0xffffffff, x
1253     unsigned int i = -1;
1254     int n;
1255     CHECK_EQUAL( sscanf( string + 73, "%x%n", &i, &n ), 1 );
1256     CHECK_FEQUAL( i, 4294967295, unsigned int, "%d" );
1257     CHECK_EQUAL( n, 10 );
1258     }
1259 }
1260
1261 // octal integer matches
1262 void suite_four()
1263 {
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' );
1270     {
1271     // reading 0, o
1272     unsigned char i = -1;
1273     int n;
1274     CHECK_EQUAL( sscanf( string + 4, "%hho%n", &i, &n ), 1 );
1275     CHECK_EQUAL( i, 0u );
1276     CHECK_EQUAL( n, 1 );
1277     }
1278     {
1279     // reading +0000, o
1280     unsigned char i = -1;
1281     int n;
1282     CHECK_EQUAL( sscanf( string + 0, "%hho%n", &i, &n ), 1 );
1283     CHECK_EQUAL( i, 0u );
1284     CHECK_EQUAL( n, 5 );
1285     }
1286     {
1287     // reading -0000, o
1288     unsigned char i = -1;
1289     int n;
1290     CHECK_EQUAL( sscanf( string + 6, "%hho%n", &i, &n ), 1 );
1291     CHECK_EQUAL( i, 0u );
1292     CHECK_EQUAL( n, 5 );
1293     }
1294     {
1295     // reading 0177, o
1296     unsigned char i = -1;
1297     int n;
1298     CHECK_EQUAL( sscanf( string + 13, "%hho%n", &i, &n ), 1 );
1299     CHECK_EQUAL( i, 127u );
1300     CHECK_EQUAL( n, 4 );
1301     }
1302     {
1303     // reading +0177, o
1304     unsigned char i = -1;
1305     int n;
1306     CHECK_EQUAL( sscanf( string + 12, "%hho%n", &i, &n ), 1 );
1307     CHECK_EQUAL( i, 127u );
1308     CHECK_EQUAL( n, 5 );
1309     }
1310     {
1311     // reading 0377, o
1312     unsigned char i = -1;
1313     int n;
1314     CHECK_EQUAL( sscanf( string + 19, "%hho%n", &i, &n ), 1 );
1315     CHECK_FEQUAL( i, 255u, unsigned char, "%hhu" );
1316     CHECK_EQUAL( n, 4 );
1317     }
1318     {
1319     // reading +0377, o
1320     unsigned char i = -1;
1321     int n;
1322     CHECK_EQUAL( sscanf( string + 18, "%hho%n", &i, &n ), 1 );
1323     CHECK_FEQUAL( i, 255u, unsigned char, "%hhu" );
1324     CHECK_EQUAL( n, 5 );
1325     }
1326     {
1327     // reading -0377, o
1328     unsigned char i = -1;
1329     int n;
1330     CHECK_EQUAL( sscanf( string + 24, "%hho%n", &i, &n ), 1 );
1331     CHECK_FEQUAL( i, 1u, unsigned char, "%hhu" );
1332     CHECK_EQUAL( n, 5 );
1333     }
1334     {
1335     // reading 077777, o
1336     unsigned short i = -1;
1337     int n;
1338     CHECK_EQUAL( sscanf( string + 31, "%ho%n", &i, &n ), 1 );
1339     CHECK_EQUAL( i, 32767u );
1340     CHECK_EQUAL( n, 6 );
1341     }
1342     {
1343     // reading +077777, o
1344     unsigned short i = -1;
1345     int n;
1346     CHECK_EQUAL( sscanf( string + 30, "%ho%n", &i, &n ), 1 );
1347     CHECK_EQUAL( i, 32767u );
1348     CHECK_EQUAL( n, 7 );
1349     }
1350     {
1351     // reading 0177777, o
1352     unsigned short i = -1;
1353     int n;
1354     CHECK_EQUAL( sscanf( string + 39, "%ho%n", &i, &n ), 1 );
1355     CHECK_FEQUAL( i, 65535u, unsigned short, "%hu" );
1356     CHECK_EQUAL( n, 7 );
1357     }
1358     {
1359     // reading +0177777, o
1360     unsigned short i = -1;
1361     int n;
1362     CHECK_EQUAL( sscanf( string + 38, "%ho%n", &i, &n ), 1 );
1363     CHECK_FEQUAL( i, 65535u, unsigned short, "%hu" );
1364     CHECK_EQUAL( n, 8 );
1365     }
1366     {
1367     // reading -0177777, o
1368     unsigned short i = -1;
1369     int n;
1370     CHECK_EQUAL( sscanf( string + 47, "%ho%n", &i, &n ), 1 );
1371     CHECK_FEQUAL( i, 1u, unsigned short, "%hu" );
1372     CHECK_EQUAL( n, 8 );
1373     }
1374     {
1375     // reading 017777777777, o
1376     unsigned int i = -1;
1377     int n;
1378     CHECK_EQUAL( sscanf( string + 57, "%o%n", &i, &n ), 1 );
1379     CHECK_EQUAL( i, 2147483647u );
1380     CHECK_EQUAL( n, 12 );
1381     }
1382     {
1383     // reading +017777777777, o
1384     unsigned int i = -1;
1385     int n;
1386     CHECK_EQUAL( sscanf( string + 56, "%o%n", &i, &n ), 1 );
1387     CHECK_EQUAL( i, 2147483647u );
1388     CHECK_EQUAL( n, 13 );
1389     }
1390     {
1391     // reading 037777777777, o
1392     unsigned int i = -1;
1393     int n;
1394     CHECK_EQUAL( sscanf( string + 71, "%o%n", &i, &n ), 1 );
1395     CHECK_FEQUAL( i, 4294967295u, unsigned int, "%u" );
1396     CHECK_EQUAL( n, 12 );
1397     }
1398     {
1399     // reading +037777777777, o
1400     unsigned int i = -1;
1401     int n;
1402     CHECK_EQUAL( sscanf( string + 70, "%o%n", &i, &n ), 1 );
1403     CHECK_FEQUAL( i, 4294967295u, unsigned int, "%u" );
1404     CHECK_EQUAL( n, 13 );
1405     }
1406     {
1407     // reading -037777777777, o
1408     unsigned int i = -1;
1409     int n;
1410     CHECK_EQUAL( sscanf( string + 84, "%o%n", &i, &n ), 1 );
1411     CHECK_FEQUAL( i, 1u, unsigned int, "%u" );
1412     CHECK_EQUAL( n, 13 );
1413     }
1414     {
1415     // reading 017777777777, o
1416     unsigned long i = -1;
1417     int n;
1418     CHECK_EQUAL( sscanf( string + 57, "%lo%n", &i, &n ), 1 );
1419     CHECK_EQUAL( i, 2147483647lu );
1420     CHECK_EQUAL( n, 12 );
1421     }
1422     {
1423     // reading +017777777777, o
1424     unsigned long i = -1;
1425     int n;
1426     CHECK_EQUAL( sscanf( string + 56, "%lo%n", &i, &n ), 1 );
1427     CHECK_EQUAL( i, 2147483647lu );
1428     CHECK_EQUAL( n, 13 );
1429     }
1430     {
1431     // reading 037777777777, o
1432     unsigned long i = -1;
1433     int n;
1434     CHECK_EQUAL( sscanf( string + 71, "%lo%n", &i, &n ), 1 );
1435     CHECK_FEQUAL( i, 4294967295lu, unsigned long, "%lu" );
1436     CHECK_EQUAL( n, 12 );
1437     }
1438     {
1439     // reading +037777777777, o
1440     unsigned long i = -1;
1441     int n;
1442     CHECK_EQUAL( sscanf( string + 70, "%lo%n", &i, &n ), 1 );
1443     CHECK_FEQUAL( i, 4294967295lu, unsigned long, "%lu" );
1444     CHECK_EQUAL( n, 13 );
1445     }
1446     {
1447     // reading -037777777777, o
1448     unsigned long i = -1;
1449     int n;
1450     CHECK_EQUAL( sscanf( string + 84, "%lo%n", &i, &n ), 1 );
1451     CHECK_FEQUAL( i, 1lu, unsigned long, "%lu" );
1452     CHECK_EQUAL( n, 13 );
1453     }
1454     {
1455     // reading 0777777777777777777777, o
1456     unsigned long long i = -1;
1457     int n;
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 );
1461     }
1462     {
1463     // reading +0777777777777777777777, o
1464     unsigned long long i = -1;
1465     int n;
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 );
1469     }
1470     {
1471     // reading 01777777777777777777777, o
1472     unsigned long long i = -1;
1473     int n;
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 );
1477     }
1478     {
1479     // reading +01777777777777777777777, o
1480     unsigned long long i = -1;
1481     int n;
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 );
1485     }
1486     {
1487     // reading -01777777777777777777777, o
1488     unsigned long long i = -1;
1489     int n;
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 );
1493     }
1494 }
1495
1496 // string matches
1497 void suite_five()
1498 {
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 ];
1503     {
1504     // reading abc
1505     memset( buffer, '\0', BUFSIZE );
1506     int n;
1507     CHECK_EQUAL( sscanf( string + 0, "%[abc]%n", buffer, &n ), 1 );
1508     CHECK_EQUAL( n, 3 );
1509     CHECK_FALSE( memcmp( buffer, "abc", n + 1 ) );
1510     }
1511     {
1512     // reading a-c
1513     memset( buffer, '\0', BUFSIZE );
1514     int n;
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 ) );
1518     }
1519     {
1520     // reading a-h
1521     memset( buffer, '\0', BUFSIZE );
1522     int n;
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 ) );
1526     }
1527     {
1528     // reading o-r, including [, seperate char
1529     memset( buffer, '\0', BUFSIZE );
1530     int n;
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 ) );
1534     }
1535     {
1536     // reading v-y, including ], two groups
1537     memset( buffer, '\0', BUFSIZE );
1538     int n;
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 ) );
1542     }
1543     {
1544     // missing on first character
1545     memset( buffer, '\0', BUFSIZE );
1546     int n;
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 ) );
1551     }
1552     {
1553     // eof while reading, two groups
1554     memset( buffer, '\0', BUFSIZE );
1555     int n;
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 ) );
1559     }
1560     {
1561     // eof before reading
1562     memset( buffer, '\0', BUFSIZE );
1563     int n;
1564     CHECK_EQUAL( sscanf( string + 29, "%[a-z]%n", buffer, &n ), -1 );
1565     CHECK_FALSE( memcmp( buffer, "", 1 ) );
1566     }
1567     {
1568     // negation - [^...]
1569     memset( buffer, '\0', BUFSIZE );
1570     int n;
1571     CHECK_EQUAL( sscanf( string + 0, "%[^d-f]%n", buffer, &n ), 1 );
1572     CHECK_EQUAL( n, 3 );
1573     CHECK_FALSE( memcmp( buffer, "abc", 4 ) );
1574     }
1575 }
1576
1577 void suite_six()
1578 {
1579     char const * string = "-0xz\n";
1580     CHECK_EQUAL( string[4], '\n' );
1581     {
1582     // reading -0x, x
1583     unsigned char i = 1;
1584     int n = -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]
1603               function".
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
1612          paragraph 9.
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
1618          subject sequence.)
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.
1623     */
1624     CHECK_EQUAL( sscanf( string, "%hhx%n", &i, &n ), 0 );
1625     CHECK_EQUAL( i, 1 );
1626     CHECK_EQUAL( n, -1 );
1627     }
1628     {
1629     // reading -0x, x
1630     unsigned short i = 1;
1631     int n = -1;
1632     CHECK_EQUAL( sscanf( string, "%hx%n", &i, &n ), 0 );
1633     CHECK_EQUAL( i, 1 );
1634     CHECK_EQUAL( n, -1 );
1635     }
1636     {
1637     // reading -0x, x
1638     unsigned int i = 1;
1639     int n = -1;
1640     CHECK_EQUAL( sscanf( string, "%x%n", &i, &n ), 0 );
1641     CHECK_EQUAL( i, 1 );
1642     CHECK_EQUAL( n, -1 );
1643     }
1644 }
1645
1646 #endif
1647