diff --git a/.gitignore b/.gitignore index e38f598..1607e61 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ -build +bin *.exe *.lib *.obj diff --git a/bake.cmd b/bake.cmd index a243b17..28ffbc2 100644 --- a/bake.cmd +++ b/bake.cmd @@ -19,37 +19,30 @@ set PLATFORM=win if "%1"=="test" ( 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% - ) + +if not exist src\code\unicode\unicode_data.h ( + py src\code\unicode\unicode_compile.py ) -llvm-ar rc ciabatta.lib build\*.obj -del build\*.obj + +if exist bin rd/s/q bin +mkdir bin +mkdir bin\%PLATFORM% + +del ciabatta.lib 2> nul +for /R src\%PLATFORM% %%F in (*.c) do ( + echo %%F + clang -c -o bin\%PLATFORM%\%%~nF.obj %%F %CIABATTA_OPTIONS% +) +for /R src\code %%F in (*.c) do ( + echo %%F + clang -c -o bin\%%~nF.obj %%F %CIABATTA_OPTIONS% +) +llvm-ar rc ciabatta.lib bin\*.obj bin\%PLATFORM%\*.obj :skip_crt_compilation -echo Compiling test.. -clang -fno-builtin test\test_math.c ciabatta.lib -std=c11 -lkernel32 -luser32 -lshell32 -nostdlib %CIABATTA_OPTIONS% + +if "%TEST%"=="" set TEST=assert + +echo Compiling test_%TEST%.c +clang -fno-builtin test\test_%TEST%.c ciabatta.lib -std=c11 -lkernel32 -luser32 -lshell32 -nostdlib %CIABATTA_OPTIONS% ::cl test\test_math.c /Iinc -D_CRT_SECURE_NO_WARNINGS /Z7 /link ciabatta.lib kernel32.lib user32.lib shell32.lib -nostdlib -nodefaultlibs diff --git a/build_cuik.cmd b/build_cuik.cmd index c076edb..8e38708 100644 --- a/build_cuik.cmd +++ b/build_cuik.cmd @@ -1,12 +1,18 @@ @echo off setlocal enabledelayedexpansion +if not exist src\code\unicode\unicode_data.h ( + py src\code\unicode\unicode_compile.py +) + set PLATFORM=win set CIABATTA_OPTIONS=--crt none -I %% -I inc del ciabatta.lib -cuik %CIABATTA_OPTIONS% code\*.c code\os\%PLATFORM%\*.c -c -o ciabatta.obj +cuik %CIABATTA_OPTIONS% src\code\*.c src\%PLATFORM%\*.c -c -o ciabatta.obj lib /out:ciabatta.lib ciabatta.obj -cuik test\test.c --lib ciabatta.lib,kernel32.lib,user32.lib,shell32.lib %CIABATTA_OPTIONS% +if "%TEST%"=="" set TEST=assert + +cuik test\test_%TEST%.c --lib ciabatta.lib,kernel32.lib,user32.lib,shell32.lib %CIABATTA_OPTIONS% del ciabatta.obj diff --git a/code/assert.c b/code/assert.c deleted file mode 100644 index 47d3636..0000000 --- a/code/assert.c +++ /dev/null @@ -1,24 +0,0 @@ -#include -#include -#include -#include - -#include <_compiler.h> -#include <_os.h> - -// TODO: use abort() to break - -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); - } - printf("\tFile: %s\n", file); - printf("\tLine: %s\n", line); - abort(); -} diff --git a/code/locale.c b/code/locale.c deleted file mode 100644 index 32bb6f7..0000000 --- a/code/locale.c +++ /dev/null @@ -1,69 +0,0 @@ - -// TODO: X-macros -// TODO: data race possible (see 7.11.1.1 p. 5) -// TODO: something about restoring locales (see 7.11.1.1 p. 8) -#include -#include -#include -#include - -#define _LC_FIRST 0 -#define _LC_LAST 5 - -static struct lconv _locale; -static char _locale_str[16]; - -// Even if the user doesn't enable LIB_EXT1 we still have it existing -size_t strnlen_s(const char *s, size_t maxsize); - -char *setlocale(int category, const char *locale) { - if (_LC_FIRST <= category && category <= _LC_LAST) return NULL; - if (locale == NULL) return _locale_str; - - // Validate the string a bit - size_t locale_len = strnlen_s(locale, sizeof(_locale_str)); - if (locale_len == 0 || locale_len >= sizeof(_locale_str)) return NULL; - - if(strcmp(locale, "C") == 0) { - switch (category) { - case LC_ALL: { - _locale.decimal_point = "."; - _locale.thousands_sep = ""; - _locale.grouping = ""; - _locale.mon_decimal_point = ""; - _locale.mon_thousands_sep = ""; - _locale.mon_grouping = ""; - _locale.positive_sign = ""; - _locale.negative_sign = ""; - _locale.currency_symbol = ""; - _locale.frac_digits = CHAR_MAX; - _locale.p_cs_precedes = CHAR_MAX; - _locale.n_cs_precedes = CHAR_MAX; - _locale.p_sep_by_space = CHAR_MAX; - _locale.n_sep_by_space = CHAR_MAX; - _locale.p_sign_posn = CHAR_MAX; - _locale.n_sign_posn = CHAR_MAX; - _locale.int_curr_symbol = ""; - _locale.int_frac_digits = CHAR_MAX; - _locale.int_p_cs_precedes = CHAR_MAX; - _locale.int_n_cs_precedes = CHAR_MAX; - _locale.int_p_sep_by_space = CHAR_MAX; - _locale.int_n_sep_by_space = CHAR_MAX; - _locale.int_p_sign_posn = CHAR_MAX; - _locale.int_n_sign_posn = CHAR_MAX; - break; - } - - default: return NULL; - } - } else { - return NULL; - } - - memcpy(_locale_str, locale, locale_len); - return _locale_str; -} - -struct lconv *localeconv(void) { - return &_locale; -} diff --git a/inc/_compiler.h b/inc/_compiler.h index 189d069..44a33cb 100644 --- a/inc/_compiler.h +++ b/inc/_compiler.h @@ -6,7 +6,7 @@ #endif #if defined(__GNUC__) && !defined(__clang__) - #define _compiler_gnu + #define _compiler_gcc #endif #if defined(__clang__) @@ -18,17 +18,9 @@ #endif #if !(defined(_compiler_msvc) \ - || defined(_compiler_gnu) \ + || defined(_compiler_gcc) \ || defined(_compiler_cuik) \ || defined(_compiler_clang)) #error "Unsupported Compiler" #endif -#if defined(_compiler_msvc) || defined(_compiler_cuik) - #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 diff --git a/inc/_macros.h b/inc/_macros.h deleted file mode 100644 index fa90589..0000000 --- a/inc/_macros.h +++ /dev/null @@ -1,9 +0,0 @@ - -#pragma once - -#define _str_(x) #x -#define _str(x) _str_(x) - -#define _con(a,b) a ## b - -#define _countof(arr) (sizeof (arr) / sizeof ((arr)[0])) diff --git a/inc/_os.h b/inc/_os.h index 994a282..58cd699 100644 --- a/inc/_os.h +++ b/inc/_os.h @@ -4,9 +4,6 @@ #if defined(_WIN32) #define _os_win - - // Weird hack because this function is used by a weird function windows.h defines - int _wcsicmp(wchar_t const* s1, wchar_t const* s2); #endif #if defined(__linux__) && !defined(__ANDROID__) diff --git a/inc/assert.h b/inc/assert.h index d3d5122..02dd3d8 100644 --- a/inc/assert.h +++ b/inc/assert.h @@ -4,14 +4,11 @@ #define __func__ __FUNCTION__ #endif -#define _assert_str_(x) #x -#define _assert_str(x) _assert_str_(x) - -extern void _assert_error( - char *cond, +void _Noreturn _assert( + char const *cond, char const *func, char const *file, - char const *line + int line ); #if defined(NDEBUG) @@ -21,11 +18,7 @@ extern void _assert_error( #define assert(condition) \ do { \ if(!(condition)) { \ - _assert_error( \ - #condition, \ - __func__, \ - __FILE__, \ - _assert_str(__LINE__)); \ + _assert(#condition, __func__, __FILE__, __LINE__); \ } \ } while(0) #endif diff --git a/inc/ctype.h b/inc/ctype.h index a2b8114..e24a3d9 100644 --- a/inc/ctype.h +++ b/inc/ctype.h @@ -1,3 +1,4 @@ + #pragma once int isalnum(int c); diff --git a/inc/fenv.h b/inc/fenv.h index 87e6c78..dd166d4 100644 --- a/inc/fenv.h +++ b/inc/fenv.h @@ -4,12 +4,12 @@ typedef unsigned fexcept_t; typedef unsigned fenv_t; +// These constants correspond to bits in MXCSR register #define FE_INVALID (1 << 0) #define FE_DIVBYZERO (1 << 2) #define FE_OVERFLOW (1 << 3) #define FE_UNDERFLOW (1 << 4) #define FE_INEXACT (1 << 5) -// Implementation-defined flags #define FE_DENORM (1 << 1) #define FE_DAZ (1 << 6) @@ -22,6 +22,7 @@ typedef unsigned fenv_t; | FE_DENORM \ | FE_DAZ ) +// These constants correspond to the rounding field in MXCSR register #define FE_TONEAREST 0x00 #define FE_DOWNWARD 0x01 #define FE_UPWARD 0x02 @@ -56,6 +57,6 @@ int _feenabletraps(int excepts); int _fedisabletraps(int excepts); #if defined(_CIABATTA_EXT) - #define feenabletraps _feenabletraps - #define _fedisabletraps _fedisabletraps + #define feenabletraps _feenabletraps + #define fedisabletraps _fedisabletraps #endif \ No newline at end of file diff --git a/lakefile.lua b/lakefile.lua index 2803f47..db54fd1 100644 --- a/lakefile.lua +++ b/lakefile.lua @@ -1,5 +1,9 @@ local lake = require 'lakebuild' +-- NOTE(bumbread): change this to reflect the fact that +-- now platform-independent stuff is in src/code and +-- platform-dependent stuff is in src/$PALTFORM + local function buildcmd(target) local deps = "" if target.userdata.add_deps then diff --git a/src/code/assert.c b/src/code/assert.c new file mode 100644 index 0000000..d3a5f3e --- /dev/null +++ b/src/code/assert.c @@ -0,0 +1,18 @@ + +#include + +#include // printf +#include // abort + +void _Noreturn _assert( + char const *cond, + char const *func, + 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); + abort(); +} diff --git a/code/ctype.c b/src/code/ctype.c similarity index 94% rename from code/ctype.c rename to src/code/ctype.c index e07fd09..6c04c62 100644 --- a/code/ctype.c +++ b/src/code/ctype.c @@ -1,9 +1,5 @@ -// TODO: table-driven? -// TODO: other locales - #include -#include #define in_range(low, v, high) ((low <= v) && (v <= high)) diff --git a/code/errno.c b/src/code/errno.c similarity index 100% rename from code/errno.c rename to src/code/errno.c diff --git a/code/fenv.c b/src/code/fenv.c similarity index 96% rename from code/fenv.c rename to src/code/fenv.c index 0de9a8d..3e6e386 100644 --- a/code/fenv.c +++ b/src/code/fenv.c @@ -6,10 +6,9 @@ #define fe_flags(excepts) ((fexcept_t)(excepts)) #define fe_excepts(masks) ((int)(masks >> 7)) -fenv_t _fe_dfl_env = 0x1f80; // Based (on my machine) +fenv_t _fe_dfl_env = 0x1f80; -int feclearexcept(int excepts) -{ +int feclearexcept(int excepts) { if((excepts & FE_ALL_EXCEPT) != excepts) { return 1; } diff --git a/src/code/locale.c b/src/code/locale.c new file mode 100644 index 0000000..e498fd1 --- /dev/null +++ b/src/code/locale.c @@ -0,0 +1,69 @@ + +// TODO: X-macros +// TODO: data race possible (see 7.11.1.1 p. 5) +// TODO: something about restoring locales (see 7.11.1.1 p. 8) +#include +#include +#include +#include + +#define _LC_FIRST 0 +#define _LC_LAST 5 + +static struct lconv _locale; +static char _locale_str[16]; + +// Even if the user doesn't enable LIB_EXT1 we still have it existing +size_t strnlen_s(const char *s, size_t maxsize); + +char *setlocale(int category, const char *locale) { + if (_LC_FIRST <= category && category <= _LC_LAST) return NULL; + if (locale == NULL) return _locale_str; + + // Validate the string a bit + size_t locale_len = strnlen_s(locale, sizeof(_locale_str)); + if (locale_len == 0 || locale_len >= sizeof(_locale_str)) return NULL; + + if(strcmp(locale, "C") == 0) { + switch (category) { + case LC_ALL: { + _locale.decimal_point = "."; + _locale.thousands_sep = ""; + _locale.grouping = ""; + _locale.mon_decimal_point = ""; + _locale.mon_thousands_sep = ""; + _locale.mon_grouping = ""; + _locale.positive_sign = ""; + _locale.negative_sign = ""; + _locale.currency_symbol = ""; + _locale.frac_digits = CHAR_MAX; + _locale.p_cs_precedes = CHAR_MAX; + _locale.n_cs_precedes = CHAR_MAX; + _locale.p_sep_by_space = CHAR_MAX; + _locale.n_sep_by_space = CHAR_MAX; + _locale.p_sign_posn = CHAR_MAX; + _locale.n_sign_posn = CHAR_MAX; + _locale.int_curr_symbol = ""; + _locale.int_frac_digits = CHAR_MAX; + _locale.int_p_cs_precedes = CHAR_MAX; + _locale.int_n_cs_precedes = CHAR_MAX; + _locale.int_p_sep_by_space = CHAR_MAX; + _locale.int_n_sep_by_space = CHAR_MAX; + _locale.int_p_sign_posn = CHAR_MAX; + _locale.int_n_sign_posn = CHAR_MAX; + break; + } + + default: return NULL; + } + } else { + return NULL; + } + + memcpy(_locale_str, locale, locale_len); + return _locale_str; +} + +struct lconv *localeconv(void) { + return &_locale; +} diff --git a/code/math/_util.h b/src/code/math/_util.h similarity index 100% rename from code/math/_util.h rename to src/code/math/_util.h diff --git a/code/math/basic.c b/src/code/math/basic.c similarity index 100% rename from code/math/basic.c rename to src/code/math/basic.c diff --git a/code/math/division.c b/src/code/math/division.c similarity index 100% rename from code/math/division.c rename to src/code/math/division.c diff --git a/code/math/generic.c b/src/code/math/generic.c similarity index 100% rename from code/math/generic.c rename to src/code/math/generic.c diff --git a/code/math/generic.h b/src/code/math/generic.h similarity index 100% rename from code/math/generic.h rename to src/code/math/generic.h diff --git a/code/math/ieee754.c b/src/code/math/ieee754.c similarity index 100% rename from code/math/ieee754.c rename to src/code/math/ieee754.c diff --git a/code/math/round.c b/src/code/math/round.c similarity index 100% rename from code/math/round.c rename to src/code/math/round.c diff --git a/code/signal.c b/src/code/signal.c similarity index 100% rename from code/signal.c rename to src/code/signal.c diff --git a/code/stdio/files.c b/src/code/stdio/files.c similarity index 100% rename from code/stdio/files.c rename to src/code/stdio/files.c diff --git a/code/stdio/fmt_print.h b/src/code/stdio/fmt_print.h similarity index 100% rename from code/stdio/fmt_print.h rename to src/code/stdio/fmt_print.h diff --git a/code/stdio/stdio.c b/src/code/stdio/stdio.c similarity index 100% rename from code/stdio/stdio.c rename to src/code/stdio/stdio.c diff --git a/code/stdlib.c b/src/code/stdlib.c similarity index 100% rename from code/stdlib.c rename to src/code/stdlib.c diff --git a/code/stdlib/conv.c b/src/code/stdlib/conv.c similarity index 100% rename from code/stdlib/conv.c rename to src/code/stdlib/conv.c diff --git a/code/stdlib/env.c b/src/code/stdlib/env.c similarity index 100% rename from code/stdlib/env.c rename to src/code/stdlib/env.c diff --git a/code/stdlib/rand.c b/src/code/stdlib/rand.c similarity index 100% rename from code/stdlib/rand.c rename to src/code/stdlib/rand.c diff --git a/code/string.c b/src/code/string.c similarity index 100% rename from code/string.c rename to src/code/string.c diff --git a/code/unicode/readme b/src/code/unicode/readme similarity index 100% rename from code/unicode/readme rename to src/code/unicode/readme diff --git a/code/unicode/unicode_compile.py b/src/code/unicode/unicode_compile.py similarity index 96% rename from code/unicode/unicode_compile.py rename to src/code/unicode/unicode_compile.py index 4cc89a2..b69ce9d 100644 --- a/code/unicode/unicode_compile.py +++ b/src/code/unicode/unicode_compile.py @@ -6,7 +6,7 @@ abspath = os.path.abspath(sys.argv[0]) dname = os.path.dirname(abspath) os.chdir(dname) -with open('unicode.h', 'w') as header: +with open('unicode_data.h', 'w') as header: header.write('\n'); header.write('#pragma once\n\n'); header.write('#define Cc 0\n'); diff --git a/code/unicode/unicode.h b/src/code/unicode/unicode_data.h similarity index 100% rename from code/unicode/unicode.h rename to src/code/unicode/unicode_data.h diff --git a/code/unicode/unicode_data.txt b/src/code/unicode/unicode_data.txt similarity index 100% rename from code/unicode/unicode_data.txt rename to src/code/unicode/unicode_data.txt diff --git a/code/unicode/wctype.c b/src/code/unicode/wctype.c similarity index 89% rename from code/unicode/wctype.c rename to src/code/unicode/wctype.c index cd39b86..a5e0e8e 100644 --- a/code/unicode/wctype.c +++ b/src/code/unicode/wctype.c @@ -2,7 +2,7 @@ #include #include -#include "unicode.h" +#include "unicode_data.h" static inline int char_cat(wint_t wc) { return uni_codepoints[wc].cat; @@ -86,13 +86,26 @@ int iswpunct(wint_t wc) { case Pi: case Po: case Ps: + case Sk: + case Sc: + case Sm: + case So: return 1; } return 0; } int iswspace(wint_t wc) { - return char_cat(wc) == Zs; + switch(wc) { + case ' ': + case '\t': + case '\v': + case '\r': + case '\n': + case '\f': + return 1; + } + return 0; } int iswupper(wint_t wc) { diff --git a/code/os/win/win.h b/src/win/win.h similarity index 100% rename from code/os/win/win.h rename to src/win/win.h diff --git a/code/os/win/win_entry.c b/src/win/win_entry.c similarity index 100% rename from code/os/win/win_entry.c rename to src/win/win_entry.c diff --git a/code/os/win/win_env.c b/src/win/win_env.c similarity index 100% rename from code/os/win/win_env.c rename to src/win/win_env.c diff --git a/code/os/win/win_except.c b/src/win/win_except.c similarity index 96% rename from code/os/win/win_except.c rename to src/win/win_except.c index 0e4c131..0df42d2 100644 --- a/code/os/win/win_except.c +++ b/src/win/win_except.c @@ -6,7 +6,8 @@ #include #include -#include <_macros.h> + +#define _countof(arr) (sizeof (arr) / sizeof ((arr)[0])) typedef struct SignalMapping { DWORD code; diff --git a/code/os/win/win_io.c b/src/win/win_io.c similarity index 100% rename from code/os/win/win_io.c rename to src/win/win_io.c diff --git a/code/os/win/win_mem.c b/src/win/win_mem.c similarity index 100% rename from code/os/win/win_mem.c rename to src/win/win_mem.c diff --git a/code/os/win/win_mutex.c b/src/win/win_mutex.c similarity index 100% rename from code/os/win/win_mutex.c rename to src/win/win_mutex.c diff --git a/code/os/win/win_time.c b/src/win/win_time.c similarity index 100% rename from code/os/win/win_time.c rename to src/win/win_time.c diff --git a/test/test_assert.c b/test/test_assert.c new file mode 100644 index 0000000..5304081 --- /dev/null +++ b/test/test_assert.c @@ -0,0 +1,7 @@ + +#include + +int main() { + assert(2+2 == 4); + assert(0 != 0); // Bad case of assert +} diff --git a/test/test4.c b/test/test_bsearch.c similarity index 100% rename from test/test4.c rename to test/test_bsearch.c diff --git a/test/test_ctype.c b/test/test_ctype.c new file mode 100644 index 0000000..a1a6533 --- /dev/null +++ b/test/test_ctype.c @@ -0,0 +1,24 @@ + +#include +#include + +#include +#include +#include +#include + +int main() { + float start = (float)clock()/CLOCKS_PER_SEC; + for(int i = 0; i != 1000000; ++i) { + int c = rand() % 128; + assert(ispunct(c) == iswpunct((wint_t)c)); + assert(isalpha(c) == iswalpha((wint_t)c)); + assert(isspace(c) == iswspace((wint_t)c)); + assert(isgraph(c) == iswgraph((wint_t)c)); + assert(iscntrl(c) == iswcntrl((wint_t)c)); + } + float end = (float)clock()/CLOCKS_PER_SEC; + float elaps = end-start; + printf("Elapsed: %f\n", elaps); + return 0; +} diff --git a/test/test3.c b/test/test_entry.c similarity index 100% rename from test/test3.c rename to test/test_entry.c diff --git a/test/test6.c b/test/test_fenv.c similarity index 100% rename from test/test6.c rename to test/test_fenv.c diff --git a/test/test2.c b/test/test_strtod.c similarity index 100% rename from test/test2.c rename to test/test_strtod.c diff --git a/test/test.c b/test/test_strtok.c similarity index 100% rename from test/test.c rename to test/test_strtok.c