stdio: more compact scanf format parsing

This commit is contained in:
Lephenixnoir 2024-01-14 21:34:46 +01:00
parent 527c2e48fc
commit 177c4eea3f
Signed by: Lephenixnoir
GPG Key ID: 1BBA026E13FC0495
1 changed files with 31 additions and 60 deletions

View File

@ -191,79 +191,52 @@ static int parse_fmt(char const *fmt, int *pos, struct scanf_format *opt)
int width = 0;
char size_letter = 0;
while(1) {
(*pos)++;
for((*pos)++;; (*pos)++) {
int c = fmt[*pos];
switch(fmt[*pos]) {
case '*':
if(c == '*')
opt->skip = true;
break;
else if(strchr("hlzjtL", c)) {
if(c == 'h')
opt->size = (size_letter=='h') ? sizeof(char) : sizeof(short);
else if(c == 'l')
opt->size = (size_letter=='l') ? sizeof(long long) :
sizeof(long);
else if(c == 'z')
opt->size = sizeof(size_t);
else if(c == 'j')
opt->size = sizeof(intmax_t);
else if(c == 't')
opt->size = sizeof(ptrdiff_t);
else if(c == 'L')
opt->size = sizeof(long double);
case 'h':
opt->size = (size_letter=='h') ? sizeof(char) : sizeof(short);
size_letter = 'h';
break;
case 'l':
opt->size = (size_letter=='l') ? sizeof(long long) : sizeof(long);
size_letter = 'l';
break;
case 'L':
opt->size = sizeof(long double);
size_letter = 'L';
break;
case 'j':
opt->size = sizeof(intmax_t);
break;
case 'z':
opt->size = sizeof(size_t);
break;
case 't':
opt->size = sizeof(ptrdiff_t);
break;
case '0' ... '9':
size_letter = c;
}
else if(isdigit(c)) {
width = width * 10 + (fmt[*pos] - '0');
opt->field_width = width;
break;
case '[':
}
else if(c == '[') {
(*pos)++;
return bracket_set_parse(opt->bracket_set, fmt, pos) ? '[' : 0;
case 'd':
case 'i':
case 'o':
case 'u':
case 'x':
case 'X':
case 'p':
case 's':
case 'n':
return fmt[*pos];
case 'a':
case 'A':
case 'e':
case 'E':
case 'f':
case 'F':
case 'g':
case 'G':
}
else if(strchr("diouxXpsn", c))
return c;
else if(strchr("aAeEfFgG", c)) {
/* Adjust interpretation of no size / 'l' size */
if(size_letter == 0)
opt->size = sizeof(float);
if(size_letter == 'l')
opt->size = sizeof(double);
return fmt[*pos];
case 'c':
return c;
}
else if(c == 'c') {
if(opt->field_width == INT_MAX)
opt->field_width = 1;
return 'c';
default:
return 0;
return c;
}
else return 0;
}
return 0;
}
@ -301,7 +274,6 @@ int __scanf(
return validrets;
switch(spec) {
// we need to decrypt the corresponding scanf set of character
case '[': {
int currentlength = 0;
// we need to assign the read char to the corresponding pointer
@ -324,7 +296,6 @@ int __scanf(
break;
}
// return the number of char read so far (cannot be skipped %*n is not valid)
case 'n':
*va_arg(*args, int *) = in->bytes_read;
break;