forked from Vhex-Kernel-Core/fxlibc
skip parameter
This commit is contained in:
parent
00392b42a1
commit
af4692fe0b
|
@ -8,6 +8,7 @@ extern "C" {
|
|||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/*
|
||||
** General utilities for scanf(); we expose them here as we use subfunctions of
|
||||
|
@ -26,9 +27,12 @@ struct __scanf_input {
|
|||
int readmaxlength;
|
||||
int currentlength;
|
||||
|
||||
int skip;
|
||||
// total number of char read so far in the current call of a XYscanf() function (to return a %n when required)
|
||||
int readsofar;
|
||||
|
||||
bool purgewhitespace;
|
||||
|
||||
int buffer;
|
||||
};
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#include <ctype.h>
|
||||
#include <fxlibc/scanf.h>
|
||||
#include <fxlibc/stdlib_p.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
void __scanf_start(struct __scanf_input *in)
|
||||
{
|
||||
|
@ -40,6 +41,7 @@ void __scanf_end(struct __scanf_input *in)
|
|||
|
||||
enum
|
||||
{
|
||||
MODSKIP,
|
||||
MODSHORTSHORT,
|
||||
MODSHORT,
|
||||
MODNORMAL,
|
||||
|
@ -48,9 +50,15 @@ enum
|
|||
MODLONGDOUBLE,
|
||||
};
|
||||
|
||||
void __purge_space( struct __scanf_input * __restrict__ in )
|
||||
{
|
||||
while (isspace(__scanf_peek(in))) __scanf_in(in);
|
||||
}
|
||||
|
||||
void __scanf_store_i(int64_t value, int size, va_list *args)
|
||||
{
|
||||
if (size==MODSKIP) return;
|
||||
|
||||
if(size == MODSHORTSHORT)
|
||||
*va_arg(*args, int8_t *) = value;
|
||||
else if(size == MODSHORT)
|
||||
|
@ -63,6 +71,8 @@ void __scanf_store_i(int64_t value, int size, va_list *args)
|
|||
|
||||
void __scanf_store_d(long double value, int size, va_list *args)
|
||||
{
|
||||
if (size==MODSKIP) return;
|
||||
|
||||
if(size == MODLONG)
|
||||
*va_arg(*args, double *) = value;
|
||||
else if(size == MODLONGDOUBLE)
|
||||
|
@ -126,7 +136,8 @@ int __scanf(
|
|||
|
||||
in->readsofar = 0;
|
||||
in->readmaxlength = -1;
|
||||
|
||||
in->purgewhitespace = false;
|
||||
in->skip = false;
|
||||
|
||||
__scanf_start( in );
|
||||
|
||||
|
@ -137,17 +148,7 @@ int __scanf(
|
|||
|
||||
if ( format[i] == ' ' ) // a space in the format string mean that all white-space after the last read and before the next one are to be removed
|
||||
{
|
||||
char flush;
|
||||
for(;;)
|
||||
{
|
||||
flush = __scanf_peek( in ); // check if the next character is a whitespace
|
||||
if (isspace(flush))
|
||||
{
|
||||
flush = __scanf_in( in ); // if so, we remove it from the pile and advance
|
||||
}
|
||||
else break; // if not, we can move to the following
|
||||
}
|
||||
in->readmaxlength = -1;
|
||||
in->purgewhitespace = true;
|
||||
i++;
|
||||
}
|
||||
else if ( format[i] == '%' ) // read conversion
|
||||
|
@ -163,6 +164,12 @@ int __scanf(
|
|||
switch( format[i] )
|
||||
{
|
||||
|
||||
case '*':
|
||||
{
|
||||
in->skip = true;
|
||||
goto loopagain;
|
||||
}
|
||||
|
||||
case 'h': // we start with MODNORMAL and decrease the length first to MODSHORT and after to MODSHORTSHORT
|
||||
{
|
||||
if(mod==MODNORMAL)
|
||||
|
@ -225,30 +232,58 @@ int __scanf(
|
|||
|
||||
case '%':
|
||||
{
|
||||
char c = __scanf_peek( in );
|
||||
if (c=='%')
|
||||
{
|
||||
__scanf_in( in );
|
||||
ret++;
|
||||
}
|
||||
else return ret++; // TODO check if needed
|
||||
|
||||
// NOthing to do this is just the character '%'
|
||||
in->readmaxlength = -1;
|
||||
in->purgewhitespace = false;
|
||||
in->skip = false;
|
||||
break;
|
||||
}
|
||||
|
||||
case 'c':
|
||||
{
|
||||
if (in->purgewhitespace==true)
|
||||
{
|
||||
__purge_space( in );
|
||||
in->purgewhitespace=false;
|
||||
}
|
||||
|
||||
// read a char from the current input stream
|
||||
// and store in the corresponding arg as a char by reference
|
||||
char *c = (char *) va_arg( *args, char* );
|
||||
|
||||
if (in->readmaxlength==-1)
|
||||
{
|
||||
*c = __scanf_in( in );
|
||||
if (in->skip==false) *c = __scanf_in( in );
|
||||
else
|
||||
{
|
||||
char dummy = __scanf_in( in );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(int u = 0; u < in->readmaxlength; u++ )
|
||||
{
|
||||
*c = __scanf_in( in );
|
||||
c++;
|
||||
if (in->skip==false)
|
||||
{
|
||||
*c = __scanf_in( in );
|
||||
c++;
|
||||
}
|
||||
else
|
||||
{
|
||||
char dummy = __scanf_in( in );
|
||||
}
|
||||
}
|
||||
}
|
||||
in->readmaxlength=-1;
|
||||
in->skip = false;
|
||||
ret++;
|
||||
|
||||
break;
|
||||
|
@ -258,11 +293,14 @@ int __scanf(
|
|||
{
|
||||
// read a long int (in base 10 - decimal) from the current input stream
|
||||
// and store in the corresponding arg as a char by reference
|
||||
in->purgewhitespace = false;
|
||||
long long int temp;
|
||||
err = __strto_int( in, 10, NULL, &temp, false ); // base is 10 as for strtol
|
||||
if (err == 0)
|
||||
{
|
||||
__scanf_store_i( temp, mod, args );
|
||||
if (in->skip==false) __scanf_store_i( temp, mod, args );
|
||||
else __scanf_store_i( temp, MODSKIP, args );
|
||||
in->skip = false;
|
||||
mod = MODNORMAL;
|
||||
ret++;
|
||||
}
|
||||
|
@ -273,12 +311,14 @@ int __scanf(
|
|||
{
|
||||
// read a long int (in base determined by the first character) from the current input stream
|
||||
// and store in the corresponding arg as a char by reference
|
||||
|
||||
in->purgewhitespace = false;
|
||||
long long int temp;
|
||||
err = __strto_int( in, 0, NULL, &temp, false ); // base is 0 as for strtol
|
||||
if (err == 0)
|
||||
{
|
||||
__scanf_store_i( temp, mod, args );
|
||||
if (in->skip==false) __scanf_store_i( temp, mod, args );
|
||||
else __scanf_store_i( temp, MODSKIP, args );
|
||||
in->skip = false;
|
||||
mod = MODNORMAL;
|
||||
ret++;
|
||||
}
|
||||
|
@ -290,11 +330,14 @@ int __scanf(
|
|||
{
|
||||
// read a unsigned long int (in base 10 - decimal) from the current input stream
|
||||
// and store in the corresponding arg as a char by reference
|
||||
in->purgewhitespace = false;
|
||||
long long int temp;
|
||||
err = __strto_int( in, 10, NULL, &temp, true ); // base is 10 as for strtol
|
||||
if (err == 0)
|
||||
{
|
||||
__scanf_store_i( temp, mod, args );
|
||||
if (in->skip==false) __scanf_store_i( temp, mod, args );
|
||||
else __scanf_store_i( temp, MODSKIP, args );
|
||||
in->skip = false;
|
||||
mod = MODNORMAL;
|
||||
ret++;
|
||||
}
|
||||
|
@ -305,11 +348,14 @@ int __scanf(
|
|||
{
|
||||
// read a unsigned long int (in base 8 - octal) from the current input stream
|
||||
// and store in the corresponding arg as a char by reference
|
||||
in->purgewhitespace = false;
|
||||
long long int temp;
|
||||
err = __strto_int( in, 8, NULL, &temp, true ); // base is 8 as for strtol
|
||||
if (err == 0)
|
||||
{
|
||||
__scanf_store_i( temp, mod, args );
|
||||
if (in->skip==false) __scanf_store_i( temp, mod, args );
|
||||
else __scanf_store_i( temp, MODSKIP, args );
|
||||
in->skip = false;
|
||||
mod = MODNORMAL;
|
||||
ret++;
|
||||
}
|
||||
|
@ -321,11 +367,14 @@ int __scanf(
|
|||
{
|
||||
// read a unsigned long int (in base 16 - hexadecimal) from the current input stream
|
||||
// and store in the corresponding arg as a char by reference
|
||||
in->purgewhitespace = false;
|
||||
long long int temp;
|
||||
err = __strto_int( in, 16, NULL, &temp, true ); // base is 16 as for strtol
|
||||
if (err == 0)
|
||||
{
|
||||
__scanf_store_i( temp, mod, args );
|
||||
if (in->skip==false) __scanf_store_i( temp, mod, args );
|
||||
else __scanf_store_i( temp, MODSKIP, args );
|
||||
in->skip = false;
|
||||
mod = MODNORMAL;
|
||||
ret++;
|
||||
}
|
||||
|
@ -341,11 +390,14 @@ int __scanf(
|
|||
case 'g':
|
||||
case 'G':
|
||||
{
|
||||
in->purgewhitespace = false;
|
||||
long double temp;
|
||||
err = __strto_fp( in, NULL, NULL, &temp );
|
||||
if (err == 0)
|
||||
{
|
||||
__scanf_store_d( temp, mod, args );
|
||||
if (in->skip==false) __scanf_store_d( temp, mod, args );
|
||||
else __scanf_store_d( temp, MODSKIP, args );
|
||||
in->skip = false;
|
||||
mod = MODNORMAL;
|
||||
ret++;
|
||||
}
|
||||
|
@ -354,6 +406,9 @@ int __scanf(
|
|||
|
||||
case 's':
|
||||
{
|
||||
__purge_space( in );
|
||||
in->purgewhitespace=false;
|
||||
|
||||
// read a serie of non whitespace char from the current input stream
|
||||
// and store in the corresponding arg as a char by reference
|
||||
char *c = (char *) va_arg( *args, char* );
|
||||
|
@ -365,8 +420,15 @@ int __scanf(
|
|||
temp = __scanf_peek( in );
|
||||
if (!isspace(temp) && temp != EOF)
|
||||
{
|
||||
*c = __scanf_in( in );
|
||||
c++;
|
||||
if (in->skip == false )
|
||||
{
|
||||
*c = __scanf_in( in );
|
||||
c++;
|
||||
}
|
||||
else
|
||||
{
|
||||
char dummy = __scanf_in( in );
|
||||
}
|
||||
}
|
||||
else break;
|
||||
}
|
||||
|
@ -379,8 +441,15 @@ int __scanf(
|
|||
temp = __scanf_peek( in );
|
||||
if (!isspace(temp) && temp != EOF)
|
||||
{
|
||||
*c = __scanf_in( in );
|
||||
c++;
|
||||
if (in->skip == false )
|
||||
{
|
||||
*c = __scanf_in( in );
|
||||
c++;
|
||||
}
|
||||
else
|
||||
{
|
||||
char dummy = __scanf_in( in );
|
||||
}
|
||||
}
|
||||
else break;
|
||||
}
|
||||
|
@ -393,6 +462,7 @@ int __scanf(
|
|||
|
||||
case 'n':
|
||||
{
|
||||
in->purgewhitespace = false;
|
||||
// rreturn the number of characters read so far
|
||||
int *n = (int *) va_arg( *args, int* );
|
||||
*n = in->readsofar;
|
||||
|
@ -403,15 +473,36 @@ int __scanf(
|
|||
|
||||
case 'p':
|
||||
{
|
||||
void *p = (void *) va_arg( *args, void** ); // get the adress of the target pointer (void**)
|
||||
err = __strto_int( in, 0, p, NULL, true );
|
||||
/* FORMER CODE
|
||||
void *p = (void *) va_arg( *args, void** ); // get the adress of the target pointer (void**)
|
||||
err = __strto_int( in, 0, p, NULL, true );
|
||||
if (err == 0) ret++;
|
||||
*/
|
||||
|
||||
|
||||
in->purgewhitespace = false;
|
||||
long int dummy;
|
||||
err = __strto_int( in, 0, &dummy, NULL, true );
|
||||
|
||||
if (in->skip == false)
|
||||
{
|
||||
void *p = (void *) va_arg( *args, void** ); // get the adress of the target pointer (void**)
|
||||
p=(void*) dummy;
|
||||
}
|
||||
|
||||
if (err == 0) ret++;
|
||||
|
||||
in->skip = false;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else i++;
|
||||
else
|
||||
{
|
||||
if (format[i] == __scanf_in( in )) i++;
|
||||
else err=1;
|
||||
}
|
||||
|
||||
if (err!=0) break; // an error occured somewhere whiloe parsing the values
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue