stdio: more syntaxic refactoring of scanf

This commit is contained in:
Lephenixnoir 2024-01-14 21:27:48 +01:00
parent 9f6e0c8039
commit 527c2e48fc
No known key found for this signature in database
GPG key ID: 1BBA026E13FC0495

View file

@ -273,39 +273,28 @@ int __scanf(
char const * __restrict__ format, char const * __restrict__ format,
va_list *args) va_list *args)
{ {
/* Number of successful assignments */
in->bytes_read = 0; // we haven't started to read char from the input stream int validrets = 0;
int validrets = 0; // to be incremented each time we successfully read and store an input as per the format
int err = 0; // err control on __strto_xx( ) functions
int pos = 0; // current pos in the format string
__scanf_start( in ); __scanf_start( in );
// TODO: No __scanf_end() in any of the "return validrets"!! // TODO: No __scanf_end() in any of the "return validrets"!!
for(; format[pos]; pos++) { for(int pos = 0; format[pos]; pos++) {
if(format[pos] == ' ') { if(format[pos] == ' ') {
__purge_space(in); __purge_space(in);
continue; continue;
} }
else if(format[pos] != '%') { else if(format[pos] != '%' || format[pos + 1] == '%') {
// if the next char of the stream is corresponding, we validate the read and go to the following char /* Expect this specific character */
if(format[pos] == __scanf_peek( in )) { if(__scanf_peek(in) != format[pos])
__scanf_in( in ); return validrets;
pos++; __scanf_in(in);
continue; pos += (format[pos] == '%');
}
else return validrets; // else we return the number of valid read
}
else if(format[pos + 1] == '%') {
if(__scanf_peek(in) != '%') return validrets;
else __scanf_in( in );
pos++;
continue; continue;
} }
/* Perform a conversion */ /* Perform a conversion */
else {
struct scanf_format opt; struct scanf_format opt;
int spec = parse_fmt(format, &pos, &opt); int spec = parse_fmt(format, &pos, &opt);
if(spec == 0) if(spec == 0)
@ -353,12 +342,12 @@ int __scanf(
bool use_unsigned = (f == 'o' || f == 'x' || f == 'X'); bool use_unsigned = (f == 'o' || f == 'x' || f == 'X');
long long int temp; long long int temp;
err = __strto_int(in, base, NULL, &temp, use_unsigned, int err = __strto_int(in, base, NULL, &temp, use_unsigned,
opt.field_width); opt.field_width);
if (err == EOF && validrets == 0) return EOF; if(err == EOF && validrets == 0) return EOF;
if (err != 0) return validrets; if(err) return validrets;
if(!opt.skip) if(!opt.skip)
__scanf_store_i( temp, opt.size, args ); __scanf_store_i(temp, opt.size, args);
validrets++; validrets++;
break; break;
} }
@ -374,27 +363,25 @@ int __scanf(
// read a double from the current input stream // read a double from the current input stream
// and store in the corresponding arg as a char by reference // and store in the corresponding arg as a char by reference
long double temp; long double temp;
err = __strto_fp( in, NULL, NULL, &temp, int err = __strto_fp(in, NULL, NULL, &temp, opt.field_width);
opt.field_width); if(err == EOF && validrets == 0) return EOF;
if (err == EOF && validrets == 0) return EOF; if(err) return validrets;
if (err != 0) return validrets;
if(!opt.skip) if(!opt.skip)
__scanf_store_d( temp, opt.size, args ); __scanf_store_d(temp, opt.size, args);
validrets++; validrets++;
break; break;
} }
case 'p': { case 'p': {
long int temp; long int temp;
if (!opt.skip) { int err = 0;
void *p = (void *) va_arg( *args, void** ); // get the adress of the target pointer (void**) if(!opt.skip) {
err = __strto_int( in, 0, p, NULL, true, void *p = va_arg(*args, void *);
opt.field_width); err = __strto_int(in, 0, p, NULL, true, opt.field_width);
validrets += (err == 0);
} }
else err = __strto_int( in, 0, &temp, NULL, true, else err = __strto_int(in, 0, &temp, NULL, true, opt.field_width);
opt.field_width); if(err) return validrets;
if (err == 0) validrets++;
else return validrets;
break; break;
} }
@ -427,7 +414,7 @@ int __scanf(
break; break;
} }
else { else {
int temp = __scanf_in( in ); int temp = __scanf_in(in);
if(c) if(c)
*c++ = temp; *c++ = temp;
curstrlength++; curstrlength++;
@ -437,7 +424,6 @@ int __scanf(
} }
} }
} }
}
__scanf_end( in ); __scanf_end( in );
return validrets; return validrets;