// a simple C debug mechanism #define _itoa(x) _str(x) #define _str(x) #x #define _ul(n,s,l,r) "\e[3"#n"m"l"\e[9"#n";4m" s "\e[;3"#n"m"r"\e[m" #define _hl(n,s,l,r) "\e[3"#n"m"l"\e[9"#n"m" s "\e[;3"#n"m"r"\e[m" #define _hlstr _ul(5,"%s","“","”") #define _hlpath _ul(4,"%s","“","”") #define _hlvar(v) _hl(2,v,"$","") #if defined(_debug) || defined(_live_debug) # include # define _var_pos "\e[34mat \e[94;4m" __FILE__ "#" _itoa(__LINE__) "\e[;34m:\e[m " # ifdef _live_debug # define say(fmt,...) (debug ? fprintf(stderr, \ _var_pos fmt "\n", __VA_ARGS__) : 0) # else # define say(fmt,...) fprintf(stderr, \ _var_pos fmt "\n", __VA_ARGS__) # endif # define _var_expr(name,code,prefix,suffix) _var_pos "\e[1m" name "\e[m \e[35m= \e[35m" \ prefix "\e[95;4m" "%" #code "\e[24;35m" suffix "\e[m\n" # define var(v) fprintf(stderr, _Generic ((v), \ char* : _var_expr(#v,s,"“","”"), \ const char* : _var_expr(#v,s,"",""), \ char : _var_expr(#v,c,"‘","’"), \ signed char : _var_expr(#v,hhi,"","i"), \ unsigned char : _var_expr(#v,hhu,"","u"), \ signed short: _var_expr(#v,hi,"","I"), \ unsigned short: _var_expr(#v,hu,"","U"), \ signed int : _var_expr(#v,i,"","I"), \ unsigned int : _var_expr(#v,u,"","U"), \ signed long : _var_expr(#v,li,"","L"), \ unsigned long : _var_expr(#v,lu,"","UL"), \ signed long long : _var_expr(#v,lli,"","LL"),\ unsigned long long : _var_expr(#v,llu,"","ULL"),\ default : _var_expr(#v,p,"[","]")), v) #else # define say(...) # define var(v) #endif