dep: Add rapidyaml
This commit is contained in:
112
dep/rapidyaml/src/c4/yml/preprocess.cpp
Normal file
112
dep/rapidyaml/src/c4/yml/preprocess.cpp
Normal file
@ -0,0 +1,112 @@
|
||||
#include "c4/yml/preprocess.hpp"
|
||||
#include "c4/yml/detail/parser_dbg.hpp"
|
||||
|
||||
/** @file preprocess.hpp Functions for preprocessing YAML prior to parsing. */
|
||||
|
||||
namespace c4 {
|
||||
namespace yml {
|
||||
|
||||
C4_SUPPRESS_WARNING_GCC_CLANG_WITH_PUSH("-Wold-style-cast")
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
namespace {
|
||||
C4_ALWAYS_INLINE bool _is_idchar(char c)
|
||||
{
|
||||
return (c >= 'a' && c <= 'z')
|
||||
|| (c >= 'A' && c <= 'Z')
|
||||
|| (c >= '0' && c <= '9')
|
||||
|| (c == '_' || c == '-' || c == '~' || c == '$');
|
||||
}
|
||||
|
||||
typedef enum { kReadPending = 0, kKeyPending = 1, kValPending = 2 } _ppstate;
|
||||
C4_ALWAYS_INLINE _ppstate _next(_ppstate s)
|
||||
{
|
||||
int n = (int)s + 1;
|
||||
return (_ppstate)(n <= (int)kValPending ? n : 0);
|
||||
}
|
||||
} // empty namespace
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
size_t preprocess_rxmap(csubstr s, substr buf)
|
||||
{
|
||||
detail::_SubstrWriter writer(buf);
|
||||
_ppstate state = kReadPending;
|
||||
size_t last = 0;
|
||||
|
||||
if(s.begins_with('{'))
|
||||
{
|
||||
RYML_CHECK(s.ends_with('}'));
|
||||
s = s.offs(1, 1);
|
||||
}
|
||||
|
||||
writer.append('{');
|
||||
|
||||
for(size_t i = 0; i < s.len; ++i)
|
||||
{
|
||||
const char curr = s[i];
|
||||
const char next = i+1 < s.len ? s[i+1] : '\0';
|
||||
|
||||
if(curr == '\'' || curr == '"')
|
||||
{
|
||||
csubstr ss = s.sub(i).pair_range_esc(curr, '\\');
|
||||
i += static_cast<size_t>(ss.end() - (s.str + i));
|
||||
state = _next(state);
|
||||
}
|
||||
else if(state == kReadPending && _is_idchar(curr))
|
||||
{
|
||||
state = _next(state);
|
||||
}
|
||||
|
||||
switch(state)
|
||||
{
|
||||
case kKeyPending:
|
||||
{
|
||||
if(curr == ':' && next == ' ')
|
||||
{
|
||||
state = _next(state);
|
||||
}
|
||||
else if(curr == ',' && next == ' ')
|
||||
{
|
||||
writer.append(s.range(last, i));
|
||||
writer.append(": 1, ");
|
||||
last = i + 2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case kValPending:
|
||||
{
|
||||
if(curr == '[' || curr == '{' || curr == '(')
|
||||
{
|
||||
csubstr ss = s.sub(i).pair_range_nested(curr, '\\');
|
||||
i += static_cast<size_t>(ss.end() - (s.str + i));
|
||||
state = _next(state);
|
||||
}
|
||||
else if(curr == ',' && next == ' ')
|
||||
{
|
||||
state = _next(state);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
// nothing to do
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
writer.append(s.sub(last));
|
||||
if(state == kKeyPending)
|
||||
writer.append(": 1");
|
||||
writer.append('}');
|
||||
|
||||
return writer.pos;
|
||||
}
|
||||
|
||||
C4_SUPPRESS_WARNING_GCC_CLANG_POP
|
||||
|
||||
} // namespace yml
|
||||
} // namespace c4
|
||||
Reference in New Issue
Block a user