1 #include <iostream>
2 
3 #include "src/codegen/helpers.h"
4 
5 
6 namespace re2c {
7 
is_space(uint32_t c)8 static bool is_space(uint32_t c)
9 {
10     switch (c) {
11     case '\t':
12     case '\f':
13     case '\v':
14     case '\n':
15     case '\r':
16     case ' ':  return true;
17     default:   return false;
18     }
19 }
20 
hex(uint32_t c)21 static inline char hex(uint32_t c)
22 {
23     static const char * sHex = "0123456789ABCDEF";
24     return sHex[c & 0x0F];
25 }
26 
prtCh(std::ostream & o,uint32_t c,bool dot)27 static void prtCh(std::ostream& o, uint32_t c, bool dot)
28 {
29     switch (c) {
30     case '\'': o << (dot ? "'"     : "\\'"); break;
31     case '"':  o << (dot ? "\\\""  : "\"");  break;
32     case '\n': o << (dot ? "\\\\n" : "\\n"); break;
33     case '\t': o << (dot ? "\\\\t" : "\\t"); break;
34     case '\v': o << (dot ? "\\\\v" : "\\v"); break;
35     case '\b': o << (dot ? "\\\\b" : "\\b"); break;
36     case '\r': o << (dot ? "\\\\r" : "\\r"); break;
37     case '\f': o << (dot ? "\\\\f" : "\\f"); break;
38     case '\a': o << (dot ? "\\\\a" : "\\a"); break;
39     case '\\': o << "\\\\";                  break; // both .dot and C/C++ code expect "\\"
40     default:   o << static_cast<char> (c);   break;
41     }
42 }
43 
is_print(uint32_t c)44 bool is_print(uint32_t c)
45 {
46     return c >= 0x20 && c < 0x7F;
47 }
48 
prtHex(std::ostream & o,uint32_t c,uint32_t szcunit)49 void prtHex(std::ostream& o, uint32_t c, uint32_t szcunit)
50 {
51     o << "0x";
52 
53     if (szcunit >= 4) {
54         o << hex(c >> 28u) << hex(c >> 24u) << hex(c >> 20u) << hex(c >> 16u);
55     }
56 
57     if (szcunit >= 2) {
58         o << hex(c >> 12u) << hex(c >> 8u);
59     }
60 
61     o << hex(c >> 4u) << hex(c);
62 }
63 
prtChOrHex(std::ostream & o,uint32_t c,uint32_t szcunit,bool ebcdic,bool dot)64 void prtChOrHex(std::ostream& o, uint32_t c, uint32_t szcunit, bool ebcdic, bool dot)
65 {
66     if (!ebcdic && (is_print(c) || is_space(c))) {
67         o << '\'';
68         prtCh(o, c, dot);
69         o << '\'';
70     } else {
71         prtHex(o, c, szcunit);
72     }
73 }
74 
prtChOrHexForSpan(std::ostream & o,uint32_t c,uint32_t szcunit,bool ebcdic,bool dot)75 static void prtChOrHexForSpan(std::ostream& o, uint32_t c, uint32_t szcunit, bool ebcdic, bool dot)
76 {
77     if (!ebcdic && c != ']' && is_print(c)) {
78         prtCh(o, c, dot);
79     } else {
80         prtHex(o, c, szcunit);
81     }
82 }
83 
printSpan(std::ostream & o,uint32_t l,uint32_t u,uint32_t szcunit,bool ebcdic,bool dot)84 void printSpan(std::ostream& o, uint32_t l, uint32_t u, uint32_t szcunit, bool ebcdic, bool dot)
85 {
86     o << "[";
87     prtChOrHexForSpan(o, l, szcunit, ebcdic, dot);
88     if (u - l > 1) {
89         o << "-";
90         prtChOrHexForSpan(o, u - 1, szcunit, ebcdic, dot);
91     }
92     o << "]";
93 }
94 
95 } // namespace re2c
96