diff --git mlibc-clean/options/ansi/generic/stdio.cpp mlibc-workdir/options/ansi/generic/stdio.cpp index 070168f..827732a 100644 --- mlibc-clean/options/ansi/generic/stdio.cpp +++ mlibc-workdir/options/ansi/generic/stdio.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include @@ -379,6 +380,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 @@ -521,6 +536,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 119574e..f9f1cde 100644 --- mlibc-clean/options/glibc/generic/execinfo.cpp +++ mlibc-workdir/options/glibc/generic/execinfo.cpp @@ -7,6 +7,7 @@ #include #include +#include namespace { @@ -52,33 +53,15 @@ _Unwind_Reason_Code trace(_Unwind_Context *context, void *arg) { } // namespace int backtrace(void **buffer, int size) { - if (size <= 0) - return 0; - - if (!libgccHandle) { - libgccHandle = dlopen("libgcc_s.so.1", RTLD_LAZY | RTLD_LOCAL); - if (!libgccHandle || libgccHandle.value() == nullptr) { - mlibc::infoLogger() << "Failed to load libgcc_s.so.1: " << (dlerror() ? dlerror() : "") << frg::endlog; - return 0; - } - - unwindBacktrace = reinterpret_cast(dlsym(libgccHandle.value(), "_Unwind_Backtrace")); - unwindGetIP = reinterpret_cast(dlsym(libgccHandle.value(), "_Unwind_GetIP")); - - if (!unwindBacktrace || !unwindGetIP) { - mlibc::infoLogger() << "Failed to find unwind functions in libgcc_s.so.1: " << dlerror() << frg::endlog; - return 0; - } - } - - UnwindState state{buffer, size}; - unwindBacktrace(trace, &state); - return state.current_frame; + mlibc::infoLogger() << "mlibc: backtrace() is a stub!" << frg::endlog; + errno = ENOSYS; + return -1; } 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 *buffer, int size, int fd) {