From 5522316811fdce2216c4d1320af68dd54909aed5 Mon Sep 17 00:00:00 2001 From: solar Date: Fri, 12 Mar 2010 11:08:56 +0000 Subject: [PATCH] Intermediate debugging work on *scanf(). --- functions/_PDCLIB/scan.c | 97 +- functions/stdio/fscanf.c | 2002 +++++++++++++++++++++++++++++++++++++ functions/stdio/sscanf.c | 1578 ++++++++++++++++++++++++++++- functions/stdio/vfscanf.c | 1 + functions/stdio/vsscanf.c | 7 +- internals/_PDCLIB_int.h | 24 +- 6 files changed, 3682 insertions(+), 27 deletions(-) diff --git a/functions/_PDCLIB/scan.c b/functions/_PDCLIB/scan.c index f41079b..c392a53 100644 --- a/functions/_PDCLIB/scan.c +++ b/functions/_PDCLIB/scan.c @@ -31,27 +31,46 @@ #define E_unsigned 1<<16 +/* Helper macro for assigning a readily converted integer value to the correct + parameter type, used in a switch on status->flags (see E_* flags above). + case_cond: combination of the E_* flags above, used for the switch-case + type: integer type, used to get the correct type from the parameter + stack as well as for cast target. +*/ #define ASSIGN( case_cond, type ) \ case case_cond: \ *( va_arg( status->arg, type * ) ) = (type)( value * sign ); \ break +/* Helper function to get a character from the string or stream, whatever is + used for input. When reading from a string, returns EOF on end-of-string + so that handling of the return value can be uniform for both streams and + strings. +*/ static int GET( struct _PDCLIB_status_t * status ) { - ++(status->i); - ++(status->this); + int rc; if ( status->stream != NULL ) { - return getc( status->stream ); + rc = getc( status->stream ); } else { - return ( *status->s == '\0' ) ? EOF : *((status->s)++); + rc = ( *status->s == '\0' ) ? EOF : (unsigned char)*((status->s)++); + } + if ( rc != EOF ) + { + ++(status->i); + ++(status->this); } + return rc; } +/* Helper function to put a read character back into the string or stream, + whatever is used for input. +*/ static void UNGET( int c, struct _PDCLIB_status_t * status ) { if ( status->stream != NULL ) @@ -60,7 +79,7 @@ static void UNGET( int c, struct _PDCLIB_status_t * status ) } else { - *(--(status->s)) = c; + --(status->s); } --(status->i); --(status->this); @@ -79,7 +98,11 @@ const char * _PDCLIB_scan( const char * spec, struct _PDCLIB_status_t * status ) switch ( rc ) { case EOF: - /* matching failure */ + /* input error */ + if ( status->n == 0 ) + { + status->n = -1; + } return NULL; case '%': return ++spec; @@ -204,16 +227,19 @@ const char * _PDCLIB_scan( const char * spec, struct _PDCLIB_status_t * status ) case 'c': { char * c = va_arg( status->arg, char * ); + /* for %c, default width is one */ if ( status->width == SIZE_MAX ) { status->width = 1; } + /* reading until width reached or input exhausted */ while ( ( status->this < status->width ) && ( ( rc = GET( status ) ) != EOF ) ) { *(c++) = rc; value_parsed = true; } + /* width or input exhausted */ if ( value_parsed ) { ++status->n; @@ -221,7 +247,11 @@ const char * _PDCLIB_scan( const char * spec, struct _PDCLIB_status_t * status ) } else { - /* FIXME: Need two kinds of "no match" here: zero width, and input error */ + /* input error, no character read */ + if ( status->n == 0 ) + { + status->n = -1; + } return NULL; } } @@ -235,11 +265,13 @@ const char * _PDCLIB_scan( const char * spec, struct _PDCLIB_status_t * status ) { if ( value_parsed ) { + /* matching sequence terminated by whitespace */ *c = '\0'; return spec; } else { + /* leading whitespace not counted against width */ --(status->this); } } @@ -258,6 +290,11 @@ const char * _PDCLIB_scan( const char * spec, struct _PDCLIB_status_t * status ) } else { + /* input error, no character read */ + if ( status->n == 0 ) + { + status->n = -1; + } return NULL; } } @@ -285,8 +322,23 @@ const char * _PDCLIB_scan( const char * spec, struct _PDCLIB_status_t * status ) while ( ( status->this < status->width ) && ( ( rc = GET( status ) ) != EOF ) ) { - if ( ! sign ) + if ( isspace( rc ) ) + { + if ( sign ) + { + /* matching sequence terminated by whitespace */ + UNGET( rc, status ); + break; + } + else + { + /* leading whitespace not counted against width */ + status->this--; + } + } + else if ( ! sign ) { + /* no sign parsed yet */ switch ( rc ) { case '-': @@ -296,6 +348,7 @@ const char * _PDCLIB_scan( const char * spec, struct _PDCLIB_status_t * status ) sign = 1; break; default: + /* not a sign; put back character */ sign = 1; UNGET( rc, status ); break; @@ -303,9 +356,11 @@ const char * _PDCLIB_scan( const char * spec, struct _PDCLIB_status_t * status ) } else if ( ! prefix_parsed ) { + /* no prefix (0x... for hex, 0... for octal) parsed yet */ prefix_parsed = true; if ( rc != '0' ) { + /* not a prefix; if base not yet set, set to decimal */ if ( status->base == 0 ) { status->base = 10; @@ -314,11 +369,14 @@ const char * _PDCLIB_scan( const char * spec, struct _PDCLIB_status_t * status ) } else { + /* starts with zero, so it might be a prefix. */ + /* check what follows next (might be 0x...) */ if ( ( status->this < status->width ) && ( ( rc = GET( status ) ) != EOF ) ) { if ( tolower( rc ) == 'x' ) { + /* 0x... would be prefix for hex base... */ if ( ( status->base == 0 ) || ( status->base == 16 ) ) { @@ -326,20 +384,29 @@ const char * _PDCLIB_scan( const char * spec, struct _PDCLIB_status_t * status ) } else { + /* ...unless already set to other value */ UNGET( rc, status ); value_parsed = true; } } else { + /* 0... but not 0x.... would be octal prefix */ UNGET( rc, status ); if ( status->base == 0 ) { status->base = 8; } + /* in any case we have read a zero */ value_parsed = true; } } + else + { + /* failed to read beyond the initial zero */ + value_parsed = true; + break; + } } } else @@ -348,6 +415,7 @@ const char * _PDCLIB_scan( const char * spec, struct _PDCLIB_status_t * status ) if ( digitptr == NULL ) { /* end of input item */ + UNGET( rc, status ); break; } value *= status->base; @@ -355,12 +423,18 @@ const char * _PDCLIB_scan( const char * spec, struct _PDCLIB_status_t * status ) value_parsed = true; } } - /* width exceeded, EOF, read error, non-matching character */ + /* width or input exhausted, or non-matching character */ if ( ! value_parsed ) { - /* matching error */ + /* out of input before anything could be parsed - input error */ + /* FIXME: if first character does not match, value_parsed is not set - but it is NOT an input error */ + if ( status->n == 0 ) + { + status->n = -1; + } return NULL; } + /* convert value to target type and assign to parameter */ switch ( status->flags & ( E_char | E_short | E_long | E_llong | E_intmax | E_size | E_ptrdiff | E_unsigned ) ) @@ -383,8 +457,9 @@ const char * _PDCLIB_scan( const char * spec, struct _PDCLIB_status_t * status ) /* ASSIGN( E_ptrdiff | E_unsigned, unsigned ptrdiff_t ); */ default: puts( "UNSUPPORTED SCANF FLAG COMBINATION" ); - return NULL; + return NULL; /* behaviour unspecified */ } + ++(status->n); return ++spec; } /* TODO: Floats. */ diff --git a/functions/stdio/fscanf.c b/functions/stdio/fscanf.c index 17b0dca..da64a9d 100644 --- a/functions/stdio/fscanf.c +++ b/functions/stdio/fscanf.c @@ -27,7 +27,2008 @@ int fscanf( FILE * _PDCLIB_restrict stream, const char * _PDCLIB_restrict format #include <_PDCLIB_test.h> #include +#include +#include <_PDCLIB_aux.h> +#if 0 +#define CHECK_TRUE( a ) do { if ( a == 0 ) { fprintf( stderr, "Unexpected failure in " _PDCLIB_symbol2string( __LINE__ ) ": '" #a "' evaluated to false.\n" ); } } while ( 0 ) +#define CHECK_FALSE( a ) do { if ( a != 0 ) { fprintf( stderr, "Unexpected failure in " _PDCLIB_symbol2string( __LINE__ ) ": '" #a "' evaluated to true.\n" ); } } while ( 0 ) +#define CHECK_EQUAL( a, b ) do { int x = a; int y = b; if ( x != y ) { fprintf( stderr, "Mismatch in " _PDCLIB_symbol2string( __LINE__ ) ": result is %d, expected %d.\n", x, y ); } } while ( 0 ) +#define CHECK_FEQUAL( a, b, T, F ) do { T x = a; T y = b; if ( x != y ) { fprintf( stderr, "Mismatch in " _PDCLIB_symbol2string( __LINE__ ) ": result is " F ", expected " F ".\n", x, y ); } } while ( 0 ) +#endif + +#define CHECK_TRUE( a ) TESTCASE( a != 0 ) +#define CHECK_FALSE( a ) TESTCASE( a == 0 ) +#define CHECK_EQUAL( a, b ) do { int x = a; int y = b; TESTCASE( x == y ); } while ( 0 ) +#define CHECK_FEQUAL( a, b, T, F ) do { T x = a; T y = b; TESTCASE( x == y ); } while ( 0 ) + +// literal matches, character matches, and basic integer matches +void suite_one( void ); +// decimal integer matches +void suite_two( void ); +// hexadecimal integer matches +void suite_three( void ); +// octal integer matches +void suite_four( void ); +// string matches +void suite_five( void ); + +int main() +{ + suite_one(); + suite_two(); + suite_three(); + suite_four(); + suite_five(); +} + +// literal matches, character matches, and basic integer matches +void suite_one() +{ + FILE * file; + if ( ( file = fopen( "tmpfile", "wb+" ) ) == NULL ) + { + puts( "Failed to open tmpfile for writing." ); + return; + } + fprintf( file, "1234567890" ); + fprintf( file, "1%c3-5+7%c9%c", 0, 0, -1 ); + fprintf( file, "2 4 6 8 0%c", 255 ); + fprintf( file, "1 \011 5%%%% 0" ); + CHECK_EQUAL( ftell( file ), 40 ); + + // ----------------------------------------------------------------------- + // Literal matching + // ----------------------------------------------------------------------- + { + // matching six characters literally + // checking via %n + // should report six characters read + fseek( file, 0, SEEK_SET ); + int n; + CHECK_EQUAL( fscanf( file, "123456%n", &n ), 0 ); + CHECK_EQUAL( n, 6 ); + CHECK_EQUAL( ftell( file ), 6 ); + } + { + // matching a character, three whitespace chars, and another character + // checking via %n + // should report five characters read + fseek( file, 30, SEEK_SET ); + int n; + CHECK_EQUAL( fscanf( file, "1 5%n", &n ), 0 ); + CHECK_EQUAL( n, 5 ); + CHECK_EQUAL( ftell( file ), 35 ); + } + { + // matching three characters, not matching whitespaces, and matching another three characters + // checking via %n + // should report six characters matched + fseek( file, 0, SEEK_SET ); + int n; + CHECK_EQUAL( fscanf( file, "123 456%n", &n ), 0 ); + CHECK_EQUAL( n, 6 ); + CHECK_EQUAL( ftell( file ), 6 ); + } + { + // matching a character, two '%' characters, and two whitespaces + // checking via %n + // should report five characters matched + fseek( file, 34, SEEK_SET ); + int n; + CHECK_EQUAL( fscanf( file, "5%%%% %n", &n ), 0 ); + CHECK_EQUAL( n, 5 ); + CHECK_EQUAL( ftell( file ), 39 ); + } + { + // seeking to last character in file, trying to match that char and a whitespace + // checking via %n + // should report one character matched and EOF + fseek( file, -1, SEEK_END ); + int n; + CHECK_EQUAL( fscanf( file, "0 %n", &n ), 0 ); + CHECK_EQUAL( n, 1 ); + CHECK_TRUE( feof( file ) ); + CHECK_FALSE( ferror( file ) ); + CHECK_EQUAL( ftell( file ), 40 ); + } + { + // seeking to end of file, trying to match a -1 + // checking via %n + // should report error, not executing %n + fseek( file, 0, SEEK_END ); + int n = -1; + CHECK_EQUAL( fscanf( file, "\377%n", &n ), -1 ); + CHECK_EQUAL( n, -1 ); + CHECK_TRUE( feof( file ) ); + CHECK_FALSE( ferror( file ) ); + CHECK_EQUAL( ftell( file ), 40 ); + } + + // ----------------------------------------------------------------------- + // Character matching ('%c') + // ----------------------------------------------------------------------- + { + // reading a char array of specified width, including zero bytes + // should report the characters read, no zero termination of the array + fseek( file, 10, SEEK_SET ); + char buffer[ 8 ]; + memset( buffer, '\177', 8 ); + CHECK_EQUAL( fscanf( file, "%7c", buffer ), 1 ); + CHECK_FALSE( memcmp( buffer, "1\0003-5+7\177", 8 ) ); + CHECK_EQUAL( ftell( file ), 17 ); + } + { + // reading a char array of unspecified width when positioned at -1 value + // should default to width one, read the -1 value, no zero termination of the array + fseek( file, 19, SEEK_SET ); + char buffer[ 2 ]; + memset( buffer, '\177', 2 ); + CHECK_EQUAL( fscanf( file, "%c", buffer ), 1 ); + CHECK_FALSE( memcmp( buffer, "\377\177", 2 ) ); + CHECK_EQUAL( ftell( file ), 20 ); + } + { + // reading a char array of specified width 1 when positioned at (non-space) whitespace + // should read the whitespace (literally), no zero termination of the array + fseek( file, 32, SEEK_SET ); + char buffer[ 2 ]; + memset( buffer, '\177', 2 ); + CHECK_EQUAL( fscanf( file, "%1c", buffer ), 1 ); + CHECK_FALSE( memcmp( buffer, "\011\177", 2 ) ); + CHECK_EQUAL( ftell( file ), 33 ); + } + { + // reading a char array of specified width 2 when positioned at last char of file + // should read the character, and report EOF + fseek( file, -1, SEEK_END ); + char buffer[ 2 ]; + memset( buffer, '\177', 2 ); + CHECK_EQUAL( fscanf( file, "%2c", buffer ), 1 ); + CHECK_FALSE( memcmp( buffer, "0\177", 2 ) ); + CHECK_TRUE( feof( file ) ); + CHECK_FALSE( ferror( file ) ); + CHECK_EQUAL( ftell( file ), 40 ); + } + { + // reading a char array of specified width 1 when positioned at last char of file + // should read the character, and NOT report EOF + fseek( file, -1, SEEK_END ); + char buffer[ 2 ]; + memset( buffer, '\177', 2 ); + CHECK_EQUAL( fscanf( file, "%1c", buffer ), 1 ); + CHECK_FALSE( memcmp( buffer, "0\177", 2 ) ); + CHECK_FALSE( feof( file ) ); + CHECK_EQUAL( ftell( file ), 40 ); + } + { + // reading a char array of specified width 1 when positioned at EOF + // should report input error before any conversion (-1) + fseek( file, 0, SEEK_END ); + char buffer[ 2 ]; + memset( buffer, '\177', 2 ); + CHECK_EQUAL( fscanf( file, "%1c", buffer ), -1 ); + CHECK_FALSE( memcmp( buffer, "\177\177", 2 ) ); + CHECK_TRUE( feof( file ) ); + CHECK_FALSE( ferror( file ) ); + CHECK_EQUAL( ftell( file ), 40 ); + } + + // ----------------------------------------------------------------------- + // Integer matching ('%d') + // ----------------------------------------------------------------------- + { + // reading a whitespace-terminated integer + fseek( file, 20, SEEK_SET ); + int i; + int n; + CHECK_EQUAL( fscanf( file, "%d%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 2 ); + CHECK_EQUAL( n, 1 ); + CHECK_EQUAL( ftell( file ), 21 ); + } + { + // reading a -1 terminated integer + fseek( file, 18, SEEK_SET ); + int i; + int n; + CHECK_EQUAL( fscanf( file, "%d%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 9 ); + CHECK_EQUAL( n, 1 ); + CHECK_EQUAL( ftell( file ), 19 ); + } + { + // reading a EOF terminated integer + fseek( file, -1, SEEK_END ); + int i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%d%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 1 ); + CHECK_EQUAL( ftell( file ), 40 ); + } + { + // trying to read an integer when positioned at whitespace + // should skip whitespaces + fseek( file, 32, SEEK_SET ); + int i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%d%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 5 ); + CHECK_EQUAL( n, 3 ); + CHECK_EQUAL( ftell( file ), 35 ); + } + { + // trying to read an integer when positioned at -1 value + // should report matching failure + fseek( file, 19, SEEK_SET ); + int i = 0; + int n = -1; + CHECK_EQUAL( fscanf( file, "%d%n", &i, &n ), 0 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, -1 ); + CHECK_EQUAL( ftell( file ), 19 ); + } + { + // trying to read an integer when positioned at EOF + // should report reading failure + fseek( file, 0, SEEK_END ); + int i = 0; + int n = -1; + CHECK_EQUAL( fscanf( file, "%d%n", &i, &n ), -1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, -1 ); + CHECK_EQUAL( ftell( file ), 40 ); + } + { + // reading a '-'-prefixed integer + fseek( file, 13, SEEK_SET ); + int i; + int n; + CHECK_EQUAL( fscanf( file, "%d%n", &i, &n ), 1 ); + CHECK_EQUAL( i, -5 ); + CHECK_EQUAL( n, 2 ); + CHECK_EQUAL( ftell( file ), 15 ); + } + { + // reading a '+'-prefixed integer + fseek( file, 15, SEEK_SET ); + int i; + int n; + CHECK_EQUAL( fscanf( file, "%d%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 7 ); + CHECK_EQUAL( n, 2 ); + CHECK_EQUAL( ftell( file ), 17 ); + } + + fclose( file ); + remove( "tmpfile" ); +} + +// decimal integer matches +void suite_two() +{ + FILE * file; + if ( ( file = fopen( "tmpfile", "wb+" ) ) == NULL ) + { + puts( "Failed to open tmpfile for writing." ); + return; + } + fprintf( file, "-0 +0 -128 +127 +255 -32768 +32767 +65535\n" ); + fprintf( file, "-2147483648 +2147483647 +4294967295\n" ); + fprintf( file, "-9223372036854775808 +9223372036854775807 +18446744073709551615\n" ); + CHECK_EQUAL( ftell( file ), 142 ); + { + // reading 0, d + fseek( file, 1, SEEK_SET ); + signed char i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%hhd%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 1 ); + CHECK_EQUAL( ftell( file ), 2 ); + } + { + // reading -0, d + fseek( file, 0, SEEK_SET ); + signed char i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%hhd%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 2 ); + CHECK_EQUAL( ftell( file ), 2 ); + } + { + // reading +0, d + fseek( file, 3, SEEK_SET ); + signed char i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%hhd%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 2 ); + CHECK_EQUAL( ftell( file ), 5 ); + } + { + // reading -128, d + fseek( file, 6, SEEK_SET ); + signed char i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%hhd%n", &i, &n ), 1 ); + CHECK_EQUAL( i, -128 ); + CHECK_EQUAL( n, 4 ); + CHECK_EQUAL( ftell( file ), 10 ); + } + { + // reading 127, d + fseek( file, 12, SEEK_SET ); + signed char i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%hhd%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 127 ); + CHECK_EQUAL( n, 3 ); + CHECK_EQUAL( ftell( file ), 15 ); + } + { + // reading +127, d + fseek( file, 11, SEEK_SET ); + signed char i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%hhd%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 127 ); + CHECK_EQUAL( n, 4 ); + CHECK_EQUAL( ftell( file ), 15 ); + } + { + // reading 0, u + fseek( file, 1, SEEK_SET ); + unsigned char i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%hhu%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 1 ); + CHECK_EQUAL( ftell( file ), 2 ); + } + { + // reading -0, u + fseek( file, 0, SEEK_SET ); + unsigned char i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%hhu%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 2 ); + CHECK_EQUAL( ftell( file ), 2 ); + } + { + // reading +0, u + fseek( file, 3, SEEK_SET ); + unsigned char i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%hhu%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 2 ); + CHECK_EQUAL( ftell( file ), 5 ); + } + { + // reading 127, u + fseek( file, 12, SEEK_SET ); + unsigned char i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%hhu%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 127 ); + CHECK_EQUAL( n, 3 ); + CHECK_EQUAL( ftell( file ), 15 ); + } + { + // reading +127, u + fseek( file, 11, SEEK_SET ); + unsigned char i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%hhu%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 127 ); + CHECK_EQUAL( n, 4 ); + CHECK_EQUAL( ftell( file ), 15 ); + } + { + // reading 255, u + fseek( file, 17, SEEK_SET ); + unsigned char i = 0; + int n; + CHECK_EQUAL( fscanf( file, "%hhu%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 255 ); + CHECK_EQUAL( n, 3 ); + CHECK_EQUAL( ftell( file ), 20 ); + } + { + // reading +255, u + fseek( file, 16, SEEK_SET ); + unsigned char i = 0; + int n; + CHECK_EQUAL( fscanf( file, "%hhu%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 255 ); + CHECK_EQUAL( n, 4 ); + CHECK_EQUAL( ftell( file ), 20 ); + } + { + // reading 0, i + fseek( file, 1, SEEK_SET ); + signed char i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%hhi%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 1 ); + CHECK_EQUAL( ftell( file ), 2 ); + } + { + // reading -0, i + fseek( file, 0, SEEK_SET ); + signed char i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%hhi%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 2 ); + CHECK_EQUAL( ftell( file ), 2 ); + } + { + // reading +0, i + fseek( file, 3, SEEK_SET ); + signed char i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%hhi%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 2 ); + CHECK_EQUAL( ftell( file ), 5 ); + } + { + // reading -128, i + fseek( file, 6, SEEK_SET ); + signed char i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%hhi%n", &i, &n ), 1 ); + CHECK_EQUAL( i, -128 ); + CHECK_EQUAL( n, 4 ); + CHECK_EQUAL( ftell( file ), 10 ); + } + { + // reading 127, i + fseek( file, 12, SEEK_SET ); + signed char i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%hhi%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 127 ); + CHECK_EQUAL( n, 3 ); + CHECK_EQUAL( ftell( file ), 15 ); + } + { + // reading +127, i + fseek( file, 11, SEEK_SET ); + signed char i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%hhi%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 127 ); + CHECK_EQUAL( n, 4 ); + CHECK_EQUAL( ftell( file ), 15 ); + } + { + // reading 0, d + fseek( file, 1, SEEK_SET ); + signed short i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%hd%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 1 ); + CHECK_EQUAL( ftell( file ), 2 ); + } + { + // reading -0, d + fseek( file, 0, SEEK_SET ); + signed short i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%hd%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 2 ); + CHECK_EQUAL( ftell( file ), 2 ); + } + { + // reading +0, d + fseek( file, 3, SEEK_SET ); + signed short i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%hd%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 2 ); + CHECK_EQUAL( ftell( file ), 5 ); + } + { + // reading -32768, d + fseek( file, 21, SEEK_SET ); + signed short i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%hd%n", &i, &n ), 1 ); + CHECK_EQUAL( i, -32768 ); + CHECK_EQUAL( n, 6 ); + CHECK_EQUAL( ftell( file ), 27 ); + } + { + // reading 32767, d + fseek( file, 29, SEEK_SET ); + signed short i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%hd%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 32767 ); + CHECK_EQUAL( n, 5 ); + CHECK_EQUAL( ftell( file ), 34 ); + } + { + // reading +32767, d + fseek( file, 28, SEEK_SET ); + signed short i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%hd%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 32767 ); + CHECK_EQUAL( n, 6 ); + CHECK_EQUAL( ftell( file ), 34 ); + } + { + // reading 0, u + fseek( file, 1, SEEK_SET ); + unsigned short i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%hu%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 1 ); + CHECK_EQUAL( ftell( file ), 2 ); + } + { + // reading -0, u + fseek( file, 0, SEEK_SET ); + unsigned short i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%hu%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 2 ); + CHECK_EQUAL( ftell( file ), 2 ); + } + { + // reading +0, u + fseek( file, 3, SEEK_SET ); + unsigned short i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%hu%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 2 ); + CHECK_EQUAL( ftell( file ), 5 ); + } + { + // reading 32767, u + fseek( file, 29, SEEK_SET ); + unsigned short i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%hu%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 32767 ); + CHECK_EQUAL( n, 5 ); + CHECK_EQUAL( ftell( file ), 34 ); + } + { + // reading +32767, u + fseek( file, 28, SEEK_SET ); + unsigned short i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%hu%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 32767 ); + CHECK_EQUAL( n, 6 ); + CHECK_EQUAL( ftell( file ), 34 ); + } + { + // reading 65535, u + fseek( file, 36, SEEK_SET ); + unsigned short i = 0; + int n; + CHECK_EQUAL( fscanf( file, "%hu%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 65535 ); + CHECK_EQUAL( n, 5 ); + CHECK_EQUAL( ftell( file ), 41 ); + } + { + // reading +65535, u + fseek( file, 35, SEEK_SET ); + unsigned short i = 0; + int n; + CHECK_EQUAL( fscanf( file, "%hu%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 65535 ); + CHECK_EQUAL( n, 6 ); + CHECK_EQUAL( ftell( file ), 41 ); + } + { + // reading 0, i + fseek( file, 1, SEEK_SET ); + signed short i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%hi%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 1 ); + CHECK_EQUAL( ftell( file ), 2 ); + } + { + // reading -0, i + fseek( file, 0, SEEK_SET ); + signed short i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%hi%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 2 ); + CHECK_EQUAL( ftell( file ), 2 ); + } + { + // reading +0, i + fseek( file, 3, SEEK_SET ); + signed short i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%hi%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 2 ); + CHECK_EQUAL( ftell( file ), 5 ); + } + { + // reading -32768, i + fseek( file, 21, SEEK_SET ); + signed short i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%hi%n", &i, &n ), 1 ); + CHECK_EQUAL( i, -32768 ); + CHECK_EQUAL( n, 6 ); + CHECK_EQUAL( ftell( file ), 27 ); + } + { + // reading 32767, i + fseek( file, 29, SEEK_SET ); + signed short i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%hi%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 32767 ); + CHECK_EQUAL( n, 5 ); + CHECK_EQUAL( ftell( file ), 34 ); + } + { + // reading +32767, i + fseek( file, 28, SEEK_SET ); + signed short i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%hi%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 32767 ); + CHECK_EQUAL( n, 6 ); + CHECK_EQUAL( ftell( file ), 34 ); + } + { + // reading 0, d + fseek( file, 1, SEEK_SET ); + signed int i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%d%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 1 ); + CHECK_EQUAL( ftell( file ), 2 ); + } + { + // reading -0, d + fseek( file, 0, SEEK_SET ); + signed int i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%d%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 2 ); + CHECK_EQUAL( ftell( file ), 2 ); + } + { + // reading +0, d + fseek( file, 3, SEEK_SET ); + signed int i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%d%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 2 ); + CHECK_EQUAL( ftell( file ), 5 ); + } + { + // reading -2147483648, d + fseek( file, 42, SEEK_SET ); + signed int i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%d%n", &i, &n ), 1 ); + CHECK_EQUAL( i, -2147483648 ); + CHECK_EQUAL( n, 11 ); + CHECK_EQUAL( ftell( file ), 53 ); + } + { + // reading 2147483647, d + fseek( file, 55, SEEK_SET ); + signed int i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%d%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 2147483647 ); + CHECK_EQUAL( n, 10 ); + CHECK_EQUAL( ftell( file ), 65 ); + } + { + // reading +2147483647, d + fseek( file, 54, SEEK_SET ); + signed int i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%d%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 2147483647 ); + CHECK_EQUAL( n, 11 ); + CHECK_EQUAL( ftell( file ), 65 ); + } + { + // reading 0, u + fseek( file, 1, SEEK_SET ); + unsigned int i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%u%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 1 ); + CHECK_EQUAL( ftell( file ), 2 ); + } + { + // reading -0, u + fseek( file, 0, SEEK_SET ); + unsigned int i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%u%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 2 ); + CHECK_EQUAL( ftell( file ), 2 ); + } + { + // reading +0, u + fseek( file, 3, SEEK_SET ); + unsigned int i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%u%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 2 ); + CHECK_EQUAL( ftell( file ), 5 ); + } + { + // reading 2147483647, u + fseek( file, 55, SEEK_SET ); + unsigned int i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%u%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 2147483647 ); + CHECK_EQUAL( n, 10 ); + CHECK_EQUAL( ftell( file ), 65 ); + } + { + // reading +2147483647, u + fseek( file, 54, SEEK_SET ); + unsigned int i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%u%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 2147483647 ); + CHECK_EQUAL( n, 11 ); + CHECK_EQUAL( ftell( file ), 65 ); + } + { + // reading 4294967295, u + fseek( file, 67, SEEK_SET ); + unsigned int i = 0; + int n; + CHECK_EQUAL( fscanf( file, "%u%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, 4294967295, unsigned int, "%u" ); + CHECK_EQUAL( n, 10 ); + CHECK_EQUAL( ftell( file ), 77 ); + } + { + // reading +4294967295, u + fseek( file, 66, SEEK_SET ); + unsigned int i = 0; + int n; + CHECK_EQUAL( fscanf( file, "%u%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, 4294967295, unsigned int, "%u" ); + CHECK_EQUAL( n, 11 ); + CHECK_EQUAL( ftell( file ), 77 ); + } + { + // reading 0, i + fseek( file, 1, SEEK_SET ); + signed int i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%i%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 1 ); + CHECK_EQUAL( ftell( file ), 2 ); + } + { + // reading -0, i + fseek( file, 0, SEEK_SET ); + signed int i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%i%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 2 ); + CHECK_EQUAL( ftell( file ), 2 ); + } + { + // reading +0, i + fseek( file, 3, SEEK_SET ); + signed int i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%i%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 2 ); + CHECK_EQUAL( ftell( file ), 5 ); + } + { + // reading -2147483648, i + fseek( file, 42, SEEK_SET ); + signed int i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%i%n", &i, &n ), 1 ); + CHECK_EQUAL( i, -2147483648 ); + CHECK_EQUAL( n, 11 ); + CHECK_EQUAL( ftell( file ), 53 ); + } + { + // reading 2147483647, i + fseek( file, 55, SEEK_SET ); + signed int i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%i%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 2147483647 ); + CHECK_EQUAL( n, 10 ); + CHECK_EQUAL( ftell( file ), 65 ); + } + { + // reading +2147483647, i + fseek( file, 54, SEEK_SET ); + signed int i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%i%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 2147483647 ); + CHECK_EQUAL( n, 11 ); + CHECK_EQUAL( ftell( file ), 65 ); + } + { + // reading 0, d + fseek( file, 1, SEEK_SET ); + signed long i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%ld%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0l ); + CHECK_EQUAL( n, 1 ); + CHECK_EQUAL( ftell( file ), 2 ); + } + { + // reading -0, d + fseek( file, 0, SEEK_SET ); + signed long i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%ld%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0l ); + CHECK_EQUAL( n, 2 ); + CHECK_EQUAL( ftell( file ), 2 ); + } + { + // reading +0, d + fseek( file, 3, SEEK_SET ); + signed long i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%ld%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0l ); + CHECK_EQUAL( n, 2 ); + CHECK_EQUAL( ftell( file ), 5 ); + } + { + // reading -2147483648, d + fseek( file, 42, SEEK_SET ); + signed long i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%ld%n", &i, &n ), 1 ); + CHECK_EQUAL( i, -2147483648l ); + CHECK_EQUAL( n, 11 ); + CHECK_EQUAL( ftell( file ), 53 ); + } + { + // reading 2147483647, d + fseek( file, 55, SEEK_SET ); + signed long i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%ld%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 2147483647l ); + CHECK_EQUAL( n, 10 ); + CHECK_EQUAL( ftell( file ), 65 ); + } + { + // reading +2147483647, d + fseek( file, 54, SEEK_SET ); + signed long i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%ld%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 2147483647l ); + CHECK_EQUAL( n, 11 ); + CHECK_EQUAL( ftell( file ), 65 ); + } + { + // reading 0, u + fseek( file, 1, SEEK_SET ); + unsigned long i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%lu%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0ul ); + CHECK_EQUAL( n, 1 ); + CHECK_EQUAL( ftell( file ), 2 ); + } + { + // reading -0, u + fseek( file, 0, SEEK_SET ); + unsigned long i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%lu%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0ul ); + CHECK_EQUAL( n, 2 ); + CHECK_EQUAL( ftell( file ), 2 ); + } + { + // reading +0, u + fseek( file, 3, SEEK_SET ); + unsigned long i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%lu%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0ul ); + CHECK_EQUAL( n, 2 ); + CHECK_EQUAL( ftell( file ), 5 ); + } + { + // reading 2147483647, u + fseek( file, 55, SEEK_SET ); + unsigned long i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%lu%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 2147483647ul ); + CHECK_EQUAL( n, 10 ); + CHECK_EQUAL( ftell( file ), 65 ); + } + { + // reading +2147483647, u + fseek( file, 54, SEEK_SET ); + unsigned long i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%lu%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 2147483647ul ); + CHECK_EQUAL( n, 11 ); + CHECK_EQUAL( ftell( file ), 65 ); + } + { + // reading 4294967295, u + fseek( file, 67, SEEK_SET ); + unsigned long i = 0; + int n; + CHECK_EQUAL( fscanf( file, "%lu%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, 4294967295ul, unsigned long, "%lu" ); + CHECK_EQUAL( n, 10 ); + CHECK_EQUAL( ftell( file ), 77 ); + } + { + // reading +4294967295, u + fseek( file, 66, SEEK_SET ); + unsigned long i = 0; + int n; + CHECK_EQUAL( fscanf( file, "%lu%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, 4294967295ul, unsigned long, "%lu" ); + CHECK_EQUAL( n, 11 ); + CHECK_EQUAL( ftell( file ), 77 ); + } + { + // reading 0, i + fseek( file, 1, SEEK_SET ); + signed long i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%li%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0l ); + CHECK_EQUAL( n, 1 ); + CHECK_EQUAL( ftell( file ), 2 ); + } + { + // reading -0, i + fseek( file, 0, SEEK_SET ); + signed long i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%li%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0l ); + CHECK_EQUAL( n, 2 ); + CHECK_EQUAL( ftell( file ), 2 ); + } + { + // reading +0, i + fseek( file, 3, SEEK_SET ); + signed long i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%li%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0l ); + CHECK_EQUAL( n, 2 ); + CHECK_EQUAL( ftell( file ), 5 ); + } + { + // reading -2147483648, i + fseek( file, 42, SEEK_SET ); + signed long i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%li%n", &i, &n ), 1 ); + CHECK_EQUAL( i, -2147483648l ); + CHECK_EQUAL( n, 11 ); + CHECK_EQUAL( ftell( file ), 53 ); + } + { + // reading 2147483647, i + fseek( file, 55, SEEK_SET ); + signed long i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%li%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 2147483647l ); + CHECK_EQUAL( n, 10 ); + CHECK_EQUAL( ftell( file ), 65 ); + } + { + // reading +2147483647, i + fseek( file, 54, SEEK_SET ); + signed long i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%li%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 2147483647l ); + CHECK_EQUAL( n, 11 ); + CHECK_EQUAL( ftell( file ), 65 ); + } + { + // reading 0, d + fseek( file, 1, SEEK_SET ); + signed long long i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%lld%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0ll ); + CHECK_EQUAL( n, 1 ); + CHECK_EQUAL( ftell( file ), 2 ); + } + { + // reading -0, d + fseek( file, 0, SEEK_SET ); + signed long long i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%lld%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0ll ); + CHECK_EQUAL( n, 2 ); + CHECK_EQUAL( ftell( file ), 2 ); + } + { + // reading +0, d + fseek( file, 3, SEEK_SET ); + signed long long i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%lld%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0ll ); + CHECK_EQUAL( n, 2 ); + CHECK_EQUAL( ftell( file ), 5 ); + } + { + // reading -9223372036854775808, d + fseek( file, 78, SEEK_SET ); + signed long long i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%lld%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, LLONG_MIN, signed long long, "%lld" ); // should be literal -9223372036854775808ll but GCC balks. + CHECK_EQUAL( i < 0ll, 1 ); + CHECK_EQUAL( n, 20 ); + CHECK_EQUAL( ftell( file ), 98 ); + } + { + // reading 9223372036854775807, d + fseek( file, 100, SEEK_SET ); + signed long long i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%lld%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, 9223372036854775807ll, signed long long, "%lld" ); + CHECK_EQUAL( n, 19 ); + CHECK_EQUAL( ftell( file ), 119 ); + } + { + // reading +9223372036854775807, d + fseek( file, 99, SEEK_SET ); + signed long long i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%lld%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, 9223372036854775807ll, signed long long, "%lld" ); + CHECK_EQUAL( n, 20 ); + CHECK_EQUAL( ftell( file ), 119 ); + } + { + // reading 0, u + fseek( file, 1, SEEK_SET ); + unsigned long long i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%llu%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0ull ); + CHECK_EQUAL( n, 1 ); + CHECK_EQUAL( ftell( file ), 2 ); + } + { + // reading -0, u + fseek( file, 0, SEEK_SET ); + unsigned long long i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%llu%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0ull ); + CHECK_EQUAL( n, 2 ); + CHECK_EQUAL( ftell( file ), 2 ); + } + { + // reading +0, u + fseek( file, 3, SEEK_SET ); + unsigned long long i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%llu%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0ull ); + CHECK_EQUAL( n, 2 ); + CHECK_EQUAL( ftell( file ), 5 ); + } + { + // reading 9223372036854775807, u + fseek( file, 100, SEEK_SET ); + unsigned long long i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%llu%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, 9223372036854775807ull, unsigned long long, "%llu" ); + CHECK_EQUAL( n, 19 ); + CHECK_EQUAL( ftell( file ), 119 ); + } + { + // reading +9223372036854775807, u + fseek( file, 99, SEEK_SET ); + unsigned long long i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%llu%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, 9223372036854775807ull, unsigned long long, "%llu" ); + CHECK_EQUAL( n, 20 ); + CHECK_EQUAL( ftell( file ), 119 ); + } + { + // reading 18446744073709551615, u + fseek( file, 121, SEEK_SET ); + unsigned long long i = 0; + int n; + CHECK_EQUAL( fscanf( file, "%llu%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, 18446744073709551615ull, unsigned long long, "%llu" ); + CHECK_EQUAL( n, 20 ); + CHECK_EQUAL( ftell( file ), 141 ); + } + { + // reading +18446744073709551615, u + fseek( file, 120, SEEK_SET ); + unsigned long long i = 0; + int n; + CHECK_EQUAL( fscanf( file, "%llu%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, 18446744073709551615ull, unsigned long long, "%llu" ); + CHECK_EQUAL( n, 21 ); + CHECK_EQUAL( ftell( file ), 141 ); + } + { + // reading 0, i + fseek( file, 1, SEEK_SET ); + signed long long i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%lli%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0ll ); + CHECK_EQUAL( n, 1 ); + CHECK_EQUAL( ftell( file ), 2 ); + } + { + // reading -0, i + fseek( file, 0, SEEK_SET ); + signed long long i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%lli%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0ll ); + CHECK_EQUAL( n, 2 ); + CHECK_EQUAL( ftell( file ), 2 ); + } + { + // reading +0, i + fseek( file, 3, SEEK_SET ); + signed long long i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%lli%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0ll ); + CHECK_EQUAL( n, 2 ); + CHECK_EQUAL( ftell( file ), 5 ); + } + { + // reading -9223372036854775808, i + fseek( file, 78, SEEK_SET ); + signed long long i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%lli%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, LLONG_MIN, signed long long, "%lli" ); // should be literal -9223372036854775808ll but GCC balks. + CHECK_EQUAL( i < 0ll, 1 ); + CHECK_EQUAL( n, 20 ); + CHECK_EQUAL( ftell( file ), 98 ); + } + { + // reading 9223372036854775807, i + fseek( file, 100, SEEK_SET ); + signed long long i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%lli%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, 9223372036854775807ll, signed long long, "%lli" ); + CHECK_EQUAL( n, 19 ); + CHECK_EQUAL( ftell( file ), 119 ); + } + { + // reading +9223372036854775807, i + fseek( file, 99, SEEK_SET ); + signed long long i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%lli%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, 9223372036854775807ll, signed long long, "%lli" ); + CHECK_EQUAL( n, 20 ); + CHECK_EQUAL( ftell( file ), 119 ); + } + + fclose( file ); + remove( "tmpfile" ); +} + +// hexadecimal integer matches +void suite_three() +{ + FILE * file; + if ( ( file = fopen( "tmpfile", "wb+" ) ) == NULL ) + { + puts( "Failed to open tmpfile for writing." ); + return; + } + fprintf( file, "-0x0 -0x000 -0x7f 0x80 0xff -0x7fff 0x8000 0xffff -0x7fffffff 0x80000000 0xffffffff\n" ); + fprintf( file, "-0x7fffffffffffffff 0x8000000000000000 0xffffffffffffffff -0x\n" ); + CHECK_EQUAL( ftell( file ), 146 ); + { + // reading 0, x + fseek( file, 3, SEEK_SET ); + unsigned char i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%hhx%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 1 ); + CHECK_EQUAL( ftell( file ), 4 ); + } + { + // reading -0x0, x + fseek( file, 0, SEEK_SET ); + unsigned char i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%hhx%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 4 ); + CHECK_EQUAL( ftell( file ), 4 ); + } + { + // reading -0x, x + fseek( file, -4, SEEK_END ); + unsigned char i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%hhx%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 3 ); + CHECK_EQUAL( ftell( file ), 145 ); + } + { + // reading 0x000, x + fseek( file, 5, SEEK_SET ); + unsigned char i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%hhx%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 6 ); + CHECK_EQUAL( ftell( file ), 11 ); + } + { + // reading 0x0, i + fseek( file, 0, SEEK_SET ); + signed char i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%hhi%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 4 ); + CHECK_EQUAL( ftell( file ), 4 ); + } + { + // reading 7f, x + fseek( file, 15, SEEK_SET ); + unsigned char i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%hhx%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 127 ); + CHECK_EQUAL( n, 2 ); + CHECK_EQUAL( ftell( file ), 17 ); + } + { + // reading -0x7f, x + fseek( file, 12, SEEK_SET ); + unsigned char i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%hhx%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, -127, unsigned char, "%hhu" ); + CHECK_EQUAL( n, 5 ); + CHECK_EQUAL( ftell( file ), 17 ); + } + { + // reading 0x80, i + fseek( file, 18, SEEK_SET ); + signed char i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%hhi%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, -128, signed char, "%hd" ); + CHECK_EQUAL( n, 4 ); + CHECK_EQUAL( ftell( file ), 22 ); + } + { + // reading ff, x + fseek( file, 25, SEEK_SET ); + unsigned char i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%hhx%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0xff ); + CHECK_EQUAL( n, 2 ); + CHECK_EQUAL( ftell( file ), 27 ); + } + { + // reading 0xff, x + fseek( file, 23, SEEK_SET ); + unsigned char i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%hhx%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 255 ); + CHECK_EQUAL( n, 4 ); + CHECK_EQUAL( ftell( file ), 27 ); + } + { + // reading 0xff, i + fseek( file, 23, SEEK_SET ); + signed char i = 0; + int n; + CHECK_EQUAL( fscanf( file, "%hhi%n", &i, &n ), 1 ); + CHECK_EQUAL( i, -1 ); + CHECK_EQUAL( n, 4 ); + CHECK_EQUAL( ftell( file ), 27 ); + } + { + // reading 0, x + fseek( file, 3, SEEK_SET ); + unsigned short i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%hx%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 1 ); + CHECK_EQUAL( ftell( file ), 4 ); + } + { + // reading -0x0, x + fseek( file, 0, SEEK_SET ); + unsigned short i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%hx%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 4 ); + CHECK_EQUAL( ftell( file ), 4 ); + } + { + // reading -0x, x + fseek( file, -4, SEEK_END ); + unsigned short i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%hx%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 3 ); + CHECK_EQUAL( ftell( file ), 145 ); + } + { + // reading 0x000, x + fseek( file, 5, SEEK_SET ); + unsigned short i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%hx%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 6 ); + CHECK_EQUAL( ftell( file ), 11 ); + } + { + // reading 0x0, i + fseek( file, 0, SEEK_SET ); + signed short i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%hi%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 4 ); + CHECK_EQUAL( ftell( file ), 4 ); + } + { + // reading 7fff, x + fseek( file, 31, SEEK_SET ); + unsigned short i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%hx%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 32767 ); + CHECK_EQUAL( n, 4 ); + CHECK_EQUAL( ftell( file ), 35 ); + } + { + // reading -0x7fff, x + fseek( file, 28, SEEK_SET ); + unsigned short i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%hx%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, -32767, unsigned short, "%hu" ); + CHECK_EQUAL( n, 7 ); + CHECK_EQUAL( ftell( file ), 35 ); + } + { + // reading 0x8000, i + fseek( file, 36, SEEK_SET ); + signed short i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%hi%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, -32768, signed short, "%hd" ); + CHECK_EQUAL( n, 6 ); + CHECK_EQUAL( ftell( file ), 42 ); + } + { + // reading ffff, x + fseek( file, 45, SEEK_SET ); + unsigned short i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%hx%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 65535 ); + CHECK_EQUAL( n, 4 ); + CHECK_EQUAL( ftell( file ), 49 ); + } + { + // reading 0xffff, x + fseek( file, 43, SEEK_SET ); + unsigned short i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%hx%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 65535 ); + CHECK_EQUAL( n, 6 ); + CHECK_EQUAL( ftell( file ), 49 ); + } + { + // reading 0xffff, i + fseek( file, 43, SEEK_SET ); + signed short i = 0; + int n; + CHECK_EQUAL( fscanf( file, "%hi%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, -1, signed short, "%hd" ); + CHECK_EQUAL( n, 6 ); + CHECK_EQUAL( ftell( file ), 49 ); + } + { + // reading 0, x + fseek( file, 3, SEEK_SET ); + unsigned int i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%x%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 1 ); + CHECK_EQUAL( ftell( file ), 4 ); + } + { + // reading -0x0, x + fseek( file, 0, SEEK_SET ); + unsigned int i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%x%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 4 ); + CHECK_EQUAL( ftell( file ), 4 ); + } + { + // reading -0x, x + fseek( file, -4, SEEK_END ); + unsigned int i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%x%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 3 ); + CHECK_EQUAL( ftell( file ), 145 ); + } + { + // reading 0x000, x + fseek( file, 5, SEEK_SET ); + unsigned int i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%x%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 6 ); + CHECK_EQUAL( ftell( file ), 11 ); + } + { + // reading 0x0, i + fseek( file, 0, SEEK_SET ); + signed int i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%i%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 4 ); + CHECK_EQUAL( ftell( file ), 4 ); + } + { + // reading 7fffffff, x + fseek( file, 53, SEEK_SET ); + unsigned int i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%x%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 2147483647 ); + CHECK_EQUAL( n, 8 ); + CHECK_EQUAL( ftell( file ), 61 ); + } + { + // reading -0x7fffffff, x + fseek( file, 50, SEEK_SET ); + unsigned int i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%x%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, -2147483647, unsigned int, "%u" ); + CHECK_EQUAL( n, 11 ); + CHECK_EQUAL( ftell( file ), 61 ); + } + { + // reading 0x80000000, i + fseek( file, 62, SEEK_SET ); + signed int i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%i%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, 2147483647, signed int, "%d" ); // NOT overflowing, see strtol() specs. + CHECK_EQUAL( n, 10 ); + CHECK_EQUAL( ftell( file ), 72 ); + } + { + // reading ffffffff, x + fseek( file, 75, SEEK_SET ); + unsigned int i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%x%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, 4294967295, unsigned int, "%d" ); + CHECK_EQUAL( n, 8 ); + CHECK_EQUAL( ftell( file ), 83 ); + } + { + // reading 0xffffffff, x + fseek( file, 73, SEEK_SET ); + unsigned int i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%x%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, 4294967295, unsigned int, "%d" ); + CHECK_EQUAL( n, 10 ); + CHECK_EQUAL( ftell( file ), 83 ); + } + { + // reading 0xffffffff, i + fseek( file, 73, SEEK_SET ); + signed int i = 0; + int n; + CHECK_EQUAL( fscanf( file, "%i%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, 2147483647, signed int, "%d" ); // NOT overflowing; see strtol() specs. + CHECK_EQUAL( n, 10 ); + CHECK_EQUAL( ftell( file ), 83 ); + } + fclose( file ); + remove( "tmpfile" ); +} + +// octal integer matches +void suite_four() +{ + FILE * file; + if ( ( file = fopen( "tmpfile", "wb+" ) ) == NULL ) + { + puts( "Failed to open tmpfile for writing." ); + return; + } + fprintf( file, "+0000 -0000 +0177 +0377 -0377 +077777 +0177777 -0177777\n" ); + fprintf( file, "+017777777777 +037777777777 -037777777777\n" ); + fprintf( file, "+0777777777777777777777 +01777777777777777777777\n" ); + fprintf( file, "-01777777777777777777777\n" ); + CHECK_EQUAL( ftell( file ), 172 ); + { + // reading 0, o + fseek( file, 4, SEEK_SET ); + unsigned char i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%hho%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0u ); + CHECK_EQUAL( n, 1 ); + CHECK_EQUAL( ftell( file ), 5 ); + } + { + // reading +0000, o + fseek( file, 0, SEEK_SET ); + unsigned char i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%hho%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0u ); + CHECK_EQUAL( n, 5 ); + CHECK_EQUAL( ftell( file ), 5 ); + } + { + // reading -0000, o + fseek( file, 6, SEEK_SET ); + unsigned char i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%hho%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0u ); + CHECK_EQUAL( n, 5 ); + CHECK_EQUAL( ftell( file ), 11 ); + } + { + // reading 0177, o + fseek( file, 13, SEEK_SET ); + unsigned char i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%hho%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 127u ); + CHECK_EQUAL( n, 4 ); + CHECK_EQUAL( ftell( file ), 17 ); + } + { + // reading +0177, o + fseek( file, 12, SEEK_SET ); + unsigned char i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%hho%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 127u ); + CHECK_EQUAL( n, 5 ); + CHECK_EQUAL( ftell( file ), 17 ); + } + { + // reading 0377, o + fseek( file, 19, SEEK_SET ); + unsigned char i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%hho%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, 255u, unsigned char, "%hhu" ); + CHECK_EQUAL( n, 4 ); + CHECK_EQUAL( ftell( file ), 23 ); + } + { + // reading +0377, o + fseek( file, 18, SEEK_SET ); + unsigned char i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%hho%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, 255u, unsigned char, "%hhu" ); + CHECK_EQUAL( n, 5 ); + CHECK_EQUAL( ftell( file ), 23 ); + } + { + // reading -0377, o + fseek( file, 24, SEEK_SET ); + unsigned char i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%hho%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, 1u, unsigned char, "%hhu" ); + CHECK_EQUAL( n, 5 ); + CHECK_EQUAL( ftell( file ), 29 ); + } + { + // reading 077777, o + fseek( file, 31, SEEK_SET ); + unsigned short i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%ho%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 32767u ); + CHECK_EQUAL( n, 6 ); + CHECK_EQUAL( ftell( file ), 37 ); + } + { + // reading +077777, o + fseek( file, 30, SEEK_SET ); + unsigned short i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%ho%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 32767u ); + CHECK_EQUAL( n, 7 ); + CHECK_EQUAL( ftell( file ), 37 ); + } + { + // reading 0177777, o + fseek( file, 39, SEEK_SET ); + unsigned short i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%ho%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, 65535u, unsigned short, "%hu" ); + CHECK_EQUAL( n, 7 ); + CHECK_EQUAL( ftell( file ), 46 ); + } + { + // reading +0177777, o + fseek( file, 38, SEEK_SET ); + unsigned short i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%ho%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, 65535u, unsigned short, "%hu" ); + CHECK_EQUAL( n, 8 ); + CHECK_EQUAL( ftell( file ), 46 ); + } + { + // reading -0177777, o + fseek( file, 47, SEEK_SET ); + unsigned short i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%ho%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, 1u, unsigned short, "%hu" ); + CHECK_EQUAL( n, 8 ); + CHECK_EQUAL( ftell( file ), 55 ); + } + { + // reading 017777777777, o + fseek( file, 57, SEEK_SET ); + unsigned int i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%o%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 2147483647u ); + CHECK_EQUAL( n, 12 ); + CHECK_EQUAL( ftell( file ), 69 ); + } + { + // reading +017777777777, o + fseek( file, 56, SEEK_SET ); + unsigned int i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%o%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 2147483647u ); + CHECK_EQUAL( n, 13 ); + CHECK_EQUAL( ftell( file ), 69 ); + } + { + // reading 037777777777, o + fseek( file, 71, SEEK_SET ); + unsigned int i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%o%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, 4294967295u, unsigned int, "%u" ); + CHECK_EQUAL( n, 12 ); + CHECK_EQUAL( ftell( file ), 83 ); + } + { + // reading +037777777777, o + fseek( file, 70, SEEK_SET ); + unsigned int i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%o%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, 4294967295u, unsigned int, "%u" ); + CHECK_EQUAL( n, 13 ); + CHECK_EQUAL( ftell( file ), 83 ); + } + { + // reading -037777777777, o + fseek( file, 84, SEEK_SET ); + unsigned int i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%o%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, 1u, unsigned int, "%u" ); + CHECK_EQUAL( n, 13 ); + CHECK_EQUAL( ftell( file ), 97 ); + } + { + // reading 017777777777, o + fseek( file, 57, SEEK_SET ); + unsigned long i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%lo%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 2147483647lu ); + CHECK_EQUAL( n, 12 ); + CHECK_EQUAL( ftell( file ), 69 ); + } + { + // reading +017777777777, o + fseek( file, 56, SEEK_SET ); + unsigned long i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%lo%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 2147483647lu ); + CHECK_EQUAL( n, 13 ); + CHECK_EQUAL( ftell( file ), 69 ); + } + { + // reading 037777777777, o + fseek( file, 71, SEEK_SET ); + unsigned long i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%lo%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, 4294967295lu, unsigned long, "%lu" ); + CHECK_EQUAL( n, 12 ); + CHECK_EQUAL( ftell( file ), 83 ); + } + { + // reading +037777777777, o + fseek( file, 70, SEEK_SET ); + unsigned long i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%lo%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, 4294967295lu, unsigned long, "%lu" ); + CHECK_EQUAL( n, 13 ); + CHECK_EQUAL( ftell( file ), 83 ); + } + { + // reading -037777777777, o + fseek( file, 84, SEEK_SET ); + unsigned long i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%lo%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, 1lu, unsigned long, "%lu" ); + CHECK_EQUAL( n, 13 ); + CHECK_EQUAL( ftell( file ), 97 ); + } + { + // reading 0777777777777777777777, o + fseek( file, 99, SEEK_SET ); + unsigned long long i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%llo%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, 9223372036854775807llu, unsigned long long, "%llu" ); + CHECK_EQUAL( n, 22 ); + CHECK_EQUAL( ftell( file ), 121 ); + } + { + // reading +0777777777777777777777, o + fseek( file, 98, SEEK_SET ); + unsigned long long i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%llo%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, 9223372036854775807llu, unsigned long long, "%llu" ); + CHECK_EQUAL( n, 23 ); + CHECK_EQUAL( ftell( file ), 121 ); + } + { + // reading 01777777777777777777777, o + fseek( file, 123, SEEK_SET ); + unsigned long long i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%llo%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, 18446744073709551615llu, unsigned long long, "%llu" ); + CHECK_EQUAL( n, 23 ); + CHECK_EQUAL( ftell( file ), 146 ); + } + { + // reading +01777777777777777777777, o + fseek( file, 122, SEEK_SET ); + unsigned long long i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%llo%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, 18446744073709551615llu, unsigned long long, "%llu" ); + CHECK_EQUAL( n, 24 ); + CHECK_EQUAL( ftell( file ), 146 ); + } + { + // reading -01777777777777777777777, o + fseek( file, 147, SEEK_SET ); + unsigned long long i = -1; + int n; + CHECK_EQUAL( fscanf( file, "%llo%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, 1llu, unsigned long long, "%llu" ); + CHECK_EQUAL( n, 24 ); + CHECK_EQUAL( ftell( file ), 171 ); + } + fclose( file ); + remove( "tmpfile" ); +} + +// string matches +void suite_five() +{ + int const BUFSIZE = 1000; + FILE * file; + if ( ( file = fopen( "tmpfile", "wb+" ) ) == NULL ) + { + puts( "Failed to open tmpfile for writing." ); + return; + } + fprintf( file, "abcdefgh-ijklmnop[qrs%%uvw]xyz" ); + CHECK_EQUAL( ftell( file ), 29 ); + char buffer[ BUFSIZE ]; + { + // reading abc + fseek( file, 0, SEEK_SET ); + memset( buffer, '\0', BUFSIZE ); + int n; + CHECK_EQUAL( fscanf( file, "%[abc]%n", buffer, &n ), 1 ); + CHECK_EQUAL( n, 3 ); + CHECK_FALSE( memcmp( buffer, "abc", n + 1 ) ); + CHECK_EQUAL( ftell( file ), 3 ); + } + { + // reading a-c + fseek( file, 0, SEEK_SET ); + memset( buffer, '\0', BUFSIZE ); + int n; + CHECK_EQUAL( fscanf( file, "%[a-c]%n", buffer, &n ), 1 ); + CHECK_EQUAL( n, 3 ); + CHECK_FALSE( memcmp( buffer, "abc", n + 1 ) ); + CHECK_EQUAL( ftell( file ), 3 ); + } + { + // reading a-h + fseek( file, 0, SEEK_SET ); + memset( buffer, '\0', BUFSIZE ); + int n; + CHECK_EQUAL( fscanf( file, "%[a-h]%n", buffer, &n ), 1 ); + CHECK_EQUAL( n, 8 ); + CHECK_FALSE( memcmp( buffer, "abcdefgh", n + 1 ) ); + CHECK_EQUAL( ftell( file ), 8 ); + } + { + // reading o-r, including [, seperate char + fseek( file, 15, SEEK_SET ); + memset( buffer, '\0', BUFSIZE ); + int n; + CHECK_EQUAL( fscanf( file, "%[[o-qr]%n", buffer, &n ), 1 ); + CHECK_EQUAL( n, 5 ); + CHECK_FALSE( memcmp( buffer, "op[qr", n + 1 ) ); + CHECK_EQUAL( ftell( file ), 20 ); + } + { + // reading v-y, including ], two groups + fseek( file, 23, SEEK_SET ); + memset( buffer, '\0', BUFSIZE ); + int n; + CHECK_EQUAL( fscanf( file, "%[]v-wx-y]%n", buffer, &n ), 1 ); + CHECK_EQUAL( n, 5 ); + CHECK_FALSE( memcmp( buffer, "vw]xy", n + 1 ) ); + CHECK_EQUAL( ftell( file ), 28 ); + } + { + // missing on first character + fseek( file, 0, SEEK_SET ); + memset( buffer, '\0', BUFSIZE ); + int n; + CHECK_EQUAL( fscanf( file, "%[b]%n", buffer, &n ), 0 ); + CHECK_FALSE( memcmp( buffer, "", 1 ) ); + CHECK_EQUAL( ftell( file ), 0 ); + } + { + // eof while reading, two groups + fseek( file, 27, SEEK_SET ); + memset( buffer, '\0', BUFSIZE ); + int n; + CHECK_EQUAL( fscanf( file, "%[a-zA-Z]%n", buffer, &n ), 1 ); + CHECK_EQUAL( n, 2 ); + CHECK_FALSE( memcmp( buffer, "yz", n + 1 ) ); + CHECK_TRUE( feof( file ) ); + CHECK_FALSE( ferror( file ) ); + CHECK_EQUAL( ftell( file ), 29 ); + } + { + // eof before reading + fseek( file, 29, SEEK_SET ); + memset( buffer, '\0', BUFSIZE ); + int n; + CHECK_EQUAL( fscanf( file, "%[a-z]%n", buffer, &n ), -1 ); + CHECK_FALSE( memcmp( buffer, "", 1 ) ); + CHECK_TRUE( feof( file ) ); + CHECK_FALSE( ferror( file ) ); + CHECK_EQUAL( ftell( file ), 29 ); + } + { + // negation - [^...] + fseek( file, 0, SEEK_SET ); + memset( buffer, '\0', BUFSIZE ); + int n; + CHECK_EQUAL( fscanf( file, "%[^d-f]%n", buffer, &n ), 1 ); + CHECK_EQUAL( n, 3 ); + CHECK_FALSE( memcmp( buffer, "abc", 4 ) ); + CHECK_EQUAL( ftell( file ), 3 ); + } + fclose( file ); + remove( "tmpfile" ); +} + +#if 0 char scanstring[] = " 1 23\00045\000\00067 "; void scantest( int testnr, FILE * fh, size_t position, char const * format, @@ -77,5 +2078,6 @@ int main( void ) return TEST_RESULTS; } +#endif #endif diff --git a/functions/stdio/sscanf.c b/functions/stdio/sscanf.c index 368ae53..b701108 100644 --- a/functions/stdio/sscanf.c +++ b/functions/stdio/sscanf.c @@ -13,9 +13,12 @@ int sscanf( const char * _PDCLIB_restrict s, const char * _PDCLIB_restrict format, ... ) { + int rc; va_list ap; va_start( ap, format ); - return vsscanf( s, format, ap ); + rc = vsscanf( s, format, ap ); + va_end( ap ); + return rc; } #endif @@ -23,10 +26,1577 @@ int sscanf( const char * _PDCLIB_restrict s, const char * _PDCLIB_restrict forma #ifdef TEST #include <_PDCLIB_test.h> -int main( void ) +#include +#include + +#define symbol2value( x ) #x +#define symbol2string( x ) symbol2value( x ) + +#define CHECK_TRUE( a ) do { if ( a == 0 ) { fprintf( stderr, "Unexpected failure in " symbol2string( __LINE__ ) ": '" #a "' evaluated to false.\n" ); rc += 1; } } while ( 0 ) +#define CHECK_FALSE( a ) do { if ( a != 0 ) { fprintf( stderr, "Unexpected failure in " symbol2string( __LINE__ ) ": '" #a "' evaluated to true.\n" ); rc += 1; } } while ( 0 ) +#define CHECK_EQUAL( a, b ) do { int x = a; int y = b; if ( x != y ) { fprintf( stderr, "Mismatch in " symbol2string( __LINE__ ) ": result is %d, expected %d.\n", x, y ); rc += 1; } } while ( 0 ) +#define CHECK_FEQUAL( a, b, T, F ) do { T x = a; T y = b; if ( x != y ) { fprintf( stderr, "Mismatch in " symbol2string( __LINE__ ) ": result is " F ", expected " F ".\n", x, y ); rc += 1; } } while ( 0 ) + +// literal matches, character matches, and basic integer matches +void suite_one( void ); +// decimal integer matches +void suite_two( void ); +// hexadecimal integer matches +void suite_three( void ); +// octal integer matches +void suite_four( void ); +// string matches +void suite_five( void ); + +int main() +{ + suite_one(); + suite_two(); + suite_three(); + suite_four(); + suite_five(); +} + +// literal matches, character matches, and basic integer matches +void suite_one() +{ + char const * string = "12345678901\0003-5+7\0009\3772 4 6 8 0\3771 \011 5%% 0"; + CHECK_EQUAL( string[39], '0' ); + + // ----------------------------------------------------------------------- + // Literal matching + // ----------------------------------------------------------------------- + { + // matching six characters literally + // checking via %n + // should report six characters read + int n; + CHECK_EQUAL( sscanf( string + 0, "123456%n", &n ), 0 ); + CHECK_EQUAL( n, 6 ); + } + { + // matching a character, three whitespace chars, and another character + // checking via %n + // should report five characters read + int n; + CHECK_EQUAL( sscanf( string + 30, "1 5%n", &n ), 0 ); + CHECK_EQUAL( n, 5 ); + } + { + // matching three characters, not matching whitespaces, and matching another three characters + // checking via %n + // should report six characters matched + int n; + CHECK_EQUAL( sscanf( string + 0, "123 456%n", &n ), 0 ); + CHECK_EQUAL( n, 6 ); + } + { + // matching a character, two '%' characters, and two whitespaces + // checking via %n + // should report five characters matched + int n; + CHECK_EQUAL( sscanf( string + 34, "5%%%% %n", &n ), 0 ); + CHECK_EQUAL( n, 5 ); + } + { + // seeking to last character in file, trying to match that char and a whitespace + // checking via %n + // should report one character matched and EOF + int n; + CHECK_EQUAL( sscanf( string + 39, "0 %n", &n ), 0 ); + CHECK_EQUAL( n, 1 ); + } + { + // seeking to end of file, trying to match a -1 + // checking via %n + // should report error, not executing %n + int n = -1; + CHECK_EQUAL( sscanf( string + 0, "\377%n", &n ), 0 ); + CHECK_EQUAL( n, -1 ); + } + + // ----------------------------------------------------------------------- + // Character matching ('%c') + // ----------------------------------------------------------------------- + { + // reading a char array of specified width, including zero bytes + // should report the characters read up to first zero + char buffer[ 8 ]; + memset( buffer, '\177', 8 ); + CHECK_EQUAL( sscanf( string + 10, "%7c", buffer ), 1 ); + CHECK_FALSE( memcmp( buffer, "1\177\177", 3 ) ); + } + { + // reading a char array of unspecified width when positioned at -1 value + // should default to width one, read the -1 value, no zero termination of the array + char buffer[ 2 ]; + memset( buffer, '\177', 2 ); + CHECK_EQUAL( sscanf( string + 19, "%c", buffer ), 1 ); + CHECK_FALSE( memcmp( buffer, "\377\177", 2 ) ); + } + { + // reading a char array of specified width 1 when positioned at (non-space) whitespace + // should read the whitespace (literally), no zero termination of the array + char buffer[ 2 ]; + memset( buffer, '\177', 2 ); + CHECK_EQUAL( sscanf( string + 32, "%1c", buffer ), 1 ); + CHECK_FALSE( memcmp( buffer, "\011\177", 2 ) ); + } + { + // reading a char array of specified width 2 when positioned at last char of file + // should read the character, and report EOF + char buffer[ 2 ]; + memset( buffer, '\177', 2 ); + CHECK_EQUAL( sscanf( string + 39, "%2c", buffer ), 1 ); + CHECK_FALSE( memcmp( buffer, "0\177", 2 ) ); + } + { + // reading a char array of specified width 1 when positioned at last char of file + // should read the character, and NOT report EOF + char buffer[ 2 ]; + memset( buffer, '\177', 2 ); + CHECK_EQUAL( sscanf( string + 39, "%1c", buffer ), 1 ); + CHECK_FALSE( memcmp( buffer, "0\177", 2 ) ); + } + { + // reading a char array of specified width 1 when positioned at EOF + // should report input error before any conversion (-1) + char buffer[ 2 ]; + memset( buffer, '\177', 2 ); + CHECK_EQUAL( sscanf( string + 40, "%1c", buffer ), -1 ); + CHECK_FALSE( memcmp( buffer, "\177\177", 2 ) ); + } + + // ----------------------------------------------------------------------- + // Integer matching ('%d') + // ----------------------------------------------------------------------- + { + // reading a whitespace-terminated integer + int i; + int n; + CHECK_EQUAL( sscanf( string + 20, "%d%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 2 ); + CHECK_EQUAL( n, 1 ); + } + { + // reading a -1 terminated integer + int i; + int n; + CHECK_EQUAL( sscanf( string + 18, "%d%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 9 ); + CHECK_EQUAL( n, 1 ); + } + { + // reading a EOF terminated integer + int i = -1; + int n; + CHECK_EQUAL( sscanf( string + 39, "%d%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 1 ); + } + { + // trying to read an integer when positioned at whitespace + // should skip whitespaces + int i = -1; + int n; + CHECK_EQUAL( sscanf( string + 32, "%d%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 5 ); + CHECK_EQUAL( n, 3 ); + } + { + // trying to read an integer when positioned at -1 value + // should report matching failure + int i = 0; + int n = -1; + CHECK_EQUAL( sscanf( string + 19, "%d%n", &i, &n ), 0 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, -1 ); + } + { + // trying to read an integer when positioned at EOF + // should report reading failure + int i = 0; + int n = -1; + CHECK_EQUAL( sscanf( string + 40, "%d%n", &i, &n ), -1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, -1 ); + } + { + // reading a '-'-prefixed integer + int i; + int n; + CHECK_EQUAL( sscanf( string + 13, "%d%n", &i, &n ), 1 ); + CHECK_EQUAL( i, -5 ); + CHECK_EQUAL( n, 2 ); + } + { + // reading a '+'-prefixed integer + int i; + int n; + CHECK_EQUAL( sscanf( string + 15, "%d%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 7 ); + CHECK_EQUAL( n, 2 ); + } +} + +// decimal integer matches +void suite_two() +{ + char const * string = "-0 +0 -128 +127 +255 -32768 +32767 +65535\n" + "-2147483648 +2147483647 +4294967295\n" + "-9223372036854775808 +9223372036854775807\n" + "+18446744073709551615\n"; + CHECK_EQUAL( string[141], '\n' ); + { + // reading 0, d + signed char i = -1; + int n; + CHECK_EQUAL( sscanf( string + 1, "%hhd%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 1 ); + } + { + // reading -0, d + signed char i = -1; + int n; + CHECK_EQUAL( sscanf( string + 0, "%hhd%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 2 ); + } + { + // reading +0, d + signed char i = -1; + int n; + CHECK_EQUAL( sscanf( string + 3, "%hhd%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 2 ); + } + { + // reading -128, d + signed char i = -1; + int n; + CHECK_EQUAL( sscanf( string + 6, "%hhd%n", &i, &n ), 1 ); + CHECK_EQUAL( i, -128 ); + CHECK_EQUAL( n, 4 ); + } + { + // reading 127, d + signed char i = -1; + int n; + CHECK_EQUAL( sscanf( string + 12, "%hhd%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 127 ); + CHECK_EQUAL( n, 3 ); + } + { + // reading +127, d + signed char i = -1; + int n; + CHECK_EQUAL( sscanf( string + 11, "%hhd%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 127 ); + CHECK_EQUAL( n, 4 ); + } + { + // reading 0, u + unsigned char i = -1; + int n; + CHECK_EQUAL( sscanf( string + 1, "%hhu%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 1 ); + } + { + // reading -0, u + unsigned char i = -1; + int n; + CHECK_EQUAL( sscanf( string + 0, "%hhu%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 2 ); + } + { + // reading +0, u + unsigned char i = -1; + int n; + CHECK_EQUAL( sscanf( string + 3, "%hhu%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 2 ); + } + { + // reading 127, u + unsigned char i = -1; + int n; + CHECK_EQUAL( sscanf( string + 12, "%hhu%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 127 ); + CHECK_EQUAL( n, 3 ); + } + { + // reading +127, u + unsigned char i = -1; + int n; + CHECK_EQUAL( sscanf( string + 11, "%hhu%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 127 ); + CHECK_EQUAL( n, 4 ); + } + { + // reading 255, u + unsigned char i = 0; + int n; + CHECK_EQUAL( sscanf( string + 17, "%hhu%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 255 ); + CHECK_EQUAL( n, 3 ); + } + { + // reading +255, u + unsigned char i = 0; + int n; + CHECK_EQUAL( sscanf( string + 16, "%hhu%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 255 ); + CHECK_EQUAL( n, 4 ); + } + { + // reading 0, i + signed char i = -1; + int n; + CHECK_EQUAL( sscanf( string + 1, "%hhi%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 1 ); + } + { + // reading -0, i + signed char i = -1; + int n; + CHECK_EQUAL( sscanf( string + 0, "%hhi%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 2 ); + } + { + // reading +0, i + signed char i = -1; + int n; + CHECK_EQUAL( sscanf( string + 3, "%hhi%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 2 ); + } + { + // reading -128, i + signed char i = -1; + int n; + CHECK_EQUAL( sscanf( string + 6, "%hhi%n", &i, &n ), 1 ); + CHECK_EQUAL( i, -128 ); + CHECK_EQUAL( n, 4 ); + } + { + // reading 127, i + signed char i = -1; + int n; + CHECK_EQUAL( sscanf( string + 12, "%hhi%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 127 ); + CHECK_EQUAL( n, 3 ); + } + { + // reading +127, i + signed char i = -1; + int n; + CHECK_EQUAL( sscanf( string + 11, "%hhi%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 127 ); + CHECK_EQUAL( n, 4 ); + } + { + // reading 0, d + signed short i = -1; + int n; + CHECK_EQUAL( sscanf( string + 1, "%hd%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 1 ); + } + { + // reading -0, d + signed short i = -1; + int n; + CHECK_EQUAL( sscanf( string + 0, "%hd%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 2 ); + } + { + // reading +0, d + signed short i = -1; + int n; + CHECK_EQUAL( sscanf( string + 3, "%hd%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 2 ); + } + { + // reading -32768, d + signed short i = -1; + int n; + CHECK_EQUAL( sscanf( string + 21, "%hd%n", &i, &n ), 1 ); + CHECK_EQUAL( i, -32768 ); + CHECK_EQUAL( n, 6 ); + } + { + // reading 32767, d + signed short i = -1; + int n; + CHECK_EQUAL( sscanf( string + 29, "%hd%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 32767 ); + CHECK_EQUAL( n, 5 ); + } + { + // reading +32767, d + signed short i = -1; + int n; + CHECK_EQUAL( sscanf( string + 28, "%hd%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 32767 ); + CHECK_EQUAL( n, 6 ); + } + { + // reading 0, u + unsigned short i = -1; + int n; + CHECK_EQUAL( sscanf( string + 1, "%hu%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 1 ); + } + { + // reading -0, u + unsigned short i = -1; + int n; + CHECK_EQUAL( sscanf( string + 0, "%hu%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 2 ); + } + { + // reading +0, u + unsigned short i = -1; + int n; + CHECK_EQUAL( sscanf( string + 3, "%hu%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 2 ); + } + { + // reading 32767, u + unsigned short i = -1; + int n; + CHECK_EQUAL( sscanf( string + 29, "%hu%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 32767 ); + CHECK_EQUAL( n, 5 ); + } + { + // reading +32767, u + unsigned short i = -1; + int n; + CHECK_EQUAL( sscanf( string + 28, "%hu%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 32767 ); + CHECK_EQUAL( n, 6 ); + } + { + // reading 65535, u + unsigned short i = 0; + int n; + CHECK_EQUAL( sscanf( string + 36, "%hu%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 65535 ); + CHECK_EQUAL( n, 5 ); + } + { + // reading +65535, u + unsigned short i = 0; + int n; + CHECK_EQUAL( sscanf( string + 35, "%hu%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 65535 ); + CHECK_EQUAL( n, 6 ); + } + { + // reading 0, i + signed short i = -1; + int n; + CHECK_EQUAL( sscanf( string + 1, "%hi%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 1 ); + } + { + // reading -0, i + signed short i = -1; + int n; + CHECK_EQUAL( sscanf( string + 0, "%hi%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 2 ); + } + { + // reading +0, i + signed short i = -1; + int n; + CHECK_EQUAL( sscanf( string + 3, "%hi%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 2 ); + } + { + // reading -32768, i + signed short i = -1; + int n; + CHECK_EQUAL( sscanf( string + 21, "%hi%n", &i, &n ), 1 ); + CHECK_EQUAL( i, -32768 ); + CHECK_EQUAL( n, 6 ); + } + { + // reading 32767, i + signed short i = -1; + int n; + CHECK_EQUAL( sscanf( string + 29, "%hi%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 32767 ); + CHECK_EQUAL( n, 5 ); + } + { + // reading +32767, i + signed short i = -1; + int n; + CHECK_EQUAL( sscanf( string + 28, "%hi%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 32767 ); + CHECK_EQUAL( n, 6 ); + } + { + // reading 0, d + signed int i = -1; + int n; + CHECK_EQUAL( sscanf( string + 1, "%d%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 1 ); + } + { + // reading -0, d + signed int i = -1; + int n; + CHECK_EQUAL( sscanf( string + 0, "%d%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 2 ); + } + { + // reading +0, d + signed int i = -1; + int n; + CHECK_EQUAL( sscanf( string + 3, "%d%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 2 ); + } + { + // reading -2147483648, d + signed int i = -1; + int n; + CHECK_EQUAL( sscanf( string + 42, "%d%n", &i, &n ), 1 ); + CHECK_EQUAL( i, -2147483648 ); + CHECK_EQUAL( n, 11 ); + } + { + // reading 2147483647, d + signed int i = -1; + int n; + CHECK_EQUAL( sscanf( string + 55, "%d%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 2147483647 ); + CHECK_EQUAL( n, 10 ); + } + { + // reading +2147483647, d + signed int i = -1; + int n; + CHECK_EQUAL( sscanf( string + 54, "%d%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 2147483647 ); + CHECK_EQUAL( n, 11 ); + } + { + // reading 0, u + unsigned int i = -1; + int n; + CHECK_EQUAL( sscanf( string + 1, "%u%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 1 ); + } + { + // reading -0, u + unsigned int i = -1; + int n; + CHECK_EQUAL( sscanf( string + 0, "%u%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 2 ); + } + { + // reading +0, u + unsigned int i = -1; + int n; + CHECK_EQUAL( sscanf( string + 3, "%u%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 2 ); + } + { + // reading 2147483647, u + unsigned int i = -1; + int n; + CHECK_EQUAL( sscanf( string + 55, "%u%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 2147483647 ); + CHECK_EQUAL( n, 10 ); + } + { + // reading +2147483647, u + unsigned int i = -1; + int n; + CHECK_EQUAL( sscanf( string + 54, "%u%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 2147483647 ); + CHECK_EQUAL( n, 11 ); + } + { + // reading 4294967295, u + unsigned int i = 0; + int n; + CHECK_EQUAL( sscanf( string + 67, "%u%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, 4294967295, unsigned int, "%u" ); + CHECK_EQUAL( n, 10 ); + } + { + // reading +4294967295, u + unsigned int i = 0; + int n; + CHECK_EQUAL( sscanf( string + 66, "%u%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, 4294967295, unsigned int, "%u" ); + CHECK_EQUAL( n, 11 ); + } + { + // reading 0, i + signed int i = -1; + int n; + CHECK_EQUAL( sscanf( string + 1, "%i%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 1 ); + } + { + // reading -0, i + signed int i = -1; + int n; + CHECK_EQUAL( sscanf( string + 0, "%i%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 2 ); + } + { + // reading +0, i + signed int i = -1; + int n; + CHECK_EQUAL( sscanf( string + 3, "%i%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 2 ); + } + { + // reading -2147483648, i + signed int i = -1; + int n; + CHECK_EQUAL( sscanf( string + 42, "%i%n", &i, &n ), 1 ); + CHECK_EQUAL( i, -2147483648 ); + CHECK_EQUAL( n, 11 ); + } + { + // reading 2147483647, i + signed int i = -1; + int n; + CHECK_EQUAL( sscanf( string + 55, "%i%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 2147483647 ); + CHECK_EQUAL( n, 10 ); + } + { + // reading +2147483647, i + signed int i = -1; + int n; + CHECK_EQUAL( sscanf( string + 54, "%i%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 2147483647 ); + CHECK_EQUAL( n, 11 ); + } + { + // reading 0, d + signed long i = -1; + int n; + CHECK_EQUAL( sscanf( string + 1, "%ld%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0l ); + CHECK_EQUAL( n, 1 ); + } + { + // reading -0, d + signed long i = -1; + int n; + CHECK_EQUAL( sscanf( string + 0, "%ld%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0l ); + CHECK_EQUAL( n, 2 ); + } + { + // reading +0, d + signed long i = -1; + int n; + CHECK_EQUAL( sscanf( string + 3, "%ld%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0l ); + CHECK_EQUAL( n, 2 ); + } + { + // reading -2147483648, d + signed long i = -1; + int n; + CHECK_EQUAL( sscanf( string + 42, "%ld%n", &i, &n ), 1 ); + CHECK_EQUAL( i, -2147483648l ); + CHECK_EQUAL( n, 11 ); + } + { + // reading 2147483647, d + signed long i = -1; + int n; + CHECK_EQUAL( sscanf( string + 55, "%ld%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 2147483647l ); + CHECK_EQUAL( n, 10 ); + } + { + // reading +2147483647, d + signed long i = -1; + int n; + CHECK_EQUAL( sscanf( string + 54, "%ld%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 2147483647l ); + CHECK_EQUAL( n, 11 ); + } + { + // reading 0, u + unsigned long i = -1; + int n; + CHECK_EQUAL( sscanf( string + 1, "%lu%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0ul ); + CHECK_EQUAL( n, 1 ); + } + { + // reading -0, u + unsigned long i = -1; + int n; + CHECK_EQUAL( sscanf( string + 0, "%lu%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0ul ); + CHECK_EQUAL( n, 2 ); + } + { + // reading +0, u + unsigned long i = -1; + int n; + CHECK_EQUAL( sscanf( string + 3, "%lu%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0ul ); + CHECK_EQUAL( n, 2 ); + } + { + // reading 2147483647, u + unsigned long i = -1; + int n; + CHECK_EQUAL( sscanf( string + 55, "%lu%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 2147483647ul ); + CHECK_EQUAL( n, 10 ); + } + { + // reading +2147483647, u + unsigned long i = -1; + int n; + CHECK_EQUAL( sscanf( string + 54, "%lu%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 2147483647ul ); + CHECK_EQUAL( n, 11 ); + } + { + // reading 4294967295, u + unsigned long i = 0; + int n; + CHECK_EQUAL( sscanf( string + 67, "%lu%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, 4294967295ul, unsigned long, "%lu" ); + CHECK_EQUAL( n, 10 ); + } + { + // reading +4294967295, u + unsigned long i = 0; + int n; + CHECK_EQUAL( sscanf( string + 66, "%lu%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, 4294967295ul, unsigned long, "%lu" ); + CHECK_EQUAL( n, 11 ); + } + { + // reading 0, i + signed long i = -1; + int n; + CHECK_EQUAL( sscanf( string + 1, "%li%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0l ); + CHECK_EQUAL( n, 1 ); + } + { + // reading -0, i + signed long i = -1; + int n; + CHECK_EQUAL( sscanf( string + 0, "%li%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0l ); + CHECK_EQUAL( n, 2 ); + } + { + // reading +0, i + signed long i = -1; + int n; + CHECK_EQUAL( sscanf( string + 3, "%li%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0l ); + CHECK_EQUAL( n, 2 ); + } + { + // reading -2147483648, i + signed long i = -1; + int n; + CHECK_EQUAL( sscanf( string + 42, "%li%n", &i, &n ), 1 ); + CHECK_EQUAL( i, -2147483648l ); + CHECK_EQUAL( n, 11 ); + } + { + // reading 2147483647, i + signed long i = -1; + int n; + CHECK_EQUAL( sscanf( string + 55, "%li%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 2147483647l ); + CHECK_EQUAL( n, 10 ); + } + { + // reading +2147483647, i + signed long i = -1; + int n; + CHECK_EQUAL( sscanf( string + 54, "%li%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 2147483647l ); + CHECK_EQUAL( n, 11 ); + } + { + // reading 0, d + signed long long i = -1; + int n; + CHECK_EQUAL( sscanf( string + 1, "%lld%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0ll ); + CHECK_EQUAL( n, 1 ); + } + { + // reading -0, d + signed long long i = -1; + int n; + CHECK_EQUAL( sscanf( string + 0, "%lld%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0ll ); + CHECK_EQUAL( n, 2 ); + } + { + // reading +0, d + signed long long i = -1; + int n; + CHECK_EQUAL( sscanf( string + 3, "%lld%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0ll ); + CHECK_EQUAL( n, 2 ); + } + { + // reading -9223372036854775808, d + signed long long i = -1; + int n; + CHECK_EQUAL( sscanf( string + 78, "%lld%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, LLONG_MIN, signed long long, "%lld" ); // should be literal -9223372036854775808ll but GCC balks. + CHECK_EQUAL( i < 0ll, 1 ); + CHECK_EQUAL( n, 20 ); + } + { + // reading 9223372036854775807, d + signed long long i = -1; + int n; + CHECK_EQUAL( sscanf( string + 100, "%lld%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, 9223372036854775807ll, signed long long, "%lld" ); + CHECK_EQUAL( n, 19 ); + } + { + // reading +9223372036854775807, d + signed long long i = -1; + int n; + CHECK_EQUAL( sscanf( string + 99, "%lld%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, 9223372036854775807ll, signed long long, "%lld" ); + CHECK_EQUAL( n, 20 ); + } + { + // reading 0, u + unsigned long long i = -1; + int n; + CHECK_EQUAL( sscanf( string + 1, "%llu%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0ull ); + CHECK_EQUAL( n, 1 ); + } + { + // reading -0, u + unsigned long long i = -1; + int n; + CHECK_EQUAL( sscanf( string + 0, "%llu%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0ull ); + CHECK_EQUAL( n, 2 ); + } + { + // reading +0, u + unsigned long long i = -1; + int n; + CHECK_EQUAL( sscanf( string + 3, "%llu%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0ull ); + CHECK_EQUAL( n, 2 ); + } + { + // reading 9223372036854775807, u + unsigned long long i = -1; + int n; + CHECK_EQUAL( sscanf( string + 100, "%llu%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, 9223372036854775807ull, unsigned long long, "%llu" ); + CHECK_EQUAL( n, 19 ); + } + { + // reading +9223372036854775807, u + unsigned long long i = -1; + int n; + CHECK_EQUAL( sscanf( string + 99, "%llu%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, 9223372036854775807ull, unsigned long long, "%llu" ); + CHECK_EQUAL( n, 20 ); + } + { + // reading 18446744073709551615, u + unsigned long long i = 0; + int n; + CHECK_EQUAL( sscanf( string + 121, "%llu%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, 18446744073709551615ull, unsigned long long, "%llu" ); + CHECK_EQUAL( n, 20 ); + } + { + // reading +18446744073709551615, u + unsigned long long i = 0; + int n; + CHECK_EQUAL( sscanf( string + 120, "%llu%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, 18446744073709551615ull, unsigned long long, "%llu" ); + CHECK_EQUAL( n, 21 ); + } + { + // reading 0, i + signed long long i = -1; + int n; + CHECK_EQUAL( sscanf( string + 1, "%lli%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0ll ); + CHECK_EQUAL( n, 1 ); + } + { + // reading -0, i + signed long long i = -1; + int n; + CHECK_EQUAL( sscanf( string + 0, "%lli%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0ll ); + CHECK_EQUAL( n, 2 ); + } + { + // reading +0, i + signed long long i = -1; + int n; + CHECK_EQUAL( sscanf( string + 3, "%lli%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0ll ); + CHECK_EQUAL( n, 2 ); + } + { + // reading -9223372036854775808, i + signed long long i = -1; + int n; + CHECK_EQUAL( sscanf( string + 78, "%lli%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, LLONG_MIN, signed long long, "%lli" ); // should be literal -9223372036854775808ll but GCC balks. + CHECK_EQUAL( i < 0ll, 1 ); + CHECK_EQUAL( n, 20 ); + } + { + // reading 9223372036854775807, i + signed long long i = -1; + int n; + CHECK_EQUAL( sscanf( string + 100, "%lli%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, 9223372036854775807ll, signed long long, "%lli" ); + CHECK_EQUAL( n, 19 ); + } + { + // reading +9223372036854775807, i + signed long long i = -1; + int n; + CHECK_EQUAL( sscanf( string + 99, "%lli%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, 9223372036854775807ll, signed long long, "%lli" ); + CHECK_EQUAL( n, 20 ); + } +} + +// hexadecimal integer matches +void suite_three() +{ + char const * string = "-0x0 -0x000 -0x7f 0x80 0xff -0x7fff 0x8000\n" + "0xffff -0x7fffffff 0x80000000 0xffffffff\n" + "-0x7fffffffffffffff 0x8000000000000000\n" + "0xffffffffffffffff -0x\n"; + CHECK_EQUAL( string[145], '\n' ); + { + // reading 0, x + unsigned char i = -1; + int n; + CHECK_EQUAL( sscanf( string + 3, "%hhx%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 1 ); + } + { + // reading -0x0, x + unsigned char i = -1; + int n; + CHECK_EQUAL( sscanf( string + 0, "%hhx%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 4 ); + } + { + // reading -0x, x + unsigned char i = -1; + int n; + CHECK_EQUAL( sscanf( string + 142, "%hhx%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 3 ); + } + { + // reading 0x000, x + unsigned char i = -1; + int n; + CHECK_EQUAL( sscanf( string + 5, "%hhx%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 6 ); + } + { + // reading 0x0, i + signed char i = -1; + int n; + CHECK_EQUAL( sscanf( string + 0, "%hhi%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 4 ); + } + { + // reading 7f, x + unsigned char i = -1; + int n; + CHECK_EQUAL( sscanf( string + 15, "%hhx%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 127 ); + CHECK_EQUAL( n, 2 ); + } + { + // reading -0x7f, x + unsigned char i = -1; + int n; + CHECK_EQUAL( sscanf( string + 12, "%hhx%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, -127, unsigned char, "%hhu" ); + CHECK_EQUAL( n, 5 ); + } + { + // reading 0x80, i + signed char i = -1; + int n; + CHECK_EQUAL( sscanf( string + 18, "%hhi%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, -128, signed char, "%hd" ); + CHECK_EQUAL( n, 4 ); + } + { + // reading ff, x + unsigned char i = -1; + int n; + CHECK_EQUAL( sscanf( string + 25, "%hhx%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0xff ); + CHECK_EQUAL( n, 2 ); + } + { + // reading 0xff, x + unsigned char i = -1; + int n; + CHECK_EQUAL( sscanf( string + 23, "%hhx%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 255 ); + CHECK_EQUAL( n, 4 ); + } + { + // reading 0xff, i + signed char i = 0; + int n; + CHECK_EQUAL( sscanf( string + 23, "%hhi%n", &i, &n ), 1 ); + CHECK_EQUAL( i, -1 ); + CHECK_EQUAL( n, 4 ); + } + { + // reading 0, x + unsigned short i = -1; + int n; + CHECK_EQUAL( sscanf( string + 3, "%hx%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 1 ); + } + { + // reading -0x0, x + unsigned short i = -1; + int n; + CHECK_EQUAL( sscanf( string + 0, "%hx%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 4 ); + } + { + // reading -0x, x + unsigned short i = -1; + int n; + CHECK_EQUAL( sscanf( string + 142, "%hx%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 3 ); + } + { + // reading 0x000, x + unsigned short i = -1; + int n; + CHECK_EQUAL( sscanf( string + 5, "%hx%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 6 ); + } + { + // reading 0x0, i + signed short i = -1; + int n; + CHECK_EQUAL( sscanf( string + 0, "%hi%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 4 ); + } + { + // reading 7fff, x + unsigned short i = -1; + int n; + CHECK_EQUAL( sscanf( string + 31, "%hx%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 32767 ); + CHECK_EQUAL( n, 4 ); + } + { + // reading -0x7fff, x + unsigned short i = -1; + int n; + CHECK_EQUAL( sscanf( string + 28, "%hx%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, -32767, unsigned short, "%hu" ); + CHECK_EQUAL( n, 7 ); + } + { + // reading 0x8000, i + signed short i = -1; + int n; + CHECK_EQUAL( sscanf( string + 36, "%hi%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, -32768, signed short, "%hd" ); + CHECK_EQUAL( n, 6 ); + } + { + // reading ffff, x + unsigned short i = -1; + int n; + CHECK_EQUAL( sscanf( string + 45, "%hx%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 65535 ); + CHECK_EQUAL( n, 4 ); + } + { + // reading 0xffff, x + unsigned short i = -1; + int n; + CHECK_EQUAL( sscanf( string + 43, "%hx%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 65535 ); + CHECK_EQUAL( n, 6 ); + } + { + // reading 0xffff, i + signed short i = 0; + int n; + CHECK_EQUAL( sscanf( string + 43, "%hi%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, -1, signed short, "%hd" ); + CHECK_EQUAL( n, 6 ); + } + { + // reading 0, x + unsigned int i = -1; + int n; + CHECK_EQUAL( sscanf( string + 3, "%x%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 1 ); + } + { + // reading -0x0, x + unsigned int i = -1; + int n; + CHECK_EQUAL( sscanf( string + 0, "%x%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 4 ); + } + { + // reading -0x, x + unsigned int i = -1; + int n; + CHECK_EQUAL( sscanf( string + 142, "%x%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 3 ); + } + { + // reading 0x000, x + unsigned int i = -1; + int n; + CHECK_EQUAL( sscanf( string + 5, "%x%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 6 ); + } + { + // reading 0x0, i + signed int i = -1; + int n; + CHECK_EQUAL( sscanf( string + 0, "%i%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0 ); + CHECK_EQUAL( n, 4 ); + } + { + // reading 7fffffff, x + unsigned int i = -1; + int n; + CHECK_EQUAL( sscanf( string + 53, "%x%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 2147483647 ); + CHECK_EQUAL( n, 8 ); + } + { + // reading -0x7fffffff, x + unsigned int i = -1; + int n; + CHECK_EQUAL( sscanf( string + 50, "%x%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, -2147483647, unsigned int, "%u" ); + CHECK_EQUAL( n, 11 ); + } + { + // reading 0x80000000, i + signed int i = -1; + int n; + CHECK_EQUAL( sscanf( string + 62, "%i%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, 2147483647, signed int, "%d" ); // NOT overflowing, see strtol() specs. + CHECK_EQUAL( n, 10 ); + } + { + // reading ffffffff, x + unsigned int i = -1; + int n; + CHECK_EQUAL( sscanf( string + 75, "%x%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, 4294967295, unsigned int, "%d" ); + CHECK_EQUAL( n, 8 ); + } + { + // reading 0xffffffff, x + unsigned int i = -1; + int n; + CHECK_EQUAL( sscanf( string + 73, "%x%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, 4294967295, unsigned int, "%d" ); + CHECK_EQUAL( n, 10 ); + } + { + // reading 0xffffffff, i + signed int i = 0; + int n; + CHECK_EQUAL( sscanf( string + 73, "%i%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, 2147483647, signed int, "%d" ); // NOT overflowing; see strtol() specs. + CHECK_EQUAL( n, 10 ); + } +} + +// octal integer matches +void suite_four() +{ + char const * string = "+0000 -0000 +0177 +0377 -0377 +077777 +0177777\n" + "-0177777 +017777777777 +037777777777\n" + "-037777777777 +0777777777777777777777\n" + "+01777777777777777777777\n" + "-01777777777777777777777\n"; + CHECK_EQUAL( string[171], '\n' ); + { + // reading 0, o + unsigned char i = -1; + int n; + CHECK_EQUAL( sscanf( string + 4, "%hho%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0u ); + CHECK_EQUAL( n, 1 ); + } + { + // reading +0000, o + unsigned char i = -1; + int n; + CHECK_EQUAL( sscanf( string + 0, "%hho%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0u ); + CHECK_EQUAL( n, 5 ); + } + { + // reading -0000, o + unsigned char i = -1; + int n; + CHECK_EQUAL( sscanf( string + 6, "%hho%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 0u ); + CHECK_EQUAL( n, 5 ); + } + { + // reading 0177, o + unsigned char i = -1; + int n; + CHECK_EQUAL( sscanf( string + 13, "%hho%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 127u ); + CHECK_EQUAL( n, 4 ); + } + { + // reading +0177, o + unsigned char i = -1; + int n; + CHECK_EQUAL( sscanf( string + 12, "%hho%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 127u ); + CHECK_EQUAL( n, 5 ); + } + { + // reading 0377, o + unsigned char i = -1; + int n; + CHECK_EQUAL( sscanf( string + 19, "%hho%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, 255u, unsigned char, "%hhu" ); + CHECK_EQUAL( n, 4 ); + } + { + // reading +0377, o + unsigned char i = -1; + int n; + CHECK_EQUAL( sscanf( string + 18, "%hho%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, 255u, unsigned char, "%hhu" ); + CHECK_EQUAL( n, 5 ); + } + { + // reading -0377, o + unsigned char i = -1; + int n; + CHECK_EQUAL( sscanf( string + 24, "%hho%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, 1u, unsigned char, "%hhu" ); + CHECK_EQUAL( n, 5 ); + } + { + // reading 077777, o + unsigned short i = -1; + int n; + CHECK_EQUAL( sscanf( string + 31, "%ho%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 32767u ); + CHECK_EQUAL( n, 6 ); + } + { + // reading +077777, o + unsigned short i = -1; + int n; + CHECK_EQUAL( sscanf( string + 30, "%ho%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 32767u ); + CHECK_EQUAL( n, 7 ); + } + { + // reading 0177777, o + unsigned short i = -1; + int n; + CHECK_EQUAL( sscanf( string + 39, "%ho%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, 65535u, unsigned short, "%hu" ); + CHECK_EQUAL( n, 7 ); + } + { + // reading +0177777, o + unsigned short i = -1; + int n; + CHECK_EQUAL( sscanf( string + 38, "%ho%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, 65535u, unsigned short, "%hu" ); + CHECK_EQUAL( n, 8 ); + } + { + // reading -0177777, o + unsigned short i = -1; + int n; + CHECK_EQUAL( sscanf( string + 47, "%ho%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, 1u, unsigned short, "%hu" ); + CHECK_EQUAL( n, 8 ); + } + { + // reading 017777777777, o + unsigned int i = -1; + int n; + CHECK_EQUAL( sscanf( string + 57, "%o%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 2147483647u ); + CHECK_EQUAL( n, 12 ); + } + { + // reading +017777777777, o + unsigned int i = -1; + int n; + CHECK_EQUAL( sscanf( string + 56, "%o%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 2147483647u ); + CHECK_EQUAL( n, 13 ); + } + { + // reading 037777777777, o + unsigned int i = -1; + int n; + CHECK_EQUAL( sscanf( string + 71, "%o%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, 4294967295u, unsigned int, "%u" ); + CHECK_EQUAL( n, 12 ); + } + { + // reading +037777777777, o + unsigned int i = -1; + int n; + CHECK_EQUAL( sscanf( string + 70, "%o%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, 4294967295u, unsigned int, "%u" ); + CHECK_EQUAL( n, 13 ); + } + { + // reading -037777777777, o + unsigned int i = -1; + int n; + CHECK_EQUAL( sscanf( string + 84, "%o%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, 1u, unsigned int, "%u" ); + CHECK_EQUAL( n, 13 ); + } + { + // reading 017777777777, o + unsigned long i = -1; + int n; + CHECK_EQUAL( sscanf( string + 57, "%lo%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 2147483647lu ); + CHECK_EQUAL( n, 12 ); + } + { + // reading +017777777777, o + unsigned long i = -1; + int n; + CHECK_EQUAL( sscanf( string + 56, "%lo%n", &i, &n ), 1 ); + CHECK_EQUAL( i, 2147483647lu ); + CHECK_EQUAL( n, 13 ); + } + { + // reading 037777777777, o + unsigned long i = -1; + int n; + CHECK_EQUAL( sscanf( string + 71, "%lo%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, 4294967295lu, unsigned long, "%lu" ); + CHECK_EQUAL( n, 12 ); + } + { + // reading +037777777777, o + unsigned long i = -1; + int n; + CHECK_EQUAL( sscanf( string + 70, "%lo%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, 4294967295lu, unsigned long, "%lu" ); + CHECK_EQUAL( n, 13 ); + } + { + // reading -037777777777, o + unsigned long i = -1; + int n; + CHECK_EQUAL( sscanf( string + 84, "%lo%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, 1lu, unsigned long, "%lu" ); + CHECK_EQUAL( n, 13 ); + } + { + // reading 0777777777777777777777, o + unsigned long long i = -1; + int n; + CHECK_EQUAL( sscanf( string + 99, "%llo%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, 9223372036854775807llu, unsigned long long, "%llu" ); + CHECK_EQUAL( n, 22 ); + } + { + // reading +0777777777777777777777, o + unsigned long long i = -1; + int n; + CHECK_EQUAL( sscanf( string + 98, "%llo%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, 9223372036854775807llu, unsigned long long, "%llu" ); + CHECK_EQUAL( n, 23 ); + } + { + // reading 01777777777777777777777, o + unsigned long long i = -1; + int n; + CHECK_EQUAL( sscanf( string + 123, "%llo%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, 18446744073709551615llu, unsigned long long, "%llu" ); + CHECK_EQUAL( n, 23 ); + } + { + // reading +01777777777777777777777, o + unsigned long long i = -1; + int n; + CHECK_EQUAL( sscanf( string + 122, "%llo%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, 18446744073709551615llu, unsigned long long, "%llu" ); + CHECK_EQUAL( n, 24 ); + } + { + // reading -01777777777777777777777, o + unsigned long long i = -1; + int n; + CHECK_EQUAL( sscanf( string + 147, "%llo%n", &i, &n ), 1 ); + CHECK_FEQUAL( i, 1llu, unsigned long long, "%llu" ); + CHECK_EQUAL( n, 24 ); + } +} + +// string matches +void suite_five() { - TESTCASE( NO_TESTDRIVER ); - return TEST_RESULTS; + char const * string = "abcdefgh-ijklmnop[qrs%uvw]xyz"; + CHECK_EQUAL( string[28], 'z' ); + size_t const BUFSIZE = 29; + char buffer[ BUFSIZE ]; + { + // reading abc + memset( buffer, '\0', BUFSIZE ); + int n; + CHECK_EQUAL( sscanf( string + 0, "%[abc]%n", buffer, &n ), 1 ); + CHECK_EQUAL( n, 3 ); + CHECK_FALSE( memcmp( buffer, "abc", n + 1 ) ); + } + { + // reading a-c + memset( buffer, '\0', BUFSIZE ); + int n; + CHECK_EQUAL( sscanf( string + 0, "%[a-c]%n", buffer, &n ), 1 ); + CHECK_EQUAL( n, 3 ); + CHECK_FALSE( memcmp( buffer, "abc", n + 1 ) ); + } + { + // reading a-h + memset( buffer, '\0', BUFSIZE ); + int n; + CHECK_EQUAL( sscanf( string + 0, "%[a-h]%n", buffer, &n ), 1 ); + CHECK_EQUAL( n, 8 ); + CHECK_FALSE( memcmp( buffer, "abcdefgh", n + 1 ) ); + } + { + // reading o-r, including [, seperate char + memset( buffer, '\0', BUFSIZE ); + int n; + CHECK_EQUAL( sscanf( string + 15, "%[[o-qr]%n", buffer, &n ), 1 ); + CHECK_EQUAL( n, 5 ); + CHECK_FALSE( memcmp( buffer, "op[qr", n + 1 ) ); + } + { + // reading v-y, including ], two groups + memset( buffer, '\0', BUFSIZE ); + int n; + CHECK_EQUAL( sscanf( string + 23, "%[]v-wx-y]%n", buffer, &n ), 1 ); + CHECK_EQUAL( n, 5 ); + CHECK_FALSE( memcmp( buffer, "vw]xy", n + 1 ) ); + } + { + // missing on first character + memset( buffer, '\0', BUFSIZE ); + int n; + CHECK_EQUAL( sscanf( string + 0, "%[b]%n", buffer, &n ), 0 ); + CHECK_FALSE( memcmp( buffer, "", 1 ) ); + } + { + // eof while reading, two groups + memset( buffer, '\0', BUFSIZE ); + int n; + CHECK_EQUAL( sscanf( string + 27, "%[a-zA-Z]%n", buffer, &n ), 1 ); + CHECK_EQUAL( n, 2 ); + CHECK_FALSE( memcmp( buffer, "yz", n + 1 ) ); + } + { + // eof before reading + memset( buffer, '\0', BUFSIZE ); + int n; + CHECK_EQUAL( sscanf( string + 29, "%[a-z]%n", buffer, &n ), -1 ); + CHECK_FALSE( memcmp( buffer, "", 1 ) ); + } + { + // negation - [^...] + memset( buffer, '\0', BUFSIZE ); + int n; + CHECK_EQUAL( sscanf( string + 0, "%[^d-f]%n", buffer, &n ), 1 ); + CHECK_EQUAL( n, 3 ); + CHECK_FALSE( memcmp( buffer, "abc", 4 ) ); + } } #endif diff --git a/functions/stdio/vfscanf.c b/functions/stdio/vfscanf.c index 0667c99..f5b1f3f 100644 --- a/functions/stdio/vfscanf.c +++ b/functions/stdio/vfscanf.c @@ -25,6 +25,7 @@ int vfscanf( FILE * _PDCLIB_restrict stream, const char * _PDCLIB_restrict forma status.prec = 0; status.stream = stream; va_copy( status.arg, arg ); + // FIXME: This whole shebang should operate on STREAM, not S... while ( *format != '\0' ) { const char * rc; diff --git a/functions/stdio/vsscanf.c b/functions/stdio/vsscanf.c index f33b8c4..fd35889 100644 --- a/functions/stdio/vsscanf.c +++ b/functions/stdio/vsscanf.c @@ -59,9 +59,14 @@ int vsscanf( const char * _PDCLIB_restrict s, const char * _PDCLIB_restrict form } else { - /* NULL return code indicates matching error */ + /* NULL return code indicates input error */ if ( rc == NULL ) { + if ( status.n == 0 ) + { + /* input error before any conversion returns EOF */ + status.n = EOF; + } break; } /* Continue parsing after conversion specifier */ diff --git a/internals/_PDCLIB_int.h b/internals/_PDCLIB_int.h index 9019f72..a950cf2 100644 --- a/internals/_PDCLIB_int.h +++ b/internals/_PDCLIB_int.h @@ -319,14 +319,14 @@ struct _PDCLIB_status_t _PDCLIB_int_fast32_t flags; /* flags and length modifiers */ _PDCLIB_size_t n; /* print: maximum characters to be written */ /* scan: number matched conversion specifiers */ - _PDCLIB_size_t i; /* number of characters already written */ - _PDCLIB_size_t this; /* output chars in the current conversion */ - char * s; /* print: target buffer */ - /* scan: source string */ - _PDCLIB_size_t width; /* width of current field */ - _PDCLIB_size_t prec; /* precision of current field */ - struct _PDCLIB_file_t * stream;/* for to-stream output */ - _PDCLIB_va_list arg; /* argument stack passed to the printf function */ + _PDCLIB_size_t i; /* number of characters read/written */ + _PDCLIB_size_t this; /* chars read/written in the CURRENT conversion */ + char * s; /* *sprintf(): target buffer */ + /* *sscanf(): source string */ + _PDCLIB_size_t width; /* specified field width */ + _PDCLIB_size_t prec; /* specified field precision */ + struct _PDCLIB_file_t * stream; /* *fprintf() / *fscanf() stream */ + _PDCLIB_va_list arg; /* argument stack */ }; /* -------------------------------------------------------------------------- */ @@ -356,9 +356,11 @@ const char * _PDCLIB_print( const char * spec, struct _PDCLIB_status_t * status /* The worker for all scanf() type of functions. The pointer spec should point to the introducing '%' of a conversion specifier. The status structure is to be that of the current scanf() function, of which the member stream will be - preserved, n, i, and s will be updated; and all others will be trashed by the - function. - Returns a pointer to the first character not parsed as conversion specifier. + preserved; n, i, and s will be updated; and all others will be trashed by + the function. + Returns a pointer to the first character not parsed as conversion specifier, + or NULL in case of error. + FIXME: Should distinguish between matching and input error */ const char * _PDCLIB_scan( const char * spec, struct _PDCLIB_status_t * status ); -- 2.40.0