diff --git a/bake.cmd b/bake.cmd new file mode 100644 index 0000000..15e4ac2 --- /dev/null +++ b/bake.cmd @@ -0,0 +1,54 @@ +@echo off +setlocal enabledelayedexpansion + +:: Make sure that if I ctrl+c out of the script the dir is popped +:: If there's anything that requires user input, this script will break +:: in that case I recommend you removing the 'echo y' part. +:: although you will have to confirm termination of the script twice +if "%~1" neq "_start_" ( + pushd %~pd0 + echo y | cmd /c "%~f0" _start_ %* + popd + exit /b +) +shift /1 + +set CIABATTA_OPTIONS=-Iinc -Wall -g -gcodeview -nodefaultlibs -D_CRT_SECURE_NO_WARNINGS +set PLATFORM=win + +if "%1"=="fast" ( + goto :skip_crt_compilation +) +:: For each C file in code/ we check whether it's OS-dependent. +:: If so, we check whether the platform is the chosen one. If not, we ignore +:: that file (set ok=0). Otherwise we compile it. +:: Man, batch files are sure scary, when you try to do something serious +:: it took me a lot of time to figure out how to write this if it breaks +:: im gonna be seriously disappointed :kekw: +del ciabatta.lib 2> nul +for /R code %%F in (*.c) do ( + set ok=1 + set os_dependent=0 + set is_cur_os=0 + echo %%F | findstr /c:"%~pd0code\os" > nul + if !errorlevel! neq 1 ( + set os_dependent=1 + ) + echo %%F | findstr /c:"%~pd0code\os\%PLATFORM%" > nul + if !errorlevel! neq 1 ( + set is_cur_os=1 + ) + if "!os_dependent!"=="1" if "!is_cur_os!"=="0" ( + set ok=0 + ) + if "!ok!"=="1" ( + echo %%F + clang -c -o build\%%~nF.obj %%F %CIABATTA_OPTIONS% + ) +) +llvm-ar rc ciabatta.lib build\*.obj +del build\*.obj + +:skip_crt_compilation +echo Compiling test.. +clang test\test.c ciabatta.lib -std=c11 -lkernel32 -luser32 -lshell32 -nostdlib %CIABATTA_OPTIONS% diff --git a/build.cmd b/build.cmd deleted file mode 100644 index dcf336b..0000000 --- a/build.cmd +++ /dev/null @@ -1,20 +0,0 @@ -@echo off -setlocal enabledelayedexpansion - -set PLATFORM=win32 -set CIABATTA_OPTIONS=-Iinc -g -gcodeview -nodefaultlibs -D_CRT_SECURE_NO_WARNINGS - -del ciabatta.lib -for /R code %%F in (*.c) do ( - echo %%F - clang -c -o build\%%~nF.obj %%F %CIABATTA_OPTIONS% -) -for /R platform\%PLATFORM% %%F in (*.c) do ( - echo %%F - clang -c -o build\%%~nF.obj %%F %CIABATTA_OPTIONS% -) -llvm-ar rc ciabatta.lib build\*.obj - -clang test\test.c ciabatta.lib -lkernel32 -luser32 -lshell32 -nostdlib %CIABATTA_OPTIONS% -del build\*.obj - diff --git a/code/assert.c b/code/assert.c index 323f943..00ddc71 100644 --- a/code/assert.c +++ b/code/assert.c @@ -1,45 +1,24 @@ #include #include #include -#include <_platform.h> +#include + +#include <_compiler.h> +#include <_os.h> // TODO: use abort() to break -#if defined(_compiler_msvc) -#include -#define brk __debugbreak -#else -#define brk __builtin_trap -#endif -#if defined(_os_win) -#define WIN32_LEAN_AND_MEAN -#include - -// TODO: make it work via printf -static void _assert_win32_prints(HANDLE conout, char const *str) { - DWORD written = 0; - WriteConsole(conout, str, strlen(str), &written, NULL); -} - -extern void _assert_error(char *cond, char const *func, char const *file, char const *line) { - HANDLE conout = GetStdHandle(STD_OUTPUT_HANDLE); - if(conout != INVALID_HANDLE_VALUE) { - _assert_win32_prints(conout, "Assertion Failed: "); - _assert_win32_prints(conout, cond); - _assert_win32_prints(conout, "\n\tFile: "); - _assert_win32_prints(conout, file); - _assert_win32_prints(conout, "\n\tFunc: "); - _assert_win32_prints(conout, func); - _assert_win32_prints(conout, "\n\tLine: "); - _assert_win32_prints(conout, line); +extern void _assert_error( + char *cond, + char const *func, + char const *file, + char const *line +) { + printf("Assertion failed: %s\n", cond); + if(*func != 0) { + printf("\tFunction: %s\n", func); } - else { - // TODO: - MessageBoxA(NULL, - "Assertion Failed Somewhere, good luck finding it!\n", - "Error", - MB_OK); - } - brk(); + printf("\tFile: %s\n", file); + printf("\tLine: %s\n", line); + _compiler_brk(); } -#endif \ No newline at end of file diff --git a/platform/win32/entry.c b/code/os/win/entry.c similarity index 98% rename from platform/win32/entry.c rename to code/os/win/entry.c index 94896eb..500d69e 100644 --- a/platform/win32/entry.c +++ b/code/os/win/entry.c @@ -21,11 +21,10 @@ static size_t count_wide_chars(const wchar_t* str) { static bool convert_wide_chars_to_ansi(char* out, const wchar_t* str, size_t len) { for (size_t i = 0; i < len; i++) { wchar_t ch = *str++; - if (ch <= 0 && ch > 0x7F) { + if (ch < 0 || 0x7F >= ch) { *out++ = 0; return false; } - *out++ = ch; } diff --git a/code/os/win/env.c b/code/os/win/env.c new file mode 100644 index 0000000..c97a4f3 --- /dev/null +++ b/code/os/win/env.c @@ -0,0 +1,2 @@ + +#include diff --git a/platform/win32/memory.c b/code/os/win/memory.c similarity index 95% rename from platform/win32/memory.c rename to code/os/win/memory.c index 746c706..0b218bc 100644 --- a/platform/win32/memory.c +++ b/code/os/win/memory.c @@ -39,7 +39,7 @@ void *aligned_alloc(size_t alignment, size_t size) { if(alignment > 8) { min_req_size += alignment; } - void *block_start = HeapAlloc(_heap, HEAP_ZERO_MEMORY, size+alignment); + void *block_start = HeapAlloc(_heap, HEAP_ZERO_MEMORY, min_req_size); intptr_t block_start_i = (intptr_t)block_start; intptr_t aligned_block_start_i = align_forward(block_start_i, alignment); void *aligned_block_start = (void *)aligned_block_start_i; @@ -72,3 +72,4 @@ void *realloc(void *ptr, size_t size) { void *buffer = HeapReAlloc(_heap, 0, ptr, size); return buffer; } + diff --git a/platform/win32/win32.h b/code/os/win/win32.h similarity index 100% rename from platform/win32/win32.h rename to code/os/win/win32.h diff --git a/code/printf.h b/code/printf.h index 5c00884..5e68ca1 100644 --- a/code/printf.h +++ b/code/printf.h @@ -29,6 +29,7 @@ inline static int FMT_FUNC_NAME (void *ctx, OutputFunc out, const FMT_CHAR_TYPE if (isdigit(*fmt)) { // just a small atoi + // TODO: handle overflow, just in case(?) while (isdigit(*fmt)) { precision *= 10u; precision += (*fmt - '0'); diff --git a/code/stdio.c b/code/stdio.c index c518e3d..1db2ec8 100644 --- a/code/stdio.c +++ b/code/stdio.c @@ -2,8 +2,10 @@ #include #include -// Even if the user doesn't enable LIB_EXT1 we still have it existing -size_t strnlen_s(const char *s, size_t maxsize); +#include <_os.h> + +#define __STDC_WANT_LIB_EXT1__ 1 +#include typedef void(*OutputFunc)(void* ctx, size_t n, const char str[]); diff --git a/code/stdlib/conv.c b/code/stdlib/conv.c index 582c540..60362d8 100644 --- a/code/stdlib/conv.c +++ b/code/stdlib/conv.c @@ -20,7 +20,7 @@ typedef unsigned intu; #define inrange(start, c, end) ((start) <= (c) && (c) <= (end)) static bool isbase(int c, int base) { - int val; + int val = 0; if(isdigit(c)) { val = c-'0'; } @@ -48,7 +48,7 @@ static bool strprefix_i(char const *restrict str, char const *restrict prefix) { // Called only when isbase(c, base) for some base in range static long todigit(int c) { - int val; + int val = 0; if(isdigit(c)) { val = c-'0'; } @@ -70,6 +70,7 @@ static intull strtoi_generic(const char *restrict nptr, intull value = 0; int digits_read = 0; bool is_signed = (coefptr != NULL); + intl coef = 1; // Find max{abs(int)}. Signed integers have negative, // whose absolute value is 1 bigger than int_max. intull int_abs_max = int_max; @@ -85,7 +86,6 @@ static intull strtoi_generic(const char *restrict nptr, ++str; } // Parse sign - intl coef = 1; if(is_signed) { if(*str == '-') { coef = -1; diff --git a/code/string.c b/code/string.c index b2e128b..938cfef 100644 --- a/code/string.c +++ b/code/string.c @@ -1,8 +1,18 @@ #include +#include +#include +#include +#include +#include +#include + +// TODO: rewrite memmove to not allocate anything + +typedef unsigned char byte; void *memcpy(void *restrict s1, const void *restrict s2, size_t n) { - const unsigned char *restrict c2 = s2; - unsigned char *restrict c1 = s1; + const byte *restrict c2 = s2; + byte *restrict c1 = s1; while (n--) { *c1++ = *c2++; @@ -10,35 +20,171 @@ void *memcpy(void *restrict s1, const void *restrict s2, size_t n) { return s1; } -int memcmp(const void *s1, const void *s2, size_t n) { - const unsigned char *u1 = s1; - const unsigned char *u2 = s2; - - for (; n--; u1++, u2++) { - if (*u1 != *u2) return *u1 - *u2; - } - - return 0; +void *memmove(void *s1, const void *s2, size_t n) +{ + void *buffer = malloc(n); + memcpy(buffer, s2, n); + memcpy(s1, buffer, n); + free(buffer); + return s1; } void *memset(void *s, int c, size_t n) { - unsigned char *restrict buf = s; + byte *restrict buf = s; while (n--) { *buf++ = c; } return s; } -int strcmp(const char *s1, const char *s2) { - while (*s1 != 0 && *s2 != 0) { - if (*s1 != *s2) break; +char *strcpy(char *restrict s1, const char *restrict s2) +{ + while(*s2 != 0) { + *s1++ = *s2++; } + *s1 = 0; + return s1; +} - if(*s1 > *s2) return 1; - if(*s1 < *s2) return -1; +char *strncpy(char *restrict s1, const char *restrict s2, size_t n) +{ + while(n-->0 && *s2 != 0) { + *s1++ = *s2++; + } + while(n-->0) { + *s1++ = 0; + } + return s1; +} + + +char *strncat(char *restrict s1, const char *restrict s2, size_t n) +{ + size_t start = strlen(s1); + for(size_t i = 0; i != n && *s2 != 0; ++i) { + s1[start+i] = s2[i]; + } + s1[start+n] = 0; + return s1; +} + + +int memcmp(const void *s1, const void *s2, size_t n) { + const byte *u1 = s1; + const byte *u2 = s2; + for (; n--; u1++, u2++) { + if (*u1 != *u2) return *u1 - *u2; + } return 0; } +int strcmp(const char *s1, const char *s2) { + int diff; + do { + diff = *s1 - *s2; + } while(diff != 0 && *s1 != 0 && *s2 != 0); + return diff; +} + +int strncmp(const char *s1, const char *s2, size_t n) +{ + int diff = 0; + size_t i = 0; + if(n != 0) do { + diff = *s1 - *s2; + } while(++i < n && diff != 0 && *s1 != 0 && *s2 != 0); + return diff; +} + +// fuck locales +int strcoll(const char *s1, const char *s2) +{ + return strcmp(s1, s2); +} + +// fuck bad implementation of strcoll +size_t strxfrm(char *restrict s1, const char *restrict s2, size_t n) +{ + size_t len = strlen(s2); + if(s1 != NULL && n != 0) { + for(size_t i = 0; i != n; ++i) { + *s1 = *s2; + } + } + return len; +} + +void *memchr(const void *ptr, int c, size_t n) +{ + const byte *s = ptr; + size_t i = 0; + for(; i != n && *s != c; ++i, ++s) { + ++s; + } + if(i == n) return NULL; + return (void *)s; // fuck clang +} + +char *strchr(const char *s, int c) +{ + while(*s && *s != c) ++s; + if(*s != c) return NULL; + return (void *)s; // fuck clang +} + +size_t strcspn(const char *s1, const char *s2) +{ + size_t i = 0; + while(*s1) { + if(strchr(s2, *s1) != NULL) { + break; + } + ++s1; + ++i; + } + return i; +} + +char *strpbrk(const char *s1, const char *s2) +{ + while(*s1) { + if(strchr(s2, *s1) == NULL) { + break; + } + ++s1; + } + return (char *)s1; +} + +char *strstr(const char *s1, const char *s2) +{ + if(!*s2) return (char *)s1; + size_t len = strlen(s2); + while(*s1 != 0) { + bool match = true; + for(size_t i = 0; i != len; ++i) { + if(!*s1 || s1[i] != s2[i]) { + match = false; + break; + } + } + ++s1; + if(match) return (char *)s1; + } + return NULL; +} + +char *strerror(int errnum) +{ + switch(errnum) { + case 0: return "No errors"; + case EDOM: return "Value is out of domain of the function"; + case EILSEQ: return "Illegal byte sequence"; + case ERANGE: return "Value is out of range"; + } + return "Unkown error"; +} + size_t strlen(const char *s) { size_t i = 0; while (s[i]) { @@ -47,10 +193,8 @@ size_t strlen(const char *s) { return i; } -// __STDC_WANT_LIB_EXT1__ size_t strnlen_s(const char *s, size_t maxsize) { if (s == NULL) return 0; - size_t i = 0; while (s[i] && i < maxsize) { i++; diff --git a/inc/_compiler.h b/inc/_compiler.h new file mode 100644 index 0000000..41c74f3 --- /dev/null +++ b/inc/_compiler.h @@ -0,0 +1,42 @@ + +#pragma once + +#if defined(_MSC_VER) && !defined(__clang__) + #define _compiler_msvc +#endif + +#if defined(__GNUC__) && !defined(__clang__) + #define _compiler_gnu +#endif + +#if defined(__clang__) + #define _compiler_clang +#endif + +#if defined(__CUIKC__) + #define _compiler_cuik +#endif + +#if !(defined(_compiler_msvc) \ + || defined(_compiler_gnu) \ + || defined(_compiler_cuik) \ + || defined(_compiler_clang)) + #error "Unsupported Compiler" +#endif + +#if defined(_compiler_msvc) + #include + #define _compiler_brk __debugbreak +#elif defined(_compiler_gcc) || defined(_compiler_clang) + #define _compiler_brk __builtin_trap +#else + #error "_compiler_brk is not implemented for this compiler" +#endif + +#if defined(_compiler_msvc) + #define _compiler_curfunc __FUNCTION__ +#elif defined(_compiler_gcc) || defined(_compiler_clang) + #define _compiler_curfunc __func__ +#else + #error "_compiler_curfunc not implemented for this compiler" +#endif diff --git a/inc/_macros.h b/inc/_macros.h index dc9df71..0f4e977 100644 --- a/inc/_macros.h +++ b/inc/_macros.h @@ -4,10 +4,5 @@ #define _str_(x) #x #define _str(x) _str_(x) -#if !defined(_func) - #if defined(_compiler_msvc) - #define _func __FUNCTION__ - #else - #define _func __func__ - #endif -#endif +#define _con(a,b) a ## b + diff --git a/inc/_os.h b/inc/_os.h new file mode 100644 index 0000000..cc49a99 --- /dev/null +++ b/inc/_os.h @@ -0,0 +1,15 @@ + +#pragma once + +#if defined(_WIN32) + #define _os_win +#endif + +#if defined(__linux__) && !defined(__ANDROID__) + #define _os_linux +#endif + +#if !(defined(_os_win) \ + || defined(_os_linux)) + #error "Unsupported OS" +#endif diff --git a/inc/assert.h b/inc/assert.h index c00bb14..478f8ba 100644 --- a/inc/assert.h +++ b/inc/assert.h @@ -1,7 +1,12 @@ #pragma once -#include "_macros.h" +#include "_compiler.h" -extern void _assert_error(char *cond, char const *func, char const *file, char const *line); +extern void _assert_error( + char *cond, + char const *func, + char const *file, + char const *line +); #if defined(NDEBUG) #define assert(ignore) ((void)0) @@ -10,7 +15,11 @@ extern void _assert_error(char *cond, char const *func, char const *file, char c #define assert(condition) \ do { \ if(!(condition)) { \ - _assert_error(#condition, _func, __FILE__, _str(__LINE__)); \ + _assert_error( \ + #condition, \ + _compiler_curfunc, \ + __FILE__, \ + _str(__LINE__)); \ } \ } while(0) #endif diff --git a/inc/complex.h b/inc/complex.h index 05e77a7..70a21d5 100644 --- a/inc/complex.h +++ b/inc/complex.h @@ -1,2 +1,4 @@ +#pragma once + #error "Complex Numbers aren't implemented" diff --git a/inc/ctype.h b/inc/ctype.h index 0d70ef7..de90aca 100644 --- a/inc/ctype.h +++ b/inc/ctype.h @@ -1,4 +1,4 @@ -#include "_platform.h" +#pragma once int isalnum(int c); int isalpha(int c); diff --git a/inc/errno.h b/inc/errno.h index 50f3328..54aea48 100644 --- a/inc/errno.h +++ b/inc/errno.h @@ -1,4 +1,5 @@ -#include "_platform.h" + +#pragma once #define EDOM 1 #define EILSEQ 2 diff --git a/inc/fenv.h b/inc/fenv.h index 135ba10..19b3154 100644 --- a/inc/fenv.h +++ b/inc/fenv.h @@ -1,3 +1,6 @@ + +#pragma once + typedef unsigned long fexcept_t; typedef struct fenv_t fenv_t; diff --git a/inc/inttypes.h b/inc/inttypes.h index e69de29..a60e0fc 100644 --- a/inc/inttypes.h +++ b/inc/inttypes.h @@ -0,0 +1,241 @@ + +#pragma once + +#include +#include + +// typedef struct imaxdiv_t imaxdiv_t +// It's C's fault not mine + +#define _spec8 "hh" +#define _spec16 "" +#define _spec32 "" + +#if INT64_MAX == LONG_MAX + #define _spec64 "l" +#elif INT64_MAX == LLONG_MAX + #define _spec64 "ll" +#endif + +#if INT8_LEAST_MAX == CHAR_MAX + #define _spec8l "hh" +#elif INT8_LEAST_MAX == SHORT_MAX || INT8_LEAST_MAX==INT_MAX + #define _spec8l "" +#elif INT8_LEAST_MAX == LONG_MAX + #define _spec8l "l" +#elif INT8_LEAST_MAX == LLONG_MAX + #define _spec8l "ll" +#endif + +#if INT16_LEAST_MAX == SHORT_MAX || INT16_LEAST_MAX==INT_MAX + #define _spec16l "" +#elif INT16_LEAST_MAX == LONG_MAX + #define _spec16l "l" +#elif INT16_LEAST_MAX == LLONG_MAX + #define _spec16l "ll" +#endif + +#if INT32_LEAST_MAX==INT_MAX + #define _spec32l "" +#elif INT32_LEAST_MAX == LONG_MAX + #define _spec32l "l" +#elif INT32_LEAST_MAX == LLONG_MAX + #define _spec32l "ll" +#endif + +#if INT64_LEAST_MAX == LONG_MAX + #define _spec64l "l" +#elif INT64_LEAST_MAX == LLONG_MAX + #define _spec64l "ll" +#endif + + +#if INT8_FAST_MAX == CHAR_MAX + #define _spec8f "hh" +#elif INT8_FAST_MAX == SHORT_MAX || INT8_FAST_MAX==INT_MAX + #define _spec8f "" +#elif INT8_FAST_MAX == LONG_MAX + #define _spec8f "l" +#elif INT8_FAST_MAX == LLONG_MAX + #define _spec8f "ll" +#endif + +#if INT16_FAST_MAX == SHORT_MAX || INT16_FAST_MAX==INT_MAX + #define _spec16f "" +#elif INT16_FAST_MAX == LONG_MAX + #define _spec16f "l" +#elif INT16_FAST_MAX == LLONG_MAX + #define _spec16f "ll" +#endif + +#if INT32_FAST_MAX==INT_MAX + #define _spec32f "" +#elif INT32_FAST_MAX == LONG_MAX + #define _spec32f "l" +#elif INT32_FAST_MAX == LLONG_MAX + #define _spec32f "ll" +#endif + +#if INT64_FAST_MAX == LONG_MAX + #define _spec64f "l" +#elif INT64_FAST_MAX == LLONG_MAX + #define _spec64f "ll" +#endif + +#define _specmax "j" + +#define PRId8 _spec8 "d" +#define PRId16 _spec16 "d" +#define PRId32 _spec32 "d" +#define PRId64 _spec64 "d" +#define PRIdFAST8 _spec8f "d" +#define PRIdFAST16 _spec16f "d" +#define PRIdFAST32 _spec32f "d" +#define PRIdFAST64 _spec64f "d" +#define PRIdLEAST8 _spec8l "d" +#define PRIdLEAST16 _spec16l "d" +#define PRIdLEAST32 _spec32l "d" +#define PRIdLEAST64 _spec64l "d" +#define PRIdPTR _specptr "d" +#define PRIdMAX _specmax "d" +#define PRIi8 _spec8 "i" +#define PRIi16 _spec16 "i" +#define PRIi32 _spec32 "i" +#define PRIi64 _spec64 "i" +#define PRIiFAST8 _spec8f "i" +#define PRIiFAST16 _spec16f "i" +#define PRIiFAST32 _spec32f "i" +#define PRIiFAST64 _spec64f "i" +#define PRIiLEAST8 _spec8l "i" +#define PRIiLEAST16 _spec16l "i" +#define PRIiLEAST32 _spec32l "i" +#define PRIiLEAST64 _spec64l "i" +#define PRIiPTR _specptr "i" +#define PRIiMAX _specmax "i" +#define PRIo8 _spec8 "o" +#define PRIo16 _spec16 "o" +#define PRIo32 _spec16 "o" +#define PRIo64 _spec64 "o" +#define PRIoLEAST8 _spec8l "o" +#define PRIoLEAST16 _spec16l "o" +#define PRIoLEAST32 _spec32l "o" +#define PRIoLEAST64 _spec64l "o" +#define PRIoFAST8 _spec8f "o" +#define PRIoFAST16 _spec16f "o" +#define PRIoFAST32 _spec32f "o" +#define PRIoFAST64 _spec64f "o" +#define PRIoPTR _specptr "o" +#define PRIoMAX _specmax "o" +#define PRIu8 _spec8 "u" +#define PRIu16 _spec16 "u" +#define PRIu32 _spec16 "u" +#define PRIu64 _spec64 "u" +#define PRIuLEAST8 _spec8l "u" +#define PRIuLEAST16 _spec16l "u" +#define PRIuLEAST32 _spec32l "u" +#define PRIuLEAST64 _spec64l "u" +#define PRIuFAST8 _spec8f "u" +#define PRIuFAST16 _spec16f "u" +#define PRIuFAST32 _spec32f "u" +#define PRIuFAST64 _spec64f "u" +#define PRIuPTR _specptr "u" +#define PRIuMAX _specmax "u" +#define PRIx8 _spec8 "x" +#define PRIx16 _spec16 "x" +#define PRIx32 _spec32 "x" +#define PRIx64 _spec64 "x" +#define PRIxLEAST8 _spec8l "x" +#define PRIxLEAST16 _spec16l "x" +#define PRIxLEAST32 _spec32l "x" +#define PRIxLEAST64 _spec64l "x" +#define PRIxFAST8 _spec8f "x" +#define PRIxFAST16 _spec16f "x" +#define PRIxFAST32 _spec32f "x" +#define PRIxFAST64 _spec64f "x" +#define PRIxPTR _specptr "x" +#define PRIxMAX _specmax "x" +#define PRIX8 _spec8 "X" +#define PRIX16 _spec16 "X" +#define PRIX32 _spec32 "X" +#define PRIX64 _spec64 "X" +#define PRIXLEAST8 _spec8l "X" +#define PRIXLEAST16 _spec16l "X" +#define PRIXLEAST32 _spec32l "X" +#define PRIXLEAST64 _spec64l "X" +#define PRIXFAST8 _spec8f "X" +#define PRIXFAST16 _spec16f "X" +#define PRIXFAST32 _spec32f "X" +#define PRIXFAST64 _spec64f "X" +#define PRIXPTR _specptr "X" +#define PRIXMAX _specmax "X" + +#define SCNd8 _spec8 "d" +#define SCNd16 _spec16 "d" +#define SCNd32 _spec32 "d" +#define SCNd64 _spec64 "d" +#define SCNdFAST8 _spec8f "d" +#define SCNdFAST16 _spec16f "d" +#define SCNdFAST32 _spec32f "d" +#define SCNdFAST64 _spec64f "d" +#define SCNdLEAST8 _spec8l "d" +#define SCNdLEAST16 _spec16l "d" +#define SCNdLEAST32 _spec32l "d" +#define SCNdLEAST64 _spec64l "d" +#define SCNdPTR _specptr "d" +#define SCNdMAX _specmax "d" +#define SCNi8 _spec8 "i" +#define SCNi16 _spec16 "i" +#define SCNi32 _spec32 "i" +#define SCNi64 _spec64 "i" +#define SCNiFAST8 _spec8f "i" +#define SCNiFAST16 _spec16f "i" +#define SCNiFAST32 _spec32f "i" +#define SCNiFAST64 _spec64f "i" +#define SCNiLEAST8 _spec8l "i" +#define SCNiLEAST16 _spec16l "i" +#define SCNiLEAST32 _spec32l "i" +#define SCNiLEAST64 _spec64l "i" +#define SCNiPTR _specptr "i" +#define SCNiMAX _specmax "i" +#define SCNo8 _spec8 "o" +#define SCNo16 _spec16 "o" +#define SCNo32 _spec16 "o" +#define SCNo64 _spec64 "o" +#define SCNoLEAST8 _spec8l "o" +#define SCNoLEAST16 _spec16l "o" +#define SCNoLEAST32 _spec32l "o" +#define SCNoLEAST64 _spec64l "o" +#define SCNoFAST8 _spec8f "o" +#define SCNoFAST16 _spec16f "o" +#define SCNoFAST32 _spec32f "o" +#define SCNoFAST64 _spec64f "o" +#define SCNoPTR _specptr "o" +#define SCNoMAX _specmax "o" +#define SCNu8 _spec8 "u" +#define SCNu16 _spec16 "u" +#define SCNu32 _spec16 "u" +#define SCNu64 _spec64 "u" +#define SCNuLEAST8 _spec8l "u" +#define SCNuLEAST16 _spec16l "u" +#define SCNuLEAST32 _spec32l "u" +#define SCNuLEAST64 _spec64l "u" +#define SCNuFAST8 _spec8f "u" +#define SCNuFAST16 _spec16f "u" +#define SCNuFAST32 _spec32f "u" +#define SCNuFAST64 _spec64f "u" +#define SCNuPTR _specptr "u" +#define SCNuMAX _specmax "u" +#define SCNx8 _spec8 "x" +#define SCNx16 _spec16 "x" +#define SCNx32 _spec32 "x" +#define SCNx64 _spec64 "x" +#define SCNxLEAST8 _spec8l "x" +#define SCNxLEAST16 _spec16l "x" +#define SCNxLEAST32 _spec32l "x" +#define SCNxLEAST64 _spec64l "x" +#define SCNxFAST8 _spec8f "x" +#define SCNxFAST16 _spec16f "x" +#define SCNxFAST32 _spec32f "x" +#define SCNxFAST64 _spec64f "x" +#define SCNxPTR _specptr "x" +#define SCNxMAX _specmax "x" diff --git a/inc/locale.h b/inc/locale.h index cf963d7..a59a17e 100644 --- a/inc/locale.h +++ b/inc/locale.h @@ -1,9 +1,15 @@ -#include "_platform.h" + +#pragma once + +#define _COL_IGNORE_SPACE 0x1 +#define _COL_IGNORE_SYMBOL 0x2 struct lconv { + // LC_NUMERIC char *decimal_point; // "." char *thousands_sep; // "" char *grouping; // "" + // LC_MONETARY char *mon_decimal_point; // "" char *mon_thousands_sep; // "" char *mon_grouping; // "" diff --git a/inc/math.h b/inc/math.h index 1b398fa..22ece91 100644 --- a/inc/math.h +++ b/inc/math.h @@ -1,4 +1,5 @@ -#include "_platform.h" + +#pragma once typedef float float_t; typedef double double_t; diff --git a/inc/signal.h b/inc/signal.h index 0cde095..c3016c8 100644 --- a/inc/signal.h +++ b/inc/signal.h @@ -1,11 +1,12 @@ -#include "_platform.h" + +#pragma once typedef int sig_atomic_t; // TODO: implement this -#define SIG_DFL (-1) -#define SIG_ERR (-1) -#define SIG_IGN (-1) +#define SIG_DFL 0 +#define SIG_ERR 1 +#define SIG_IGN 2 // not sure why but windows picked these, we can change it later #define SIGINT 2 diff --git a/inc/stdio.h b/inc/stdio.h index 17ca341..b2f59a9 100644 --- a/inc/stdio.h +++ b/inc/stdio.h @@ -1,8 +1,23 @@ -#include "_platform.h" + +#pragma once + +#include typedef struct FILE FILE; typedef int64_t fpos_t; +#if !defined(__STDC_LIB_EXT1__) + #define __STDC_LIB_EXT1__ + typedef int errno_t; + typedef size_t rsize_t; +#endif + +#ifdef __STDC_WANT_SECURE_LIB__ + #if !defined(__STDC_WANT_LIB_EXT1__) + #define __STDC_WANT_LIB_EXT1__ 1 + #endif +#endif + #define _IOFBF 0x0000 #define _IOLBF 0x0040 #define _IONBF 0x0004 @@ -75,10 +90,9 @@ int feof(FILE *stream); int ferror(FILE *stream); void perror(const char *s); -#ifdef __STDC_WANT_LIB_EXT1__ -#define L_tmpnam_s L_tmpnam -#define TMP_MAX_S TMP_MAX - -errno_t tmpfile_s(FILE * restrict * restrict streamptr); -errno_t tmpnam_s(char *s, rsize_t maxsize); +#if __STDC_WANT_LIB_EXT1__ == 1 + #define L_tmpnam_s L_tmpnam + #define TMP_MAX_S TMP_MAX + errno_t tmpfile_s(FILE * restrict * restrict streamptr); + errno_t tmpnam_s(char *s, rsize_t maxsize); #endif diff --git a/inc/stdlib.h b/inc/stdlib.h index 19aad8f..3ca5496 100644 --- a/inc/stdlib.h +++ b/inc/stdlib.h @@ -1,7 +1,18 @@ + #pragma once #if !defined(NULL) -#define NULL ((void *)0) + #define NULL ((void *)0) +#endif + +#if !defined(__STDC_LIB_EXT1__) + #define __STDC_LIB_EXT1__ +#endif + +#ifdef __STDC_WANT_SECURE_LIB__ + #if !defined(__STDC_WANT_LIB_EXT1__) + #define __STDC_WANT_LIB_EXT1__ 1 + #endif #endif // typedef struct div_t { diff --git a/inc/string.h b/inc/string.h index 201bc70..e9f0f0d 100644 --- a/inc/string.h +++ b/inc/string.h @@ -1,6 +1,23 @@ -#include "_platform.h" -int _wcsicmp(const wchar_t *string1, const wchar_t *string2); +#pragma once + +#if !defined(NULL) + #define NULL ((void *)0) +#endif + +#if !defined(__STDC_LIB_EXT1__) + #define __STDC_LIB_EXT1__ + typedef int errno_t; + typedef size_t rsize_t; +#endif + +#if __STDC_WANT_SECURE_LIB__ == 1 + #if !defined(__STDC_WANT_LIB_EXT1__) + #define __STDC_WANT_LIB_EXT1__ 1 + #endif +#endif + +// int _wcsicmp(const wchar_t *string1, const wchar_t *string2); void *memcpy(void * restrict s1, const void * restrict s2, size_t n); void *memmove(void *s1, const void *s2, size_t n); @@ -25,16 +42,16 @@ void *memset(void *s, int c, size_t n); char *strerror(int errnum); size_t strlen(const char *s); -#if __STDC_WANT_LIB_EXT1__ -errno_t memcpy_s(void * restrict s1, rsize_t s1max, const void * restrict s2, rsize_t n); -errno_t memmove_s(void *s1, rsize_t s1max, const void *s2, rsize_t n); -errno_t strcpy_s(char * restrict s1, rsize_t s1max, const char * restrict s2); -errno_t strncpy_s(char * restrict s1, rsize_t s1max,const char * restrict s2, rsize_t n); -errno_t strcat_s(char * restrict s1, rsize_t s1max, const char * restrict s2); -errno_t strncat_s(char * restrict s1, rsize_t s1max, const char * restrict s2, rsize_t n); -char *strtok_s(char * restrict s1, rsize_t * restrict s1max, const char * restrict s2, char ** restrict ptr); -errno_t memset_s(void *s, rsize_t smax, int c, rsize_t n); -errno_t strerror_s(char *s, rsize_t maxsize, errno_t errnum); -size_t strerrorlen_s(errno_t errnum); -size_t strnlen_s(const char *s, size_t maxsize); +#if __STDC_WANT_LIB_EXT1__ == 1 + errno_t memcpy_s(void * restrict s1, rsize_t s1max, const void * restrict s2, rsize_t n); + errno_t memmove_s(void *s1, rsize_t s1max, const void *s2, rsize_t n); + errno_t strcpy_s(char * restrict s1, rsize_t s1max, const char * restrict s2); + errno_t strncpy_s(char * restrict s1, rsize_t s1max,const char * restrict s2, rsize_t n); + errno_t strcat_s(char * restrict s1, rsize_t s1max, const char * restrict s2); + errno_t strncat_s(char * restrict s1, rsize_t s1max, const char * restrict s2, rsize_t n); + char *strtok_s(char * restrict s1, rsize_t * restrict s1max, const char * restrict s2, char ** restrict ptr); + errno_t memset_s(void *s, rsize_t smax, int c, rsize_t n); + errno_t strerror_s(char *s, rsize_t maxsize, errno_t errnum); + size_t strerrorlen_s(errno_t errnum); + size_t strnlen_s(const char *str, size_t strsz); #endif diff --git a/inc/tgmath.h b/inc/tgmath.h index 6bf9533..13e302a 100644 --- a/inc/tgmath.h +++ b/inc/tgmath.h @@ -1,3 +1,6 @@ + +#pragma once + /* these are type generic so they're macrod and use C11's _Generic diff --git a/inc/threads.h b/inc/threads.h index 722407e..fc65d53 100644 --- a/inc/threads.h +++ b/inc/threads.h @@ -1,4 +1,7 @@ -#include "_platform.h" + +#pragma once + +#include #define thread_local _Thread_local #define ONCE_FLAG_INIT 1 diff --git a/inc/time.h b/inc/time.h index 412ff11..0fa12e7 100644 --- a/inc/time.h +++ b/inc/time.h @@ -1,4 +1,9 @@ -#include "_platform.h" + +#pragma once + +#if !defined(NULL) + #define NULL ((void *)0) +#endif // The number of clock ticks per second #define CLOCKS_PER_SEC ((clock_t)1000) diff --git a/inc/uchar.h b/inc/uchar.h index 4517405..66bb9d5 100644 --- a/inc/uchar.h +++ b/inc/uchar.h @@ -1,4 +1,5 @@ -#include "_platform.h" + +#pragma once typedef struct mbstate_t mbstate_t; typedef uint16_t char16_t; diff --git a/inc/wchar.h b/inc/wchar.h index 710bc34..73557d9 100644 --- a/inc/wchar.h +++ b/inc/wchar.h @@ -1,6 +1,7 @@ -// On linux this will be UTF-32, on windows it's UTF-16 -#include "_platform.h" +#pragma once + +// On linux this will be UTF-32, on windows it's UTF-16 (or maybe UCS-2?) typedef struct mbstate_t mbstate_t; typedef wchar_t wint_t; diff --git a/inc/wctype.h b/inc/wctype.h index c4dda4f..220c748 100644 --- a/inc/wctype.h +++ b/inc/wctype.h @@ -1,4 +1,5 @@ -#include "_platform.h" + +#pragma once typedef int wint_t; wctrans_t; diff --git a/test/bake.bat b/test/bake.bat deleted file mode 100644 index 4e42cc8..0000000 --- a/test/bake.bat +++ /dev/null @@ -1,15 +0,0 @@ -@echo off -pushd %~dp0 - -cl /nologo inctoarg.c -inctoarg > temp -set /P includes= #include +#include + int main(int argc, char** argv) { - for (int i = 0; i < argc; i++) { - printf("[%d] = %s\n", i, argv[i]); - } - - printf("%d\n", 583875381); - printf("%.*s", (int)3, "Hello"); - - for (char c = 'a'; c != 'z'; ++c) { - assert(isupper(toupper(c))); - } - - double v0 = strtod("0X1.BC70A3D70A3D7P+6", NULL); - - // parsing with error handling - const char *p = "111.11 -2.22 Nan nan(2) inF 0X1.BC70A3D70A3D7P+6 1.18973e+4932zzz"; - - char *end; - for (double f = strtod(p, &end); p != end; f = strtod(p, &end)) { - printf("'%.*s' -> ", (int)(end - p), p); - p = end; - if (errno == ERANGE){ - printf("range error, got "); - } - - printf("%f\n", f); - } - - // parsing without error handling - double v1 = strtod(" -0.0000000123junk", NULL); - double v2 = strtod("junk", NULL); + uint64_t mynumber = 4; + printf("Hello, guys %"PRIu64"\n", mynumber); + return 0; } \ No newline at end of file