1 #ifndef _RE2C_CODEGEN_HELPERS_
2 #define _RE2C_CODEGEN_HELPERS_
3
4 #include <assert.h>
5 #include <stdint.h>
6 #include <string.h>
7 #include <sstream>
8
9 #include "src/debug/debug.h"
10
11
12 namespace re2c {
13
14 bool is_print(uint32_t c);
15 void prtHex(std::ostream &o, uint32_t c, uint32_t szcunit);
16 void prtChOrHex(std::ostream &o, uint32_t c, uint32_t szcunit, bool ebcdic, bool dot);
17 void printSpan(std::ostream &o, uint32_t l, uint32_t u, uint32_t szcunit, bool ebcdic,
18 bool dot);
19
20 template<typename T>
argsubst(std::ostringstream & os,const std::string & stub,const char * arg,bool allow_unnamed,T val)21 void argsubst(std::ostringstream &os, const std::string &stub, const char *arg,
22 bool allow_unnamed, T val)
23 {
24 assert(!stub.empty());
25 DASSERT(arg != NULL);
26
27 const std::string str = os.str();
28 os.str("");
29
30 const char *s = str.c_str(), *e = s + str.length(), *p, *q;
31 const size_t l = strlen(arg);
32
33 while ((p = strstr(s, stub.c_str()))) {
34 os.write(s, p - s);
35 s = p;
36 p += stub.length();
37 q = *p == '{' ? strchr(p + 1, '}') : NULL;
38
39 if (q && l == (size_t)(q - p - 1) && memcmp(p + 1, arg, l) == 0) {
40 // named substitution of the form @@{arg}
41 os << val;
42 s = q + 1;
43 } else if (allow_unnamed) {
44 // unnamed substitution of the form @@
45 os << val;
46 s = p;
47 } else {
48 // none of the above, skip one character (and not the whole
49 // placeholder) to allow cases like @@@{arg} to find @@{arg}
50 os.write(s, 1);
51 ++s;
52 }
53 }
54 os.write(s, e - s);
55 }
56
indent(uint32_t n,const std::string & s)57 inline std::string indent(uint32_t n, const std::string &s)
58 {
59 std::string ind;
60 for (; n --> 0; ind += s);
61 return ind;
62 }
63
64 } // namespace re2c
65
66 #endif // _RE2C_CODEGEN_HELPERS_
67