working and tested scanf functions all done except j/z/t modifiers

This commit is contained in:
Sylvain PILLOT 2023-03-04 13:35:43 +01:00
parent 9e99da0dff
commit 5400182d05
1 changed files with 238 additions and 3 deletions

View File

@ -109,8 +109,6 @@ void __scanf_store_d(long double value, int size, va_list *args)
/*************************************************************************************************************/
/* x,X * match a unsigned hexadecimal integer * OK * OK * OK * OK * OK * OK * XX * XX * XX * -- */
/*************************************************************************************************************/
/* d * match a decimal integer * OK * OK * OK * OK * OK * OK * XX * XX * XX * -- */
/*************************************************************************************************************/
/* n * return the nb of chars read so far * -- * -- * -- * OK * -- * -- * -- * -- * -- * -- */
/*************************************************************************************************************/
/* a,A * match a floating point number * OK * -- * -- * OK * OK * -- * -- * -- * -- * OK */
@ -147,6 +145,119 @@ void __scanf_store_d(long double value, int size, va_list *args)
#endif
bool __asciiallowed[256] = { true };
void __unallow_all_set( void )
{
for(int u =0; u<=255; u++)
__asciiallowed[u]=false;
}
void __allow_all_set( void )
{
for(int u =0; u<=255; u++)
__asciiallowed[u]=true;
}
void __define_set_range( char c1, char c2, bool value )
{
if (c1<c2)
{
for (int u=c1; u<=c2; u++)
__asciiallowed[u] = value;
}
else
{
for (int u=c2; u<=c1; u++)
__asciiallowed[u] = value;
}
}
bool __is_allowed( const unsigned char c )
{
return __asciiallowed[ c ];
}
void __scanset(char const * __restrict__ format, int *pos )
{
int START_OF_RANGE = 0;
int END_OF_RANGE = 0;
bool NEGATE = false;
__unallow_all_set();
(*pos)++;
if (format[*pos] == '^' ) // next will be a "negation" set
{
NEGATE = true;
(*pos)++;
__allow_all_set();
if (format[*pos] == ']' ) // the char ']' is part of the set
{
__asciiallowed[ ']' ] = !NEGATE;
(*pos)++;
}
}
else if (format[*pos] == ']' ) // the char ']' is included in the allowed set
{
NEGATE = false;
if (format[*pos] == ']' ) // the char ']' is part of the set
{
__asciiallowed[ ']' ] = !NEGATE;
(*pos)++;
}
}
loopset:
if (format[*pos]=='-')
{
if (format[*pos+1]==']') // the char '-' is included in the allowed set
{
__asciiallowed[ '-' ] = !NEGATE;
(*pos)++;
// we have now finished the reading of the set
goto loopexit;
}
else // the char '-' indicates a range of char to be included into the set
{
(*pos)++;
END_OF_RANGE = format[*pos];
__define_set_range( START_OF_RANGE, END_OF_RANGE, !NEGATE );
goto loopset;
}
}
else if (format[*pos]==']')
{
goto loopexit;
}
else // we are considering one particular char
{
START_OF_RANGE = format[*pos];
__asciiallowed[ START_OF_RANGE ] = !NEGATE;
(*pos)++;
goto loopset;
}
loopexit:
/*
for(int u=0;u<=255; u++ )
if (__asciiallowed[u]==true) DBGPrint( u );
*/
}
int __scanf(
struct __scanf_input * __restrict__ in,
char const * __restrict__ format,
@ -154,6 +265,7 @@ int __scanf(
{
bool SKIP = false;
int MOD = MODNORMAL;
in->readsofar = 0; // we haven't started to read char from the input stream
@ -181,6 +293,7 @@ int __scanf(
MOD = MODNORMAL;
SKIP = false;
__allow_all_set();
if( format[pos] == '%' ) // we will have to manage a given format
{
@ -196,6 +309,123 @@ int __scanf(
switch( format[pos] )
{
case '[': // we need to decrypt the corresponding scanf set of character
{
__scanset( format, &pos );
char dummy;
int currentlength = 0;
if (SKIP == false)
{
char *c = (char *) va_arg( *args, char* );
if (in->readmaxlength==-1)
{
for(;;)
{
dummy = __scanf_peek( in );
if (dummy==EOF) return EOF;
else if (__is_allowed( dummy ))
{
*c++ = __scanf_in( in );
currentlength++;
}
else
{
if (currentlength>0)
{
*c = '\0';
goto validatesetout;
}
else return VALIDRETS;
}
}
}
else
{
for( int u = 0; u < in->readmaxlength; u++ )
{
dummy = __scanf_peek( in );
if (dummy==EOF) return EOF;
else if (__is_allowed( dummy ))
{
*c++ = __scanf_in( in );
currentlength++;
}
else
{
if (currentlength>0)
{
*c = '\0';
goto validatesetout;
}
else return VALIDRETS;
}
}
if (currentlength>0)
{
*c = '\0';
goto validatesetout;
}
else return VALIDRETS;
}
}
else
{
if (in->readmaxlength==-1)
{
for(;;)
{
dummy = __scanf_peek( in );
if (dummy==EOF) return EOF;
else if (__is_allowed( dummy ))
{
__scanf_in( in );
currentlength++;
}
else
{
if (currentlength>0)
{
goto validatesetout;
}
else return VALIDRETS;
}
}
}
else
{
for( int u = 0; u < in->readmaxlength; u++ )
{
dummy = __scanf_peek( in );
if (dummy==EOF) return EOF;
else if (__is_allowed( dummy )) __scanf_in( in );
else
{
if (currentlength>0)
{
goto validatesetout;
}
else return VALIDRETS;
}
}
}
}
validatesetout:
VALIDRETS++;
endsetkip:
break;
}
case 'n': // return the number of char read so far (cannot be skipped %*n is not valid)
{
DBG( "'n' read");
@ -218,6 +448,7 @@ int __scanf(
SKIP = true;
goto loopagain;
break;
}
case 'h':
@ -228,6 +459,7 @@ int __scanf(
goto loopagain;
}
else return VALIDRETS; // we cannot have %hhh format modifier --> ERROR
break;
}
case 'l':
@ -238,6 +470,7 @@ int __scanf(
goto loopagain;
}
else return VALIDRETS; // we cannot have %ll format modifier --> ERROR
break;
}
case 'L':
@ -248,6 +481,7 @@ int __scanf(
goto loopagain;
}
else return VALIDRETS; // we cannot have %LL format modifier --> ERROR
break;
}
case '0':
@ -264,6 +498,7 @@ int __scanf(
user_length = user_length * 10 + (int) ( format[pos] - '0' );
in->readmaxlength = user_length;
goto loopagain;
break;
}
case 'd':
@ -416,7 +651,7 @@ int __scanf(
dummy = __scanf_peek( in );
if (dummy==EOF) return EOF;
else
else
{
*c++ = __scanf_in( in );
}