#ifndef KIcore #define KIcore #include #include #include typedef struct kvar { ksraw name; ksraw val; char* platform; } kvar; typedef struct kenv { kiochan std; kiochan err; sz argc; char** argv; kvar* vars; } kenv; /* i'm really sorry okay */ typedef #if (__STDC_VERSION__ >= 199901L) _Bool bool; #endif enum #if !(__STDC_VERSION__ >= 199901L) bool /* enum bool { */ #endif { false = 0, no = 0, true = 1, yes = 1 } #if !(__STDC_VERSION__ >= 199901L) bool /* } bool ; */ #endif ; #ifndef KFclean # if (__STDC_VERSION__ >= 199901L) ||\ (__cplusplus >= 201103L) # define KVvm_args __VA_ARGS__ # define KVvm_spec ... # define KFfeat_variadic_macro # else # define KVvm_args K_TEMP_M2QD52 # define KVvm_spec K_TEMP_M2QD52 # endif # if defined(__GNUC__) || defined(__clang__) # define KA(KVvm_spec) __attribute__((KVvm_args)) # else # define KA(KVvm_spec) # endif # define KAformat(KVvm_spec) KA(format(KVvm_args)) # define KAexport(KVvm_spec) KA(visibility(KVvm_args)) # define KAunused KA(unused) # define KAnoreturn KA(noreturn) # define KApure KA(const) # define KAinline KA(always_inline) # define KAflatten KA(flatten) # define KAexport_none KAexport("hidden") # define KAexport_force KAexport("default") /* now we define standard version flags, * to make it easy for the user to write * more portable code. */ # if (__STDC_VERSION__ >= 199901L) # define KFstd_c89 # define KFstd_c99 # define KVstd c99 # else # ifdef __STDC__ # define KFstd_c89 # define KVstd c89 # else # define KVstd K&R /* UH OH */ # endif # endif # if (__STDC_VERSION__ >= 201103L) # define KFstd_c11 # define KVstd c11 # endif # ifdef __cplusplus # define KFstd_cpp # define KVstd c++ # if (__cplusplus >= 201103L) # define KFstd_cpp11 # define KVstd c++11 # endif /* TODO: add more */ # endif #endif #ifdef KFstd_c11 # define Kassert _Static_assert #else # define Kassert(x) { struct { int assertion_failed[(x) ? 1 : -1] }; } #endif /* hooo boy. null. that one's got a storied * history across the versions and dialects. * below, we try to find the ideal way to * offer a "null" "keyword" depending on * dialect, version, and whether the user * has asked for macros to be suspended. * note that this may result in no "null" * being defined in C++ or K&R C. */ #if defined (__cplusplus) && ! defined(KFclean) # if __cplusplus >= 201103L # define null nullptr # else # define null ((void*)0) # endif #elif defined __STDC__ enum { null = 0 }; /* believe it or not, this is actually * completely legal. doesn't even raise * a single warning. i was surprised too. */ #elif ! defined(KFclean) # define null ((void*)0) #endif #ifdef __cplusplus # define noreturn [[ noreturn ]] #elif __STDC_VERSION__ >= 201103L # define noreturn _Noreturn #else # define noreturn #endif noreturn void kstop(stat_long code); #ifdef KFclean # undef noreturn #endif #endif