From 7c24e9a9b02b04dcaf9507acb94091ea70a2c02d Mon Sep 17 00:00:00 2001 From: Xavi Del Campo Date: Fri, 31 Jan 2020 10:32:23 +0100 Subject: Imported pristine psxsdk-20190410 from official repo --- libpsx/src/libc/scanf.c | 425 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 425 insertions(+) create mode 100644 libpsx/src/libc/scanf.c (limited to 'libpsx/src/libc/scanf.c') diff --git a/libpsx/src/libc/scanf.c b/libpsx/src/libc/scanf.c new file mode 100644 index 0000000..d419030 --- /dev/null +++ b/libpsx/src/libc/scanf.c @@ -0,0 +1,425 @@ +// vsscanf +// Programmed by Giuseppe Gatta, 2011 + +#include +#include +#include +#include +#include + +char libc_vsscanf_buf[512]; +char libc_vsscanf_allow[256]; + +enum +{ + elem_skip_space = 1, +}; + +int libc_vsscanf_get_element(char *dst, const char *src, int flag, int s) +{ + int i; + const char *osrc = src; + + if(flag & elem_skip_space) + { + while(*src == ' ') + src++; + } + + for(i=0;i 512) + fsz = 512; // 512 is the maximum. + break; + + case '@': // Binary. Non-standard extension + libc_vsscanf_get_element(libc_vsscanf_buf, &str[sp], elem_skip_space, fsz); + buf = strtoll(libc_vsscanf_buf, &ep, 2); + sp += ep - libc_vsscanf_buf; + + if(!suppress) + { + switch(sz) + { + case scanf_s_char: *(va_arg(ap, signed char*)) = (signed char)buf;break; + case scanf_s_short: *(va_arg(ap, short*)) = (short)buf; break; + case scanf_s_int: *(va_arg(ap, int*)) = (int)buf; break; + case scanf_s_long: *(va_arg(ap, long*)) = (long)buf; break; + case scanf_s_long_long: *(va_arg(ap, long long*)) = buf; break; + } + r++; + } + + conv = 0; + break; + + case 'D': + sz++; + case 'd': // Decimal + case 'u': + libc_vsscanf_get_element(libc_vsscanf_buf, &str[sp], elem_skip_space, fsz); + buf = strtoll(libc_vsscanf_buf, &ep, 10); + sp += ep - libc_vsscanf_buf; + + if(!suppress) + { + switch(sz) + { + case scanf_s_char: *(va_arg(ap, signed char*)) = (signed char)buf;break; + case scanf_s_short: *(va_arg(ap, short*)) = (short)buf; break; + case scanf_s_int: *(va_arg(ap, int*)) = (int)buf; break; + case scanf_s_long: *(va_arg(ap, long*)) = (long)buf; break; + case scanf_s_long_long: *(va_arg(ap, long long*)) = buf; break; + } + r++; + } + + conv = 0; + break; + + case 's': // String + sp += libc_vsscanf_get_element(libc_vsscanf_buf, &str[sp], elem_skip_space, fsz); + + if(!suppress) + { + strcpy(va_arg(ap, char*), libc_vsscanf_buf); + r++; + } + + conv = 0; + break; + + case 'c': + if(def_fsz) + fsz = 1; + + sp += (i = libc_vsscanf_get_element(libc_vsscanf_buf, &str[sp], (exspace ? elem_skip_space : 0), fsz)); + if(!suppress) + { + memcpy(va_arg(ap, char*), libc_vsscanf_buf, (fsz>i)?i:fsz); + r++; + } + break; + + case 'n': + if(!suppress) + { + *(va_arg(ap, int*)) = sp; + r++; + } + break; + + case 'p': + case 'x': + case 'X': + libc_vsscanf_get_element(libc_vsscanf_buf, &str[sp], elem_skip_space, fsz); + buf = strtoll(libc_vsscanf_buf, &ep, 16); + sp += ep - libc_vsscanf_buf; + + if(!suppress) + { + switch(sz) + { + case scanf_s_char: *(va_arg(ap, unsigned char*)) = (unsigned char)buf; break; + case scanf_s_short: *(va_arg(ap, unsigned short*)) = (unsigned short)buf; break; + case scanf_s_int: *(va_arg(ap, unsigned int*)) = (unsigned int)buf; break; + case scanf_s_long: *(va_arg(ap, unsigned long*)) = (unsigned long)buf; break; + case scanf_s_long_long: *(va_arg(ap, unsigned long long*)) = (unsigned long long)buf; break; + } + r++; + } + + conv = 0; + break; + + case 'O': + sz++; + case 'o': // Octal integer + libc_vsscanf_get_element(libc_vsscanf_buf, &str[sp], elem_skip_space, fsz); + buf = strtoll(libc_vsscanf_buf, &ep, 8); + sp += ep - libc_vsscanf_buf; + + if(!suppress) + { + switch(sz) + { + case scanf_s_char: *(va_arg(ap, unsigned char*)) = (unsigned char)buf;break; + case scanf_s_short: *(va_arg(ap, unsigned short*)) = (unsigned short)buf; break; + case scanf_s_int: *(va_arg(ap, unsigned int*)) = (unsigned int)buf;break; + case scanf_s_long: *(va_arg(ap, unsigned long*)) = (unsigned long)buf; break; + case scanf_s_long_long: *(va_arg(ap, unsigned long long*)) = (unsigned long long)buf;break; + } + r++; + } + + conv = 0; + break; + + case 'i': + libc_vsscanf_get_element(libc_vsscanf_buf, &str[sp], elem_skip_space, fsz); + + if(libc_vsscanf_buf[0] == '0') + { + if(libc_vsscanf_buf[1] == 'x' || libc_vsscanf_buf[1] == 'X') + i = 16; + else + i = 8; + } + else + i = 10; + + buf = strtoll(libc_vsscanf_buf, &ep, i); + sp += ep - libc_vsscanf_buf; + + if(!suppress) + { + switch(sz) + { + case scanf_s_char: *(va_arg(ap, signed char*)) = (signed char)buf; break; + case scanf_s_short: *(va_arg(ap, short*)) = (short)buf; break; + case scanf_s_int: *(va_arg(ap, int*)) = (int)buf; break; + case scanf_s_long: *(va_arg(ap, long*)) = (long)buf; break; + case scanf_s_long_long: *(va_arg(ap, long long*)) = (long long)buf; break; + } + r++; + } + + conv = 0; + break; + + case '[': + i=0; + x=0; // Exclusion? + //h=0; // Hyphen? + + fp++; + i++; + + while(format[fp]) + { + if(format[fp] == '^' && i==1) + { + memset(libc_vsscanf_allow, 1, 256); + x = 1; + fp++; i++; continue; + } + + if(x) + { + if(format[fp] == ']' && i>=3) + break; + } + else + { + if(format[fp] == ']' && i>=2) + break; + } + + if(format[fp] == '-') + { + if(format[fp+1] != ']') + y = 1; + else + libc_vsscanf_allow['-'] = x^1; + } + else + { + if(y == 1) + { + if(format[fp] < format[fp-2]) + libc_vsscanf_allow[(unsigned char)format[fp]] = x^1; + else + for(z = format[fp-2]; z <= format[fp]; z++) + libc_vsscanf_allow[z] = x^1; + + y = 0; + + //printf("%s all chars from %c to %c\n", x?"Excluding":"Including",format[fp-2], format[fp]); + } + else + libc_vsscanf_allow[(unsigned char)format[fp]] = x^1; + } + + fp++; + i++; + } + +// Now as we know what our character set is, let's get data from the string + /* puts("Character set:"); + + for(y=0;y<16;y++) + { + for(x=0;x<16;x++) + if(libc_vsscanf_allow[(y*16) + x]) + putchar((y*16)+x); + else + putchar('*'); + + putchar('\n'); + } + */ + i = 0; + + while(libc_vsscanf_allow[(unsigned char)str[sp]] && i<512) + libc_vsscanf_buf[i++] = str[sp++]; + + libc_vsscanf_buf[i] = 0; + + if(!suppress) + { + strcpy(va_arg(ap, char*), libc_vsscanf_buf); + r++; + } + break; + + case 'f': // Floating point number + libc_vsscanf_get_element(libc_vsscanf_buf, &str[sp], elem_skip_space, fsz); + fbuf = strtod(libc_vsscanf_buf, &ep); + sp += ep - libc_vsscanf_buf; + + if(!suppress) + { + switch(sz) + { + case scanf_s_char: + case scanf_s_short: + case scanf_s_int: + *(va_arg(ap, float*)) = (float)fbuf; + break; + + case scanf_s_long: + case scanf_s_long_long: + *(va_arg(ap, double*)) = fbuf; + break; + } + r++; + } + + conv = 0; + break; + + } + } + else + { + if(format[fp] == '%') + { + // conv = 1; + // neg = 0; + suppress = 0; + sz = scanf_s_int; + fsz = 512; + def_fsz = 1; + exspace = 0; + // alt = 0; + bzero(libc_vsscanf_allow, 256); + //chset = 0; + } + else if(format[fp] != ' ') + { + if(format[fp] != str[sp]) + exit_loop=1; + + sp++; + } + + } + + fp++; + } + + return r; +} + +int sscanf(const char *str, const char *fmt, ...) +{ + int r; + va_list ap; + + va_start(ap, fmt); + r = vsscanf(str, fmt, ap); + + va_end(ap); + return r; +} -- cgit v1.2.3