diff --git mlibc-clean/options/ansi/generic/stdio.cpp mlibc-workdir/options/ansi/generic/stdio.cpp index a5e177a..91a9db7 100644 --- mlibc-clean/options/ansi/generic/stdio.cpp +++ mlibc-workdir/options/ansi/generic/stdio.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include @@ -348,6 +349,20 @@ static void store_int(void *dest, unsigned int size, unsigned long long i) { } } +static void store_float(void *dest, unsigned int size, long double f) { + switch(size) { + case SCANF_TYPE_LL: + *(long double *)dest = f; + break; + case SCANF_TYPE_L: + *(double *)dest = f; + break; + default: + *(float *)dest = f; + break; + } +} + template static int do_scanf(H &handler, const char *fmt, __builtin_va_list args) { #define NOMATCH_CHECK(cond) ({ if(cond) return match_count; }) // if cond is true, matching error @@ -476,6 +491,141 @@ static int do_scanf(H &handler, const char *fmt, __builtin_va_list args) { } switch (*fmt) { + case 'a': + case 'A': + case 'E': + case 'e': + case 'G': + case 'g': + case 'F': + case 'f': { + bool is_negative = false; + long double divisor = 10; + long double result = 0; + int count = 0; + bool dot = false; + char c = handler.look_ahead(); + EOF_CHECK(c == '\0'); + + if((c == '-')) { + handler.consume(); + is_negative = true; + c = handler.look_ahead(); + } + + if((c == '+')) { + handler.consume(); + c = handler.look_ahead(); + } + + // nan? + if(tolower(c) == 'n') { + handler.consume(); + c = handler.look_ahead(); + if(tolower(c) != 'a') + return match_count; + + handler.consume(); + c = handler.look_ahead(); + if(tolower(c) != 'n') + return match_count; + + handler.consume(); + if(dest) + store_float(dest, type, NAN); + + continue; + } + + // inf? + if(tolower(c) == 'i') { + handler.consume(); + c = handler.look_ahead(); + size_t i; + for(i = 0; i < strlen("nfinity"); ++i) { + if (tolower(c) != "nfinity"[i]) + break; + handler.consume(); + c = handler.look_ahead(); + } + + NOMATCH_CHECK(i != 2 && i != 8); + + if(dest) + store_float(dest, type, is_negative ? -INFINITY : INFINITY); + + continue; + } + + // check if hexadecimal + if (c == '0') { + handler.consume(); + c = handler.look_ahead(); + if (tolower(c) == 'x') { + mlibc::infoLogger() << "mlibc: no support for hexadecimal floats on scanf" << frg::endlog; + return match_count; + } + + ++count; + } + + while(isdigit(c) || (dot == false && c == '.')) { + handler.consume(); + if(c == '.') { + dot = true; + c = handler.look_ahead(); + continue; + } + + long double character_value = c - '0'; + + if(dot) { + result = result + character_value / divisor; + divisor *= 10; + } else { + result = result * 10 + character_value; + } + + ++count; + c = handler.look_ahead(); + } + + NOMATCH_CHECK(count == 0); + + result = is_negative ? -result : result; + + // check for scientific notation + if (tolower(c) == 'e') { + handler.consume(); + c = handler.look_ahead(); + bool negative_exponent = false; + if(c == '+') { + handler.consume(); + c = handler.look_ahead(); + } + + if(c == '-') { + negative_exponent = true; + handler.consume(); + c = handler.look_ahead(); + } + + int exponent = 0; + + while(isdigit(c)) { + handler.consume(); + int value = c - '0'; + exponent = exponent * 10 + value; + c = handler.look_ahead(); + } + + result = result * powl(10, negative_exponent ? -exponent : exponent); + } + + if (dest) + store_float(dest, type, result); + break; + } case 'd': case 'u': base = 10; diff --git mlibc-clean/options/glibc/generic/execinfo.cpp mlibc-workdir/options/glibc/generic/execinfo.cpp index 6b6a9c0..e1a37e2 100644 --- mlibc-clean/options/glibc/generic/execinfo.cpp +++ mlibc-workdir/options/glibc/generic/execinfo.cpp @@ -2,6 +2,7 @@ #include #include +#include int backtrace(void **, int) { mlibc::infoLogger() << "mlibc: backtrace() is a stub!" << frg::endlog; @@ -9,8 +10,9 @@ int backtrace(void **, int) { } char **backtrace_symbols(void *const *, int) { - __ensure(!"Not implemented"); - __builtin_unreachable(); + mlibc::infoLogger() << "mlibc: backtrace() is a stub!" << frg::endlog; + errno = ENOSYS; + return NULL; } void backtrace_symbols_fd(void *const *, int, int) {