if ( rc != EOF )
{
++(status->i);
- ++(status->this);
+ ++(status->current);
}
return rc;
}
--(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;
}
/* Initializing status structure */
status->flags = 0;
status->base = -1;
- status->this = 0;
+ status->current = 0;
status->width = 0;
status->prec = 0;
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;
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 ) )
} 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;
}
else
{
- if ( status->n == 0 )
+ if ( rc == EOF )
{
status->n = -1;
}
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 ) )
else
{
/* leading whitespace not counted against width */
- status->this--;
+ status->current--;
}
}
else if ( ! sign )
{
/* 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' )
#ifdef TEST
+#define _PDCLIB_FILEID "_PDCLIB/scan.c"
+#define _PDCLIB_STRINGIO
+
#include <_PDCLIB_test.h>
-#include <limits.h>
+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;
}