X-Git-Url: https://pd.if.org/git/?a=blobdiff_plain;f=functions%2F_PDCLIB%2Fscan.c;h=b346ffc2bb81dc7943d1db696e168241e2a77370;hb=a7a8d2f1c85c2d7760d4d3479e90466cc3a81b04;hp=63afff235e25281778b4bdc584ca42b1e8952596;hpb=519fc78c528a1d4e07fbd5f8353d5c3f81b8e99b;p=pdclib diff --git a/functions/_PDCLIB/scan.c b/functions/_PDCLIB/scan.c index 63afff2..b346ffc 100644 --- a/functions/_PDCLIB/scan.c +++ b/functions/_PDCLIB/scan.c @@ -63,7 +63,7 @@ static int GET( struct _PDCLIB_status_t * status ) if ( rc != EOF ) { ++(status->i); - ++(status->this); + ++(status->current); } return rc; } @@ -83,15 +83,45 @@ static void UNGET( int c, struct _PDCLIB_status_t * status ) --(status->s); } --(status->i); - --(status->this); + --(status->current); } /* Helper function to check if a character is part of a given scanset */ -static bool NOT_IN_SCANSET( const char * start_scanlist, const char * end_scanlist, bool negate_scanlist, int rc ) +static bool IN_SCANSET( const char * scanlist, const char * end_scanlist, int rc ) { // SOLAR - return true; + int previous = -1; + while ( scanlist != end_scanlist ) + { + if ( ( *scanlist == '-' ) && ( previous != -1 ) ) + { + /* possible scangroup ("a-z") */ + if ( ++scanlist == end_scanlist ) + { + /* '-' at end of scanlist does not describe a scangroup */ + return rc == '-'; + } + while ( ++previous <= (unsigned char)*scanlist ) + { + if ( previous == rc ) + { + return true; + } + } + previous = -1; + } + else + { + /* not a scangroup, check verbatim */ + if ( rc == (unsigned char)*scanlist ) + { + return true; + } + previous = (unsigned char)(*scanlist++); + } + } + return false; } @@ -123,7 +153,7 @@ const char * _PDCLIB_scan( const char * spec, struct _PDCLIB_status_t * status ) /* Initializing status structure */ status->flags = 0; status->base = -1; - status->this = 0; + status->current = 0; status->width = 0; status->prec = 0; @@ -242,7 +272,7 @@ const char * _PDCLIB_scan( const char * spec, struct _PDCLIB_status_t * status ) status->width = 1; } /* reading until width reached or input exhausted */ - while ( ( status->this < status->width ) && + while ( ( status->current < status->width ) && ( ( rc = GET( status ) ) != EOF ) ) { *(c++) = rc; @@ -267,7 +297,7 @@ const char * _PDCLIB_scan( const char * spec, struct _PDCLIB_status_t * status ) case 's': { char * c = va_arg( status->arg, char * ); - while ( ( status->this < status->width ) && + while ( ( status->current < status->width ) && ( ( rc = GET( status ) ) != EOF ) ) { if ( isspace( rc ) ) @@ -327,12 +357,24 @@ const char * _PDCLIB_scan( const char * spec, struct _PDCLIB_status_t * status ) } while ( *endspec != ']' ); // read according to scanlist, equiv. to %s above char * c = va_arg( status->arg, char * ); - while ( ( status->this < status->width ) && + while ( ( status->current < status->width ) && ( ( rc = GET( status ) ) != EOF ) ) { - if ( NOT_IN_SCANSET( spec, endspec, negative_scanlist, rc ) ) + if ( negative_scanlist ) { - break; + if ( IN_SCANSET( spec, endspec, rc ) ) + { + UNGET( rc, status ); + break; + } + } + else + { + if ( ! IN_SCANSET( spec, endspec, rc ) ) + { + UNGET( rc, status ); + break; + } } value_parsed = true; *(c++) = rc; @@ -345,7 +387,7 @@ const char * _PDCLIB_scan( const char * spec, struct _PDCLIB_status_t * status ) } else { - if ( status->n == 0 ) + if ( rc == EOF ) { status->n = -1; } @@ -373,7 +415,7 @@ const char * _PDCLIB_scan( const char * spec, struct _PDCLIB_status_t * status ) uintmax_t value = 0; /* absolute value read */ bool prefix_parsed = false; int sign = 0; - while ( ( status->this < status->width ) && + while ( ( status->current < status->width ) && ( ( rc = GET( status ) ) != EOF ) ) { if ( isspace( rc ) ) @@ -387,7 +429,7 @@ const char * _PDCLIB_scan( const char * spec, struct _PDCLIB_status_t * status ) else { /* leading whitespace not counted against width */ - status->this--; + status->current--; } } else if ( ! sign ) @@ -425,7 +467,7 @@ const char * _PDCLIB_scan( const char * spec, struct _PDCLIB_status_t * status ) { /* starts with zero, so it might be a prefix. */ /* check what follows next (might be 0x...) */ - if ( ( status->this < status->width ) && + if ( ( status->current < status->width ) && ( ( rc = GET( status ) ) != EOF ) ) { if ( tolower( rc ) == 'x' ) @@ -522,14 +564,34 @@ const char * _PDCLIB_scan( const char * spec, struct _PDCLIB_status_t * status ) #ifdef TEST +#define _PDCLIB_FILEID "_PDCLIB/scan.c" +#define _PDCLIB_STRINGIO + #include <_PDCLIB_test.h> -#include +static int testscanf( char const * s, char const * format, ... ) +{ + struct _PDCLIB_status_t status; + status.n = 0; + status.i = 0; + status.s = (char *)s; + status.stream = NULL; + va_start( status.arg, format ); + if ( *(_PDCLIB_scan( format, &status )) != '\0' ) + { + printf( "_PDCLIB_scan() did not return end-of-specifier on '%s'.\n", format ); + ++TEST_RESULTS; + } + va_end( status.arg ); + return status.n; +} + +#define TEST_CONVERSION_ONLY - int main( void ) { - /* Testing covered by fscanf.c */ + char source[100]; +#include "scanf_testcases.h" return TEST_RESULTS; }