diff --git a/src/stdio/scanf/scan.c b/src/stdio/scanf/scan.c index 2e702d5..15673a2 100644 --- a/src/stdio/scanf/scan.c +++ b/src/stdio/scanf/scan.c @@ -248,183 +248,183 @@ int __scanf( pos++; - switch( format[pos] ) { - // we need to decrypt the corresponding scanf set of character - case '[': { - err = __scanset( format, &pos ); - if (err!=0) return validrets; - int currentlength = 0; - // we need to assign the read char to the corresponding pointer - char *c = skip ? NULL : va_arg(*args, char *); - for(int u=0; ubytes_read; - break; + if(!currentlength) + return validrets; + *c = '\0'; + validrets += !skip; + break; + } - // we are expecting the char '%' to be in the input stream, if not err and return - case '%': { - if (__scanf_peek(in) != '%') return validrets; - else __scanf_in( in ); - 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; - // the next read, even if valid, will not be stored - case '*': - skip = true; - goto loopagain; + // we are expecting the char '%' to be in the input stream, if not err and return + case '%': { + if (__scanf_peek(in) != '%') return validrets; + else __scanf_in( in ); + break; + } - case 'h': - MOD = (size_letter == 'h') ? sizeof(char) : sizeof(short); - size_letter = 'h'; - goto loopagain; - case 'l': - MOD = (size_letter == 'l') ? sizeof(long long) : sizeof(long); - /* FP conversions will adjust to sizeof(double) later */ - size_letter = 'l'; - goto loopagain; - case 'L': - MOD = sizeof(long double); - size_letter = 'L'; - goto loopagain; - case 'j': - MOD = sizeof(intmax_t); - goto loopagain; - case 'z': - MOD = sizeof(size_t); - goto loopagain; - case 't': - MOD = sizeof(ptrdiff_t); - goto loopagain; + // the next read, even if valid, will not be stored + case '*': + skip = true; + goto loopagain; - case '0' ... '9': { - user_length = user_length * 10 + (int) ( format[pos] - '0' ); - readmaxlength = user_length; - goto loopagain; - break; - } + case 'h': + MOD = (size_letter == 'h') ? sizeof(char) : sizeof(short); + size_letter = 'h'; + goto loopagain; + case 'l': + MOD = (size_letter == 'l') ? sizeof(long long) : sizeof(long); + /* FP conversions will adjust to sizeof(double) later */ + size_letter = 'l'; + goto loopagain; + case 'L': + MOD = sizeof(long double); + size_letter = 'L'; + goto loopagain; + case 'j': + MOD = sizeof(intmax_t); + goto loopagain; + case 'z': + MOD = sizeof(size_t); + goto loopagain; + case 't': + MOD = sizeof(ptrdiff_t); + goto loopagain; - case 'd': - case 'i': - case 'o': - case 'u': - case 'x': - case 'X': { - int f = format[pos]; - int base = (f == 'd' || f == 'u') ? 10 : - (f == 'o') ? 8: - (f == 'x' || f == 'X') ? 16 : 0; - bool use_unsigned = (f == 'o' || f == 'x' || f == 'X'); + case '0' ... '9': { + user_length = user_length * 10 + (int) ( format[pos] - '0' ); + readmaxlength = user_length; + goto loopagain; + break; + } - long long int temp; - err = __strto_int(in, base, NULL, &temp, use_unsigned, + case 'd': + case 'i': + case 'o': + case 'u': + case 'x': + case 'X': { + int f = format[pos]; + int base = (f == 'd' || f == 'u') ? 10 : + (f == 'o') ? 8: + (f == 'x' || f == 'X') ? 16 : 0; + bool use_unsigned = (f == 'o' || f == 'x' || f == 'X'); + + long long int temp; + err = __strto_int(in, base, NULL, &temp, use_unsigned, + readmaxlength); + if (err == EOF && validrets == 0) return EOF; + if (err != 0) return validrets; + if (skip) __scanf_store_i( temp, 0, args ); + else __scanf_store_i( temp, MOD, args ); + validrets++; + break; + } + + case 'a': + case 'A': + case 'e': + case 'E': + case 'f': + case 'F': + case 'g': + case 'G': { + /* Adjust interpretation of no size / 'l' size */ + if(size_letter == 0) + MOD = sizeof(float); + if(size_letter == 'l') + MOD = sizeof(double); + + // read a double from the current input stream + // and store in the corresponding arg as a char by reference + long double temp; + err = __strto_fp( in, NULL, NULL, &temp, + readmaxlength); + if (err == EOF && validrets == 0) return EOF; + if (err != 0) return validrets; + if (skip) __scanf_store_d( temp, 0, args ); + else __scanf_store_d( temp, MOD, args ); + validrets++; + break; + } + + case 'p': { + long int temp; + if (!skip) { + void *p = (void *) va_arg( *args, void** ); // get the adress of the target pointer (void**) + err = __strto_int( in, 0, p, NULL, true, readmaxlength); - if (err == EOF && validrets == 0) return EOF; - if (err != 0) return validrets; - if (skip) __scanf_store_i( temp, 0, args ); - else __scanf_store_i( temp, MOD, args ); - validrets++; - break; } + else err = __strto_int( in, 0, &temp, NULL, true, + readmaxlength); + if (err == 0) validrets++; + else return validrets; + skip = false; + break; + } - case 'a': - case 'A': - case 'e': - case 'E': - case 'f': - case 'F': - case 'g': - case 'G': { - /* Adjust interpretation of no size / 'l' size */ - if(size_letter == 0) - MOD = sizeof(float); - if(size_letter == 'l') - MOD = sizeof(double); + case 'c': { + if(readmaxlength == INT_MAX) + readmaxlength = 1; + char *c = skip ? NULL : va_arg(*args, char *); - // read a double from the current input stream - // and store in the corresponding arg as a char by reference - long double temp; - err = __strto_fp( in, NULL, NULL, &temp, - readmaxlength); - if (err == EOF && validrets == 0) return EOF; - if (err != 0) return validrets; - if (skip) __scanf_store_d( temp, 0, args ); - else __scanf_store_d( temp, MOD, args ); - validrets++; - break; - } - - case 'p': { - long int temp; - if (!skip) { - void *p = (void *) va_arg( *args, void** ); // get the adress of the target pointer (void**) - err = __strto_int( in, 0, p, NULL, true, - readmaxlength); - } - else err = __strto_int( in, 0, &temp, NULL, true, - readmaxlength); - if (err == 0) validrets++; - else return validrets; - skip = false; - break; + for(int u = 0; u < readmaxlength; u++) { + int temp = __scanf_in(in); + if(temp==EOF) return EOF; + else if(c) *c++ = temp; } + validrets += !skip; + break; + } - case 'c': { - if(readmaxlength == INT_MAX) - readmaxlength = 1; - char *c = skip ? NULL : va_arg(*args, char *); + case 's': { + char temp; + int curstrlength = 0; + __purge_space(in); - for(int u = 0; u < readmaxlength; u++) { - int temp = __scanf_in(in); - if(temp==EOF) return EOF; - else if(c) *c++ = temp; - } - validrets += !skip; - break; - } - - case 's': { - char temp; - int curstrlength = 0; - __purge_space(in); - - char *c = skip ? NULL : va_arg(*args, char *); - for(int u = 0; u < readmaxlength; u++) { - temp = __scanf_peek(in); - if(temp==EOF && curstrlength==0) return validrets; - if(isspace(temp) || ((temp==EOF && curstrlength!=0))) { - if(c) { - *c = 0; - validrets++; - } - break; - } - else { - int temp = __scanf_in( in ); - if(c) - *c++ = temp; - curstrlength++; + char *c = skip ? NULL : va_arg(*args, char *); + for(int u = 0; u < readmaxlength; u++) { + temp = __scanf_peek(in); + if(temp==EOF && curstrlength==0) return validrets; + if(isspace(temp) || ((temp==EOF && curstrlength!=0))) { + if(c) { + *c = 0; + validrets++; } + break; + } + else { + int temp = __scanf_in( in ); + if(c) + *c++ = temp; + curstrlength++; } - break; } + break; + } } } // we are looking for a specific character in the input stream