parser_dbg.hpp (5249B)
1 #ifndef _C4_YML_DETAIL_PARSER_DBG_HPP_ 2 #define _C4_YML_DETAIL_PARSER_DBG_HPP_ 3 4 #ifndef _C4_YML_COMMON_HPP_ 5 #include "../common.hpp" 6 #endif 7 #include <cstdio> 8 9 //----------------------------------------------------------------------------- 10 // some debugging scaffolds 11 12 #if defined(_MSC_VER) 13 # pragma warning(push) 14 # pragma warning(disable: 4068/*unknown pragma*/) 15 #endif 16 17 #pragma GCC diagnostic push 18 #pragma GCC diagnostic ignored "-Wunknown-pragmas" 19 //#pragma GCC diagnostic ignored "-Wpragma-system-header-outside-header" 20 #pragma GCC system_header 21 22 #pragma clang diagnostic push 23 #pragma clang diagnostic ignored "-Werror" 24 #pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments" 25 26 // some debugging scaffolds 27 #ifdef RYML_DBG 28 #include <c4/dump.hpp> 29 namespace c4 { 30 inline void _dbg_dumper(csubstr s) { fwrite(s.str, 1, s.len, stdout); }; 31 template<class ...Args> 32 void _dbg_printf(c4::csubstr fmt, Args&& ...args) 33 { 34 static char writebuf[256]; 35 auto results = c4::format_dump_resume<&_dbg_dumper>(writebuf, fmt, std::forward<Args>(args)...); 36 // resume writing if the results failed to fit the buffer 37 if(C4_UNLIKELY(results.bufsize > sizeof(writebuf))) // bufsize will be that of the largest element serialized. Eg int(1), will require 1 byte. 38 { 39 results = format_dump_resume<&_dbg_dumper>(results, writebuf, fmt, std::forward<Args>(args)...); 40 if(C4_UNLIKELY(results.bufsize > sizeof(writebuf))) 41 { 42 results = format_dump_resume<&_dbg_dumper>(results, writebuf, fmt, std::forward<Args>(args)...); 43 } 44 } 45 } 46 } // namespace c4 47 48 # define _c4dbgt(fmt, ...) this->_dbg ("{}:{}: " fmt , __FILE__, __LINE__, ## __VA_ARGS__) 49 # define _c4dbgpf(fmt, ...) _dbg_printf("{}:{}: " fmt "\n", __FILE__, __LINE__, ## __VA_ARGS__) 50 # define _c4dbgp(msg) _dbg_printf("{}:{}: " msg "\n", __FILE__, __LINE__ ) 51 # define _c4dbgq(msg) _dbg_printf(msg "\n") 52 # define _c4err(fmt, ...) \ 53 do { if(c4::is_debugger_attached()) { C4_DEBUG_BREAK(); } \ 54 this->_err("ERROR:\n" "{}:{}: " fmt, __FILE__, __LINE__, ## __VA_ARGS__); } while(0) 55 #else 56 # define _c4dbgt(fmt, ...) 57 # define _c4dbgpf(fmt, ...) 58 # define _c4dbgp(msg) 59 # define _c4dbgq(msg) 60 # define _c4err(fmt, ...) \ 61 do { if(c4::is_debugger_attached()) { C4_DEBUG_BREAK(); } \ 62 this->_err("ERROR: " fmt, ## __VA_ARGS__); } while(0) 63 #endif 64 65 #define _c4prsp(sp) sp 66 #define _c4presc(s) __c4presc(s.str, s.len) 67 inline c4::csubstr _c4prc(const char &C4_RESTRICT c) 68 { 69 switch(c) 70 { 71 case '\n': return c4::csubstr("\\n"); 72 case '\t': return c4::csubstr("\\t"); 73 case '\0': return c4::csubstr("\\0"); 74 case '\r': return c4::csubstr("\\r"); 75 case '\f': return c4::csubstr("\\f"); 76 case '\b': return c4::csubstr("\\b"); 77 case '\v': return c4::csubstr("\\v"); 78 case '\a': return c4::csubstr("\\a"); 79 default: return c4::csubstr(&c, 1); 80 } 81 } 82 inline void __c4presc(const char *s, size_t len) 83 { 84 size_t prev = 0; 85 for(size_t i = 0; i < len; ++i) 86 { 87 switch(s[i]) 88 { 89 case '\n' : fwrite(s+prev, 1, i-prev, stdout); putchar('\\'); putchar('n'); putchar('\n'); prev = i+1; break; 90 case '\t' : fwrite(s+prev, 1, i-prev, stdout); putchar('\\'); putchar('t'); prev = i+1; break; 91 case '\0' : fwrite(s+prev, 1, i-prev, stdout); putchar('\\'); putchar('0'); prev = i+1; break; 92 case '\r' : fwrite(s+prev, 1, i-prev, stdout); putchar('\\'); putchar('r'); prev = i+1; break; 93 case '\f' : fwrite(s+prev, 1, i-prev, stdout); putchar('\\'); putchar('f'); prev = i+1; break; 94 case '\b' : fwrite(s+prev, 1, i-prev, stdout); putchar('\\'); putchar('b'); prev = i+1; break; 95 case '\v' : fwrite(s+prev, 1, i-prev, stdout); putchar('\\'); putchar('v'); prev = i+1; break; 96 case '\a' : fwrite(s+prev, 1, i-prev, stdout); putchar('\\'); putchar('a'); prev = i+1; break; 97 case '\x1b': fwrite(s+prev, 1, i-prev, stdout); putchar('\\'); putchar('e'); prev = i+1; break; 98 case -0x3e/*0xc2u*/: 99 if(i+1 < len) 100 { 101 if(s[i+1] == -0x60/*0xa0u*/) 102 { 103 fwrite(s+prev, 1, i-prev, stdout); putchar('\\'); putchar('_'); prev = i+2; ++i; 104 } 105 else if(s[i+1] == -0x7b/*0x85u*/) 106 { 107 fwrite(s+prev, 1, i-prev, stdout); putchar('\\'); putchar('N'); prev = i+2; ++i; 108 } 109 break; 110 } 111 case -0x1e/*0xe2u*/: 112 if(i+2 < len && s[i+1] == -0x80/*0x80u*/) 113 { 114 if(s[i+2] == -0x58/*0xa8u*/) 115 { 116 fwrite(s+prev, 1, i-prev, stdout); putchar('\\'); putchar('L'); prev = i+3; i += 2; 117 } 118 else if(s[i+2] == -0x57/*0xa9u*/) 119 { 120 fwrite(s+prev, 1, i-prev, stdout); putchar('\\'); putchar('P'); prev = i+3; i += 2; 121 } 122 break; 123 } 124 } 125 } 126 fwrite(s + prev, 1, len - prev, stdout); 127 } 128 129 #pragma clang diagnostic pop 130 #pragma GCC diagnostic pop 131 132 #if defined(_MSC_VER) 133 # pragma warning(pop) 134 #endif 135 136 137 #endif /* _C4_YML_DETAIL_PARSER_DBG_HPP_ */