diff --git a/inc/stdlib.h b/inc/stdlib.h index d5b1fe1..ecf2fba 100644 --- a/inc/stdlib.h +++ b/inc/stdlib.h @@ -52,6 +52,9 @@ long int strtol(const char *restrict nptr, char **restrict endptr, int base); long long int strtoll(const char *restrict nptr, char **restrict endptr, int base); unsigned long int strtoul(const char *restrict nptr, char **restrict endptr, int base); unsigned long long int strtoull(const char *restrict nptr, char **restrict endptr, int base); + +char *itoa(int value, char *str, int base); + int rand(void); void srand(unsigned int seed); @@ -63,6 +66,7 @@ void free(void *ptr); void *malloc(size_t size); void *realloc(void *ptr, size_t size); + _Noreturn void abort(void); int atexit(void (*func)(void)); // int at_quick_exit(void (*func)(void)); diff --git a/src/code/fmt/gen_fmt.c b/src/code/fmt/gen_fmt.c new file mode 100644 index 0000000..272b482 --- /dev/null +++ b/src/code/fmt/gen_fmt.c @@ -0,0 +1,43 @@ + +#include + +#define ctype char +#define pfx(f) f +#include "gen_fmt.h" +#undef ctype +#undef pfx + +#define ctype wchar_t +#define pfx(f) w ## f +#include "gen_fmt.h" +#undef ctype +#undef pfx + +static int fprintfcb(void *ctx, char ch) { + FILE *f = ctx; + return fputc(ch, f) != EOF; +} + +int vfprintf(FILE *stream, const char *fmt, va_list args) { + return vprintfcb(stream, fprintfcb, fmt, args); +} + +int vprintf(const char *fmt, va_list args) { + return vprintfcb(stdout, fprintfcb, fmt, args); +} + +int fprintf(FILE *stream, const char *fmt, ...) { + va_list args; + va_start(args, fmt); + int len = vfprintf(stream, fmt, args); + va_end(args); + return len; +} + +int printf(const char *fmt, ...) { + va_list args; + va_start(args, fmt); + int len = vprintf(fmt, args); + va_end(args); + return len; +} diff --git a/src/code/fmt/gen_fmt.h b/src/code/fmt/gen_fmt.h new file mode 100644 index 0000000..fe186d8 --- /dev/null +++ b/src/code/fmt/gen_fmt.h @@ -0,0 +1,54 @@ + +#include +#include + +typedef int (pfx(cbfn))(void *ctx, ctype ch); + +static int pfx(vprintfcb)( + void *ctx, + cbfn *cb, + const ctype *fmt, + va_list args +) { + int w = 0; + while(*fmt) { + while(*fmt && *fmt != '%') { + if(!cb(ctx, *fmt)) + goto end; + ++w; + ++fmt; + } + if(*fmt == '%') { + ++fmt; + char f = *fmt++; + switch(f) { + case 's': { + char *str = va_arg(args, char *); + while(*str) { + if(!cb(ctx, *str)) + goto end; + ++str; + ++w; + } + } break; + case 'd': case 'i': { + int num = va_arg(args, int); + char buffer[20]; + char *str = buffer; + itoa(num, buffer, 10); + while(*str) { + if(!cb(ctx, *str)) + goto end; + ++str; + ++w; + } + } break; + } + } + } + goto end; +print_str: + +end: + return w; +} diff --git a/src/code/math/generic.c b/src/code/math/gen_math.c similarity index 83% rename from src/code/math/generic.c rename to src/code/math/gen_math.c index 6bf666e..7a353d2 100644 --- a/src/code/math/generic.c +++ b/src/code/math/gen_math.c @@ -4,7 +4,7 @@ #include #include -#define ln2 0.69314718055994530941723212145817 +static double LN2 = 0.693147180559945309417232121458176; static double HALF_PI = 1.570796326794896619231321691639751; static double PI = 3.141592653589793238462643383279502; static double LOG2E = 1.442695040888963407359924681001892; @@ -14,20 +14,20 @@ static double LOG2E = 1.442695040888963407359924681001892; #define ftype float #define suffix(name) name ## f #include "cordic/cordic_dataf.c" -#include "generic.h" +#include "gen_math.h" #undef ftype #undef suffix #define ftype double #define suffix(name) name #include "cordic/cordic_data.c" -#include "generic.h" +#include "gen_math.h" #undef ftype #undef suffix #define ftype long double #define suffix(name) name ## l #include "cordic/cordic_datal.c" -#include "generic.h" +#include "gen_math.h" #undef ftype #undef suffix diff --git a/src/code/math/generic.h b/src/code/math/gen_math.h similarity index 99% rename from src/code/math/generic.h rename to src/code/math/gen_math.h index e94c78f..2f22c93 100644 --- a/src/code/math/generic.h +++ b/src/code/math/gen_math.h @@ -221,7 +221,7 @@ ftype suffix(asin)(ftype x) { // } ftype suffix(exp2)(ftype x) { - return suffix(exp)(x * ln2); + return suffix(exp)(x * LN2); } ftype suffix(expm1)(ftype x) { diff --git a/src/code/stdio/generic.c b/src/code/stdio/generic.c deleted file mode 100644 index e69de29..0000000 diff --git a/src/code/stdlib/conversion.c b/src/code/stdlib/conversion.c index 60362d8..6c42d34 100644 --- a/src/code/stdlib/conversion.c +++ b/src/code/stdlib/conversion.c @@ -5,9 +5,7 @@ #include #include #include - -// TODO: strto*: locale-based parsing -// TODO: correctly rounded base 16 floats parsing +#include // Call me weak if you want but I'm actually too lazy to type // them out every time, also they take up a lot of horiz space. @@ -339,3 +337,22 @@ float strtof(const char *restrict nptr, char **restrict endptr) { long double strtold(const char *restrict nptr, char **restrict endptr) { return (long double)strtod_generic(nptr, endptr); } + +char *itoa(int value, char *str, int base) { + int sign = 0; + if(value < 0) { + sign = 1; + value = -value; + } + char buf[20] = {0}; + char *bufp = buf + sizeof buf - 1; + do { + *--bufp = value%base+'0'; + value /= base; + } while(value != 0); + if(sign) { + *--bufp = '-'; + } + strcpy(str, bufp); + return str; +} diff --git a/src/win/win.h b/src/win/win.h index c0d23c1..a145fca 100644 --- a/src/win/win.h +++ b/src/win/win.h @@ -7,6 +7,7 @@ #include #include +void _print_stack_trace(); void _setup_timer(void); void _setup_eh(); void _setup_heap(); diff --git a/src/win/win_assert.c b/src/win/win_assert.c index 3d8563d..0a39d18 100644 --- a/src/win/win_assert.c +++ b/src/win/win_assert.c @@ -2,7 +2,7 @@ #include #include -//#include // printf +#include // printf #include // abort void _Noreturn _assert( @@ -11,11 +11,11 @@ void _Noreturn _assert( char const *file, int line ) { - // printf("Assertion failed: %s\n", cond); - // printf(" Function: %s\n", func); - // printf(" File: %s\n", file); - // printf(" Line: %d\n", line); - // printf("Trace:\n"); - // _os_print_stack_trace(); + printf("Assertion failed: %s\n", cond); + printf(" Function: %s\n", func); + printf(" File: %s\n", file); + printf(" Line: %d\n", line); + printf("Trace:\n"); + _print_stack_trace(); abort(); } diff --git a/src/win/win_stack_trace.c b/src/win/win_stack_trace.c index 9f57c79..79d1fb1 100644 --- a/src/win/win_stack_trace.c +++ b/src/win/win_stack_trace.c @@ -1,8 +1,9 @@ #include #include +#include -void _os_print_stack_trace() { +void _print_stack_trace() { HANDLE process = GetCurrentProcess(); SymInitialize(process, NULL, TRUE); @@ -14,13 +15,14 @@ void _os_print_stack_trace() { symbol->SizeOfStruct = sizeof(SYMBOL_INFO); for(size_t i = 0; i < frames; i++) { SymFromAddr(process, (DWORD64)stack[i], 0, symbol); - if(strcmp(symbol->Name, "BaseThreadInitThunk") == 0) break; - if(strcmp(symbol->Name, "mainCRTStartup") == 0) break; - // printf(" %u: 0x%"PRIx64" (%s)\n", - // (int)(frames-i-1), - // symbol->Address, - // symbol->Name - // ); + // if(strcmp(symbol->Name, "BaseThreadInitThunk") == 0) break; + // if(strcmp(symbol->Name, "mainCRTStartup") == 0) break; + printf(//" %u: 0x%"PRIx64" (%s)\n", + " %d: %s\n", + (int)(frames-i-1), + //symbol->Address, + symbol->Name + ); } free(symbol); } diff --git a/test/test_io.c b/test/test_io.c index 0ebd98a..5c4a5e9 100644 --- a/test/test_io.c +++ b/test/test_io.c @@ -1,8 +1,8 @@ #include +#include int main() { - for(int i = 0; i != 512; ++i) - fputc('Z', stdout); + printf("Hello, %i World!\n", __LINE__); return 0; } diff --git a/todo b/todo index f25cc56..6cf090c 100644 --- a/todo +++ b/todo @@ -37,6 +37,7 @@ stdlib.h: qsort Better PRNG MB_CUR_MAX should be locale-dependent + strtod base 16 should be correctly rounded Probably other stuff threads.h: