forked from Vhex-Kernel-Core/fxlibc
working and tested scanf functions all done except j/z/t modifiers
This commit is contained in:
parent
9e99da0dff
commit
5400182d05
|
@ -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 );
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue