Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
stenzek
GitHub Repository: stenzek/duckstation
Path: blob/master/dep/rapidyaml/src/c4/yml/preprocess.cpp
4262 views
1
#include "c4/yml/preprocess.hpp"
2
#include "c4/yml/detail/parser_dbg.hpp"
3
4
/** @file preprocess.hpp Functions for preprocessing YAML prior to parsing. */
5
6
namespace c4 {
7
namespace yml {
8
9
C4_SUPPRESS_WARNING_GCC_CLANG_WITH_PUSH("-Wold-style-cast")
10
11
//-----------------------------------------------------------------------------
12
//-----------------------------------------------------------------------------
13
//-----------------------------------------------------------------------------
14
15
namespace {
16
C4_ALWAYS_INLINE bool _is_idchar(char c)
17
{
18
return (c >= 'a' && c <= 'z')
19
|| (c >= 'A' && c <= 'Z')
20
|| (c >= '0' && c <= '9')
21
|| (c == '_' || c == '-' || c == '~' || c == '$');
22
}
23
24
typedef enum { kReadPending = 0, kKeyPending = 1, kValPending = 2 } _ppstate;
25
C4_ALWAYS_INLINE _ppstate _next(_ppstate s)
26
{
27
int n = (int)s + 1;
28
return (_ppstate)(n <= (int)kValPending ? n : 0);
29
}
30
} // empty namespace
31
32
33
//-----------------------------------------------------------------------------
34
35
size_t preprocess_rxmap(csubstr s, substr buf)
36
{
37
detail::_SubstrWriter writer(buf);
38
_ppstate state = kReadPending;
39
size_t last = 0;
40
41
if(s.begins_with('{'))
42
{
43
RYML_CHECK(s.ends_with('}'));
44
s = s.offs(1, 1);
45
}
46
47
writer.append('{');
48
49
for(size_t i = 0; i < s.len; ++i)
50
{
51
const char curr = s[i];
52
const char next = i+1 < s.len ? s[i+1] : '\0';
53
54
if(curr == '\'' || curr == '"')
55
{
56
csubstr ss = s.sub(i).pair_range_esc(curr, '\\');
57
i += static_cast<size_t>(ss.end() - (s.str + i));
58
state = _next(state);
59
}
60
else if(state == kReadPending && _is_idchar(curr))
61
{
62
state = _next(state);
63
}
64
65
switch(state)
66
{
67
case kKeyPending:
68
{
69
if(curr == ':' && next == ' ')
70
{
71
state = _next(state);
72
}
73
else if(curr == ',' && next == ' ')
74
{
75
writer.append(s.range(last, i));
76
writer.append(": 1, ");
77
last = i + 2;
78
}
79
break;
80
}
81
case kValPending:
82
{
83
if(curr == '[' || curr == '{' || curr == '(')
84
{
85
csubstr ss = s.sub(i).pair_range_nested(curr, '\\');
86
i += static_cast<size_t>(ss.end() - (s.str + i));
87
state = _next(state);
88
}
89
else if(curr == ',' && next == ' ')
90
{
91
state = _next(state);
92
}
93
break;
94
}
95
default:
96
// nothing to do
97
break;
98
}
99
}
100
101
writer.append(s.sub(last));
102
if(state == kKeyPending)
103
writer.append(": 1");
104
writer.append('}');
105
106
return writer.pos;
107
}
108
109
C4_SUPPRESS_WARNING_GCC_CLANG_POP
110
111
} // namespace yml
112
} // namespace c4
113
114