stdio: deduplicate scanf cases and remove most gotos

This commit is contained in:
Lephenixnoir 2024-01-14 20:07:24 +01:00
parent b11c059c0f
commit 69eadb67d2
No known key found for this signature in database
GPG key ID: 1BBA026E13FC0495

View file

@ -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 */ /* 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,9 +200,7 @@ int __scanset(char const * __restrict__ format, int *pos )
} }
} }
// start of format analysis loop while(1) {
loopset:
// we find a '-' so need to check if we are considering a range or the char '-' only // we find a '-' so need to check if we are considering a range or the char '-' only
if (format[*pos]=='-') { if (format[*pos]=='-') {
// the char '-' is included in the allowed set // the char '-' is included in the allowed set
@ -217,7 +215,6 @@ int __scanset(char const * __restrict__ format, int *pos )
(*pos)++; (*pos)++;
__eor = format[*pos]; __eor = format[*pos];
__define_set_range( __sor, __eor, !__neg ); __define_set_range( __sor, __eor, !__neg );
goto loopset;
} }
} }
// we find the char ']' so it means we reach the end of this set // we find the char ']' so it means we reach the end of this set
@ -229,7 +226,7 @@ int __scanset(char const * __restrict__ format, int *pos )
__sor = format[*pos]; __sor = format[*pos];
__asciiallowed[ __sor ] = !__neg; __asciiallowed[ __sor ] = !__neg;
(*pos)++; (*pos)++;
goto loopset; }
} }
} }
@ -255,6 +252,8 @@ int __scanf(
__scanf_start( in ); __scanf_start( in );
// TODO: No __scanf_end() in any of the "return validrets"!!
while( format[pos] != 0 ) { while( format[pos] != 0 ) {
in->readmaxlength = -1; in->readmaxlength = -1;
user_length = 0; user_length = 0;
@ -278,83 +277,26 @@ int __scanf(
switch( format[pos] ) { switch( format[pos] ) {
// we need to decrypt the corresponding scanf set of character // we need to decrypt the corresponding scanf set of character
case '[': { case '[': {
char temp;
err = __scanset( format, &pos ); err = __scanset( format, &pos );
if (err!=0) return validrets; if (err!=0) return validrets;
int currentlength = 0; int currentlength = 0;
// we need to assign the read char to the corresponding pointer // we need to assign the read char to the corresponding pointer
if (!skip) { char *c = skip ? NULL : va_arg(*args, char *);
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; u<in->readmaxlength; u++) { for(unsigned int u=0; u<in->readmaxlength; u++) {
temp = __scanf_peek( in ); int temp = __scanf_peek(in);
if (temp==EOF) return EOF; if(__is_allowed(temp)) {
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;
}
}
else
{
if (in->readmaxlength==INT_MAX) {
for(;;) {
temp = __scanf_peek( in );
if (temp==EOF) return EOF;
else if (__is_allowed( temp )) {
__scanf_in(in); __scanf_in(in);
if(c) *c++ = temp;
currentlength++; currentlength++;
} }
else if (currentlength>0) goto exitset; else if(temp==EOF && !currentlength && !validrets)
else return validrets; return EOF;
else break;
} }
} if(!currentlength)
else { return validrets;
for(unsigned int u=0; u<in->readmaxlength; u++) { *c = '\0';
temp = __scanf_peek( in ); validrets += !skip;
if (temp==EOF) return EOF;
else if (__is_allowed( temp )) __scanf_in( in );
else if (currentlength>0) goto exitset;
else return validrets;
}
}
}
exitset:
break; break;
} }
@ -499,44 +441,16 @@ int __scanf(
} }
case 'c': { case 'c': {
int temp; if(in->readmaxlength == INT_MAX)
if (!skip) { in->readmaxlength = 1;
char *c = (char *) va_arg( *args, char* ); char *c = skip ? NULL : 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++; for(unsigned int u = 0; u < in->readmaxlength; u++) {
int temp = __scanf_in(in);
endcharskip: if(temp==EOF) return EOF;
else if(c) *c++ = temp;
}
validrets += !skip;
break; break;
} }
@ -544,66 +458,25 @@ int __scanf(
char temp; char temp;
int curstrlength = 0; int curstrlength = 0;
__purge_space(in); __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;
}
}
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++;
}
}
}
}
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: 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++; validrets++;
}
loopstringendskip: break;
}
else {
int temp = __scanf_in( in );
if(c)
*c++ = temp;
curstrlength++;
}
}
break; break;
} }
} }