mirror of https://github.com/flysand7/ciabatta.git
reorganize, random fixes
This commit is contained in:
parent
cca63462fc
commit
b414343f52
|
@ -1,4 +1,4 @@
|
|||
build
|
||||
bin
|
||||
*.exe
|
||||
*.lib
|
||||
*.obj
|
||||
|
|
47
bake.cmd
47
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:
|
||||
|
||||
if not exist src\code\unicode\unicode_data.h (
|
||||
py src\code\unicode\unicode_compile.py
|
||||
)
|
||||
|
||||
if exist bin rd/s/q bin
|
||||
mkdir bin
|
||||
mkdir bin\%PLATFORM%
|
||||
|
||||
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" (
|
||||
for /R src\%PLATFORM% %%F in (*.c) do (
|
||||
echo %%F
|
||||
clang -c -o build\%%~nF.obj %%F %CIABATTA_OPTIONS%
|
||||
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 build\*.obj
|
||||
del build\*.obj
|
||||
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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#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();
|
||||
}
|
|
@ -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 <locale.h>
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#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;
|
||||
}
|
|
@ -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 <intrin.h>
|
||||
#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
|
||||
|
|
|
@ -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]))
|
|
@ -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__)
|
||||
|
|
15
inc/assert.h
15
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
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
int isalnum(int c);
|
||||
|
|
|
@ -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
|
||||
|
@ -57,5 +58,5 @@ int _fedisabletraps(int excepts);
|
|||
|
||||
#if defined(_CIABATTA_EXT)
|
||||
#define feenabletraps _feenabletraps
|
||||
#define _fedisabletraps _fedisabletraps
|
||||
#define fedisabletraps _fedisabletraps
|
||||
#endif
|
|
@ -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
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
|
||||
#include <assert.h>
|
||||
|
||||
#include <stdio.h> // printf
|
||||
#include <stdlib.h> // 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();
|
||||
}
|
|
@ -1,9 +1,5 @@
|
|||
|
||||
// TODO: table-driven?
|
||||
// TODO: other locales
|
||||
|
||||
#include <ctype.h>
|
||||
#include <locale.h>
|
||||
|
||||
#define in_range(low, v, high) ((low <= v) && (v <= high))
|
||||
|
|
@ -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;
|
||||
}
|
|
@ -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 <locale.h>
|
||||
#include <limits.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#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;
|
||||
}
|
|
@ -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');
|
|
@ -2,7 +2,7 @@
|
|||
#include <wctype.h>
|
||||
#include <string.h>
|
||||
|
||||
#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) {
|
|
@ -6,7 +6,8 @@
|
|||
|
||||
#include <signal.h>
|
||||
#include <stddef.h>
|
||||
#include <_macros.h>
|
||||
|
||||
#define _countof(arr) (sizeof (arr) / sizeof ((arr)[0]))
|
||||
|
||||
typedef struct SignalMapping {
|
||||
DWORD code;
|
|
@ -0,0 +1,7 @@
|
|||
|
||||
#include <assert.h>
|
||||
|
||||
int main() {
|
||||
assert(2+2 == 4);
|
||||
assert(0 != 0); // Bad case of assert
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
|
||||
#include <ctype.h>
|
||||
#include <wctype.h>
|
||||
|
||||
#include <time.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
||||
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;
|
||||
}
|
Loading…
Reference in New Issue