3 #include "c4/yml/detail/parser_dbg.hpp"
11 if((tag.len > 2) && (tag.str[0] ==
'!'))
13 size_t pos = tag.find(
'!', 1);
14 return pos !=
npos && pos > 1 && tag.str[1] !=
'<';
24 if(tag.begins_with(
"!<"))
26 if(tag.begins_with(
"<!"))
36 if(tag.begins_with(
"!<"))
38 if(tag.begins_with(
"<!"))
46 if(result.begins_with(
"!!"))
49 const csubstr pfx =
"<tag:yaml.org,2002:";
50 const size_t len = pfx.len + tag.len + 1;
53 memcpy(output.str , pfx.str, pfx.len);
54 memcpy(output.str + pfx.len, tag.str, tag.len);
55 output[pfx.len + tag.len] =
'>';
56 result = output.first(len);
69 if(tag.begins_with(
"!<"))
71 if(tag.begins_with(
"!!"))
73 else if(tag.begins_with(
'!'))
75 else if(tag.begins_with(
"tag:yaml.org,2002:"))
77 RYML_ASSERT(csubstr(
"tag:yaml.org,2002:").len == 18);
80 else if(tag.begins_with(
"<tag:yaml.org,2002:"))
82 RYML_ASSERT(csubstr(
"<tag:yaml.org,2002:").len == 19);
91 else if(tag ==
"omap")
93 else if(tag ==
"pairs")
99 else if(tag ==
"binary")
101 else if(tag ==
"bool")
103 else if(tag ==
"float")
105 else if(tag ==
"int")
107 else if(tag ==
"merge")
109 else if(tag ==
"null")
111 else if(tag ==
"str")
113 else if(tag ==
"timestamp")
115 else if(tag ==
"value")
117 else if(tag ==
"yaml")
128 return {
"<tag:yaml.org,2002:map>"};
130 return {
"<tag:yaml.org,2002:omap>"};
132 return {
"<tag:yaml.org,2002:pairs>"};
134 return {
"<tag:yaml.org,2002:set>"};
136 return {
"<tag:yaml.org,2002:seq>"};
138 return {
"<tag:yaml.org,2002:binary>"};
140 return {
"<tag:yaml.org,2002:bool>"};
142 return {
"<tag:yaml.org,2002:float>"};
144 return {
"<tag:yaml.org,2002:int>"};
146 return {
"<tag:yaml.org,2002:merge>"};
148 return {
"<tag:yaml.org,2002:null>"};
150 return {
"<tag:yaml.org,2002:str>"};
152 return {
"<tag:yaml.org,2002:timestamp>"};
154 return {
"<tag:yaml.org,2002:value>"};
156 return {
"<tag:yaml.org,2002:yaml>"};
192 return {
"!!timestamp"};
206 csubstr directive = directive_;
207 directive = directive.sub(4);
208 if(!directive.begins_with(
' '))
210 directive = directive.triml(
' ');
211 size_t pos = directive.find(
' ');
214 handle = directive.first(pos);
215 directive = directive.sub(
handle.len).triml(
' ');
216 pos = directive.find(
' ');
218 directive = directive.first(pos);
227 _RYML_CB_CHECK(tree->
callbacks(), directive_.begins_with(
"%TAG "));
230 _RYML_CB_ERR(tree->
callbacks(),
"invalid tag directive");
246 _RYML_CB_ASSERT(callbacks, tag.len >=
handle.len);
247 csubstr rest = tag.sub(
handle.len);
248 _c4dbgpf(
"%TAG: rest={}", rest);
249 if(rest.begins_with(
'<'))
251 _c4dbgpf(
"%TAG: begins with <. rest={}", rest);
252 if(C4_UNLIKELY(!rest.ends_with(
'>')))
253 _RYML_CB_ERR(callbacks,
"malformed tag");
254 rest = rest.offs(1, 1);
255 if(rest.begins_with(
prefix))
257 _c4dbgpf(
"%TAG: already transformed! actual={}", rest.sub(
prefix.len));
261 size_t len = 1u +
prefix.len + rest.len + 1u;
262 size_t numpc = rest.count(
'%');
265 if(len <= output.len)
269 memcpy(1u + output.str +
prefix.len, rest.str, rest.len);
270 output.str[1u +
prefix.len + rest.len] =
'>';
276 size_t pos = rest.find(
'%');
277 _RYML_CB_ASSERT(callbacks, pos !=
npos);
279 size_t next = rest.first_not_of(
"0123456789abcdefABCDEF", pos+1);
282 _RYML_CB_CHECK(callbacks, pos+1 < next);
283 _RYML_CB_CHECK(callbacks, pos+1 + 2 <= next);
284 size_t delta = next - (pos+1);
286 pos = rest.find(
'%', pos+1);
287 }
while(pos !=
npos);
288 if(len <= output.len)
290 size_t prev = 0, wpos = 0;
291 auto appendstr = [&](csubstr s) { memcpy(output.str + wpos, s.str, s.len); wpos += s.len; };
292 auto appendchar = [&](
char c) { output.str[wpos++] = c; };
295 pos = rest.find(
'%');
296 _RYML_CB_ASSERT(callbacks, pos !=
npos);
298 size_t next = rest.first_not_of(
"0123456789abcdefABCDEF", pos+1);
301 _RYML_CB_CHECK(callbacks, pos+1 < next);
302 _RYML_CB_CHECK(callbacks, pos+1 + 2 <= next);
304 if(C4_UNLIKELY(!
read_hex(rest.range(pos+1, next), &val) || val > 127))
305 _RYML_CB_ERR(callbacks,
"invalid URI character");
306 appendstr(rest.range(prev, pos));
307 appendchar(
static_cast<char>(val));
309 pos = rest.find(
'%', pos+1);
310 }
while(pos !=
npos);
311 _RYML_CB_ASSERT(callbacks, pos ==
npos);
312 _RYML_CB_ASSERT(callbacks, prev > 0);
313 _RYML_CB_ASSERT(callbacks, rest.len >= prev);
314 appendstr(rest.sub(prev));
316 _RYML_CB_ASSERT(callbacks, wpos == len);
bool is_stream(id_type node) const
NodeType type(id_type node) const
bool is_root(id_type node) const
Callbacks const & callbacks() const
@ NOTYPE
no node type or style is set
bool read_hex(csubstr s, I *v) noexcept
read an hexadecimal integer from a string.
csubstr from_tag_long(YamlTag_e tag)
bool is_custom_tag(csubstr tag)
csubstr normalize_tag_long(csubstr tag)
YamlTag_e
a bit mask for marking tags for types
csubstr normalize_tag(csubstr tag)
csubstr from_tag(YamlTag_e tag)
YamlTag_e to_tag(csubstr tag)
@ TAG_SET
!!set Unordered set of non-equal values.
@ TAG_MERGE
!!merge Specify one or more mapping to be merged with the current one.
@ TAG_INT
!!float Mathematical integers.
@ TAG_SEQ
!!seq Sequence of arbitrary values.
@ TAG_NULL
!!null Devoid of value.
@ TAG_YAML
!!yaml Specify the default value of a mapping https://yaml.org/type/yaml.html
@ TAG_TIMESTAMP
!!timestamp A point in time https://yaml.org/type/timestamp.html
@ TAG_STR
!!str A sequence of zero or more Unicode characters.
@ TAG_BOOL
!!bool Mathematical Booleans.
@ TAG_MAP
!!map Unordered set of key: value pairs without duplicates.
@ TAG_BINARY
!!binary A sequence of zero or more octets (8 bit values).
@ TAG_PAIRS
!!pairs Ordered sequence of key: value pairs allowing duplicates.
@ TAG_VALUE
!!value Specify the default value of a mapping https://yaml.org/type/value.html
@ TAG_OMAP
!!omap Ordered sequence of key: value pairs without duplicates.
@ TAG_FLOAT
!!float Floating-point approximation to real numbers.
RYML_ID_TYPE id_type
The type of a node id in the YAML tree; to override the default type, define the macro RYML_ID_TYPE t...
@ npos
a null string position
a c-style callbacks class.
bool create_from_str(csubstr directive_)
leaves next_node_id unfilled
id_type next_node_id
The next node to which this tag directive applies.
size_t transform(csubstr tag, substr output, Callbacks const &callbacks) const