@@ -3,10 +3,8 @@ #include #include #include -static void* const null = (void*)0; - typedef struct kvar { ksraw name; ksraw val; char* platform; @@ -18,5 +16,115 @@ 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 + +/* 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(longstat code); + +#ifdef KFclean +# undef noreturn +#endif + #endif