From 69eadb67d2e5b7c2207de066c1a13aaa8614bf00 Mon Sep 17 00:00:00 2001 From: Lephenixnoir Date: Sun, 14 Jan 2024 20:07:24 +0100 Subject: [PATCH] stdio: deduplicate scanf cases and remove most gotos --- src/stdio/scanf/scan.c | 257 +++++++++++------------------------------ 1 file changed, 65 insertions(+), 192 deletions(-) diff --git a/src/stdio/scanf/scan.c b/src/stdio/scanf/scan.c index 9643852..f6684ca 100644 --- a/src/stdio/scanf/scan.c +++ b/src/stdio/scanf/scan.c @@ -161,9 +161,9 @@ void __define_set_range( char c1, char c2, bool value ) } /* return true if the char is in the allowed set or false otherwise */ -bool __is_allowed( const unsigned char c ) +bool __is_allowed(int c) { - return __asciiallowed[ c ]; + return (c != EOF) && __asciiallowed[c]; } @@ -200,37 +200,34 @@ int __scanset(char const * __restrict__ format, int *pos ) } } - // start of format analysis loop - loopset: - - // we find a '-' so need to check if we are considering a range or the char '-' only - if (format[*pos]=='-') { - // the char '-' is included in the allowed set - if (format[*pos+1]==']') { - __asciiallowed[ '-' ] = !__neg; // if set in very final position before']', this is the char '-' only - (*pos)++; - // we have now finished the reading of the set cause the following char is ']' - return 0; + while(1) { + // we find a '-' so need to check if we are considering a range or the char '-' only + if (format[*pos]=='-') { + // the char '-' is included in the allowed set + if (format[*pos+1]==']') { + __asciiallowed[ '-' ] = !__neg; // if set in very final position before']', this is the char '-' only + (*pos)++; + // we have now finished the reading of the set cause the following char is ']' + return 0; + } + // the char '-' indicates a range of char to be included into the set + else { + (*pos)++; + __eor = format[*pos]; + __define_set_range( __sor, __eor, !__neg ); + } } - // the char '-' indicates a range of char to be included into the set + // we find the char ']' so it means we reach the end of this set + else if (format[*pos]==']') return 0; + // if we reach the '\0' we have a syntax problem + else if (format[*pos]=='\0') return -1; + // we are considering one particular char and prepare for a potential range if we find the char '-' later on else { + __sor = format[*pos]; + __asciiallowed[ __sor ] = !__neg; (*pos)++; - __eor = format[*pos]; - __define_set_range( __sor, __eor, !__neg ); - goto loopset; } } - // we find the char ']' so it means we reach the end of this set - else if (format[*pos]==']') return 0; - // if we reach the '\0' we have a syntax problem - else if (format[*pos]=='\0') return -1; - // we are considering one particular char and prepare for a potential range if we find the char '-' later on - else { - __sor = format[*pos]; - __asciiallowed[ __sor ] = !__neg; - (*pos)++; - goto loopset; - } } @@ -255,6 +252,8 @@ int __scanf( __scanf_start( in ); + // TODO: No __scanf_end() in any of the "return validrets"!! + while( format[pos] != 0 ) { in->readmaxlength = -1; user_length = 0; @@ -278,83 +277,26 @@ int __scanf( switch( format[pos] ) { // we need to decrypt the corresponding scanf set of character case '[': { - char temp; err = __scanset( format, &pos ); if (err!=0) return validrets; int currentlength = 0; // we need to assign the read char to the corresponding pointer - if (!skip) { - char *c = (char *) va_arg( *args, char* ); - if (in->readmaxlength==INT_MAX) { - for(;;) { - temp = __scanf_peek( in ); - if (temp==EOF) return EOF; - else if (__is_allowed( temp )) { - *c++ = __scanf_in( in ); - currentlength++; - } - else { - if (currentlength>0) { - *c = '\0'; - validrets++; - goto exitset; - } - else return validrets; - } - } - } - else { - for(unsigned int u=0; ureadmaxlength; u++) { - temp = __scanf_peek( in ); - if (temp==EOF) return EOF; - else if (__is_allowed( temp )) { - *c++ = __scanf_in( in ); - currentlength++; - } - else { - if (currentlength>0) { - *c = '\0'; - validrets++; - goto exitset; - } - else return validrets; - } - } - if (currentlength>0) { - *c = '\0'; - validrets++; - goto exitset; - } - else return validrets; + char *c = skip ? NULL : va_arg(*args, char *); + for(unsigned int u=0; ureadmaxlength; u++) { + int temp = __scanf_peek(in); + if(__is_allowed(temp)) { + __scanf_in(in); + if(c) *c++ = temp; + currentlength++; } + else if(temp==EOF && !currentlength && !validrets) + return EOF; + else break; } - - else - { - if (in->readmaxlength==INT_MAX) { - for(;;) { - temp = __scanf_peek( in ); - if (temp==EOF) return EOF; - else if (__is_allowed( temp )) { - __scanf_in( in ); - currentlength++; - } - else if (currentlength>0) goto exitset; - else return validrets; - } - } - else { - for(unsigned int u=0; ureadmaxlength; u++) { - temp = __scanf_peek( in ); - if (temp==EOF) return EOF; - else if (__is_allowed( temp )) __scanf_in( in ); - else if (currentlength>0) goto exitset; - else return validrets; - } - } - } - - exitset: + if(!currentlength) + return validrets; + *c = '\0'; + validrets += !skip; break; } @@ -499,111 +441,42 @@ int __scanf( } case 'c': { - int temp; - if (!skip) { - char *c = (char *) va_arg( *args, char* ); - if (in->readmaxlength==INT_MAX) { - temp = __scanf_peek( in ); - if (temp==EOF) return EOF; - else *c = __scanf_in( in ); - } - else { - for( unsigned int u = 0; u < in->readmaxlength; u++ ) { - temp = __scanf_peek( in ); - if (temp==EOF) return EOF; - else *c++ = __scanf_in( in ); - } - } - } - else { - if (in->readmaxlength==INT_MAX) { - temp = __scanf_peek( in ); - if (temp==EOF) return EOF; - else { - __scanf_in( in ); - goto endcharskip; - } - } - else { - for( unsigned int u = 0; u < in->readmaxlength; u++ ) { - temp = __scanf_peek( in ); - if (temp==EOF) return EOF; - else __scanf_in( in ); - } - goto endcharskip; - } - } - - validrets++; + if(in->readmaxlength == INT_MAX) + in->readmaxlength = 1; + char *c = skip ? NULL : va_arg(*args, char *); - endcharskip: + for(unsigned int u = 0; u < in->readmaxlength; u++) { + int temp = __scanf_in(in); + if(temp==EOF) return EOF; + else if(c) *c++ = temp; + } + validrets += !skip; break; } case 's': { char temp; int curstrlength = 0; - __purge_space( in ); - if (!skip) { - char *c = (char *) va_arg( *args, char* ); - if (in->readmaxlength==INT_MAX) { - loopstring: - temp = __scanf_peek( in ); - if (temp==EOF && curstrlength==0) return validrets; - if (isspace(temp) || ( (temp==EOF && curstrlength!=0) )) { - *c = 0; - goto loopstringend; - } - else { - *c++ = __scanf_in( in ); - curstrlength++; - goto loopstring; + __purge_space(in); + + char *c = skip ? NULL : va_arg(*args, char *); + for(unsigned int u = 0; u < in->readmaxlength; u++) { + temp = __scanf_peek(in); + if(temp==EOF && curstrlength==0) return validrets; + if(isspace(temp) || ((temp==EOF && curstrlength!=0))) { + if(c) { + *c = 0; + validrets++; } + break; } else { - for( unsigned int u = 0; u < in->readmaxlength; u++ ) { - temp = __scanf_peek( in ); - if (temp==EOF && curstrlength==0) return validrets; - if (isspace(temp) || ( (temp==EOF && curstrlength!=0) )) { - *c = 0; - goto loopstringend; - } - else { - *c++ = __scanf_in( in ); - curstrlength++; - } - } + int temp = __scanf_in( in ); + if(c) + *c++ = temp; + curstrlength++; } } - else { - if (in->readmaxlength==INT_MAX) { - loopstringskip: - temp = __scanf_peek( in ); - if (temp==EOF && curstrlength==0) return validrets; - if (isspace(temp) || ( (temp==EOF && curstrlength!=0) )) goto loopstringendskip; - else { - __scanf_in( in ); - curstrlength++; - goto loopstringskip; - } - } - else { - for( unsigned int u = 0; u < in->readmaxlength; u++ ) { - temp = __scanf_peek( in ); - if (temp==EOF && curstrlength==0) return validrets; - if (isspace(temp) || ( (temp==EOF && curstrlength!=0) )) goto loopstringendskip; - else { - __scanf_in( in ); - curstrlength++; - } - } - } - } - - loopstringend: - validrets++; - - loopstringendskip: break; } }