#ifndef KIcore #define KIcore #include typedef u16 kcond; /* this will probably not need to be altered, * as libk sports a modest number of modules, * and there are few enough error conditions * in each that 16-bit address space should * be more than enough for the foreseeable * future. however if that changes, altering * the definition here will effect all the * necessary changes throughout the library */ /* 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 ; bool kokay(kcond); #ifndef KFclean # include # define Kokay(cond) (((cond) % kglobal_module_offset) == 0) # 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_c89 # 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__ && (!defined __clang__ || defined KFclean) enum { null = 0 }; /* believe it or not, this is actually * completely legal. doesn't even raise * a single warning in GCC. i was surprised * too. alas, it later turned out that * clang will throw a fit about this, so * we only use the enum method if __clang__ * is undefined, or if the alternative is * no null keyword at all. */ #elif ! defined(KFclean) # define null ((void*)0) #endif #ifndef KFclean # ifdef __cplusplus # define noreturn [[ noreturn ]] # elif __STDC_VERSION__ >= 201103L # define noreturn _Noreturn # else # define noreturn # endif #endif #ifdef __cplusplus [[noreturn]] void kstop(stat_long code); #elif __STDC_VERSION__ >= 201103L _Noreturn void kstop(stat_long code); #else void kstop(stat_long code); #endif typedef struct kerror { const char* module_name, * module_desc, * error_string; kcond cond; } kerror; #include #include #include #ifdef __cplusplus extern "C" { #endif typedef struct kvar { ksraw name; ksraw val; char* platform; } kvar; typedef struct kenv { kiochan std; kiochan err; sz argc; const char** args; sz varc; kvar* vars; } kenv; kerror kexplain(kcond); #ifdef __cplusplus } #endif #endif