From: solar Date: Thu, 6 Jul 2006 05:17:17 +0000 (+0000) Subject: Improved testdrivers. X-Git-Tag: v0.5~148 X-Git-Url: https://pd.if.org/git/?p=pdclib;a=commitdiff_plain;h=d9e48b611b63bcfc55727463cb9d9d0e87a7a405 Improved testdrivers. --- diff --git a/functions/_PDCLIB/filemode.c b/functions/_PDCLIB/filemode.c new file mode 100644 index 0000000..460cc6e --- /dev/null +++ b/functions/_PDCLIB/filemode.c @@ -0,0 +1,88 @@ +/* $Id$ */ + +/* _PDCLIB_filemode( const char * ) + + This file is part of the Public Domain C Library (PDCLib). + Permission is granted to use, modify, and / or redistribute at will. +*/ + +#ifndef REGTEST + +#include + +/* Helper function that parses the C-style mode string passed to fopen() into + the PDCLib flags FREAD, FWRITE, FAPPEND, FRW (read-write) and FBIN (binary + mode). +*/ +unsigned int _PDCLIB_filemode( char const * const mode ) +{ + int rc = 0; + switch ( mode[0] ) + { + case 'r': + rc |= _PDCLIB_FREAD; + break; + case 'w': + rc |= _PDCLIB_FWRITE; + break; + case 'a': + rc |= _PDCLIB_FAPPEND; + break; + default: + /* Other than read, write, or append - invalid */ + return 0; + } + for ( size_t i = 1; i < 4; ++i ) + { + switch ( mode[i] ) + { + case '+': + if ( rc & _PDCLIB_FRW ) return 0; /* Duplicates are invalid */ + rc |= _PDCLIB_FRW; + break; + case 'b': + if ( rc & _PDCLIB_FBIN ) return 0; /* Duplicates are invalid */ + rc |= _PDCLIB_FBIN; + break; + case '\0': + /* End of mode */ + return rc; + default: + /* Other than read/write or binary - invalid. */ + return 0; + } + } + /* Longer than three chars - invalid. */ + return 0; +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ +#ifndef REGTEST + TESTCASE( _PDCLIB_filemode( "r" ) == _PDCLIB_FREAD ); + TESTCASE( _PDCLIB_filemode( "w" ) == _PDCLIB_FWRITE ); + TESTCASE( _PDCLIB_filemode( "a" ) == _PDCLIB_FAPPEND ); + TESTCASE( _PDCLIB_filemode( "r+" ) == ( _PDCLIB_FREAD | _PDCLIB_FRW ) ); + TESTCASE( _PDCLIB_filemode( "w+" ) == ( _PDCLIB_FWRITE | _PDCLIB_FRW ) ); + TESTCASE( _PDCLIB_filemode( "a+" ) == ( _PDCLIB_FAPPEND | _PDCLIB_FRW ) ); + TESTCASE( _PDCLIB_filemode( "rb" ) == ( _PDCLIB_FREAD | _PDCLIB_FBIN ) ); + TESTCASE( _PDCLIB_filemode( "wb" ) == ( _PDCLIB_FWRITE | _PDCLIB_FBIN ) ); + TESTCASE( _PDCLIB_filemode( "ab" ) == ( _PDCLIB_FAPPEND | _PDCLIB_FBIN ) ); + TESTCASE( _PDCLIB_filemode( "r+b" ) == ( _PDCLIB_FREAD | _PDCLIB_FRW | _PDCLIB_FBIN ) ); + TESTCASE( _PDCLIB_filemode( "w+b" ) == ( _PDCLIB_FWRITE | _PDCLIB_FRW | _PDCLIB_FBIN ) ); + TESTCASE( _PDCLIB_filemode( "a+b" ) == ( _PDCLIB_FAPPEND | _PDCLIB_FRW | _PDCLIB_FBIN ) ); + TESTCASE( _PDCLIB_filemode( "rb+" ) == ( _PDCLIB_FREAD | _PDCLIB_FRW | _PDCLIB_FBIN ) ); + TESTCASE( _PDCLIB_filemode( "wb+" ) == ( _PDCLIB_FWRITE | _PDCLIB_FRW | _PDCLIB_FBIN ) ); + TESTCASE( _PDCLIB_filemode( "ab+" ) == ( _PDCLIB_FAPPEND | _PDCLIB_FRW | _PDCLIB_FBIN ) ); +#else + puts( " NOTEST fopen() test driver is PDCLib-specific." ); +#endif + return TEST_RESULTS; +} + +#endif diff --git a/functions/stdio/fclose.c b/functions/stdio/fclose.c index 9ddff44..0b42330 100644 --- a/functions/stdio/fclose.c +++ b/functions/stdio/fclose.c @@ -29,12 +29,13 @@ int fclose( struct _PDCLIB_file_t * stream ) _PDCLIB_close( stream->handle ); if ( previous != NULL ) { - previous->next = current->next; + previous->next = stream->next; } else { - _PDCLIB_filelist = current->next; + _PDCLIB_filelist = stream->next; } + free( stream ); return 0; } previous = current; diff --git a/functions/stdio/fopen.c b/functions/stdio/fopen.c index 96fdcc1..14ce3a8 100644 --- a/functions/stdio/fopen.c +++ b/functions/stdio/fopen.c @@ -15,52 +15,6 @@ /* FIXME: This approach is a possible attack vector. */ struct _PDCLIB_file_t * _PDCLIB_filelist = NULL; -/* Helper function that parses the C-style mode string passed to fopen() into - the PDCLib flags FREAD, FWRITE, FAPPEND, FRW (read-write) and FBIN (binary - mode). -*/ -static unsigned int filemode( char const * const mode ) -{ - int rc = 0; - switch ( mode[0] ) - { - case 'r': - rc |= _PDCLIB_FREAD; - break; - case 'w': - rc |= _PDCLIB_FWRITE; - break; - case 'a': - rc |= _PDCLIB_FAPPEND; - break; - default: - /* Other than read, write, or append - invalid */ - return 0; - } - for ( size_t i = 1; i < 4; ++i ) - { - switch ( mode[i] ) - { - case '+': - if ( rc & _PDCLIB_FRW ) return 0; /* Duplicates are invalid */ - rc |= _PDCLIB_FRW; - break; - case 'b': - if ( rc & _PDCLIB_FBIN ) return 0; /* Duplicates are invalid */ - rc |= _PDCLIB_FBIN; - break; - case '\0': - /* End of mode */ - return rc; - default: - /* Other than read/write or binary - invalid. */ - return 0; - } - } - /* Longer than three chars - invalid. */ - return 0; -} - struct _PDCLIB_file_t * fopen( const char * _PDCLIB_restrict filename, const char * _PDCLIB_restrict mode ) { struct _PDCLIB_file_t * rc; @@ -74,7 +28,7 @@ struct _PDCLIB_file_t * fopen( const char * _PDCLIB_restrict filename, const cha /* no memory for another FILE */ return NULL; } - if ( ( rc->status = filemode( mode ) ) == 0 ) goto fail; /* invalid mode */ + if ( ( rc->status = _PDCLIB_filemode( mode ) ) == 0 ) goto fail; /* invalid mode */ rc->handle = _PDCLIB_open( filename, rc->status ); if ( rc->handle == _PDCLIB_NOHANDLE ) goto fail; /* OS open() failed */ /* Adding to list of open files */ @@ -99,22 +53,6 @@ fail: int main( void ) { -#ifndef REGTEST - TESTCASE( filemode( "r" ) == _PDCLIB_FREAD ); - TESTCASE( filemode( "w" ) == _PDCLIB_FWRITE ); - TESTCASE( filemode( "a" ) == _PDCLIB_FAPPEND ); - TESTCASE( filemode( "r+" ) == ( _PDCLIB_FREAD | _PDCLIB_FRW ) ); - TESTCASE( filemode( "w+" ) == ( _PDCLIB_FWRITE | _PDCLIB_FRW ) ); - TESTCASE( filemode( "a+" ) == ( _PDCLIB_FAPPEND | _PDCLIB_FRW ) ); - TESTCASE( filemode( "rb" ) == ( _PDCLIB_FREAD | _PDCLIB_FBIN ) ); - TESTCASE( filemode( "wb" ) == ( _PDCLIB_FWRITE | _PDCLIB_FBIN ) ); - TESTCASE( filemode( "ab" ) == ( _PDCLIB_FAPPEND | _PDCLIB_FBIN ) ); - TESTCASE( filemode( "r+b" ) == ( _PDCLIB_FREAD | _PDCLIB_FRW | _PDCLIB_FBIN ) ); - TESTCASE( filemode( "w+b" ) == ( _PDCLIB_FWRITE | _PDCLIB_FRW | _PDCLIB_FBIN ) ); - TESTCASE( filemode( "a+b" ) == ( _PDCLIB_FAPPEND | _PDCLIB_FRW | _PDCLIB_FBIN ) ); - TESTCASE( filemode( "rb+" ) == ( _PDCLIB_FREAD | _PDCLIB_FRW | _PDCLIB_FBIN ) ); - TESTCASE( filemode( "wb+" ) == ( _PDCLIB_FWRITE | _PDCLIB_FRW | _PDCLIB_FBIN ) ); - TESTCASE( filemode( "ab+" ) == ( _PDCLIB_FAPPEND | _PDCLIB_FRW | _PDCLIB_FBIN ) ); TESTCASE( fopen( NULL, NULL ) == NULL ); TESTCASE( fopen( NULL, "w" ) == NULL ); TESTCASE( fopen( "", NULL ) == NULL ); @@ -124,9 +62,6 @@ int main( void ) TESTCASE( fopen( "testfile", "wr" ) == NULL ); /* Illegal mode */ TESTCASE( fopen( "testfile", "w" ) != NULL ); system( "rm testfile" ); -#else - puts( " NOTEST fopen() test driver is PDCLib-specific." ); -#endif return TEST_RESULTS; } diff --git a/functions/stdio/fprintf.c b/functions/stdio/fprintf.c index 8378a95..1afe87a 100644 --- a/functions/stdio/fprintf.c +++ b/functions/stdio/fprintf.c @@ -24,11 +24,226 @@ int fprintf( struct _PDCLIB_file_t * _PDCLIB_restrict stream, const char * _PDCL #endif #ifdef TEST +#include +#include #include <_PDCLIB_test.h> +#define testprintf( stream, n, format, ... ) fprintf( stream, format, __VA_ARGS__ ) + int main( void ) { - TESTCASE( NO_TESTDRIVER ); + FILE * buffer; + TESTCASE( ( buffer = fopen( "testfile", "w" ) ) != NULL ); + TESTCASE( testprintf( buffer, 100, "%hhd", CHAR_MIN ) == 4 ); + //TESTCASE( strcmp( buffer, "-128" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%hhd", CHAR_MAX ) == 3 ); + //TESTCASE( strcmp( buffer, "127" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%hhd", 0 ) == 1 ); + //TESTCASE( strcmp( buffer, "0" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%hd", SHRT_MIN ) == 6 ); + //TESTCASE( strcmp( buffer, "-32768" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%hd", SHRT_MAX ) == 5 ); + //TESTCASE( strcmp( buffer, "32767" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%hd", 0 ) == 1 ); + //TESTCASE( strcmp( buffer, "0" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%d", INT_MIN ) == 11 ); + //TESTCASE( strcmp( buffer, "-2147483648" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%d", INT_MAX ) == 10 ); + //TESTCASE( strcmp( buffer, "2147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%d", 0 ) == 1 ); + //TESTCASE( strcmp( buffer, "0" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%ld", LONG_MIN ) == 11 ); + //TESTCASE( strcmp( buffer, "-2147483648" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%ld", LONG_MAX ) == 10 ); + //TESTCASE( strcmp( buffer, "2147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%ld", 0l ) == 1 ); + //TESTCASE( strcmp( buffer, "0" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%lld", LLONG_MIN ) == 20 ); + //TESTCASE( strcmp( buffer, "-9223372036854775808" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%lld", LLONG_MAX ) == 19 ); + //TESTCASE( strcmp( buffer, "9223372036854775807" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%lld", 0ll ) ); + //TESTCASE( strcmp( buffer, "0" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%hhu", UCHAR_MAX ) == 3 ); + //TESTCASE( strcmp( buffer, "255" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%hhu", (unsigned char)-1 ) == 3 ); + //TESTCASE( strcmp( buffer, "255" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%hu", USHRT_MAX ) == 5 ); + //TESTCASE( strcmp( buffer, "65535" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%hu", (unsigned short)-1 ) == 5 ); + //TESTCASE( strcmp( buffer, "65535" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%u", UINT_MAX ) == 10 ); + //TESTCASE( strcmp( buffer, "4294967295" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%u", -1u ) == 10 ); + //TESTCASE( strcmp( buffer, "4294967295" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%lu", ULONG_MAX ) == 10 ); + //TESTCASE( strcmp( buffer, "4294967295" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%lu", -1ul ) == 10 ); + //TESTCASE( strcmp( buffer, "4294967295" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%llu", ULLONG_MAX ) == 20 ); + //TESTCASE( strcmp( buffer, "18446744073709551615" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%llu", -1ull ) == 20 ); + //TESTCASE( strcmp( buffer, "18446744073709551615" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%X", UINT_MAX ) == 8 ); + //TESTCASE( strcmp( buffer, "FFFFFFFF" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%#X", -1u ) == 10 ); + //TESTCASE( strcmp( buffer, "0XFFFFFFFF" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%x", UINT_MAX ) == 8 ); + //TESTCASE( strcmp( buffer, "ffffffff" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%#x", -1u ) == 10 ); + //TESTCASE( strcmp( buffer, "0xffffffff" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%o", UINT_MAX ) == 11 ); + //TESTCASE( strcmp( buffer, "37777777777" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%#o", -1u ) == 12 ); + //TESTCASE( strcmp( buffer, "037777777777" ) == 0 ); + /* TODO: This test case is broken, doesn't test what it was intended to. */ + TESTCASE( testprintf( buffer, 100, "%.0#o", 0 ) == 5 ); + //TESTCASE( strcmp( buffer, "%.0#o" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%+d", INT_MIN ) == 11 ); + //TESTCASE( strcmp( buffer, "-2147483648" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%+d", INT_MAX ) == 11 ); + //TESTCASE( strcmp( buffer, "+2147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%+d", 0 ) == 2 ); + //TESTCASE( strcmp( buffer, "+0" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%+u", UINT_MAX ) == 10 ); + //TESTCASE( strcmp( buffer, "4294967295" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%+u", -1u ) == 10 ); + //TESTCASE( strcmp( buffer, "4294967295" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "% d", INT_MIN ) == 11 ); + //TESTCASE( strcmp( buffer, "-2147483648" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "% d", INT_MAX ) == 11 ); + //TESTCASE( strcmp( buffer, " 2147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "% d", 0 ) == 2 ); + //TESTCASE( strcmp( buffer, " 0" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "% u", UINT_MAX ) == 10 ); + //TESTCASE( strcmp( buffer, "4294967295" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "% u", -1u ) == 10 ); + //TESTCASE( strcmp( buffer, "4294967295" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%9d", INT_MIN ) == 11 ); + //TESTCASE( strcmp( buffer, "-2147483648" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%9d", INT_MAX ) == 10 ); + //TESTCASE( strcmp( buffer, "2147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%10d", INT_MIN ) == 11 ); + //TESTCASE( strcmp( buffer, "-2147483648" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%10d", INT_MAX ) == 10 ); + //TESTCASE( strcmp( buffer, "2147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%11d", INT_MIN ) == 11 ); + //TESTCASE( strcmp( buffer, "-2147483648" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%11d", INT_MAX ) == 11 ); + //TESTCASE( strcmp( buffer, " 2147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%12d", INT_MIN ) == 12 ); + //TESTCASE( strcmp( buffer, " -2147483648" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%12d", INT_MAX ) == 12 ); + //TESTCASE( strcmp( buffer, " 2147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%-9d", INT_MIN ) == 11 ); + //TESTCASE( strcmp( buffer, "-2147483648" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%-9d", INT_MAX ) == 10 ); + //TESTCASE( strcmp( buffer, "2147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%-10d", INT_MIN ) == 11 ); + //TESTCASE( strcmp( buffer, "-2147483648" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%-10d", INT_MAX ) == 10 ); + //TESTCASE( strcmp( buffer, "2147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%-11d", INT_MIN ) == 11 ); + //TESTCASE( strcmp( buffer, "-2147483648" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%-11d", INT_MAX ) == 11 ); + //TESTCASE( strcmp( buffer, "2147483647 " ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%-12d", INT_MIN ) == 12 ); + //TESTCASE( strcmp( buffer, "-2147483648 " ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%-12d", INT_MAX ) == 12 ); + //TESTCASE( strcmp( buffer, "2147483647 " ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%09d", INT_MIN ) == 11 ); + //TESTCASE( strcmp( buffer, "-2147483648" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%09d", INT_MAX ) == 10 ); + //TESTCASE( strcmp( buffer, "2147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%010d", INT_MIN ) == 11 ); + //TESTCASE( strcmp( buffer, "-2147483648" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%010d", INT_MAX ) == 10 ); + //TESTCASE( strcmp( buffer, "2147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%011d", INT_MIN ) == 11 ); + //TESTCASE( strcmp( buffer, "-2147483648" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%011d", INT_MAX ) == 11 ); + //TESTCASE( strcmp( buffer, "02147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%012d", INT_MIN ) == 12 ); + //TESTCASE( strcmp( buffer, "-02147483648" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%012d", INT_MAX ) == 12 ); + //TESTCASE( strcmp( buffer, "002147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%-09d", INT_MIN ) == 11 ); + //TESTCASE( strcmp( buffer, "-2147483648" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%-09d", INT_MAX ) == 10 ); + //TESTCASE( strcmp( buffer, "2147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%-010d", INT_MIN ) == 11 ); + //TESTCASE( strcmp( buffer, "-2147483648" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%-010d", INT_MAX ) == 10 ); + //TESTCASE( strcmp( buffer, "2147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%-011d", INT_MIN ) == 11 ); + //TESTCASE( strcmp( buffer, "-2147483648" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%-011d", INT_MAX ) == 11 ); + //TESTCASE( strcmp( buffer, "2147483647 " ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%-012d", INT_MIN ) == 12 ); + //TESTCASE( strcmp( buffer, "-2147483648 " ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%-012d", INT_MAX ) == 12 ); + //TESTCASE( strcmp( buffer, "2147483647 " ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%030.20d", INT_MAX ) == 30 ); + //TESTCASE( strcmp( buffer, " 00000000002147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%.6x", UINT_MAX ) == 8 ); + //TESTCASE( strcmp( buffer, "ffffffff" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%#6.3x", UINT_MAX ) == 10 ); + //TESTCASE( strcmp( buffer, "0xffffffff" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%#3.6x", UINT_MAX ) == 10 ); + //TESTCASE( strcmp( buffer, "0xffffffff" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%.6d", INT_MIN ) == 11 ); + //TESTCASE( strcmp( buffer, "-2147483648" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%6.3d", INT_MIN ) == 11 ); + //TESTCASE( strcmp( buffer, "-2147483648" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%3.6d", INT_MIN ) == 11 ); + //TESTCASE( strcmp( buffer, "-2147483648" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%#0.6x", UINT_MAX ) == 10 ); + //TESTCASE( strcmp( buffer, "0xffffffff" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%#06.3x", UINT_MAX ) == 10 ); + //TESTCASE( strcmp( buffer, "0xffffffff" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%#03.6x", UINT_MAX ) == 10 ); + //TESTCASE( strcmp( buffer, "0xffffffff" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%#0.6d", INT_MAX ) == 10 ); + //TESTCASE( strcmp( buffer, "2147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%#06.3d", INT_MAX ) == 10 ); + //TESTCASE( strcmp( buffer, "2147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%#03.6d", INT_MAX ) == 10 ); + //TESTCASE( strcmp( buffer, "2147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%#+.6d", INT_MAX ) == 11 ); + //TESTCASE( strcmp( buffer, "+2147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%#+6.3d", INT_MAX ) == 11 ); + //TESTCASE( strcmp( buffer, "+2147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%#+3.6d", INT_MAX ) == 11 ); + //TESTCASE( strcmp( buffer, "+2147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%+0.6d", INT_MAX ) == 11 ); + //TESTCASE( strcmp( buffer, "+2147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%+06.3d", INT_MAX ) == 11 ); + //TESTCASE( strcmp( buffer, "+2147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%+03.6d", INT_MAX ) == 11 ); + //TESTCASE( strcmp( buffer, "+2147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "- %d", INT_MAX ) == 12 ); + //TESTCASE( strcmp( buffer, "- 2147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "- %d %% %d", INT_MAX, INT_MIN ) == 26 ); + //TESTCASE( strcmp( buffer, "- 2147483647 % -2147483648" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%c", 'x' ) == 1 ); + //TESTCASE( strcmp( buffer, "x" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%s", "abcdef" ) == 6 ); + //TESTCASE( strcmp( buffer, "abcdef" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%p", (void *)0xdeadbeef ) == 10 ); + //TESTCASE( strcmp( buffer, "0xdeadbeef" ) == 0 ); + { + int val1, val2; + TESTCASE( testprintf( buffer, 100, "123456%n789%n", &val1, &val2 ) == 9 ); + //TESTCASE( strcmp( buffer, "123456789" ) == 0 ); + TESTCASE( val1 == 6 ); + TESTCASE( val2 == 9 ); + } + TESTCASE( fclose( buffer ) == 0 ); + char readbuffer[1000]; + TESTCASE( ( buffer = fopen( "testfile", "r" ) ) != NULL ); + TESTCASE( fread( readbuffer, 1, 1000, buffer ) == 985 ); + TESTCASE( fclose( buffer ) == 0 ); + TESTCASE( memcmp( readbuffer, "-1281270-32768327670-214748364821474836470-214748364821474836470-922337203685477580892233720368547758070255255655356553542949672954294967295429496729542949672951844674407370955161518446744073709551615FFFFFFFF0XFFFFFFFFffffffff0xffffffff37777777777037777777777%.0#o-2147483648+2147483647+042949672954294967295-2147483648 2147483647 042949672954294967295-21474836482147483647-21474836482147483647-2147483648 2147483647 -2147483648 2147483647-21474836482147483647-21474836482147483647-21474836482147483647 -2147483648 2147483647 -21474836482147483647-21474836482147483647-214748364802147483647-02147483648002147483647-21474836482147483647-21474836482147483647-21474836482147483647 -2147483648 2147483647 00000000002147483647ffffffff0xffffffff0xffffffff-2147483648-2147483648-21474836480xffffffff0xffffffff0xffffffff214748364721474836472147483647+2147483647+2147483647+2147483647+2147483647+2147483647+2147483647- 2147483647- 2147483647 % -2147483648xabcdef0xdeadbeef123456789", 985 ) == 0 ); return TEST_RESULTS; } diff --git a/functions/stdio/freopen.c b/functions/stdio/freopen.c new file mode 100644 index 0000000..be4b95e --- /dev/null +++ b/functions/stdio/freopen.c @@ -0,0 +1,55 @@ +/* $Id$ */ + +/* freopen( const char *, const char * ) + + This file is part of the Public Domain C Library (PDCLib). + Permission is granted to use, modify, and / or redistribute at will. +*/ + +#include + +#ifndef REGTEST + +#include <_PDCLIB_glue.h> +#include + +/* Close any file currently associated with the given stream. Open the file + identified by the given filename with the given mode (equivalent to fopen()), + and associate it with the given stream. If filename is a NULL pointer, + attempt to change the mode of the given stream. + This implementation allows the following mode changes: TODO + (Primary use of this function is to redirect stdin, stdout, and stderr.) +*/ + +struct _PDCLIB_file_t * freopen( const char * _PDCLIB_restrict filename, const char * _PDCLIB_restrict mode, struct _PDCLIB_file_t * stream ) +{ + /* FIXME: This is ad-hoc (to make the vprintf() testdriver work), and must be checked. */ + /* FIXME: If filename is NULL, change mode. */ + if ( filename == NULL ) return NULL; + if ( stream->status & _PDCLIB_WROTELAST ) fflush( stream ); + if ( stream->status & _PDCLIB_LIBBUFFER ) free( stream->buffer ); + _PDCLIB_close( stream->handle ); + clearerr( stream ); + if ( ( mode == NULL ) || ( filename[0] == '\0' ) ) return NULL; + if ( ( stream->status = _PDCLIB_filemode( mode ) ) == 0 ) return NULL; + stream->handle = _PDCLIB_open( filename, stream->status ); + if ( ( stream->buffer = malloc( BUFSIZ ) ) == NULL ) return NULL; + stream->bufsize = BUFSIZ; + stream->bufidx = 0; + stream->status |= ( _PDCLIB_LIBBUFFER | _PDCLIB_VIRGINSTR ); + /* TODO: Setting mbstate */ + return stream; +} + +#endif + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ + TESTCASE( NO_TESTDRIVER ); + return TEST_RESULTS; +} + +#endif diff --git a/functions/stdio/vfprintf.c b/functions/stdio/vfprintf.c index 9a9a950..8c8c022 100644 --- a/functions/stdio/vfprintf.c +++ b/functions/stdio/vfprintf.c @@ -39,9 +39,11 @@ int vfprintf( struct _PDCLIB_file_t * _PDCLIB_restrict stream, const char * _PDC #ifdef TEST #include +#include +#include #include <_PDCLIB_test.h> -static int testprintf( FILE * stream, const char * format, ... ) +static int testprintf( FILE * stream, size_t n, const char * format, ... ) { int i; va_list arg; @@ -53,11 +55,218 @@ static int testprintf( FILE * stream, const char * format, ... ) int main( void ) { - FILE * fh; - TESTCASE( ( fh = fopen( "testfile", "w" ) ) != NULL ); - TESTCASE( testprintf( fh, "Hallo\n" ) == 6 ); - TESTCASE( fclose( fh ) == 0 ); - /* FIXME: Testfile doesn't exist... */ + FILE * buffer; + TESTCASE( ( buffer = fopen( "testfile", "w" ) ) != NULL ); + TESTCASE( testprintf( buffer, 100, "%hhd", CHAR_MIN ) == 4 ); + //TESTCASE( strcmp( buffer, "-128" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%hhd", CHAR_MAX ) == 3 ); + //TESTCASE( strcmp( buffer, "127" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%hhd", 0 ) == 1 ); + //TESTCASE( strcmp( buffer, "0" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%hd", SHRT_MIN ) == 6 ); + //TESTCASE( strcmp( buffer, "-32768" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%hd", SHRT_MAX ) == 5 ); + //TESTCASE( strcmp( buffer, "32767" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%hd", 0 ) == 1 ); + //TESTCASE( strcmp( buffer, "0" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%d", INT_MIN ) == 11 ); + //TESTCASE( strcmp( buffer, "-2147483648" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%d", INT_MAX ) == 10 ); + //TESTCASE( strcmp( buffer, "2147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%d", 0 ) == 1 ); + //TESTCASE( strcmp( buffer, "0" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%ld", LONG_MIN ) == 11 ); + //TESTCASE( strcmp( buffer, "-2147483648" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%ld", LONG_MAX ) == 10 ); + //TESTCASE( strcmp( buffer, "2147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%ld", 0l ) == 1 ); + //TESTCASE( strcmp( buffer, "0" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%lld", LLONG_MIN ) == 20 ); + //TESTCASE( strcmp( buffer, "-9223372036854775808" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%lld", LLONG_MAX ) == 19 ); + //TESTCASE( strcmp( buffer, "9223372036854775807" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%lld", 0ll ) ); + //TESTCASE( strcmp( buffer, "0" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%hhu", UCHAR_MAX ) == 3 ); + //TESTCASE( strcmp( buffer, "255" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%hhu", (unsigned char)-1 ) == 3 ); + //TESTCASE( strcmp( buffer, "255" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%hu", USHRT_MAX ) == 5 ); + //TESTCASE( strcmp( buffer, "65535" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%hu", (unsigned short)-1 ) == 5 ); + //TESTCASE( strcmp( buffer, "65535" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%u", UINT_MAX ) == 10 ); + //TESTCASE( strcmp( buffer, "4294967295" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%u", -1u ) == 10 ); + //TESTCASE( strcmp( buffer, "4294967295" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%lu", ULONG_MAX ) == 10 ); + //TESTCASE( strcmp( buffer, "4294967295" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%lu", -1ul ) == 10 ); + //TESTCASE( strcmp( buffer, "4294967295" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%llu", ULLONG_MAX ) == 20 ); + //TESTCASE( strcmp( buffer, "18446744073709551615" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%llu", -1ull ) == 20 ); + //TESTCASE( strcmp( buffer, "18446744073709551615" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%X", UINT_MAX ) == 8 ); + //TESTCASE( strcmp( buffer, "FFFFFFFF" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%#X", -1u ) == 10 ); + //TESTCASE( strcmp( buffer, "0XFFFFFFFF" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%x", UINT_MAX ) == 8 ); + //TESTCASE( strcmp( buffer, "ffffffff" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%#x", -1u ) == 10 ); + //TESTCASE( strcmp( buffer, "0xffffffff" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%o", UINT_MAX ) == 11 ); + //TESTCASE( strcmp( buffer, "37777777777" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%#o", -1u ) == 12 ); + //TESTCASE( strcmp( buffer, "037777777777" ) == 0 ); + /* TODO: This test case is broken, doesn't test what it was intended to. */ + TESTCASE( testprintf( buffer, 100, "%.0#o", 0 ) == 5 ); + //TESTCASE( strcmp( buffer, "%.0#o" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%+d", INT_MIN ) == 11 ); + //TESTCASE( strcmp( buffer, "-2147483648" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%+d", INT_MAX ) == 11 ); + //TESTCASE( strcmp( buffer, "+2147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%+d", 0 ) == 2 ); + //TESTCASE( strcmp( buffer, "+0" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%+u", UINT_MAX ) == 10 ); + //TESTCASE( strcmp( buffer, "4294967295" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%+u", -1u ) == 10 ); + //TESTCASE( strcmp( buffer, "4294967295" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "% d", INT_MIN ) == 11 ); + //TESTCASE( strcmp( buffer, "-2147483648" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "% d", INT_MAX ) == 11 ); + //TESTCASE( strcmp( buffer, " 2147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "% d", 0 ) == 2 ); + //TESTCASE( strcmp( buffer, " 0" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "% u", UINT_MAX ) == 10 ); + //TESTCASE( strcmp( buffer, "4294967295" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "% u", -1u ) == 10 ); + //TESTCASE( strcmp( buffer, "4294967295" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%9d", INT_MIN ) == 11 ); + //TESTCASE( strcmp( buffer, "-2147483648" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%9d", INT_MAX ) == 10 ); + //TESTCASE( strcmp( buffer, "2147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%10d", INT_MIN ) == 11 ); + //TESTCASE( strcmp( buffer, "-2147483648" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%10d", INT_MAX ) == 10 ); + //TESTCASE( strcmp( buffer, "2147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%11d", INT_MIN ) == 11 ); + //TESTCASE( strcmp( buffer, "-2147483648" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%11d", INT_MAX ) == 11 ); + //TESTCASE( strcmp( buffer, " 2147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%12d", INT_MIN ) == 12 ); + //TESTCASE( strcmp( buffer, " -2147483648" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%12d", INT_MAX ) == 12 ); + //TESTCASE( strcmp( buffer, " 2147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%-9d", INT_MIN ) == 11 ); + //TESTCASE( strcmp( buffer, "-2147483648" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%-9d", INT_MAX ) == 10 ); + //TESTCASE( strcmp( buffer, "2147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%-10d", INT_MIN ) == 11 ); + //TESTCASE( strcmp( buffer, "-2147483648" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%-10d", INT_MAX ) == 10 ); + //TESTCASE( strcmp( buffer, "2147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%-11d", INT_MIN ) == 11 ); + //TESTCASE( strcmp( buffer, "-2147483648" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%-11d", INT_MAX ) == 11 ); + //TESTCASE( strcmp( buffer, "2147483647 " ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%-12d", INT_MIN ) == 12 ); + //TESTCASE( strcmp( buffer, "-2147483648 " ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%-12d", INT_MAX ) == 12 ); + //TESTCASE( strcmp( buffer, "2147483647 " ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%09d", INT_MIN ) == 11 ); + //TESTCASE( strcmp( buffer, "-2147483648" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%09d", INT_MAX ) == 10 ); + //TESTCASE( strcmp( buffer, "2147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%010d", INT_MIN ) == 11 ); + //TESTCASE( strcmp( buffer, "-2147483648" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%010d", INT_MAX ) == 10 ); + //TESTCASE( strcmp( buffer, "2147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%011d", INT_MIN ) == 11 ); + //TESTCASE( strcmp( buffer, "-2147483648" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%011d", INT_MAX ) == 11 ); + //TESTCASE( strcmp( buffer, "02147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%012d", INT_MIN ) == 12 ); + //TESTCASE( strcmp( buffer, "-02147483648" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%012d", INT_MAX ) == 12 ); + //TESTCASE( strcmp( buffer, "002147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%-09d", INT_MIN ) == 11 ); + //TESTCASE( strcmp( buffer, "-2147483648" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%-09d", INT_MAX ) == 10 ); + //TESTCASE( strcmp( buffer, "2147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%-010d", INT_MIN ) == 11 ); + //TESTCASE( strcmp( buffer, "-2147483648" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%-010d", INT_MAX ) == 10 ); + //TESTCASE( strcmp( buffer, "2147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%-011d", INT_MIN ) == 11 ); + //TESTCASE( strcmp( buffer, "-2147483648" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%-011d", INT_MAX ) == 11 ); + //TESTCASE( strcmp( buffer, "2147483647 " ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%-012d", INT_MIN ) == 12 ); + //TESTCASE( strcmp( buffer, "-2147483648 " ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%-012d", INT_MAX ) == 12 ); + //TESTCASE( strcmp( buffer, "2147483647 " ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%030.20d", INT_MAX ) == 30 ); + //TESTCASE( strcmp( buffer, " 00000000002147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%.6x", UINT_MAX ) == 8 ); + //TESTCASE( strcmp( buffer, "ffffffff" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%#6.3x", UINT_MAX ) == 10 ); + //TESTCASE( strcmp( buffer, "0xffffffff" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%#3.6x", UINT_MAX ) == 10 ); + //TESTCASE( strcmp( buffer, "0xffffffff" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%.6d", INT_MIN ) == 11 ); + //TESTCASE( strcmp( buffer, "-2147483648" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%6.3d", INT_MIN ) == 11 ); + //TESTCASE( strcmp( buffer, "-2147483648" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%3.6d", INT_MIN ) == 11 ); + //TESTCASE( strcmp( buffer, "-2147483648" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%#0.6x", UINT_MAX ) == 10 ); + //TESTCASE( strcmp( buffer, "0xffffffff" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%#06.3x", UINT_MAX ) == 10 ); + //TESTCASE( strcmp( buffer, "0xffffffff" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%#03.6x", UINT_MAX ) == 10 ); + //TESTCASE( strcmp( buffer, "0xffffffff" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%#0.6d", INT_MAX ) == 10 ); + //TESTCASE( strcmp( buffer, "2147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%#06.3d", INT_MAX ) == 10 ); + //TESTCASE( strcmp( buffer, "2147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%#03.6d", INT_MAX ) == 10 ); + //TESTCASE( strcmp( buffer, "2147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%#+.6d", INT_MAX ) == 11 ); + //TESTCASE( strcmp( buffer, "+2147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%#+6.3d", INT_MAX ) == 11 ); + //TESTCASE( strcmp( buffer, "+2147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%#+3.6d", INT_MAX ) == 11 ); + //TESTCASE( strcmp( buffer, "+2147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%+0.6d", INT_MAX ) == 11 ); + //TESTCASE( strcmp( buffer, "+2147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%+06.3d", INT_MAX ) == 11 ); + //TESTCASE( strcmp( buffer, "+2147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%+03.6d", INT_MAX ) == 11 ); + //TESTCASE( strcmp( buffer, "+2147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "- %d", INT_MAX ) == 12 ); + //TESTCASE( strcmp( buffer, "- 2147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "- %d %% %d", INT_MAX, INT_MIN ) == 26 ); + //TESTCASE( strcmp( buffer, "- 2147483647 % -2147483648" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%c", 'x' ) == 1 ); + //TESTCASE( strcmp( buffer, "x" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%s", "abcdef" ) == 6 ); + //TESTCASE( strcmp( buffer, "abcdef" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%p", (void *)0xdeadbeef ) == 10 ); + //TESTCASE( strcmp( buffer, "0xdeadbeef" ) == 0 ); + { + int val1, val2; + TESTCASE( testprintf( buffer, 100, "123456%n789%n", &val1, &val2 ) == 9 ); + //TESTCASE( strcmp( buffer, "123456789" ) == 0 ); + TESTCASE( val1 == 6 ); + TESTCASE( val2 == 9 ); + } + TESTCASE( fclose( buffer ) == 0 ); + char readbuffer[1000]; + TESTCASE( ( buffer = fopen( "testfile", "r" ) ) != NULL ); + TESTCASE( fread( readbuffer, 1, 1000, buffer ) == 985 ); + TESTCASE( fclose( buffer ) == 0 ); + TESTCASE( memcmp( readbuffer, "-1281270-32768327670-214748364821474836470-214748364821474836470-922337203685477580892233720368547758070255255655356553542949672954294967295429496729542949672951844674407370955161518446744073709551615FFFFFFFF0XFFFFFFFFffffffff0xffffffff37777777777037777777777%.0#o-2147483648+2147483647+042949672954294967295-2147483648 2147483647 042949672954294967295-21474836482147483647-21474836482147483647-2147483648 2147483647 -2147483648 2147483647-21474836482147483647-21474836482147483647-21474836482147483647 -2147483648 2147483647 -21474836482147483647-21474836482147483647-214748364802147483647-02147483648002147483647-21474836482147483647-21474836482147483647-21474836482147483647 -2147483648 2147483647 00000000002147483647ffffffff0xffffffff0xffffffff-2147483648-2147483648-21474836480xffffffff0xffffffff0xffffffff214748364721474836472147483647+2147483647+2147483647+2147483647+2147483647+2147483647+2147483647- 2147483647- 2147483647 % -2147483648xabcdef0xdeadbeef123456789", 985 ) == 0 ); return TEST_RESULTS; } diff --git a/functions/stdio/vprintf.c b/functions/stdio/vprintf.c index a8ca45f..d7ad502 100644 --- a/functions/stdio/vprintf.c +++ b/functions/stdio/vprintf.c @@ -19,11 +19,234 @@ int vprintf( const char * _PDCLIB_restrict format, _PDCLIB_va_list arg ) #endif #ifdef TEST +#include +#include #include <_PDCLIB_test.h> +static int testprintf( FILE * stream, size_t n, const char * format, ... ) +{ + int i; + va_list arg; + va_start( arg, format ); + i = vprintf( format, arg ); + va_end( arg ); + return i; +} + int main( void ) { - TESTCASE( NO_TESTDRIVER ); + FILE * buffer; + TESTCASE( ( buffer = freopen( "testfile", "w", stdout ) ) != NULL ); + TESTCASE( testprintf( buffer, 100, "%hhd", CHAR_MIN ) == 4 ); + //TESTCASE( strcmp( buffer, "-128" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%hhd", CHAR_MAX ) == 3 ); + //TESTCASE( strcmp( buffer, "127" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%hhd", 0 ) == 1 ); + //TESTCASE( strcmp( buffer, "0" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%hd", SHRT_MIN ) == 6 ); + //TESTCASE( strcmp( buffer, "-32768" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%hd", SHRT_MAX ) == 5 ); + //TESTCASE( strcmp( buffer, "32767" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%hd", 0 ) == 1 ); + //TESTCASE( strcmp( buffer, "0" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%d", INT_MIN ) == 11 ); + //TESTCASE( strcmp( buffer, "-2147483648" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%d", INT_MAX ) == 10 ); + //TESTCASE( strcmp( buffer, "2147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%d", 0 ) == 1 ); + //TESTCASE( strcmp( buffer, "0" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%ld", LONG_MIN ) == 11 ); + //TESTCASE( strcmp( buffer, "-2147483648" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%ld", LONG_MAX ) == 10 ); + //TESTCASE( strcmp( buffer, "2147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%ld", 0l ) == 1 ); + //TESTCASE( strcmp( buffer, "0" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%lld", LLONG_MIN ) == 20 ); + //TESTCASE( strcmp( buffer, "-9223372036854775808" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%lld", LLONG_MAX ) == 19 ); + //TESTCASE( strcmp( buffer, "9223372036854775807" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%lld", 0ll ) ); + //TESTCASE( strcmp( buffer, "0" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%hhu", UCHAR_MAX ) == 3 ); + //TESTCASE( strcmp( buffer, "255" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%hhu", (unsigned char)-1 ) == 3 ); + //TESTCASE( strcmp( buffer, "255" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%hu", USHRT_MAX ) == 5 ); + //TESTCASE( strcmp( buffer, "65535" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%hu", (unsigned short)-1 ) == 5 ); + //TESTCASE( strcmp( buffer, "65535" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%u", UINT_MAX ) == 10 ); + //TESTCASE( strcmp( buffer, "4294967295" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%u", -1u ) == 10 ); + //TESTCASE( strcmp( buffer, "4294967295" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%lu", ULONG_MAX ) == 10 ); + //TESTCASE( strcmp( buffer, "4294967295" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%lu", -1ul ) == 10 ); + //TESTCASE( strcmp( buffer, "4294967295" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%llu", ULLONG_MAX ) == 20 ); + //TESTCASE( strcmp( buffer, "18446744073709551615" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%llu", -1ull ) == 20 ); + //TESTCASE( strcmp( buffer, "18446744073709551615" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%X", UINT_MAX ) == 8 ); + //TESTCASE( strcmp( buffer, "FFFFFFFF" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%#X", -1u ) == 10 ); + //TESTCASE( strcmp( buffer, "0XFFFFFFFF" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%x", UINT_MAX ) == 8 ); + //TESTCASE( strcmp( buffer, "ffffffff" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%#x", -1u ) == 10 ); + //TESTCASE( strcmp( buffer, "0xffffffff" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%o", UINT_MAX ) == 11 ); + //TESTCASE( strcmp( buffer, "37777777777" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%#o", -1u ) == 12 ); + //TESTCASE( strcmp( buffer, "037777777777" ) == 0 ); + /* TODO: This test case is broken, doesn't test what it was intended to. */ + TESTCASE( testprintf( buffer, 100, "%.0#o", 0 ) == 5 ); + //TESTCASE( strcmp( buffer, "%.0#o" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%+d", INT_MIN ) == 11 ); + //TESTCASE( strcmp( buffer, "-2147483648" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%+d", INT_MAX ) == 11 ); + //TESTCASE( strcmp( buffer, "+2147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%+d", 0 ) == 2 ); + //TESTCASE( strcmp( buffer, "+0" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%+u", UINT_MAX ) == 10 ); + //TESTCASE( strcmp( buffer, "4294967295" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%+u", -1u ) == 10 ); + //TESTCASE( strcmp( buffer, "4294967295" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "% d", INT_MIN ) == 11 ); + //TESTCASE( strcmp( buffer, "-2147483648" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "% d", INT_MAX ) == 11 ); + //TESTCASE( strcmp( buffer, " 2147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "% d", 0 ) == 2 ); + //TESTCASE( strcmp( buffer, " 0" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "% u", UINT_MAX ) == 10 ); + //TESTCASE( strcmp( buffer, "4294967295" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "% u", -1u ) == 10 ); + //TESTCASE( strcmp( buffer, "4294967295" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%9d", INT_MIN ) == 11 ); + //TESTCASE( strcmp( buffer, "-2147483648" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%9d", INT_MAX ) == 10 ); + //TESTCASE( strcmp( buffer, "2147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%10d", INT_MIN ) == 11 ); + //TESTCASE( strcmp( buffer, "-2147483648" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%10d", INT_MAX ) == 10 ); + //TESTCASE( strcmp( buffer, "2147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%11d", INT_MIN ) == 11 ); + //TESTCASE( strcmp( buffer, "-2147483648" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%11d", INT_MAX ) == 11 ); + //TESTCASE( strcmp( buffer, " 2147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%12d", INT_MIN ) == 12 ); + //TESTCASE( strcmp( buffer, " -2147483648" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%12d", INT_MAX ) == 12 ); + //TESTCASE( strcmp( buffer, " 2147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%-9d", INT_MIN ) == 11 ); + //TESTCASE( strcmp( buffer, "-2147483648" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%-9d", INT_MAX ) == 10 ); + //TESTCASE( strcmp( buffer, "2147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%-10d", INT_MIN ) == 11 ); + //TESTCASE( strcmp( buffer, "-2147483648" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%-10d", INT_MAX ) == 10 ); + //TESTCASE( strcmp( buffer, "2147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%-11d", INT_MIN ) == 11 ); + //TESTCASE( strcmp( buffer, "-2147483648" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%-11d", INT_MAX ) == 11 ); + //TESTCASE( strcmp( buffer, "2147483647 " ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%-12d", INT_MIN ) == 12 ); + //TESTCASE( strcmp( buffer, "-2147483648 " ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%-12d", INT_MAX ) == 12 ); + //TESTCASE( strcmp( buffer, "2147483647 " ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%09d", INT_MIN ) == 11 ); + //TESTCASE( strcmp( buffer, "-2147483648" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%09d", INT_MAX ) == 10 ); + //TESTCASE( strcmp( buffer, "2147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%010d", INT_MIN ) == 11 ); + //TESTCASE( strcmp( buffer, "-2147483648" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%010d", INT_MAX ) == 10 ); + //TESTCASE( strcmp( buffer, "2147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%011d", INT_MIN ) == 11 ); + //TESTCASE( strcmp( buffer, "-2147483648" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%011d", INT_MAX ) == 11 ); + //TESTCASE( strcmp( buffer, "02147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%012d", INT_MIN ) == 12 ); + //TESTCASE( strcmp( buffer, "-02147483648" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%012d", INT_MAX ) == 12 ); + //TESTCASE( strcmp( buffer, "002147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%-09d", INT_MIN ) == 11 ); + //TESTCASE( strcmp( buffer, "-2147483648" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%-09d", INT_MAX ) == 10 ); + //TESTCASE( strcmp( buffer, "2147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%-010d", INT_MIN ) == 11 ); + //TESTCASE( strcmp( buffer, "-2147483648" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%-010d", INT_MAX ) == 10 ); + //TESTCASE( strcmp( buffer, "2147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%-011d", INT_MIN ) == 11 ); + //TESTCASE( strcmp( buffer, "-2147483648" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%-011d", INT_MAX ) == 11 ); + //TESTCASE( strcmp( buffer, "2147483647 " ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%-012d", INT_MIN ) == 12 ); + //TESTCASE( strcmp( buffer, "-2147483648 " ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%-012d", INT_MAX ) == 12 ); + //TESTCASE( strcmp( buffer, "2147483647 " ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%030.20d", INT_MAX ) == 30 ); + //TESTCASE( strcmp( buffer, " 00000000002147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%.6x", UINT_MAX ) == 8 ); + //TESTCASE( strcmp( buffer, "ffffffff" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%#6.3x", UINT_MAX ) == 10 ); + //TESTCASE( strcmp( buffer, "0xffffffff" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%#3.6x", UINT_MAX ) == 10 ); + //TESTCASE( strcmp( buffer, "0xffffffff" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%.6d", INT_MIN ) == 11 ); + //TESTCASE( strcmp( buffer, "-2147483648" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%6.3d", INT_MIN ) == 11 ); + //TESTCASE( strcmp( buffer, "-2147483648" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%3.6d", INT_MIN ) == 11 ); + //TESTCASE( strcmp( buffer, "-2147483648" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%#0.6x", UINT_MAX ) == 10 ); + //TESTCASE( strcmp( buffer, "0xffffffff" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%#06.3x", UINT_MAX ) == 10 ); + //TESTCASE( strcmp( buffer, "0xffffffff" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%#03.6x", UINT_MAX ) == 10 ); + //TESTCASE( strcmp( buffer, "0xffffffff" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%#0.6d", INT_MAX ) == 10 ); + //TESTCASE( strcmp( buffer, "2147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%#06.3d", INT_MAX ) == 10 ); + //TESTCASE( strcmp( buffer, "2147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%#03.6d", INT_MAX ) == 10 ); + //TESTCASE( strcmp( buffer, "2147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%#+.6d", INT_MAX ) == 11 ); + //TESTCASE( strcmp( buffer, "+2147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%#+6.3d", INT_MAX ) == 11 ); + //TESTCASE( strcmp( buffer, "+2147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%#+3.6d", INT_MAX ) == 11 ); + //TESTCASE( strcmp( buffer, "+2147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%+0.6d", INT_MAX ) == 11 ); + //TESTCASE( strcmp( buffer, "+2147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%+06.3d", INT_MAX ) == 11 ); + //TESTCASE( strcmp( buffer, "+2147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%+03.6d", INT_MAX ) == 11 ); + //TESTCASE( strcmp( buffer, "+2147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "- %d", INT_MAX ) == 12 ); + //TESTCASE( strcmp( buffer, "- 2147483647" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "- %d %% %d", INT_MAX, INT_MIN ) == 26 ); + //TESTCASE( strcmp( buffer, "- 2147483647 % -2147483648" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%c", 'x' ) == 1 ); + //TESTCASE( strcmp( buffer, "x" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%s", "abcdef" ) == 6 ); + //TESTCASE( strcmp( buffer, "abcdef" ) == 0 ); + TESTCASE( testprintf( buffer, 100, "%p", (void *)0xdeadbeef ) == 10 ); + //TESTCASE( strcmp( buffer, "0xdeadbeef" ) == 0 ); + { + int val1, val2; + TESTCASE( testprintf( buffer, 100, "123456%n789%n", &val1, &val2 ) == 9 ); + //TESTCASE( strcmp( buffer, "123456789" ) == 0 ); + TESTCASE( val1 == 6 ); + TESTCASE( val2 == 9 ); + } + TESTCASE( fclose( buffer ) == 0 ); + char readbuffer[1000]; + TESTCASE( ( buffer = fopen( "testfile", "r" ) ) != NULL ); + TESTCASE( fread( readbuffer, 1, 1000, buffer ) == 985 ); + TESTCASE( fclose( buffer ) == 0 ); + TESTCASE( memcmp( readbuffer, "-1281270-32768327670-214748364821474836470-214748364821474836470-922337203685477580892233720368547758070255255655356553542949672954294967295429496729542949672951844674407370955161518446744073709551615FFFFFFFF0XFFFFFFFFffffffff0xffffffff37777777777037777777777%.0#o-2147483648+2147483647+042949672954294967295-2147483648 2147483647 042949672954294967295-21474836482147483647-21474836482147483647-2147483648 2147483647 -2147483648 2147483647-21474836482147483647-21474836482147483647-21474836482147483647 -2147483648 2147483647 -21474836482147483647-21474836482147483647-214748364802147483647-02147483648002147483647-21474836482147483647-21474836482147483647-21474836482147483647 -2147483648 2147483647 00000000002147483647ffffffff0xffffffff0xffffffff-2147483648-2147483648-21474836480xffffffff0xffffffff0xffffffff214748364721474836472147483647+2147483647+2147483647+2147483647+2147483647+2147483647+2147483647- 2147483647- 2147483647 % -2147483648xabcdef0xdeadbeef123456789", 985 ) == 0 ); return TEST_RESULTS; } diff --git a/internals/_PDCLIB_int.h b/internals/_PDCLIB_int.h index 1c89ae0..0ce2c99 100644 --- a/internals/_PDCLIB_int.h +++ b/internals/_PDCLIB_int.h @@ -344,3 +344,6 @@ extern char _PDCLIB_Xdigits[]; Returns a pointer to the first character not parsed as conversion specifier. */ const char * _PDCLIB_print( const char * spec, struct _PDCLIB_status_t * status ); + +/* Parsing any fopen() style filemode string into a number of flags. */ +unsigned int _PDCLIB_filemode( const char * mode );