1 #ifndef _C4_YML_PARSE_ENGINE_DEF_HPP_
2 #define _C4_YML_PARSE_ENGINE_DEF_HPP_
5 #include "c4/error.hpp"
12 #include "c4/yml/detail/parser_dbg.hpp"
15 #include "c4/yml/detail/print.hpp"
19 #if defined(RYML_WITH_TAB_TOKENS)
20 #define _RYML_WITH_TAB_TOKENS(...) __VA_ARGS__
21 #define _RYML_WITHOUT_TAB_TOKENS(...)
22 #define _RYML_WITH_OR_WITHOUT_TAB_TOKENS(with, without) with
24 #define _RYML_WITH_TAB_TOKENS(...)
25 #define _RYML_WITHOUT_TAB_TOKENS(...) __VA_ARGS__
26 #define _RYML_WITH_OR_WITHOUT_TAB_TOKENS(with, without) without
31 #define _set_flags2(f) this->set_flags2(f)()
32 #define _add_flags2(f) this->add_flags2(f)()
33 #define _addrem_flags2(on, off) this->addrem_flags(on, off)
34 #define _rem_flags2(off) this->rem_flags2(off)
35 #define m_state (m_evt_handler->m_curr)
36 #define _c4dbgnextline() \
38 _c4dbgq("\n-----------"); \
39 _c4dbgt("handling line={}, offset={}B", \
41 m_state->pos.offset); \
46 # pragma warning(push)
47 # pragma warning(disable: 4296)
48 # pragma warning(disable: 4702)
49 #elif defined(__clang__)
50 # pragma clang diagnostic push
51 # pragma clang diagnostic ignored "-Wtype-limits"
52 # pragma clang diagnostic ignored "-Wformat-nonliteral"
53 # pragma clang diagnostic ignored "-Wold-style-cast"
54 #elif defined(__GNUC__)
55 # pragma GCC diagnostic push
56 # pragma GCC diagnostic ignored "-Wtype-limits"
57 # pragma GCC diagnostic ignored "-Wformat-nonliteral"
58 # pragma GCC diagnostic ignored "-Wold-style-cast"
60 # pragma GCC diagnostic ignored "-Wduplicated-branches"
69 C4_HOT C4_ALWAYS_INLINE
bool _is_blck_token(csubstr s) noexcept
71 RYML_ASSERT(s.len > 0);
72 RYML_ASSERT(s.str[0] ==
'-' || s.str[0] ==
':' || s.str[0] ==
'?');
76 inline bool _is_doc_begin_token(csubstr s)
78 RYML_ASSERT(s.begins_with(
'-'));
79 RYML_ASSERT(!s.ends_with(
"\n"));
80 RYML_ASSERT(!s.ends_with(
"\r"));
81 return (s.len >= 3 && s.str[1] ==
'-' && s.str[2] ==
'-')
85 inline bool _is_doc_end_token(csubstr s)
87 RYML_ASSERT(s.begins_with(
'.'));
88 RYML_ASSERT(!s.ends_with(
"\n"));
89 RYML_ASSERT(!s.ends_with(
"\r"));
90 return (s.len >= 3 && s.str[1] ==
'.' && s.str[2] ==
'.')
94 inline bool _is_doc_token(csubstr s)
99 return _is_doc_begin_token(s);
100 else if(s.str[0] ==
'.')
101 return _is_doc_end_token(s);
106 inline size_t _is_special_json_scalar(csubstr s)
112 if(s.len >= 5 && s.begins_with(
"false"))
116 if(s.len >= 4 && s.begins_with(
"true"))
120 if(s.len >= 4 && s.begins_with(
"null"))
130 C4_ALWAYS_INLINE
size_t _extend_from_combined_newline(
char nl,
char following)
132 return (nl ==
'\n' && following ==
'\r') || (nl ==
'\r' && following ==
'\n');
136 inline substr from_next_line(substr rem)
138 size_t nlpos = rem.first_of(
"\r\n");
141 const char nl = rem[nlpos];
142 rem = rem.right_of(nlpos);
145 if(_extend_from_combined_newline(nl, rem.front()))
153 inline size_t _count_following_newlines(csubstr r,
size_t *C4_RESTRICT i)
155 RYML_ASSERT(r[*i] ==
'\n');
156 size_t numnl_following = 0;
158 for( ; *i < r.len; ++(*i))
160 if(r.str[*i] ==
'\n')
163 else if(r.str[*i] ==
' ' || r.str[*i] ==
'\t' || r.str[*i] ==
'\r')
168 return numnl_following;
173 inline size_t _count_following_newlines(csubstr r,
size_t *C4_RESTRICT i,
size_t indentation)
175 RYML_ASSERT(r[*i] ==
'\n');
176 size_t numnl_following = 0;
180 for( ; *i < r.len; ++(*i))
182 if(r.str[*i] ==
'\n')
185 else if(r.str[*i] ==
' ' || r.str[*i] ==
'\t' || r.str[*i] ==
'\r')
193 for( ; *i < r.len; ++(*i))
195 if(r.str[*i] ==
'\n')
199 size_t stop = *i + indentation;
200 for( ; *i < r.len; ++(*i))
202 if(r.str[*i] !=
' ' && r.str[*i] !=
'\r')
204 RYML_ASSERT(*i < stop);
209 else if(r.str[*i] ==
' ' || r.str[*i] ==
'\t' || r.str[*i] ==
'\r')
215 return numnl_following;
225 template<
class EventHandler>
232 template<
class EventHandler>
237 , m_evt_handler(evt_handler)
238 , m_pending_anchors()
240 , m_newline_offsets()
241 , m_newline_offsets_size(0)
242 , m_newline_offsets_capacity(0)
243 , m_newline_offsets_buf()
245 RYML_CHECK(evt_handler);
248 template<
class EventHandler>
250 : m_options(that.m_options)
251 , m_file(that.m_file)
253 , m_evt_handler(that.m_evt_handler)
254 , m_pending_anchors(that.m_pending_anchors)
255 , m_pending_tags(that.m_pending_tags)
256 , m_newline_offsets(that.m_newline_offsets)
257 , m_newline_offsets_size(that.m_newline_offsets_size)
258 , m_newline_offsets_capacity(that.m_newline_offsets_capacity)
259 , m_newline_offsets_buf(that.m_newline_offsets_buf)
264 template<
class EventHandler>
266 : m_options(that.m_options)
267 , m_file(that.m_file)
269 , m_evt_handler(that.m_evt_handler)
270 , m_pending_anchors(that.m_pending_anchors)
271 , m_pending_tags(that.m_pending_tags)
272 , m_newline_offsets()
273 , m_newline_offsets_size()
274 , m_newline_offsets_capacity()
275 , m_newline_offsets_buf()
277 if(that.m_newline_offsets_capacity)
279 _resize_locations(that.m_newline_offsets_capacity);
280 _RYML_CB_CHECK(m_evt_handler->m_stack.m_callbacks, m_newline_offsets_capacity == that.m_newline_offsets_capacity);
281 memcpy(m_newline_offsets, that.m_newline_offsets, that.m_newline_offsets_size *
sizeof(
size_t));
282 m_newline_offsets_size = that.m_newline_offsets_size;
286 template<
class EventHandler>
290 m_options = (that.m_options);
291 m_file = (that.m_file);
292 m_buf = (that.m_buf);
293 m_evt_handler = that.m_evt_handler;
294 m_pending_anchors = that.m_pending_anchors;
295 m_pending_tags = that.m_pending_tags;
296 m_newline_offsets = (that.m_newline_offsets);
297 m_newline_offsets_size = (that.m_newline_offsets_size);
298 m_newline_offsets_capacity = (that.m_newline_offsets_capacity);
299 m_newline_offsets_buf = (that.m_newline_offsets_buf);
304 template<
class EventHandler>
308 m_options = (that.m_options);
309 m_file = (that.m_file);
310 m_buf = (that.m_buf);
311 m_evt_handler = that.m_evt_handler;
312 m_pending_anchors = that.m_pending_anchors;
313 m_pending_tags = that.m_pending_tags;
314 if(that.m_newline_offsets_capacity > m_newline_offsets_capacity)
315 _resize_locations(that.m_newline_offsets_capacity);
316 _RYML_CB_CHECK(m_evt_handler->m_stack.m_callbacks, m_newline_offsets_capacity >= that.m_newline_offsets_capacity);
317 _RYML_CB_CHECK(m_evt_handler->m_stack.m_callbacks, m_newline_offsets_capacity >= that.m_newline_offsets_size);
318 memcpy(m_newline_offsets, that.m_newline_offsets, that.m_newline_offsets_size *
sizeof(
size_t));
319 m_newline_offsets_size = that.m_newline_offsets_size;
320 m_newline_offsets_buf = that.m_newline_offsets_buf;
324 template<
class EventHandler>
331 m_pending_anchors = {};
333 m_newline_offsets = {};
334 m_newline_offsets_size = {};
335 m_newline_offsets_capacity = {};
336 m_newline_offsets_buf = {};
339 template<
class EventHandler>
340 void ParseEngine<EventHandler>::_free()
342 if(m_newline_offsets)
344 _RYML_CB_FREE(m_evt_handler->m_stack.m_callbacks, m_newline_offsets,
size_t, m_newline_offsets_capacity);
345 m_newline_offsets =
nullptr;
346 m_newline_offsets_size = 0u;
347 m_newline_offsets_capacity = 0u;
348 m_newline_offsets_buf = 0u;
355 template<
class EventHandler>
356 void ParseEngine<EventHandler>::_reset()
358 m_pending_anchors = {};
360 if(m_options.locations())
362 _prepare_locations();
364 m_was_inside_qmrk =
false;
370 template<
class EventHandler>
371 void ParseEngine<EventHandler>::_relocate_arena(csubstr prev_arena, substr next_arena)
373 #define _ryml_relocate(s) \
374 if(s.is_sub(prev_arena)) \
376 s.str = next_arena.str + (s.str - prev_arena.str); \
380 for(
size_t i = 0; i < m_pending_tags.num_entries; ++i)
382 for(
size_t i = 0; i < m_pending_anchors.num_entries; ++i)
384 #undef _ryml_relocate
387 template<
class EventHandler>
388 void ParseEngine<EventHandler>::_s_relocate_arena(
void* data, csubstr prev_arena, substr next_arena)
390 ((ParseEngine*)data)->_relocate_arena(prev_arena, next_arena);
396 template<
class EventHandler>
397 template<
class DumpFn>
398 void ParseEngine<EventHandler>::_fmt_msg(DumpFn &&dumpfn)
const
400 auto const *
const C4_RESTRICT st = m_evt_handler->m_curr;
401 auto const& lc = st->line_contents;
402 csubstr contents = lc.stripped;
406 size_t offs = 3u +
to_chars(substr{}, st->pos.line) +
to_chars(substr{}, st->pos.col);
409 detail::_dump(dumpfn,
"{}:", m_file);
410 offs += m_file.len + 1;
412 detail::_dump(dumpfn,
"{}:{}: ", st->pos.line, st->pos.col);
413 csubstr maybe_full_content = (contents.len < 80u ? contents : contents.first(80u));
414 csubstr maybe_ellipsis = (contents.len < 80u ? csubstr{} : csubstr(
"..."));
415 detail::_dump(dumpfn,
"{}{} (size={})\n", maybe_full_content, maybe_ellipsis, contents.len);
417 size_t firstcol = (size_t)(lc.rem.begin() - lc.full.begin());
418 size_t lastcol = firstcol + lc.rem.len;
419 for(
size_t i = 0; i < offs + firstcol; ++i)
422 for(
size_t i = 1, e = (lc.rem.len < 80u ? lc.rem.len : 80u); i < e; ++i)
424 detail::_dump(dumpfn,
"{} (cols {}-{})\n", maybe_ellipsis, firstcol+1, lastcol+1);
435 detail::_dump(dumpfn,
"top state: {}\n", detail::_parser_flags_to_str(flagbuf_,
m_state->flags));
443 template<
class EventHandler>
444 template<
class ...Args>
445 void ParseEngine<EventHandler>::_err(csubstr fmt, Args
const& C4_RESTRICT ...args)
const
448 detail::_SubstrWriter writer(errmsg);
449 auto dumpfn = [&writer](csubstr s){ writer.append(s); };
450 detail::_dump(dumpfn, fmt, args...);
454 m_evt_handler->cancel_parse();
455 m_evt_handler->m_stack.m_callbacks.m_error(errmsg, len,
m_state->pos, m_evt_handler->m_stack.m_callbacks.m_user_data);
461 template<
class EventHandler>
462 template<
class ...Args>
463 void ParseEngine<EventHandler>::_dbg(csubstr fmt, Args
const& C4_RESTRICT ...args)
const
467 auto dumpfn = [](csubstr s){
if(s.str) fwrite(s.str, 1, s.len, stdout); };
468 detail::_dump(dumpfn, fmt, args...);
477 template<
class EventHandler>
478 bool ParseEngine<EventHandler>::_finished_file()
const
480 bool ret =
m_state->pos.offset >= m_buf.len;
483 _c4dbgp(
"finished file!!!");
488 template<
class EventHandler>
489 C4_HOT C4_ALWAYS_INLINE
bool ParseEngine<EventHandler>::_finished_line()
const
491 return m_state->line_contents.rem.empty();
497 template<
class EventHandler>
498 void ParseEngine<EventHandler>::_maybe_skip_whitespace_tokens()
500 csubstr rem =
m_state->line_contents.rem;
506 _c4dbgpf(
"skip {} whitespace characters", pos);
507 _line_progressed(pos);
511 template<
class EventHandler>
512 void ParseEngine<EventHandler>::_maybe_skipchars(
char c)
514 csubstr rem =
m_state->line_contents.rem;
515 if(rem.len && rem.str[0] == c)
517 size_t pos = rem.first_not_of(c);
520 _c4dbgpf(
"skip {}x'{}'", pos, c);
521 _line_progressed(pos);
525 #ifdef RYML_NO_COVERAGE__TO_BE_DELETED
526 template<
class EventHandler>
527 void ParseEngine<EventHandler>::_maybe_skipchars_up_to(
char c,
size_t max_to_skip)
529 csubstr rem =
m_state->line_contents.rem;
530 if(rem.len && rem.str[0] == c)
532 size_t pos = rem.first_not_of(c);
535 if(pos > max_to_skip)
537 _c4dbgpf(
"skip {}x'{}'", pos, c);
538 _line_progressed(pos);
543 template<
class EventHandler>
545 void ParseEngine<EventHandler>::_skipchars(
const char (&chars)[N])
547 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks,
m_state->line_contents.rem.begins_with_any(chars));
548 size_t pos =
m_state->line_contents.rem.first_not_of(chars);
550 pos =
m_state->line_contents.rem.len;
551 _c4dbgpf(
"skip {} characters", pos);
552 _line_progressed(pos);
555 template<
class EventHandler>
556 void ParseEngine<EventHandler>::_skip_comment()
558 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks,
m_state->line_contents.rem.begins_with(
'#'));
559 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks,
m_state->line_contents.rem.is_sub(
m_state->line_contents.full));
560 csubstr rem =
m_state->line_contents.rem;
561 csubstr full =
m_state->line_contents.full;
563 if(!full.begins_with(
'#'))
565 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, rem.str > full.str);
566 const char c = full[(size_t)(rem.str - full.str - 1)];
567 if(C4_UNLIKELY(c !=
' ' && c !=
'\t'))
568 _RYML_CB_ERR(m_evt_handler->m_stack.m_callbacks,
"comment not preceded by whitespace");
572 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, rem.str == full.str);
574 _c4dbgpf(
"comment was '{}'", rem);
575 _line_progressed(rem.len);
578 template<
class EventHandler>
579 void ParseEngine<EventHandler>::_maybe_skip_comment()
581 csubstr s =
m_state->line_contents.rem.triml(
' ');
582 if(s.begins_with(
'#'))
584 _line_progressed((
size_t)(s.str -
m_state->line_contents.rem.str));
589 template<
class EventHandler>
590 bool ParseEngine<EventHandler>::_maybe_scan_following_colon() noexcept
592 if(
m_state->line_contents.rem.len)
594 if(
m_state->line_contents.rem.str[0] ==
' ' ||
m_state->line_contents.rem.str[0] ==
'\t')
596 size_t pos =
m_state->line_contents.rem.first_not_of(
" \t");
598 pos =
m_state->line_contents.rem.len;
599 _c4dbgpf(
"skip {}x'{}'", pos,
' ');
600 _line_progressed(pos);
602 if(
m_state->line_contents.rem.len && (
m_state->line_contents.rem.str[0] ==
':'))
604 _c4dbgp(
"found ':' colon next");
612 template<
class EventHandler>
613 bool ParseEngine<EventHandler>::_maybe_scan_following_comma() noexcept
615 if(
m_state->line_contents.rem.len)
617 if(
m_state->line_contents.rem.str[0] ==
' ' ||
m_state->line_contents.rem.str[0] ==
'\t')
619 size_t pos =
m_state->line_contents.rem.first_not_of(
" \t");
621 pos =
m_state->line_contents.rem.len;
622 _c4dbgpf(
"skip {}x'{}'", pos,
' ');
623 _line_progressed(pos);
625 if(
m_state->line_contents.rem.len && (
m_state->line_contents.rem.str[0] ==
','))
627 _c4dbgp(
"found ',' comma next");
638 template<
class EventHandler>
639 csubstr ParseEngine<EventHandler>::_scan_anchor()
641 csubstr s = m_evt_handler->m_curr->line_contents.rem;
642 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, s.begins_with(
'&'));
643 csubstr anchor = s.range(1, s.first_of(
' '));
644 _line_progressed(1u + anchor.len);
645 _maybe_skipchars(
' ');
649 template<
class EventHandler>
650 csubstr ParseEngine<EventHandler>::_scan_ref_seq()
652 csubstr s = m_evt_handler->m_curr->line_contents.rem;
653 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, s.begins_with(
'*'));
654 csubstr ref = s.first(s.first_of(
",] :"));
655 _line_progressed(ref.len);
659 template<
class EventHandler>
660 csubstr ParseEngine<EventHandler>::_scan_ref_map()
662 csubstr s = m_evt_handler->m_curr->line_contents.rem;
663 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, s.begins_with(
'*'));
664 csubstr ref = s.first(s.first_of(
",} "));
665 _line_progressed(ref.len);
669 template<
class EventHandler>
670 csubstr ParseEngine<EventHandler>::_scan_tag()
672 csubstr rem =
m_state->line_contents.rem.triml(
' ');
673 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, rem.begins_with(
'!'));
675 if(rem.begins_with(
"!!"))
677 _c4dbgp(
"begins with '!!'");
679 t = rem.left_of(rem.first_of(
" ,"));
681 t = rem.left_of(rem.first_of(
' '));
683 else if(rem.begins_with(
"!<"))
685 _c4dbgp(
"begins with '!<'");
686 t = rem.left_of(rem.first_of(
'>'),
true);
688 #ifdef RYML_NO_COVERAGE__TO_BE_DELETED
689 else if(rem.begins_with(
"!h!"))
691 _c4dbgp(
"begins with '!h!'");
692 t = rem.left_of(rem.first_of(
' '));
697 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, rem.begins_with(
'!'));
698 _c4dbgp(
"begins with '!'");
700 t = rem.left_of(rem.first_of(
" ,"));
702 t = rem.left_of(rem.first_of(
' '));
704 _line_progressed(t.len);
705 _maybe_skip_whitespace_tokens();
712 template<
class EventHandler>
713 bool ParseEngine<EventHandler>::_is_valid_start_scalar_plain_flow(csubstr s)
715 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, !s.empty());
731 _c4dbgpf(
"not a scalar: found non-scalar token '{}'", _c4prc(s.str[0]));
745 _c4err(
"invalid token \":{}\"", _c4prc(s.str[1]));
752 _c4dbgpf(
"not a scalar: found non-scalar token '{}{}'", s.str[0], s.str[1]);
774 _c4dbgpf(
"not a scalar: found non-scalar token '?{}'", _c4prc(s.str[1]));
780 _c4err(
"invalid token \"?{}\"", _c4prc(s.str[1]));
799 template<
class EventHandler>
800 bool ParseEngine<EventHandler>::_scan_scalar_plain_seq_flow(ScannedScalar *C4_RESTRICT sc)
802 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
RMAP));
803 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
BLCK));
804 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_any(
RSEQ|
RSEQIMAP));
805 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_any(
FLOW));
806 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_any(
RVAL));
808 substr s =
m_state->line_contents.rem;
809 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, !s.begins_with(
' '));
810 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, !s.begins_with(
'\n'));
815 if(!_is_valid_start_scalar_plain_flow(s))
818 _c4dbgp(
"scanning seqflow scalar...");
820 const size_t start_offset =
m_state->pos.offset;
821 bool needs_filter =
false;
824 _c4dbgpf(
"scanning scalar: curr line=[{}]~~~{}~~~", s.len, s);
825 for(
size_t i = 0; i < s.len; ++i)
827 const char c = s.str[i];
831 _c4dbgpf(
"found terminating character at {}: '{}'", i, c);
833 if(
m_state->pos.offset + i > start_offset)
839 _c4dbgp(
"at the beginning. no scalar here.");
844 _c4dbgpf(
"found terminating character at {}: '{}'", i, c);
849 _c4dbgp(
"found suspicious '#'");
852 _c4dbgpf(
"found terminating character at {}: '{}'", i, c);
858 _c4dbgp(
"found suspicious ':'");
861 const char next = s.str[i+1];
862 _c4dbgpf(
"next char is '{}'", _c4prc(next));
865 _c4dbgp(
"map starting!");
866 if(
m_state->pos.offset + i > start_offset)
868 _c4dbgp(
"scalar finished!");
874 _c4dbgp(
"at the beginning. no scalar here.");
880 _c4dbgp(
"it's a scalar indeed.");
884 else if(s.len == i+1)
886 _c4dbgp(
"':' at line end. map starting!");
894 _c4err(
"invalid character: '{}'", c);
899 _line_progressed(s.len);
900 if(!_finished_file())
902 _c4dbgp(
"next line!");
908 _c4dbgp(
"file finished!");
911 s =
m_state->line_contents.rem;
918 sc->needs_filter = needs_filter;
920 _c4prscalar(
"scanned plain scalar", sc->scalar,
true);
925 template<
class EventHandler>
926 bool ParseEngine<EventHandler>::_scan_scalar_plain_map_flow(ScannedScalar *C4_RESTRICT sc)
928 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
RSEQ) || has_any(
RSEQIMAP));
929 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
BLCK));
930 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_any(
RMAP|
RSEQIMAP));
931 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_any(
FLOW));
932 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_any(
RKEY|
RVAL|
QMRK));
934 substr s =
m_state->line_contents.rem;
935 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, !s.begins_with(
' '));
940 if(!_is_valid_start_scalar_plain_flow(s))
943 _c4dbgp(
"scanning scalar...");
945 const size_t start_offset =
m_state->pos.offset;
946 bool needs_filter =
false;
949 for(
size_t i = 0; i < s.len; ++i)
951 const char c = s.str[i];
957 _c4dbgpf(
"found terminating character: '{}'", c);
960 if(s.len == i+1 || s.str[i+1] ==
' ' || s.str[i+1] ==
',' || s.str[i+1] ==
'}' _RYML_WITH_TAB_TOKENS(|| s.str[i+1] ==
'\t'))
963 _c4dbgpf(
"found terminating character: '{}'", c);
970 _c4err(
"invalid character: '{}'", c);
977 _c4err(
"invalid character: '{}'", c);
983 _c4dbgpf(
"found terminating character: '{}'", c);
991 _c4dbgp(
"next line!");
992 _line_progressed(s.len);
993 if(!_finished_file())
995 _c4dbgp(
"next line!");
1001 _c4dbgp(
"file finished!");
1004 s =
m_state->line_contents.rem;
1005 needs_filter =
true;
1011 sc->needs_filter = needs_filter;
1013 _c4dbgpf(
"scalar was [{}]~~~{}~~~", sc->scalar.len, sc->scalar);
1018 template<
class EventHandler>
1019 bool ParseEngine<EventHandler>::_scan_scalar_seq_json(ScannedScalar *C4_RESTRICT sc)
1021 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
RMAP));
1022 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
BLCK));
1023 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_any(
RSEQ));
1024 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_any(
FLOW));
1026 substr s =
m_state->line_contents.rem;
1027 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, !s.begins_with(
' '));
1032 _c4dbgp(
"scanning scalar...");
1039 _c4dbgp(
"not a scalar.");
1044 const size_t len = _is_special_json_scalar(s);
1047 sc->scalar = s.first(len);
1048 sc->needs_filter =
false;
1049 _c4dbgpf(
"special json scalar: '{}'", sc->scalar);
1050 _line_progressed(len);
1057 for( ; i < s.len; ++i)
1059 const char c = s.str[i];
1066 _c4dbgpf(
"found terminating character: '{}'", c);
1069 if(!i || s.str[i-1] ==
' ')
1071 _c4dbgpf(
"found terminating character: '{}'", c);
1082 if(C4_LIKELY(i > 0))
1084 _line_progressed(i);
1085 sc->scalar = s.first(i);
1086 sc->needs_filter =
false;
1087 _c4dbgpf(
"scalar was [{}]~~~{}~~~", sc->scalar.len, sc->scalar);
1094 template<
class EventHandler>
1095 bool ParseEngine<EventHandler>::_scan_scalar_map_json(ScannedScalar *C4_RESTRICT sc)
1097 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
RSEQ));
1098 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
BLCK));
1099 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_any(
RMAP));
1100 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_any(
FLOW));
1101 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_any(
RKEY|
RVAL));
1103 substr s =
m_state->line_contents.rem;
1104 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, !s.begins_with(
' '));
1109 _c4dbgp(
"scanning scalar...");
1112 const size_t len = _is_special_json_scalar(s);
1115 sc->scalar = s.first(len);
1116 sc->needs_filter =
false;
1117 _c4dbgpf(
"special json scalar: '{}'", sc->scalar);
1118 _line_progressed(len);
1125 for( ; i < s.len; ++i)
1127 const char c = s.str[i];
1134 _c4dbgpf(
"found terminating character: '{}'", c);
1137 if(!i || s.str[i-1] ==
' ')
1139 _c4dbgpf(
"found terminating character: '{}'", c);
1150 if(C4_LIKELY(i > 0))
1152 _line_progressed(i);
1153 sc->scalar = s.first(i);
1154 sc->needs_filter =
false;
1155 _c4dbgpf(
"scalar was [{}]~~~{}~~~", sc->scalar.len, sc->scalar);
1162 template<
class EventHandler>
1163 bool ParseEngine<EventHandler>::_is_doc_begin(csubstr s)
1165 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, s[0] ==
'-');
1166 return (
m_state->line_contents.indentation == 0u && _at_line_begin() && _is_doc_begin_token(s));
1169 template<
class EventHandler>
1170 bool ParseEngine<EventHandler>::_is_doc_end(csubstr s)
1172 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, s[0] ==
'.');
1173 return (
m_state->line_contents.indentation == 0u && _at_line_begin() && _is_doc_end_token(s));
1176 template<
class EventHandler>
1177 bool ParseEngine<EventHandler>::_scan_scalar_plain_blck(ScannedScalar *C4_RESTRICT sc,
size_t indentation)
1179 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
FLOW));
1180 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
RSEQIMAP));
1181 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_any(
BLCK|
RUNK|
USTY));
1183 substr s =
m_state->line_contents.rem;
1184 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, !s.begins_with(
' '));
1192 if(_is_blck_token(s))
1196 else if(_is_doc_begin(s))
1198 _c4dbgp(
"token is doc start");
1204 if(_is_blck_token(s))
1217 _c4dbgp(
"token is doc end");
1223 _c4dbgpf(
"plain scalar! indentation={}", indentation);
1225 const size_t start_offset =
m_state->pos.offset;
1226 const size_t start_line =
m_state->pos.line;
1228 bool needs_filter =
false;
1231 _c4dbgpf(
"plain scalar line: [{}]~~~{}~~~", s.len, s);
1232 for(
size_t i = 0; i < s.len; ++i)
1234 const char curr = s.str[i];
1239 _c4dbgpf(
"[{}]: got suspicious ':'", i);
1243 _c4dbgpf(
"followed by '{}'", i+1 == s.len ? csubstr(
"\\n") : _c4prc(s.str[i+1]));
1244 _line_progressed(i);
1246 if(C4_LIKELY(
m_state->pos.line == start_line))
1248 _c4dbgp(
"start line. scalar ends here");
1253 _c4err(
"parse error");
1259 while(j + 1 < s.len && s.str[j+1] ==
':')
1261 _c4dbgp(
"skip colon");
1264 i = j > i ? j-1 : i;
1265 _c4dbgp(
"nothing to see here");
1269 _c4dbgp(
"got suspicious '#'");
1270 if(!i || (s.str[i-1] ==
' ' || s.str[i-1] ==
'\t'))
1272 _c4dbgp(
"comment! scalar ends here");
1273 _line_progressed(i);
1278 _c4dbgp(
"nothing to see here");
1283 _line_progressed(s.len);
1284 csubstr next_peeked = _peek_next_line(
m_state->pos.offset);
1285 next_peeked = next_peeked.trimr(
"\n\r");
1286 const size_t next_indentation = next_peeked.first_not_of(
' ');
1287 _c4dbgpf(
"indentation curr={} next={}", indentation, next_indentation);
1288 if(next_indentation < indentation)
1290 _c4dbgp(
"smaller indentation! scalar ended");
1293 else if(next_indentation == 0 && next_peeked.len > 0)
1295 const char first = next_peeked.str[0];
1299 next_peeked = next_peeked.trimr(
"\n\r");
1300 _c4dbgpf(
"doc begin? peeked=[{}]~~~{}{}~~~", next_peeked.len, next_peeked.len >= 3 ? next_peeked.first(3) : next_peeked, next_peeked.len > 3 ?
"..." :
"");
1301 if(_is_doc_begin_token(next_peeked))
1303 _c4dbgp(
"doc begin! scalar ended");
1308 next_peeked = next_peeked.trimr(
"\n\r");
1309 _c4dbgpf(
"doc end? peeked=[{}]~~~{}{}~~~", next_peeked.len, next_peeked.len >= 3 ? next_peeked.first(3) : next_peeked, next_peeked.len > 3 ?
"..." :
"");
1310 if(_is_doc_end_token(next_peeked))
1312 _c4dbgp(
"doc end! scalar ended");
1319 _c4dbgp(
"next line!");
1320 if(!_finished_file())
1322 _c4dbgp(
"next line!");
1328 _c4dbgp(
"file finished!");
1331 s =
m_state->line_contents.rem;
1332 needs_filter =
true;
1337 sc->scalar = m_buf.range(start_offset,
m_state->pos.offset).trimr(
" \n\r\t");
1338 sc->needs_filter = needs_filter;
1340 _c4dbgpf(
"scalar was [{}]~~~{}~~~", sc->scalar.len, sc->scalar);
1345 template<
class EventHandler>
1346 bool ParseEngine<EventHandler>::_scan_scalar_plain_seq_blck(ScannedScalar *C4_RESTRICT sc)
1348 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
RMAP));
1349 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
FLOW));
1350 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
RSEQIMAP));
1351 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_any(
RSEQ));
1352 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_any(
BLCK));
1353 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_any(
RVAL));
1354 return _scan_scalar_plain_blck(sc,
m_state->indref + 1u);
1357 template<
class EventHandler>
1358 bool ParseEngine<EventHandler>::_scan_scalar_plain_map_blck(ScannedScalar *C4_RESTRICT sc)
1360 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
RSEQ));
1361 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
FLOW));
1362 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_any(
RMAP));
1363 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_any(
BLCK));
1364 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_any(
RKEY|
RVAL|
QMRK));
1365 return _scan_scalar_plain_blck(sc,
m_state->indref + 1u);
1368 template<
class EventHandler>
1369 bool ParseEngine<EventHandler>::_scan_scalar_plain_unk(ScannedScalar *C4_RESTRICT sc)
1371 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_any(
RUNK|
USTY));
1372 return _scan_scalar_plain_blck(sc,
m_state->indref);
1378 template<
class EventHandler>
1379 substr ParseEngine<EventHandler>::_peek_next_line(
size_t pos)
const
1384 if(pos >= m_buf.len)
1388 rem = from_next_line(m_buf.sub(pos));
1393 nlpos = rem.first_of(
"\r\n");
1395 nlpos += _extend_from_combined_newline(rem[nlpos], rem[nlpos+1]);
1396 rem = rem.left_of(nlpos,
true);
1398 _c4dbgpf(
"peek next line @ {}: (len={})'{}'", pos, rem.len, rem.trimr(
"\r\n"));
1402 _c4dbgpf(
"peek next line @ {}: (len=0)''", pos);
1408 template<
class EventHandler>
1409 void ParseEngine<EventHandler>::_scan_line()
1411 if(C4_LIKELY(
m_state->pos.offset < m_buf.len))
1412 m_state->line_contents.reset_with_next_line(m_buf,
m_state->pos.offset);
1414 m_state->line_contents.reset(m_buf.last(0), m_buf.last(0));
1417 template<
class EventHandler>
1418 void ParseEngine<EventHandler>::_line_progressed(
size_t ahead)
1420 _c4dbgpf(
"line[{}] ({} cols) progressed by {}: col {}-->{} offset {}-->{}",
m_state->pos.line,
m_state->line_contents.full.len, ahead,
m_state->pos.col,
m_state->pos.col+ahead,
m_state->pos.offset,
m_state->pos.offset+ahead);
1423 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks,
m_state->pos.col <=
m_state->line_contents.stripped.len+1);
1424 m_state->line_contents.rem =
m_state->line_contents.rem.sub(ahead);
1427 template<
class EventHandler>
1428 void ParseEngine<EventHandler>::_line_ended()
1430 _c4dbgpf(
"line[{}] ({} cols) ended! offset {}-->{} / col {}-->{}",
1432 m_state->line_contents.full.len,
1435 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks,
m_state->pos.col ==
m_state->line_contents.stripped.len + 1);
1441 template<
class EventHandler>
1442 void ParseEngine<EventHandler>::_line_ended_undo()
1444 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks,
m_state->pos.col == 1u);
1445 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks,
m_state->pos.line > 0u);
1446 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks,
m_state->pos.offset >=
m_state->line_contents.full.len -
m_state->line_contents.stripped.len);
1447 const size_t delta =
m_state->line_contents.full.len -
m_state->line_contents.stripped.len;
1448 _c4dbgpf(
"line[{}] undo ended! line {}-->{}, offset {}-->{}",
m_state->pos.line,
m_state->pos.line,
m_state->pos.line - 1,
m_state->pos.offset,
m_state->pos.offset - delta);
1459 template<
class EventHandler>
1460 void ParseEngine<EventHandler>::_set_indentation(
size_t indentation)
1462 m_state->indref = indentation;
1463 _c4dbgpf(
"state[{}]: saving indentation: {}",
m_state->level,
m_state->indref);
1466 template<
class EventHandler>
1467 void ParseEngine<EventHandler>::_save_indentation()
1469 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks,
m_state->line_contents.rem.begin() >=
m_state->line_contents.full.begin());
1471 _c4dbgpf(
"state[{}]: saving indentation: {}",
m_state->level,
m_state->indref);
1477 template<
class EventHandler>
1478 void ParseEngine<EventHandler>::_end_map_blck()
1480 _c4dbgp(
"mapblck: end");
1483 _c4dbgp(
"mapblck: set missing val");
1484 _handle_annotations_before_blck_val_scalar();
1485 m_evt_handler->set_val_scalar_plain({});
1487 else if(has_any(
QMRK))
1489 _c4dbgp(
"mapblck: set missing keyval");
1490 _handle_annotations_before_blck_key_scalar();
1491 m_evt_handler->set_key_scalar_plain({});
1492 _handle_annotations_before_blck_val_scalar();
1493 m_evt_handler->set_val_scalar_plain({});
1495 m_evt_handler->end_map();
1498 template<
class EventHandler>
1499 void ParseEngine<EventHandler>::_end_seq_blck()
1503 _c4dbgp(
"seqblck: set missing val");
1504 _handle_annotations_before_blck_val_scalar();
1505 m_evt_handler->set_val_scalar_plain({});
1507 m_evt_handler->end_seq();
1510 template<
class EventHandler>
1511 void ParseEngine<EventHandler>::_end2_map()
1513 _c4dbgp(
"map: end");
1514 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_any(
RMAP));
1521 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
FLOW));
1522 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_any(
USTY));
1523 m_evt_handler->_pop();
1527 template<
class EventHandler>
1528 void ParseEngine<EventHandler>::_end2_seq()
1530 _c4dbgp(
"seq: end");
1531 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_any(
RSEQ));
1538 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
FLOW));
1539 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_any(
USTY));
1540 m_evt_handler->_pop();
1544 template<
class EventHandler>
1545 void ParseEngine<EventHandler>::_begin2_doc()
1549 m_evt_handler->begin_doc();
1550 m_evt_handler->m_curr->indref = 0;
1553 template<
class EventHandler>
1554 void ParseEngine<EventHandler>::_begin2_doc_expl()
1558 m_evt_handler->begin_doc_expl();
1559 m_evt_handler->m_curr->indref = 0;
1562 template<
class EventHandler>
1563 void ParseEngine<EventHandler>::_end2_doc()
1565 _c4dbgp(
"doc: end");
1566 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_any(
RDOC));
1569 _c4dbgp(
"doc was empty; add empty val");
1570 m_evt_handler->set_val_scalar_plain({});
1572 m_evt_handler->end_doc();
1575 template<
class EventHandler>
1576 void ParseEngine<EventHandler>::_end2_doc_expl()
1578 _c4dbgp(
"doc: end");
1581 _c4dbgp(
"doc: no children; add empty val");
1582 m_evt_handler->set_val_scalar_plain({});
1584 m_evt_handler->end_doc_expl();
1587 template<
class EventHandler>
1588 void ParseEngine<EventHandler>::_maybe_begin_doc()
1592 _c4dbgp(
"doc must be started");
1596 template<
class EventHandler>
1597 void ParseEngine<EventHandler>::_maybe_end_doc()
1601 _c4dbgp(
"doc must be finished");
1606 template<
class EventHandler>
1607 void ParseEngine<EventHandler>::_end_doc_suddenly__pop()
1609 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, m_evt_handler->m_stack.size() >= 1);
1610 if(m_evt_handler->m_stack[0].flags &
RDOC)
1612 _c4dbgp(
"root is RDOC");
1614 _handle_indentation_pop(&m_evt_handler->m_stack[0]);
1616 else if((m_evt_handler->m_stack.size() > 1) && (m_evt_handler->m_stack[1].flags &
RDOC))
1618 _c4dbgp(
"root is STREAM");
1620 _handle_indentation_pop(&m_evt_handler->m_stack[1]);
1624 _c4err(
"internal error");
1626 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_any(
RDOC));
1629 template<
class EventHandler>
1630 void ParseEngine<EventHandler>::_end_doc_suddenly()
1632 _c4dbgp(
"end doc suddenly");
1633 _end_doc_suddenly__pop();
1638 template<
class EventHandler>
1639 void ParseEngine<EventHandler>::_start_doc_suddenly()
1641 _c4dbgp(
"start doc suddenly");
1642 _end_doc_suddenly__pop();
1647 template<
class EventHandler>
1648 void ParseEngine<EventHandler>::_end_stream()
1650 _c4dbgpf(
"end_stream, level={} node_id={}",
m_state->level,
m_state->node_id);
1652 _c4err(
"missing terminating ]");
1654 _c4err(
"missing terminating }");
1655 if(m_evt_handler->m_stack.size() > 1)
1656 _handle_indentation_pop(m_evt_handler->m_stack.begin());
1663 if(m_pending_anchors.num_entries || m_pending_tags.num_entries)
1667 m_evt_handler->begin_doc();
1668 _handle_annotations_before_blck_val_scalar();
1669 m_evt_handler->set_val_scalar_plain({});
1670 m_evt_handler->end_doc();
1674 m_evt_handler->end_stream();
1678 template<
class EventHandler>
1679 void ParseEngine<EventHandler>::_handle_indentation_pop(ParserState
const* popto)
1681 _c4dbgpf(
"popping {} level{}: from level {}(@ind={}) to level {}(@ind={})",
m_state->level - popto->level, (((
m_state->level - popto->level) > 1) ?
"s" :
""),
m_state->level,
m_state->indref, popto->level, popto->indref);
1686 _c4dbgpf(
"popping seq at level {} (indentation={},addr={})",
m_state->level,
m_state->indref,
m_state);
1689 else if(has_any(
RMAP))
1691 _c4dbgpf(
"popping map at level {} (indentation={},addr={})",
m_state->level,
m_state->indref,
m_state);
1699 _c4dbgpf(
"current level is {} (indentation={})",
m_state->level,
m_state->indref);
1702 template<
class EventHandler>
1703 void ParseEngine<EventHandler>::_handle_indentation_pop_from_block_seq()
1706 using state_type =
typename EventHandler::state;
1707 state_type
const* popto =
nullptr;
1708 auto &stack = m_evt_handler->m_stack;
1709 _RYML_CB_ASSERT(stack.m_callbacks, stack.is_contiguous());
1710 _RYML_CB_ASSERT(stack.m_callbacks,
m_state >= stack.begin() &&
m_state < stack.end());
1711 const size_t ind =
m_state->line_contents.indentation;
1716 for(state_type
const& s : stack)
1717 _dbg_printf(
"state[{}]: ind={} node={} flags={}\n", s.level, s.indref, s.node_id, detail::_parser_flags_to_str(flagbuf_, s.flags));
1720 for(state_type
const* s =
m_state-1; s >= stack.begin(); --s)
1722 _c4dbgpf(
"searching for state with indentation {}. curr={} (level={},node={})", ind, s->indref, s->level, s->node_id);
1723 if(s->indref == ind)
1725 _c4dbgpf(
"gotit!!! level={} node={}", s->level, s->node_id);
1732 _c4err(
"parse error: incorrect indentation?");
1734 _handle_indentation_pop(popto);
1737 template<
class EventHandler>
1738 void ParseEngine<EventHandler>::_handle_indentation_pop_from_block_map()
1741 using state_type =
typename EventHandler::state;
1742 auto &stack = m_evt_handler->m_stack;
1743 _RYML_CB_ASSERT(stack.m_callbacks, stack.is_contiguous());
1744 _RYML_CB_ASSERT(stack.m_callbacks,
m_state >= stack.begin() &&
m_state < stack.end());
1745 const size_t ind =
m_state->line_contents.indentation;
1746 state_type
const* popto =
nullptr;
1751 for(state_type
const& s : stack)
1752 _dbg_printf(
"state[{}]: ind={} node={} flags={}\n", s.level, s.indref, s.node_id, detail::_parser_flags_to_str(flagbuf_, s.flags));
1755 for(state_type
const* s =
m_state-1; s > stack.begin(); --s)
1757 _c4dbgpf(
"searching for state with indentation {}. current: ind={},level={},node={},flags={}", ind, s->indref, s->level, s->node_id, detail::_parser_flags_to_str(flagbuf_, s->flags));
1762 else if(s->indref == ind)
1764 _c4dbgpf(
"same indentation!!! level={} node={}", s->level, s->node_id);
1765 if(popto && has_any(
RTOP, s) && has_none(
RMAP|
RSEQ, s))
1772 csubstr rem =
m_state->line_contents.rem;
1773 const size_t first = rem.first_not_of(
' ');
1774 _RYML_CB_ASSERT(stack.m_callbacks, first == ind || first ==
npos);
1775 rem = rem.right_of(first,
true);
1776 _c4dbgpf(
"indentless? rem='{}' first={}", rem, first);
1777 if(rem.begins_with(
'-') && _is_blck_token(rem))
1779 _c4dbgp(
"parent was indentless seq");
1787 _c4err(
"parse error: incorrect indentation?");
1789 _handle_indentation_pop(popto);
1794 template<
class EventHandler>
1795 typename ParseEngine<EventHandler>::ScannedScalar ParseEngine<EventHandler>::_scan_scalar_squot()
1801 size_t b =
m_state->pos.offset;
1802 substr s = m_buf.sub(b);
1803 if(s.begins_with(
' '))
1806 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, m_buf.sub(b).is_super(s));
1807 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, s.begin() >= m_buf.sub(b).begin());
1808 _line_progressed((
size_t)(s.begin() - m_buf.sub(b).begin()));
1811 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, s.begins_with(
'\''));
1814 _line_progressed(1);
1817 bool needs_filter =
false;
1819 size_t numlines = 1;
1821 while( ! _finished_file())
1823 const csubstr line =
m_state->line_contents.rem;
1824 bool line_is_blank =
true;
1825 _c4dbgpf(
"scanning single quoted scalar @ line[{}]: ~~~{}~~~",
m_state->pos.line, line);
1826 for(
size_t i = 0; i < line.len; ++i)
1828 const char curr = line.str[i];
1831 const char next = i+1 < line.len ? line.str[i+1] :
'~';
1839 needs_filter =
true;
1843 else if(curr !=
' ')
1845 line_is_blank =
false;
1850 needs_filter = needs_filter
1853 || (_at_line_begin() && line.begins_with(
' '));
1857 _line_progressed(line.len);
1862 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, pos >= 0 && pos < m_buf.len);
1863 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, m_buf[
m_state->pos.offset + pos] ==
'\'');
1864 _line_progressed(pos + 1);
1865 pos =
m_state->pos.offset - b - 1;
1875 _c4err(
"reached end of file while looking for closing quote");
1879 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, pos > 0);
1880 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, s.end() >= m_buf.begin() && s.end() <= m_buf.end());
1881 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, s.end() == m_buf.end() || *s.end() ==
'\'');
1882 s = s.sub(0, pos-1);
1885 _c4prscalar(
"scanned squoted scalar", s,
true);
1887 return ScannedScalar { s, needs_filter };
1892 template<
class EventHandler>
1893 typename ParseEngine<EventHandler>::ScannedScalar ParseEngine<EventHandler>::_scan_scalar_dquot()
1899 size_t b =
m_state->pos.offset;
1900 substr s = m_buf.sub(b);
1901 if(s.begins_with(
' '))
1904 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, m_buf.sub(b).is_super(s));
1905 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, s.begin() >= m_buf.sub(b).begin());
1906 _line_progressed((
size_t)(s.begin() - m_buf.sub(b).begin()));
1909 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, s.begins_with(
'"'));
1912 _line_progressed(1);
1915 bool needs_filter =
false;
1917 size_t numlines = 1;
1919 while( ! _finished_file())
1921 const csubstr line =
m_state->line_contents.rem;
1922 bool line_is_blank =
true;
1923 _c4dbgpf(
"scanning double quoted scalar @ line[{}]: line='{}'",
m_state->pos.line, line);
1924 for(
size_t i = 0; i < line.len; ++i)
1926 const char curr = line.str[i];
1928 line_is_blank =
false;
1932 const char next = i+1 < line.len ? line.str[i+1] :
'~';
1933 needs_filter =
true;
1934 if(next ==
'"' || next ==
'\\')
1937 else if(curr ==
'"')
1945 needs_filter = needs_filter
1948 || (_at_line_begin() && line.begins_with(
' '));
1952 _line_progressed(line.len);
1957 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, pos >= 0 && pos < m_buf.len);
1958 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, m_buf[
m_state->pos.offset + pos] ==
'"');
1959 _line_progressed(pos + 1);
1960 pos =
m_state->pos.offset - b - 1;
1970 _c4err(
"reached end of file looking for closing quote");
1974 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, pos > 0);
1975 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, s.end() == m_buf.end() || *s.end() ==
'"');
1976 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, s.end() >= m_buf.begin() && s.end() <= m_buf.end());
1977 s = s.sub(0, pos-1);
1980 _c4prscalar(
"scanned dquoted scalar", s,
true);
1982 return ScannedScalar { s, needs_filter };
1987 template<
class EventHandler>
1988 void ParseEngine<EventHandler>::_scan_block(ScannedBlock *C4_RESTRICT sb,
size_t indref)
1990 _c4dbgpf(
"blck: indref={}", indref);
1991 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, indref !=
npos);
1994 csubstr s =
m_state->line_contents.rem;
1995 csubstr trimmed = s.triml(
' ');
1996 if(trimmed.str > s.str)
1998 _c4dbgp(
"skipping whitespace");
1999 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, trimmed.str >= s.str);
2000 _line_progressed(
static_cast<size_t>(trimmed.str - s.str));
2003 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, s.begins_with(
'|') || s.begins_with(
'>'));
2005 _c4dbgpf(
"blck: specs=[{}]~~~{}~~~", s.len, s);
2008 BlockChomp_e chomp = CHOMP_CLIP;
2009 size_t indentation =
npos;
2013 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, s.begins_with_any(
"|>"));
2014 csubstr t = s.sub(1);
2015 _c4dbgpf(
"blck: spec is multichar: '{}'", t);
2016 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, t.len >= 1);
2017 size_t pos = t.first_of(
"-+");
2018 _c4dbgpf(
"blck: spec chomp char at {}", pos);
2022 chomp = CHOMP_STRIP;
2023 else if(t[pos] ==
'+')
2031 digits = t.left_of(t.first_not_of(
"0123456789"));
2032 if( ! digits.empty())
2035 _c4err(
"parse error: invalid indentation");
2036 _c4dbgpf(
"blck: parse indentation digits: [{}]~~~{}~~~", digits.len, digits);
2037 if(C4_UNLIKELY( !
c4::atou(digits, &indentation)))
2038 _c4err(
"parse error: could not read indentation as decimal");
2039 if(C4_UNLIKELY( ! indentation))
2040 _c4err(
"parse error: null indentation");
2041 _c4dbgpf(
"blck: indentation specified: {}. add {} from curr state -> {}", indentation,
m_state->indref, indentation+indref);
2042 indentation +=
m_state->indref;
2046 _c4dbgpf(
"blck: style={} chomp={} indentation={}", s.begins_with(
'>') ?
"fold" :
"literal", chomp==CHOMP_CLIP ?
"clip" : (chomp==CHOMP_STRIP ?
"strip" :
"keep"), indentation);
2049 _line_progressed(s.len);
2054 substr raw_block(m_buf.data() +
m_state->pos.offset,
size_t(0));
2055 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, raw_block.begin() ==
m_state->line_contents.full.begin());
2063 size_t num_lines = 0;
2064 size_t first =
m_state->pos.line;
2065 size_t provisional_indentation =
npos;
2067 while(( ! _finished_file()))
2070 lc.reset_with_next_line(m_buf,
m_state->pos.offset);
2071 _c4dbgpf(
"blck: peeking at [{}]~~~{}~~~", lc.stripped.len, lc.stripped);
2073 if(indentation !=
npos)
2076 if(lc.indentation < indentation && ( ! lc.rem.trim(
" \t\r\n").empty()))
2080 _c4dbgpf(
"blck: indentation decreased ref={} thisline={}", indentation, lc.indentation);
2084 _c4err(
"indentation decreased without any scalar");
2088 else if(indentation == 0)
2090 if(_is_doc_token(lc.rem))
2092 _c4dbgp(
"blck: stop. indentation=0 and doc ended");
2099 const size_t fns = lc.stripped.first_not_of(
' ');
2100 _c4dbgpf(
"blck: indentation ref not set. firstnonws={}", fns);
2104 if(C4_UNLIKELY(lc.stripped.begins_with(
'\t')))
2105 _c4err(
"parse error");
2107 _c4dbgpf(
"blck: line not empty. indref={} indprov={} indentation={}", indref, provisional_indentation, lc.indentation);
2108 if(provisional_indentation ==
npos)
2110 if(lc.indentation < indref)
2112 _c4dbgpf(
"blck: block terminated indentation={} < indref={}", lc.indentation, indref);
2113 if(raw_block.len == 0)
2115 _c4dbgp(
"blck: was empty, undo next line");
2120 else if(lc.indentation ==
m_state->indref)
2124 _c4dbgpf(
"blck: block terminated. reading container and indentation={}==indref={}", lc.indentation,
m_state->indref);
2128 _c4dbgpf(
"blck: set indentation ref from this line: ref={}", lc.indentation);
2129 indentation = lc.indentation;
2133 if(lc.indentation >= provisional_indentation)
2135 _c4dbgpf(
"blck: set indentation ref from provisional indentation: provisional_ref={}, thisline={}", provisional_indentation, lc.indentation);
2137 indentation = lc.indentation;
2148 _c4dbgpf(
"blck: line empty or {} spaces. line_indentation={} prov_indentation={}", lc.stripped.len, lc.indentation, provisional_indentation);
2149 if(provisional_indentation !=
npos)
2151 if(lc.stripped.len >= provisional_indentation)
2153 _c4dbgpf(
"blck: increase provisional_ref {} -> {}", provisional_indentation, lc.stripped.len);
2154 provisional_indentation = lc.stripped.len;
2156 #ifdef RYML_NO_COVERAGE__TO_BE_DELETED
2157 else if(lc.indentation >= provisional_indentation && lc.indentation !=
npos)
2159 _c4dbgpf(
"blck: increase provisional_ref {} -> {}", provisional_indentation, lc.indentation);
2160 provisional_indentation = lc.indentation;
2166 provisional_indentation = lc.indentation ? lc.indentation : has_any(
RSEQ|
RVAL);
2167 _c4dbgpf(
"blck: initialize provisional_ref={}", provisional_indentation);
2168 if(provisional_indentation ==
npos)
2170 provisional_indentation = lc.stripped.len ? lc.stripped.len : has_any(
RSEQ|
RVAL);
2171 _c4dbgpf(
"blck: initialize provisional_ref={}", provisional_indentation);
2173 if(provisional_indentation < indref)
2175 provisional_indentation = indref;
2176 _c4dbgpf(
"blck: initialize provisional_ref={}", provisional_indentation);
2183 _c4dbgpf(
"blck: append '{}'",
m_state->line_contents.rem);
2184 raw_block.len +=
m_state->line_contents.full.len;
2185 _line_progressed(
m_state->line_contents.rem.len);
2189 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks,
m_state->pos.line == (first + num_lines) || (raw_block.len == 0));
2190 C4_UNUSED(num_lines);
2193 if(indentation ==
npos)
2195 _c4dbgpf(
"blck: set indentation from provisional: {}", provisional_indentation);
2196 indentation = provisional_indentation;
2202 _c4prscalar(
"scanned block", raw_block,
true);
2204 sb->scalar = raw_block;
2205 sb->indentation = indentation;
2216 #define _c4dbgfws(fmt, ...) _c4dbgpf("filt_ws[{}->{}]: " fmt, proc.rpos, proc.wpos, __VA_ARGS__)
2218 #define _c4dbgfws(...)
2221 template<
class EventHandler>
2222 template<
class FilterProcessor>
2223 bool ParseEngine<EventHandler>::_filter_ws_handle_to_first_non_space(FilterProcessor &proc)
2225 _c4dbgfws(
"found whitespace '{}'", _c4prc(proc.curr()));
2226 _RYML_CB_ASSERT(this->callbacks(), proc.curr() ==
' ' || proc.curr() ==
'\t');
2228 const size_t first_pos = proc.rpos > 0 ? proc.src.first_not_of(
" \t", proc.rpos) : proc.src.first_not_of(
' ', proc.rpos);
2229 if(first_pos !=
npos)
2231 const char first_char = proc.src[first_pos];
2232 _c4dbgfws(
"firstnonws='{}'@{}", _c4prc(first_char), first_pos);
2233 if(first_char ==
'\n' || first_char ==
'\r')
2235 _c4dbgfws(
"whitespace is trailing on line",
"");
2236 proc.skip(first_pos - proc.rpos);
2241 _c4dbgfws(
"legit whitespace. sofar=[{}]~~~{}~~~", proc.wpos, proc.sofar());
2245 _c4dbgfws(
"whitespace is trailing on line",
"");
2249 template<
class EventHandler>
2250 template<
class FilterProcessor>
2251 void ParseEngine<EventHandler>::_filter_ws_copy_trailing(FilterProcessor &proc)
2253 if(!_filter_ws_handle_to_first_non_space(proc))
2255 _c4dbgfws(
"... everything else is trailing whitespace - copy {} chars", proc.src.len - proc.rpos);
2256 proc.copy(proc.src.len - proc.rpos);
2260 template<
class EventHandler>
2261 template<
class FilterProcessor>
2262 void ParseEngine<EventHandler>::_filter_ws_skip_trailing(FilterProcessor &proc)
2264 if(!_filter_ws_handle_to_first_non_space(proc))
2266 _c4dbgfws(
"... everything else is trailing whitespace - skip {} chars", proc.src.len - proc.rpos);
2267 proc.skip(proc.src.len - proc.rpos);
2281 #define _c4dbgfps(fmt, ...) _c4dbgpf("filt_plain[{}->{}]: " fmt, proc.rpos, proc.wpos, __VA_ARGS__)
2283 #define _c4dbgfps(fmt, ...)
2286 template<
class EventHandler>
2287 template<
class FilterProcessor>
2288 void ParseEngine<EventHandler>::_filter_nl_plain(FilterProcessor &C4_RESTRICT proc,
size_t indentation)
2290 _RYML_CB_ASSERT(this->callbacks(), proc.curr() ==
'\n');
2292 _c4dbgfps(
"found newline. sofar=[{}]~~~{}~~~", proc.wpos, proc.sofar());
2293 size_t ii = proc.rpos;
2294 const size_t numnl_following = _count_following_newlines(proc.src, &ii, indentation);
2297 proc.set(
'\n', numnl_following);
2298 _c4dbgfps(
"{} consecutive (empty) lines {}. totalws={}", 1+numnl_following, ii < proc.src.len ?
"in the middle" :
"at the end", proc.rpos-ii);
2302 const size_t ret = proc.src.first_not_of(
" \t", proc.rpos+1);
2306 _c4dbgfps(
"single newline. convert to space. ret={}/{}. sofar=[{}]~~~{}~~~", ii, proc.src.len, proc.wpos, proc.sofar());
2310 _c4dbgfps(
"last newline, everything else is whitespace. ii={}/{}", ii, proc.src.len);
2317 template<
class EventHandler>
2318 template<
class FilterProcessor>
2319 auto ParseEngine<EventHandler>::_filter_plain(FilterProcessor &C4_RESTRICT proc,
size_t indentation) -> decltype(proc.result())
2321 _RYML_CB_ASSERT(this->callbacks(), indentation !=
npos);
2322 _c4dbgfps(
"before=[{}]~~~{}~~~", proc.src.len, proc.src);
2324 while(proc.has_more_chars())
2326 const char curr = proc.curr();
2327 _c4dbgfps(
"'{}', sofar=[{}]~~~{}~~~", _c4prc(curr), proc.wpos, proc.sofar());
2333 _filter_ws_skip_trailing(proc);
2337 _filter_nl_plain(proc, indentation);
2340 _c4dbgfps(
"carriage return, ignore", curr);
2349 _c4dbgfps(
"after[{}]=~~~{}~~~", proc.wpos, proc.sofar());
2351 return proc.result();
2357 template<
class EventHandler>
2361 return _filter_plain(proc, indentation);
2364 template<
class EventHandler>
2368 return _filter_plain(proc, indentation);
2379 #define _c4dbgfsq(fmt, ...) _c4dbgpf("filt_squo[{}->{}]: " fmt, proc.rpos, proc.wpos, __VA_ARGS__)
2381 #define _c4dbgfsq(fmt, ...)
2384 template<
class EventHandler>
2385 template<
class FilterProcessor>
2386 void ParseEngine<EventHandler>::_filter_nl_squoted(FilterProcessor &C4_RESTRICT proc)
2388 _RYML_CB_ASSERT(this->callbacks(), proc.curr() ==
'\n');
2390 _c4dbgfsq(
"found newline. sofar=[{}]~~~{}~~~", proc.wpos, proc.sofar());
2391 size_t ii = proc.rpos;
2392 const size_t numnl_following = _count_following_newlines(proc.src, &ii);
2395 proc.set(
'\n', numnl_following);
2396 _c4dbgfsq(
"{} consecutive (empty) lines {}. totalws={}", 1+numnl_following, ii < proc.src.len ?
"in the middle" :
"at the end", proc.rpos-ii);
2400 const size_t ret = proc.src.first_not_of(
" \t", proc.rpos+1);
2404 _c4dbgfsq(
"single newline. convert to space. ret={}/{}. sofar=[{}]~~~{}~~~", ii, proc.src.len, proc.wpos, proc.sofar());
2409 _c4dbgfsq(
"single newline. convert to space. ii={}/{}. sofar=[{}]~~~{}~~~", ii, proc.src.len, proc.wpos, proc.sofar());
2415 template<
class EventHandler>
2416 template<
class FilterProcessor>
2417 auto ParseEngine<EventHandler>::_filter_squoted(FilterProcessor &C4_RESTRICT proc) -> decltype(proc.result())
2419 _c4dbgfsq(
"before=[{}]~~~{}~~~", proc.src.len, proc.src);
2423 while(proc.has_more_chars())
2425 const char curr = proc.curr();
2426 _c4dbgfsq(
"'{}', sofar=[{}]~~~{}~~~", _c4prc(curr), proc.wpos, proc.sofar());
2432 _filter_ws_copy_trailing(proc);
2436 _filter_nl_squoted(proc);
2444 if(proc.next() ==
'\'')
2446 _c4dbgfsq(
"two consecutive squotes", curr);
2452 _c4err(
"filter error");
2461 _c4dbgfsq(
": #filteredchars={} after=~~~[{}]{}~~~", proc.src.len-proc.sofar().len, proc.sofar().len, proc.sofar());
2463 return proc.result();
2468 template<
class EventHandler>
2472 return _filter_squoted(proc);
2475 template<
class EventHandler>
2479 return _filter_squoted(proc);
2490 #define _c4dbgfdq(fmt, ...) _c4dbgpf("filt_dquo[{}->{}]: " fmt, proc.rpos, proc.wpos, __VA_ARGS__)
2492 #define _c4dbgfdq(...)
2495 template<
class EventHandler>
2496 template<
class FilterProcessor>
2497 void ParseEngine<EventHandler>::_filter_nl_dquoted(FilterProcessor &C4_RESTRICT proc)
2499 _RYML_CB_ASSERT(this->callbacks(), proc.curr() ==
'\n');
2501 _c4dbgfdq(
"found newline. sofar=[{}]~~~{}~~~", proc.wpos, proc.sofar());
2502 size_t ii = proc.rpos;
2503 const size_t numnl_following = _count_following_newlines(proc.src, &ii);
2506 proc.set(
'\n', numnl_following);
2507 _c4dbgfdq(
"{} consecutive (empty) lines {}. totalws={}", 1+numnl_following, ii < proc.src.len ?
"in the middle" :
"at the end", proc.rpos-ii);
2511 const size_t ret = proc.src.first_not_of(
" \t", proc.rpos+1);
2515 _c4dbgfdq(
"single newline. convert to space. ret={}/{}. sofar=[{}]~~~{}~~~", ii, proc.src.len, proc.wpos, proc.sofar());
2520 _c4dbgfdq(
"single newline. convert to space. ii={}/{}. sofar=[{}]~~~{}~~~", ii, proc.src.len, proc.wpos, proc.sofar());
2522 if(ii < proc.src.len && proc.src.str[ii] ==
'\\')
2525 const char next = ii+1 < proc.src.len ? proc.src.str[ii+1] :
'\0';
2526 if(next ==
' ' || next ==
'\t')
2528 _c4dbgfdq(
"extend skip to backslash",
"");
2536 template<
class EventHandler>
2537 template<
class FilterProcessor>
2538 void ParseEngine<EventHandler>::_filter_dquoted_backslash(FilterProcessor &C4_RESTRICT proc)
2540 char next = proc.next();
2541 _c4dbgfdq(
"backslash, next='{}'", _c4prc(next));
2544 if(proc.rpos+2 < proc.src.len && proc.src.str[proc.rpos+2] ==
'\n')
2548 _c4dbgfdq(
"[{}]: was \\r\\n, now next='\\n'", proc.rpos);
2554 size_t ii = proc.rpos + 2;
2555 for( ; ii < proc.src.len; ++ii)
2558 if(proc.src.str[ii] ==
' ' || proc.src.str[ii] ==
'\t')
2563 proc.skip(ii - proc.rpos);
2565 else if(next ==
'"' || next ==
'/' || next ==
' ' || next ==
'\t')
2568 proc.translate_esc(next);
2569 _c4dbgfdq(
"here, used '{}'", _c4prc(next));
2571 else if(next ==
'\r')
2575 else if(next ==
'n')
2577 proc.translate_esc(
'\n');
2579 else if(next ==
'r')
2581 proc.translate_esc(
'\r');
2583 else if(next ==
't')
2585 proc.translate_esc(
'\t');
2587 else if(next ==
'\\')
2589 proc.translate_esc(
'\\');
2591 else if(next ==
'x')
2593 if(C4_UNLIKELY(proc.rpos + 1u + 2u >= proc.src.len))
2594 _c4err(
"\\x requires 2 hex digits. scalar pos={}", proc.rpos);
2595 csubstr codepoint = proc.src.sub(proc.rpos + 2u, 2u);
2596 _c4dbgfdq(
"utf8 ~~~{}~~~ rpos={} rem=~~~{}~~~", codepoint, proc.rpos, proc.src.sub(proc.rpos));
2597 uint8_t byteval = {};
2598 if(C4_UNLIKELY(!
read_hex(codepoint, &byteval)))
2599 _c4err(
"failed to read \\x codepoint. scalar pos={}", proc.rpos);
2600 proc.translate_esc_bulk((
const char*)&byteval, 1u, 3u);
2601 _c4dbgfdq(
"utf8 after rpos={} rem=~~~{}~~~", proc.rpos, proc.src.sub(proc.rpos));
2603 else if(next ==
'u')
2605 if(C4_UNLIKELY(proc.rpos + 1u + 4u >= proc.src.len))
2606 _c4err(
"\\u requires 4 hex digits. scalar pos={}", proc.rpos);
2608 csubstr codepoint = proc.src.sub(proc.rpos + 2u, 4u);
2609 uint32_t codepoint_val = {};
2610 if(C4_UNLIKELY(!
read_hex(codepoint, &codepoint_val)))
2611 _c4err(
"failed to parse \\u codepoint. scalar pos={}", proc.rpos);
2612 const size_t numbytes = decode_code_point((uint8_t*)readbuf,
sizeof(readbuf), codepoint_val);
2613 if(C4_UNLIKELY(numbytes == 0))
2614 _c4err(
"failed to decode code point={}", proc.rpos);
2615 _RYML_CB_ASSERT(callbacks(), numbytes <= 4);
2616 proc.translate_esc_bulk(readbuf, numbytes, 5u);
2618 else if(next ==
'U')
2620 if(C4_UNLIKELY(proc.rpos + 1u + 8u >= proc.src.len))
2621 _c4err(
"\\U requires 8 hex digits. scalar pos={}", proc.rpos);
2623 csubstr codepoint = proc.src.sub(proc.rpos + 2u, 8u);
2624 uint32_t codepoint_val = {};
2625 if(C4_UNLIKELY(!
read_hex(codepoint, &codepoint_val)))
2626 _c4err(
"failed to parse \\U codepoint. scalar pos={}", proc.rpos);
2627 const size_t numbytes = decode_code_point((uint8_t*)readbuf,
sizeof(readbuf), codepoint_val);
2628 if(C4_UNLIKELY(numbytes == 0))
2629 _c4err(
"failed to decode code point={}", proc.rpos);
2630 _RYML_CB_ASSERT(callbacks(), numbytes <= 4);
2631 proc.translate_esc_bulk(readbuf, numbytes, 9u);
2634 else if(next ==
'0')
2636 proc.translate_esc(
'\0');
2638 else if(next ==
'b')
2640 proc.translate_esc(
'\b');
2642 else if(next ==
'f')
2644 proc.translate_esc(
'\f');
2646 else if(next ==
'a')
2648 proc.translate_esc(
'\a');
2650 else if(next ==
'v')
2652 proc.translate_esc(
'\v');
2654 else if(next ==
'e')
2656 proc.translate_esc(
'\x1b');
2658 else if(next ==
'_')
2661 const char payload[] = {
2662 _RYML_CHCONST(-0x3e, 0xc2),
2663 _RYML_CHCONST(-0x60, 0xa0),
2665 proc.translate_esc_bulk(payload, 2, 1);
2667 else if(next ==
'N')
2670 const char payload[] = {
2671 _RYML_CHCONST(-0x3e, 0xc2),
2672 _RYML_CHCONST(-0x7b, 0x85),
2674 proc.translate_esc_bulk(payload, 2, 1);
2676 else if(next ==
'L')
2679 const char payload[] = {
2680 _RYML_CHCONST(-0x1e, 0xe2),
2681 _RYML_CHCONST(-0x80, 0x80),
2682 _RYML_CHCONST(-0x58, 0xa8),
2684 proc.translate_esc_extending(payload, 3, 1);
2686 else if(next ==
'P')
2689 const char payload[] = {
2690 _RYML_CHCONST(-0x1e, 0xe2),
2691 _RYML_CHCONST(-0x80, 0x80),
2692 _RYML_CHCONST(-0x57, 0xa9),
2694 proc.translate_esc_extending(payload, 3, 1);
2696 else if(next ==
'\0')
2702 _c4err(
"unknown character '{}' after '\\' pos={}", _c4prc(next), proc.rpos);
2704 _c4dbgfdq(
"backslash...sofar=[{}]~~~{}~~~", proc.wpos, proc.sofar());
2708 template<
class EventHandler>
2709 template<
class FilterProcessor>
2710 auto ParseEngine<EventHandler>::_filter_dquoted(FilterProcessor &C4_RESTRICT proc) -> decltype(proc.result())
2712 _c4dbgfdq(
"before=[{}]~~~{}~~~", proc.src.len, proc.src);
2715 while(proc.has_more_chars())
2717 const char curr = proc.curr();
2718 _c4dbgfdq(
"'{}' sofar=[{}]~~~{}~~~", _c4prc(curr), proc.wpos, proc.sofar());
2725 _filter_ws_copy_trailing(proc);
2731 _filter_nl_dquoted(proc);
2736 _c4dbgfdq(
"carriage return, ignore", curr);
2742 _filter_dquoted_backslash(proc);
2752 _c4dbgfdq(
"after[{}]=~~~{}~~~", proc.wpos, proc.sofar());
2753 return proc.result();
2759 template<
class EventHandler>
2763 return _filter_dquoted(proc);
2766 template<
class EventHandler>
2770 return _filter_dquoted(proc);
2779 template<
class EventHandler>
2780 template<
class FilterProcessor>
2783 _RYML_CB_ASSERT(this->callbacks(), chomp == CHOMP_CLIP || chomp == CHOMP_KEEP || chomp == CHOMP_STRIP);
2784 _RYML_CB_ASSERT(this->callbacks(), proc.rem().first_not_of(
" \n\r") ==
npos);
2788 #define _c4dbgchomp(fmt, ...) _c4dbgpf("chomp[{}->{}]: " fmt, proc.rpos, proc.wpos, __VA_ARGS__)
2790 #define _c4dbgchomp(...)
2798 _c4dbgchomp(
"found newline and larger indentation. last={}", last);
2799 last = proc.rpos + last + size_t(1) + indentation;
2800 _RYML_CB_ASSERT(this->callbacks(), last <= proc.src.len);
2802 while((proc.rpos < last) && proc.has_more_chars())
2804 const char curr = proc.curr();
2810 _c4dbgchomp(
"newline! remlen={}", proc.rem().len);
2813 csubstr at_next_line = proc.rem();
2814 if(at_next_line.begins_with(
' '))
2816 _c4dbgchomp(
"next line begins with spaces. indentation={}", indentation);
2818 size_t first_non_space = at_next_line.first_not_of(
' ');
2819 _c4dbgchomp(
"first_non_space={}", first_non_space);
2820 if(first_non_space ==
npos)
2822 _c4dbgchomp(
"{} spaces, to the end", at_next_line.len);
2823 first_non_space = at_next_line.len;
2825 if(first_non_space <= indentation)
2827 _c4dbgchomp(
"skip spaces={}<=indentation={}", first_non_space, indentation);
2828 proc.skip(first_non_space);
2832 _c4dbgchomp(
"skip indentation={}<spaces={}", indentation, first_non_space);
2833 proc.skip(indentation);
2835 _c4dbgchomp(
"copy {}={}-{} spaces", first_non_space - indentation, first_non_space, indentation);
2836 proc.copy(first_non_space - indentation);
2845 _c4err(
"parse error");
2857 bool had_one =
false;
2858 while(proc.has_more_chars())
2860 const char curr = proc.curr();
2881 _c4dbgchomp(
"chomp=CLIP: add missing newline @{}", proc.wpos);
2888 _c4dbgchomp(
"chomp=KEEP: copy all remaining new lines of {} characters", proc.rem().len);
2889 while(proc.has_more_chars())
2891 const char curr = proc.curr();
2910 _c4dbgchomp(
"chomp=STRIP: strip {} characters", proc.rem().len);
2922 #define _c4dbgfb(fmt, ...) _c4dbgpf("filt_block[{}->{}]: " fmt, proc.rpos, proc.wpos, __VA_ARGS__)
2924 #define _c4dbgfb(...)
2927 template<
class EventHandler>
2928 template<
class FilterProcessor>
2929 void ParseEngine<EventHandler>::_filter_block_indentation(FilterProcessor &C4_RESTRICT proc,
size_t indentation)
2931 csubstr rem = proc.rem();
2934 size_t first = rem.first_not_of(
' ');
2937 _c4dbgfb(
"{} spaces follow before next nonws character", first);
2938 if(first < indentation)
2940 _c4dbgfb(
"skip {}<{} spaces from indentation", first, indentation);
2945 _c4dbgfb(
"skip {} spaces from indentation", indentation);
2946 proc.skip(indentation);
2949 #ifdef RYML_NO_COVERAGE__TO_BE_DELETED
2952 _c4dbgfb(
"all spaces to the end: {} spaces", first);
2956 if(first < indentation)
2958 _c4dbgfb(
"skip everything", first);
2959 proc.skip(proc.src.len - proc.rpos);
2963 _c4dbgfb(
"skip {} spaces from indentation", indentation);
2964 proc.skip(indentation);
2972 template<
class EventHandler>
2973 template<
class FilterProcessor>
2974 size_t ParseEngine<EventHandler>::_handle_all_whitespace(FilterProcessor &C4_RESTRICT proc, BlockChomp_e chomp)
2976 csubstr contents = proc.src.trimr(
" \n\r");
2977 _c4dbgfb(
"ws: contents_len={} wslen={}", contents.len, proc.src.len-contents.len);
2980 _c4dbgfb(
"ws: all whitespace: len={}", proc.src.len);
2981 if(chomp == CHOMP_KEEP && proc.src.len)
2983 _c4dbgfb(
"ws: chomp=KEEP all {} newlines", proc.src.count(
'\n'));
2984 while(proc.has_more_chars())
2986 const char curr = proc.curr();
2998 return contents.len;
3001 template<
class EventHandler>
3002 template<
class FilterProcessor>
3003 size_t ParseEngine<EventHandler>::_extend_to_chomp(FilterProcessor &C4_RESTRICT proc,
size_t contents_len)
3005 _c4dbgfb(
"contents_len={}", contents_len);
3007 _RYML_CB_ASSERT(this->callbacks(), contents_len > 0u);
3011 size_t firstnewl = proc.src.first_of(
'\n', contents_len);
3012 if(firstnewl !=
npos)
3014 contents_len = firstnewl;
3015 _c4dbgfb(
"contents_len={} <--- firstnewl={}", contents_len, firstnewl);
3019 contents_len = proc.src.len;
3020 _c4dbgfb(
"contents_len={} <--- src.len={}", contents_len, proc.src.len);
3023 return contents_len;
3035 #define _c4dbgfbl(fmt, ...) _c4dbgpf("filt_block_lit[{}->{}]: " fmt, proc.rpos, proc.wpos, __VA_ARGS__)
3037 #define _c4dbgfbl(...)
3040 template<
class EventHandler>
3041 template<
class FilterProcessor>
3042 auto ParseEngine<EventHandler>::_filter_block_literal(FilterProcessor &C4_RESTRICT proc,
size_t indentation, BlockChomp_e chomp) -> decltype(proc.result())
3044 _c4dbgfbl(
"indentation={} before=[{}]~~~{}~~~", indentation, proc.src.len, proc.src);
3046 size_t contents_len = _handle_all_whitespace(proc, chomp);
3048 return proc.result();
3050 contents_len = _extend_to_chomp(proc, contents_len);
3052 _c4dbgfbl(
"to filter=[{}]~~~{}~~~", contents_len, proc.src.first(contents_len));
3054 _filter_block_indentation(proc, indentation);
3057 while(proc.has_more_chars(contents_len))
3059 const char curr = proc.curr();
3060 _c4dbgfbl(
"'{}' sofar=[{}]~~~{}~~~", _c4prc(curr), proc.wpos, proc.sofar());
3065 _c4dbgfbl(
"found newline. skip indentation on the next line", curr);
3067 _filter_block_indentation(proc, indentation);
3079 _c4dbgfbl(
"before chomp: #tochomp={} sofar=[{}]~~~{}~~~", proc.rem().len, proc.sofar().len, proc.sofar());
3081 _filter_chomp(proc, chomp, indentation);
3083 _c4dbgfbl(
"final=[{}]~~~{}~~~", proc.sofar().len, proc.sofar());
3085 return proc.result();
3090 template<
class EventHandler>
3094 return _filter_block_literal(proc, indentation, chomp);
3097 template<
class EventHandler>
3101 return _filter_block_literal(proc, indentation, chomp);
3111 #define _c4dbgfbf(fmt, ...) _c4dbgpf("filt_block_folded[{}->{}]: " fmt, proc.rpos, proc.wpos, __VA_ARGS__)
3113 #define _c4dbgfbf(...)
3117 template<
class EventHandler>
3118 template<
class FilterProcessor>
3119 void ParseEngine<EventHandler>::_filter_block_folded_newlines_leading(FilterProcessor &C4_RESTRICT proc,
size_t indentation,
size_t len)
3121 _filter_block_indentation(proc, indentation);
3122 while(proc.has_more_chars(len))
3124 const char curr = proc.curr();
3125 _c4dbgfbf(
"'{}' sofar=[{}]~~~{}~~~", _c4prc(curr), proc.wpos, proc.sofar());
3131 _filter_block_indentation(proc, indentation);
3139 size_t first = proc.rem().first_not_of(
" \t");
3142 first = proc.rem().len;
3143 _c4dbgfbf(
"... indentation increased to {}", first);
3144 _filter_block_folded_indented_block(proc, indentation, len, first);
3148 _c4dbgfbf(
"newl leading: not space, not newline. stop.", 0);
3154 template<
class EventHandler>
3155 template<
class FilterProcessor>
3156 size_t ParseEngine<EventHandler>::_filter_block_folded_newlines_compress(FilterProcessor &C4_RESTRICT proc,
size_t num_newl,
size_t wpos_at_first_newl)
3161 _c4dbgfbf(
"... this is the first newline. turn into space. wpos={}", proc.wpos);
3162 wpos_at_first_newl = proc.wpos;
3167 _c4dbgfbf(
"... this is the second newline. prev space (at wpos={}) must be newline", wpos_at_first_newl);
3168 _RYML_CB_ASSERT(this->callbacks(), wpos_at_first_newl !=
npos);
3169 _RYML_CB_ASSERT(this->callbacks(), proc.sofar()[wpos_at_first_newl] ==
' ');
3170 _RYML_CB_ASSERT(this->callbacks(), wpos_at_first_newl + 1u == proc.wpos);
3172 proc.set_at(wpos_at_first_newl,
'\n');
3173 _RYML_CB_ASSERT(this->callbacks(), proc.sofar()[wpos_at_first_newl] ==
'\n');
3176 _c4dbgfbf(
"... subsequent newline (num_newl={}). copy", num_newl);
3180 return wpos_at_first_newl;
3183 template<
class EventHandler>
3184 template<
class FilterProcessor>
3185 void ParseEngine<EventHandler>::_filter_block_folded_newlines(FilterProcessor &C4_RESTRICT proc,
size_t indentation,
size_t len)
3187 _RYML_CB_ASSERT(this->callbacks(), proc.curr() ==
'\n');
3188 size_t num_newl = 0;
3189 size_t wpos_at_first_newl =
npos;
3190 while(proc.has_more_chars(len))
3192 const char curr = proc.curr();
3193 _c4dbgfbf(
"'{}' sofar=[{}]~~~{}~~~", _c4prc(curr), proc.wpos, proc.sofar());
3198 _c4dbgfbf(
"newline. sofar={}", num_newl);
3234 wpos_at_first_newl = _filter_block_folded_newlines_compress(proc, ++num_newl, wpos_at_first_newl);
3235 _filter_block_indentation(proc, indentation);
3241 size_t first = proc.rem().first_not_of(
" \t");
3244 first = proc.rem().len;
3245 _c4dbgfbf(
"... indentation increased to {}", first);
3248 _c4dbgfbf(
"... prev space (at wpos={}) must be newline", wpos_at_first_newl);
3249 proc.set_at(wpos_at_first_newl,
'\n');
3253 _c4dbgfbf(
"... add missing newline", wpos_at_first_newl);
3256 _filter_block_folded_indented_block(proc, indentation, len, first);
3258 wpos_at_first_newl =
npos;
3265 _c4dbgfbf(
"not space, not newline. stop.", 0);
3272 template<
class EventHandler>
3273 template<
class FilterProcessor>
3274 void ParseEngine<EventHandler>::_filter_block_folded_indented_block(FilterProcessor &C4_RESTRICT proc,
size_t indentation,
size_t len,
size_t curr_indentation) noexcept
3276 _RYML_CB_ASSERT(this->callbacks(), (proc.rem().first_not_of(
" \t") == curr_indentation) || (proc.rem().first_not_of(
" \t") ==
npos));
3277 if(curr_indentation)
3278 proc.copy(curr_indentation);
3279 while(proc.has_more_chars(len))
3281 const char curr = proc.curr();
3282 _c4dbgfbf(
"'{}' sofar=[{}]~~~{}~~~", _c4prc(curr), proc.wpos, proc.sofar());
3288 _filter_block_indentation(proc, indentation);
3289 csubstr rem = proc.rem();
3290 const size_t first = rem.first_not_of(
' ');
3291 _c4dbgfbf(
"newline. firstns={}", first);
3294 const char c = rem[first];
3295 _c4dbgfbf(
"firstns={}='{}'", first, _c4prc(c));
3296 if(c ==
'\n' || c ==
'\r')
3302 _c4dbgfbf(
"done with indented block", first);
3306 else if(first !=
npos)
3327 template<
class EventHandler>
3328 template<
class FilterProcessor>
3329 auto ParseEngine<EventHandler>::_filter_block_folded(FilterProcessor &C4_RESTRICT proc,
size_t indentation, BlockChomp_e chomp) -> decltype(proc.result())
3331 _c4dbgfbf(
"indentation={} before=[{}]~~~{}~~~", indentation, proc.src.len, proc.src);
3333 size_t contents_len = _handle_all_whitespace(proc, chomp);
3335 return proc.result();
3337 contents_len = _extend_to_chomp(proc, contents_len);
3339 _c4dbgfbf(
"to filter=[{}]~~~{}~~~", contents_len, proc.src.first(contents_len));
3341 _filter_block_folded_newlines_leading(proc, indentation, contents_len);
3344 while(proc.has_more_chars(contents_len))
3346 const char curr = proc.curr();
3347 _c4dbgfbf(
"'{}' sofar=[{}]~~~{}~~~", _c4prc(curr), proc.wpos, proc.sofar());
3353 _filter_block_folded_newlines(proc, indentation, contents_len);
3365 _c4dbgfbf(
"before chomp: #tochomp={} sofar=[{}]~~~{}~~~", proc.rem().len, proc.sofar().len, proc.sofar());
3367 _filter_chomp(proc, chomp, indentation);
3369 _c4dbgfbf(
"final=[{}]~~~{}~~~", proc.sofar().len, proc.sofar());
3371 return proc.result();
3376 template<
class EventHandler>
3380 return _filter_block_folded(proc, indentation, chomp);
3383 template<
class EventHandler>
3387 return _filter_block_folded(proc, indentation, chomp);
3395 template<
class EventHandler>
3398 _c4dbgpf(
"filtering plain scalar: s=[{}]~~~{}~~~", s.len, s);
3399 FilterResult r = this->filter_scalar_plain_in_place(s, s.len, indentation);
3400 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, r.valid());
3401 _c4dbgpf(
"filtering plain scalar: success! s=[{}]~~~{}~~~", r.get().len, r.get());
3407 template<
class EventHandler>
3408 csubstr ParseEngine<EventHandler>::_filter_scalar_squot(substr s)
3410 _c4dbgpf(
"filtering squo scalar: s=[{}]~~~{}~~~", s.len, s);
3411 FilterResult r = this->filter_scalar_squoted_in_place(s, s.len);
3412 _RYML_CB_ASSERT(this->callbacks(), r.valid());
3413 _c4dbgpf(
"filtering squo scalar: success! s=[{}]~~~{}~~~", r.get().len, r.get());
3420 template<
class EventHandler>
3421 csubstr ParseEngine<EventHandler>::_filter_scalar_dquot(substr s)
3423 _c4dbgpf(
"filtering dquo scalar: s=[{}]~~~{}~~~", s.len, s);
3424 FilterResultExtending r = this->filter_scalar_dquoted_in_place(s, s.len);
3425 if(C4_LIKELY(r.valid()))
3427 _c4dbgpf(
"filtering dquo scalar: success! s=[{}]~~~{}~~~", r.get().len, r.get());
3432 const size_t len = r.required_len();
3433 _c4dbgpf(
"filtering dquo scalar: not enough space: needs {}, have {}", len, s.len);
3434 substr dst = m_evt_handler->alloc_arena(len, &s);
3435 _c4dbgpf(
"filtering dquo scalar: dst.len={}", dst.len);
3436 _RYML_CB_ASSERT(this->callbacks(), dst.len == len);
3437 FilterResult rsd = this->filter_scalar_dquoted(s, dst);
3438 _c4dbgpf(
"filtering dquo scalar: ... result now needs {} was {}", rsd.required_len(), len);
3439 _RYML_CB_ASSERT(this->callbacks(), rsd.required_len() <= len);
3440 _RYML_CB_CHECK(m_evt_handler->m_stack.m_callbacks, rsd.valid());
3441 _c4dbgpf(
"filtering dquo scalar: success! s=[{}]~~~{}~~~", rsd.get().len, rsd.get());
3448 template<
class EventHandler>
3449 csubstr ParseEngine<EventHandler>::_filter_scalar_literal(substr s,
size_t indentation, BlockChomp_e chomp)
3451 _c4dbgpf(
"filtering block literal scalar: s=[{}]~~~{}~~~", s.len, s);
3452 FilterResult r = this->filter_scalar_block_literal_in_place(s, s.len, indentation, chomp);
3453 if(C4_LIKELY(r.valid()))
3455 _c4dbgpf(
"filtering block literal scalar: success! s=[{}]~~~{}~~~", r.get().len, r.get());
3460 _c4dbgpf(
"filtering block literal scalar: not enough space: needs {}, have {}", r.required_len(), s.len);
3461 substr dst = m_evt_handler->alloc_arena(r.required_len(), &s);
3462 FilterResult rsd = this->filter_scalar_block_literal(s, dst, indentation, chomp);
3463 _RYML_CB_CHECK(m_evt_handler->m_stack.m_callbacks, rsd.valid());
3464 _c4dbgpf(
"filtering block literal scalar: success! s=[{}]~~~{}~~~", rsd.get().len, rsd.get());
3471 template<
class EventHandler>
3472 csubstr ParseEngine<EventHandler>::_filter_scalar_folded(substr s,
size_t indentation, BlockChomp_e chomp)
3474 _c4dbgpf(
"filtering block folded scalar: s=[{}]~~~{}~~~", s.len, s);
3475 FilterResult r = this->filter_scalar_block_folded_in_place(s, s.len, indentation, chomp);
3476 if(C4_LIKELY(r.valid()))
3478 _c4dbgpf(
"filtering block folded scalar: success! s=[{}]~~~{}~~~", r.get().len, r.get());
3483 _c4dbgpf(
"filtering block folded scalar: not enough space: needs {}, have {}", r.required_len(), s.len);
3484 substr dst = m_evt_handler->alloc_arena(r.required_len(), &s);
3485 FilterResult rsd = this->filter_scalar_block_folded(s, dst, indentation, chomp);
3486 _RYML_CB_CHECK(m_evt_handler->m_stack.m_callbacks, rsd.valid());
3487 _c4dbgpf(
"filtering block folded scalar: success! s=[{}]~~~{}~~~", rsd.get().len, rsd.get());
3495 template<
class EventHandler>
3496 csubstr ParseEngine<EventHandler>::_maybe_filter_key_scalar_plain(ScannedScalar
const& C4_RESTRICT sc,
size_t indentation)
3498 csubstr maybe_filtered = sc.scalar;
3501 if(m_options.scalar_filtering())
3503 maybe_filtered = _filter_scalar_plain(sc.scalar, indentation);
3507 _c4dbgp(
"plain scalar left unfiltered");
3508 m_evt_handler->mark_key_scalar_unfiltered();
3513 _c4dbgp(
"plain scalar doesn't need filtering");
3515 return maybe_filtered;
3518 template<
class EventHandler>
3519 csubstr ParseEngine<EventHandler>::_maybe_filter_val_scalar_plain(ScannedScalar
const& C4_RESTRICT sc,
size_t indentation)
3521 csubstr maybe_filtered = sc.scalar;
3524 if(m_options.scalar_filtering())
3526 maybe_filtered = _filter_scalar_plain(sc.scalar, indentation);
3530 _c4dbgp(
"plain scalar left unfiltered");
3531 m_evt_handler->mark_val_scalar_unfiltered();
3536 _c4dbgp(
"plain scalar doesn't need filtering");
3538 return maybe_filtered;
3544 template<
class EventHandler>
3545 csubstr ParseEngine<EventHandler>::_maybe_filter_key_scalar_squot(ScannedScalar
const& C4_RESTRICT sc)
3547 csubstr maybe_filtered = sc.scalar;
3550 if(m_options.scalar_filtering())
3552 maybe_filtered = _filter_scalar_squot(sc.scalar);
3556 _c4dbgp(
"squo key scalar left unfiltered");
3557 m_evt_handler->mark_key_scalar_unfiltered();
3562 _c4dbgp(
"squo key scalar doesn't need filtering");
3564 return maybe_filtered;
3567 template<
class EventHandler>
3568 csubstr ParseEngine<EventHandler>::_maybe_filter_val_scalar_squot(ScannedScalar
const& C4_RESTRICT sc)
3570 csubstr maybe_filtered = sc.scalar;
3573 if(m_options.scalar_filtering())
3575 maybe_filtered = _filter_scalar_squot(sc.scalar);
3579 _c4dbgp(
"squo val scalar left unfiltered");
3580 m_evt_handler->mark_val_scalar_unfiltered();
3585 _c4dbgp(
"squo val scalar doesn't need filtering");
3587 return maybe_filtered;
3593 template<
class EventHandler>
3594 csubstr ParseEngine<EventHandler>::_maybe_filter_key_scalar_dquot(ScannedScalar
const& C4_RESTRICT sc)
3596 csubstr maybe_filtered = sc.scalar;
3599 if(m_options.scalar_filtering())
3601 maybe_filtered = _filter_scalar_dquot(sc.scalar);
3605 _c4dbgp(
"dquo scalar left unfiltered");
3606 m_evt_handler->mark_key_scalar_unfiltered();
3611 _c4dbgp(
"dquo scalar doesn't need filtering");
3613 return maybe_filtered;
3616 template<
class EventHandler>
3617 csubstr ParseEngine<EventHandler>::_maybe_filter_val_scalar_dquot(ScannedScalar
const& C4_RESTRICT sc)
3619 csubstr maybe_filtered = sc.scalar;
3622 if(m_options.scalar_filtering())
3624 maybe_filtered = _filter_scalar_dquot(sc.scalar);
3628 _c4dbgp(
"dquo scalar left unfiltered");
3629 m_evt_handler->mark_val_scalar_unfiltered();
3634 _c4dbgp(
"dquo scalar doesn't need filtering");
3636 return maybe_filtered;
3642 template<
class EventHandler>
3643 csubstr ParseEngine<EventHandler>::_maybe_filter_key_scalar_literal(ScannedBlock
const& C4_RESTRICT sb)
3645 csubstr maybe_filtered = sb.scalar;
3646 if(m_options.scalar_filtering())
3648 maybe_filtered = _filter_scalar_literal(sb.scalar, sb.indentation, sb.chomp);
3652 _c4dbgp(
"literal scalar left unfiltered");
3653 m_evt_handler->mark_key_scalar_unfiltered();
3655 return maybe_filtered;
3658 template<
class EventHandler>
3659 csubstr ParseEngine<EventHandler>::_maybe_filter_val_scalar_literal(ScannedBlock
const& C4_RESTRICT sb)
3661 csubstr maybe_filtered = sb.scalar;
3662 if(m_options.scalar_filtering())
3664 maybe_filtered = _filter_scalar_literal(sb.scalar, sb.indentation, sb.chomp);
3668 _c4dbgp(
"literal scalar left unfiltered");
3669 m_evt_handler->mark_val_scalar_unfiltered();
3671 return maybe_filtered;
3677 template<
class EventHandler>
3678 csubstr ParseEngine<EventHandler>::_maybe_filter_key_scalar_folded(ScannedBlock
const& C4_RESTRICT sb)
3680 csubstr maybe_filtered = sb.scalar;
3681 if(m_options.scalar_filtering())
3683 maybe_filtered = _filter_scalar_folded(sb.scalar, sb.indentation, sb.chomp);
3687 _c4dbgp(
"folded scalar left unfiltered");
3688 m_evt_handler->mark_key_scalar_unfiltered();
3690 return maybe_filtered;
3693 template<
class EventHandler>
3694 csubstr ParseEngine<EventHandler>::_maybe_filter_val_scalar_folded(ScannedBlock
const& C4_RESTRICT sb)
3696 csubstr maybe_filtered = sb.scalar;
3697 if(m_options.scalar_filtering())
3699 maybe_filtered = _filter_scalar_folded(sb.scalar, sb.indentation, sb.chomp);
3703 _c4dbgp(
"folded scalar left unfiltered");
3704 m_evt_handler->mark_val_scalar_unfiltered();
3706 return maybe_filtered;
3716 template<
class EventHandler>
3717 void ParseEngine<EventHandler>::add_flags(
ParserFlag_t on, ParserState * s)
3719 char buf1_[64], buf2_[64], buf3_[64];
3720 csubstr buf1 = detail::_parser_flags_to_str(buf1_, on);
3721 csubstr buf2 = detail::_parser_flags_to_str(buf2_, s->flags);
3722 csubstr buf3 = detail::_parser_flags_to_str(buf3_, s->flags|on);
3723 _c4dbgpf(
"state[{}]: add {}: before={} after={}", s->level, buf1, buf2, buf3);
3727 template<
class EventHandler>
3730 char buf1_[64], buf2_[64], buf3_[64], buf4_[64];
3731 csubstr buf1 = detail::_parser_flags_to_str(buf1_, on);
3732 csubstr buf2 = detail::_parser_flags_to_str(buf2_, off);
3733 csubstr buf3 = detail::_parser_flags_to_str(buf3_, s->flags);
3734 csubstr buf4 = detail::_parser_flags_to_str(buf4_, ((s->flags|on)&(~off)));
3735 _c4dbgpf(
"state[{}]: add {} / rem {}: before={} after={}", s->level, buf1, buf2, buf3, buf4);
3740 template<
class EventHandler>
3741 void ParseEngine<EventHandler>::rem_flags(
ParserFlag_t off, ParserState * s)
3743 char buf1_[64], buf2_[64], buf3_[64];
3744 csubstr buf1 = detail::_parser_flags_to_str(buf1_, off);
3745 csubstr buf2 = detail::_parser_flags_to_str(buf2_, s->flags);
3746 csubstr buf3 = detail::_parser_flags_to_str(buf3_, s->flags&(~off));
3747 _c4dbgpf(
"state[{}]: rem {}: before={} after={}", s->level, buf1, buf2, buf3);
3751 inline C4_NO_INLINE csubstr detail::_parser_flags_to_str(substr buf,
ParserFlag_t flags)
3754 bool gotone =
false;
3756 #define _prflag(fl) \
3757 if((flags & fl) == (fl)) \
3761 if(pos + 1 < buf.len) \
3765 csubstr fltxt = #fl; \
3766 if(pos + fltxt.len <= buf.len) \
3767 memcpy(buf.str + pos, fltxt.str, fltxt.len); \
3797 RYML_CHECK(pos <= buf.len);
3799 return buf.first(pos);
3809 template<
class EventHandler>
3812 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, loc.
offset < m_buf.len);
3813 return m_buf.sub(loc.
offset);
3816 template<
class EventHandler>
3819 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, node.
readable());
3820 return location(*node.
tree(), node.
id());
3823 template<
class EventHandler>
3828 if(_location_from_node(tree, node, &loc, 0))
3830 return val_location(m_buf.str);
3833 template<
class EventHandler>
3838 csubstr k = tree.
key(node);
3839 if(C4_LIKELY(k.str !=
nullptr))
3841 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, k.is_sub(m_buf));
3842 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, m_buf.is_super(k));
3843 *loc = val_location(k.str);
3850 csubstr v = tree.
val(node);
3851 if(C4_LIKELY(v.str !=
nullptr))
3853 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, v.is_sub(m_buf));
3854 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, m_buf.is_super(v));
3855 *loc = val_location(v.str);
3862 if(_location_from_cont(tree, node, loc))
3873 if(_location_from_node(tree, prev, loc, level+1))
3882 if(_location_from_node(tree, next, loc, level+1))
3891 if(_location_from_node(tree, parent, loc, level+1))
3900 template<
class EventHandler>
3901 bool ParseEngine<EventHandler>::_location_from_cont(Tree
const& tree,
id_type node, Location *C4_RESTRICT loc)
const
3903 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, tree.is_container(node));
3904 if(!tree.is_stream(node))
3906 const char *node_start = tree._p(node)->m_val.scalar.str;
3907 if(tree.has_children(node))
3909 id_type child = tree.first_child(node);
3910 if(tree.has_key(child))
3913 csubstr k = tree.key(child);
3914 if(k.str && node_start > k.str)
3918 *loc = val_location(node_start);
3923 *loc = val_location(m_buf.str);
3929 template<
class EventHandler>
3932 if(C4_UNLIKELY(val ==
nullptr))
3933 return {m_file, 0, 0, 0};
3934 _RYML_CB_CHECK(m_evt_handler->m_stack.m_callbacks, m_options.locations());
3937 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, m_buf.str == m_newline_offsets_buf.str);
3938 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, m_buf.len == m_newline_offsets_buf.len);
3939 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, m_options.locations());
3940 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, !_locations_dirty());
3941 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, m_newline_offsets !=
nullptr);
3942 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, m_newline_offsets_size > 0);
3944 csubstr src = m_buf;
3945 _RYML_CB_CHECK(m_evt_handler->m_stack.m_callbacks, val !=
nullptr || src.str ==
nullptr);
3946 _RYML_CB_CHECK(m_evt_handler->m_stack.m_callbacks, (val >= src.begin() && val <= src.end()) || (src.str ==
nullptr && val ==
nullptr));
3948 using lineptr_type =
size_t const* C4_RESTRICT;
3949 lineptr_type lineptr =
nullptr;
3950 size_t offset = (size_t)(val - src.begin());
3954 for(lineptr_type curr = m_newline_offsets, last = m_newline_offsets + m_newline_offsets_size; curr < last; ++curr)
3969 size_t count = m_newline_offsets_size;
3972 lineptr = m_newline_offsets;
3976 it = lineptr + step;
3988 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, lineptr >= m_newline_offsets);
3989 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, lineptr <= m_newline_offsets + m_newline_offsets_size);
3990 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, *lineptr > offset);
3994 loc.
line = (size_t)(lineptr - m_newline_offsets);
3995 if(lineptr > m_newline_offsets)
3996 loc.
col = (offset - *(lineptr-1) - 1u);
4002 template<
class EventHandler>
4005 m_newline_offsets_buf = m_buf;
4006 size_t numnewlines = 1u + m_buf.count(
'\n');
4007 _resize_locations(numnewlines);
4008 m_newline_offsets_size = 0;
4009 for(
size_t i = 0; i < m_buf.len; i++)
4010 if(m_buf[i] ==
'\n')
4011 m_newline_offsets[m_newline_offsets_size++] = i;
4012 m_newline_offsets[m_newline_offsets_size++] = m_buf.len;
4013 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, m_newline_offsets_size == numnewlines);
4016 template<
class EventHandler>
4017 void ParseEngine<EventHandler>::_resize_locations(
size_t numnewlines)
4019 if(numnewlines > m_newline_offsets_capacity)
4021 if(m_newline_offsets)
4022 _RYML_CB_FREE(m_evt_handler->m_stack.m_callbacks, m_newline_offsets,
size_t, m_newline_offsets_capacity);
4023 m_newline_offsets = _RYML_CB_ALLOC_HINT(m_evt_handler->m_stack.m_callbacks,
size_t, numnewlines, m_newline_offsets);
4024 m_newline_offsets_capacity = numnewlines;
4028 template<
class EventHandler>
4029 bool ParseEngine<EventHandler>::_locations_dirty()
const
4031 return !m_newline_offsets_size;
4039 template<
class EventHandler>
4040 void ParseEngine<EventHandler>::_handle_flow_skip_whitespace()
4042 if(
m_state->line_contents.rem.len > 0)
4044 csubstr rem =
m_state->line_contents.rem;
4045 if(rem.str[0] ==
' ' || rem.str[0] ==
'\t')
4047 _c4dbgpf(
"starts with whitespace: '{}'", _c4prc(rem.str[0]));
4049 rem =
m_state->line_contents.rem;
4052 if(rem.begins_with(
'#'))
4054 _c4dbgpf(
"it's a comment: {}",
m_state->line_contents.rem);
4055 _line_progressed(
m_state->line_contents.rem.len);
4064 template<
class EventHandler>
4065 void ParseEngine<EventHandler>::_add_annotation(Annotation *C4_RESTRICT dst, csubstr str,
size_t indentation,
size_t line)
4067 _c4dbgpf(
"store annotation[{}]: '{}' indentation={} line={}", dst->num_entries, str, indentation, line);
4068 if(C4_UNLIKELY(dst->num_entries >= C4_COUNTOF(dst->annotations)))
4069 _c4err(
"too many annotations");
4070 dst->annotations[dst->num_entries].str = str;
4071 dst->annotations[dst->num_entries].indentation = indentation;
4072 dst->annotations[dst->num_entries].line = line;
4076 template<
class EventHandler>
4077 void ParseEngine<EventHandler>::_clear_annotations(Annotation *C4_RESTRICT dst)
4079 dst->num_entries = 0;
4082 #ifdef RYML_NO_COVERAGE__TO_BE_DELETED
4083 template<
class EventHandler>
4084 bool ParseEngine<EventHandler>::_handle_indentation_from_annotations()
4086 if(m_pending_anchors.num_entries == 1u || m_pending_tags.num_entries == 1u)
4088 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, m_pending_anchors.num_entries < 2u && m_pending_tags.num_entries < 2u);
4089 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, m_pending_anchors.annotations[0].line <
m_state->pos.line);
4090 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, m_pending_tags.annotations[1].line <
m_state->pos.line);
4091 size_t to_skip =
m_state->indref;
4092 if(m_pending_anchors.num_entries)
4093 to_skip = m_pending_anchors.annotations[0].indentation > to_skip ? m_pending_anchors.annotations[0].indentation : to_skip;
4094 if(m_pending_tags.num_entries)
4095 to_skip = m_pending_tags.annotations[0].indentation > to_skip ? m_pending_tags.annotations[0].indentation : to_skip;
4096 _c4dbgpf(
"annotations pending, skip indentation up to {}!", to_skip);
4097 _maybe_skipchars_up_to(
' ', to_skip);
4104 template<
class EventHandler>
4105 bool ParseEngine<EventHandler>::_annotations_require_key_container()
const
4107 return m_pending_tags.num_entries > 1 || m_pending_anchors.num_entries > 1;
4110 template<
class EventHandler>
4111 void ParseEngine<EventHandler>::_check_tag(csubstr tag)
4113 if(!tag.begins_with(
"!<"))
4115 if(C4_UNLIKELY(tag.first_of(
"[]{},") !=
npos))
4116 _RYML_CB_ERR_(m_evt_handler->m_stack.m_callbacks,
"tags must not contain any of '[]{},'",
m_state->pos);
4120 if(C4_UNLIKELY(!tag.ends_with(
'>')))
4121 _RYML_CB_ERR_(m_evt_handler->m_stack.m_callbacks,
"malformed tag",
m_state->pos);
4125 template<
class EventHandler>
4126 void ParseEngine<EventHandler>::_handle_annotations_before_blck_key_scalar()
4128 _c4dbgpf(
"annotations_before_blck_key_scalar, node={}",
m_state->node_id);
4129 if(m_pending_tags.num_entries)
4131 _c4dbgpf(
"annotations_before_blck_key_scalar, #tags={}", m_pending_tags.num_entries);
4132 if(C4_LIKELY(m_pending_tags.num_entries == 1))
4134 _check_tag(m_pending_tags.annotations[0].str);
4135 m_evt_handler->set_key_tag(m_pending_tags.annotations[0].str);
4136 _clear_annotations(&m_pending_tags);
4140 _c4err(
"too many tags");
4143 if(m_pending_anchors.num_entries)
4145 _c4dbgpf(
"annotations_before_blck_key_scalar, #anchors={}", m_pending_anchors.num_entries);
4146 if(C4_LIKELY(m_pending_anchors.num_entries == 1))
4148 m_evt_handler->set_key_anchor(m_pending_anchors.annotations[0].str);
4149 _clear_annotations(&m_pending_anchors);
4153 _c4err(
"too many anchors");
4158 template<
class EventHandler>
4159 void ParseEngine<EventHandler>::_handle_annotations_before_blck_val_scalar()
4161 _c4dbgpf(
"annotations_before_blck_val_scalar, node={}",
m_state->node_id);
4162 if(m_pending_tags.num_entries)
4164 _c4dbgpf(
"annotations_before_blck_val_scalar, #tags={}", m_pending_tags.num_entries);
4165 if(C4_LIKELY(m_pending_tags.num_entries == 1))
4167 _check_tag(m_pending_tags.annotations[0].str);
4168 m_evt_handler->set_val_tag(m_pending_tags.annotations[0].str);
4169 _clear_annotations(&m_pending_tags);
4173 _c4err(
"too many tags");
4176 if(m_pending_anchors.num_entries)
4178 _c4dbgpf(
"annotations_before_blck_val_scalar, #anchors={}", m_pending_anchors.num_entries);
4179 if(C4_LIKELY(m_pending_anchors.num_entries == 1))
4181 m_evt_handler->set_val_anchor(m_pending_anchors.annotations[0].str);
4182 _clear_annotations(&m_pending_anchors);
4186 _c4err(
"too many anchors");
4191 template<
class EventHandler>
4192 void ParseEngine<EventHandler>::_handle_annotations_before_start_mapblck(
size_t current_line)
4194 _c4dbgpf(
"annotations_before_start_mapblck, current_line={}", current_line);
4195 if(m_pending_tags.num_entries == 2)
4197 _c4dbgp(
"2 tags, setting entry 0");
4198 _check_tag(m_pending_tags.annotations[0].str);
4199 m_evt_handler->set_val_tag(m_pending_tags.annotations[0].str);
4201 else if(m_pending_tags.num_entries == 1)
4203 _c4dbgpf(
"1 tag. line={}, curr={}", m_pending_tags.annotations[0].line);
4204 if(m_pending_tags.annotations[0].line < current_line)
4206 _c4dbgp(
"...tag is for the map. setting it.");
4207 _check_tag(m_pending_tags.annotations[0].str);
4208 m_evt_handler->set_val_tag(m_pending_tags.annotations[0].str);
4209 _clear_annotations(&m_pending_tags);
4213 if(m_pending_anchors.num_entries == 2)
4215 _c4dbgp(
"2 anchors, setting entry 0");
4216 m_evt_handler->set_val_anchor(m_pending_anchors.annotations[0].str);
4218 else if(m_pending_anchors.num_entries == 1)
4220 _c4dbgpf(
"1 anchor. line={}, curr={}", m_pending_anchors.annotations[0].line);
4221 if(m_pending_anchors.annotations[0].line < current_line)
4223 _c4dbgp(
"...anchor is for the map. setting it.");
4224 m_evt_handler->set_val_anchor(m_pending_anchors.annotations[0].str);
4225 _clear_annotations(&m_pending_anchors);
4230 template<
class EventHandler>
4231 void ParseEngine<EventHandler>::_handle_annotations_before_start_mapblck_as_key()
4233 _c4dbgp(
"annotations_before_start_mapblck_as_key");
4234 if(m_pending_tags.num_entries == 2)
4236 _check_tag(m_pending_tags.annotations[0].str);
4237 m_evt_handler->set_key_tag(m_pending_tags.annotations[0].str);
4239 if(m_pending_anchors.num_entries == 2)
4241 m_evt_handler->set_key_anchor(m_pending_anchors.annotations[0].str);
4245 template<
class EventHandler>
4246 void ParseEngine<EventHandler>::_handle_annotations_and_indentation_after_start_mapblck(
size_t key_indentation,
size_t key_line)
4248 _c4dbgp(
"annotations_after_start_mapblck");
4249 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, m_pending_tags.num_entries <= 2);
4250 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, m_pending_anchors.num_entries <= 2);
4251 if(m_pending_anchors.num_entries || m_pending_tags.num_entries)
4253 key_indentation = _select_indentation_from_annotations(key_indentation, key_line);
4254 switch(m_pending_tags.num_entries)
4257 _check_tag(m_pending_tags.annotations[0].str);
4258 m_evt_handler->set_key_tag(m_pending_tags.annotations[0].str);
4259 _clear_annotations(&m_pending_tags);
4262 _check_tag(m_pending_tags.annotations[1].str);
4263 m_evt_handler->set_key_tag(m_pending_tags.annotations[1].str);
4264 _clear_annotations(&m_pending_tags);
4267 switch(m_pending_anchors.num_entries)
4270 m_evt_handler->set_key_anchor(m_pending_anchors.annotations[0].str);
4271 _clear_annotations(&m_pending_anchors);
4274 m_evt_handler->set_key_anchor(m_pending_anchors.annotations[1].str);
4275 _clear_annotations(&m_pending_anchors);
4279 _set_indentation(key_indentation);
4282 template<
class EventHandler>
4283 size_t ParseEngine<EventHandler>::_select_indentation_from_annotations(
size_t val_indentation,
size_t val_line)
4285 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, m_pending_tags.num_entries || m_pending_anchors.num_entries);
4287 auto const *C4_RESTRICT curr = m_pending_anchors.num_entries ? &m_pending_anchors.annotations[0] : &m_pending_tags.annotations[0];
4288 for(
size_t i = 0; i < m_pending_anchors.num_entries; ++i)
4290 auto const& C4_RESTRICT ann = m_pending_anchors.annotations[i];
4291 if(ann.line > curr->line)
4293 else if(ann.indentation < curr->indentation)
4296 for(
size_t j = 0; j < m_pending_tags.num_entries; ++j)
4298 auto const& C4_RESTRICT ann = m_pending_tags.annotations[j];
4299 if(ann.line > curr->line)
4301 else if(ann.indentation < curr->indentation)
4304 return curr->line < val_line ? val_indentation : curr->indentation;
4307 template<
class EventHandler>
4308 void ParseEngine<EventHandler>::_handle_directive(csubstr rem)
4310 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, rem.is_sub(
m_state->line_contents.rem));
4311 const size_t pos = rem.find(
'#');
4312 _c4dbgpf(
"handle_directive: pos={} rem={}", pos, rem);
4315 m_evt_handler->add_directive(rem);
4316 _line_progressed(rem.len);
4320 csubstr to_comment = rem.first(pos);
4321 csubstr trimmed = to_comment.trimr(
" \t");
4322 m_evt_handler->add_directive(trimmed);
4323 _line_progressed(pos);
4331 template<
class EventHandler>
4332 void ParseEngine<EventHandler>::_handle_seq_json()
4335 _c4dbgpf(
"handle2_seq_json: node_id={} level={} indentation={}",
m_state->node_id,
m_state->level,
m_state->indref);
4337 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
RKEY));
4338 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_all(
RSEQ));
4339 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_all(
FLOW));
4340 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_any(
RVAL|
RNXT));
4341 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_all(
RVAL) != has_all(
RNXT));
4343 _handle_flow_skip_whitespace();
4344 csubstr rem =
m_state->line_contents.rem;
4350 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
RNXT));
4351 const char first = rem.str[0];
4352 _c4dbgpf(
"mapjson[RVAL]: '{}'", first);
4357 _c4dbgp(
"seqjson[RVAL]: scanning double-quoted scalar");
4358 ScannedScalar sc = _scan_scalar_dquot();
4359 csubstr maybe_filtered = _maybe_filter_val_scalar_dquot(sc);
4360 m_evt_handler->set_val_scalar_dquoted(maybe_filtered);
4366 _c4dbgp(
"seqjson[RVAL]: start child seqjson");
4368 m_evt_handler->begin_seq_val_flow();
4370 _line_progressed(1);
4375 _c4dbgp(
"seqjson[RVAL]: start child mapjson");
4377 m_evt_handler->begin_map_val_flow();
4379 _line_progressed(1);
4380 goto seqjson_finish;
4384 _c4dbgp(
"seqjson[RVAL]: end!");
4386 m_evt_handler->end_seq();
4387 _line_progressed(1);
4389 goto seqjson_finish;
4395 if(_scan_scalar_seq_json(&sc))
4397 _c4dbgp(
"seqjson[RVAL]: it's a plain scalar.");
4398 csubstr maybe_filtered = _maybe_filter_val_scalar_plain(sc,
m_state->indref);
4399 m_evt_handler->set_val_scalar_plain(maybe_filtered);
4404 _c4err(
"parse error");
4411 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_any(
RNXT));
4412 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
RVAL));
4413 const char first = rem.str[0];
4414 _c4dbgpf(
"mapjson[RNXT]: '{}'", first);
4419 _c4dbgp(
"seqjson[RNXT]: expect next val");
4421 m_evt_handler->add_sibling();
4422 _line_progressed(1);
4427 _c4dbgp(
"seqjson[RNXT]: end!");
4428 m_evt_handler->end_seq();
4429 _line_progressed(1);
4430 goto seqjson_finish;
4433 _c4err(
"parse error");
4438 _c4dbgt(
"seqjson: go again", 0);
4439 if(_finished_line())
4441 if(C4_LIKELY(!_finished_file()))
4449 _c4err(
"missing terminating ]");
4455 _c4dbgp(
"seqjson: finish");
4461 template<
class EventHandler>
4462 void ParseEngine<EventHandler>::_handle_map_json()
4465 _c4dbgpf(
"handle2_map_json: node_id={} level={} indentation={}",
m_state->node_id,
m_state->level,
m_state->indref);
4467 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_all(
RMAP));
4468 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_all(
FLOW));
4469 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
QMRK));
4470 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_any(
RKEY|
RKCL|
RVAL|
RNXT));
4471 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, 1 == (has_any(
RKEY) + has_any(
RKCL) + has_any(
RVAL) + has_any(
RNXT)));
4473 _handle_flow_skip_whitespace();
4474 csubstr rem =
m_state->line_contents.rem;
4480 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
RKCL));
4481 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
RVAL));
4482 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
RNXT));
4483 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
QMRK));
4484 const char first = rem.str[0];
4485 _c4dbgpf(
"mapjson[RKEY]: '{}'", first);
4490 _c4dbgp(
"mapjson[RKEY]: scanning double-quoted scalar");
4491 ScannedScalar sc = _scan_scalar_dquot();
4492 csubstr maybe_filtered = _maybe_filter_key_scalar_dquot(sc);
4493 m_evt_handler->set_key_scalar_dquoted(maybe_filtered);
4499 _c4dbgp(
"mapjson[RKEY]: end!");
4500 m_evt_handler->end_map();
4501 _line_progressed(1);
4502 goto mapjson_finish;
4505 _c4err(
"parse error");
4508 else if(has_any(
RVAL))
4510 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
RKEY));
4511 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
RKCL));
4512 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
RNXT));
4513 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
QMRK));
4514 const char first = rem.str[0];
4515 _c4dbgpf(
"mapjson[RVAL]: '{}'", first);
4520 _c4dbgp(
"mapjson[RVAL]: scanning double-quoted scalar");
4521 ScannedScalar sc = _scan_scalar_dquot();
4522 csubstr maybe_filtered = _maybe_filter_val_scalar_dquot(sc);
4523 m_evt_handler->set_val_scalar_dquoted(maybe_filtered);
4529 _c4dbgp(
"mapjson[RVAL]: start val seqjson");
4531 m_evt_handler->begin_seq_val_flow();
4532 _set_indentation(m_evt_handler->m_parent->indref);
4534 _line_progressed(1);
4535 goto mapjson_finish;
4539 _c4dbgp(
"mapjson[RVAL]: start val mapjson");
4541 m_evt_handler->begin_map_val_flow();
4542 _set_indentation(m_evt_handler->m_parent->indref);
4544 _line_progressed(1);
4551 if(_scan_scalar_map_json(&sc))
4553 _c4dbgp(
"mapjson[RVAL]: plain scalar.");
4554 csubstr maybe_filtered = _maybe_filter_val_scalar_plain(sc,
m_state->indref);
4555 m_evt_handler->set_val_scalar_plain(maybe_filtered);
4560 _c4err(
"parse error");
4566 else if(has_any(
RKCL))
4568 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
RKEY));
4569 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
RVAL));
4570 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
RNXT));
4571 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
QMRK));
4572 const char first = rem.str[0];
4573 _c4dbgpf(
"mapjson[RKCL]: '{}'", first);
4576 _c4dbgp(
"mapjson[RKCL]: found the colon");
4578 _line_progressed(1);
4582 _c4err(
"parse error");
4585 else if(has_any(
RNXT))
4587 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
RKEY));
4588 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
RKCL));
4589 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
RVAL));
4590 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
QMRK));
4591 _c4dbgpf(
"mapjson[RNXT]: '{}'", rem.str[0]);
4592 if(rem.begins_with(
','))
4594 _c4dbgp(
"mapjson[RNXT]: expect next keyval");
4595 m_evt_handler->add_sibling();
4597 _line_progressed(1);
4599 else if(rem.begins_with(
'}'))
4601 _c4dbgp(
"mapjson[RNXT]: end!");
4602 m_evt_handler->end_map();
4603 _line_progressed(1);
4604 goto mapjson_finish;
4608 _c4err(
"parse error");
4613 _c4dbgt(
"mapjson: go again", 0);
4614 if(_finished_line())
4616 if(C4_LIKELY(!_finished_file()))
4624 _c4err(
"missing terminating }");
4630 _c4dbgp(
"mapjson: finish");
4636 template<
class EventHandler>
4637 void ParseEngine<EventHandler>::_handle_seq_imap()
4640 _c4dbgpf(
"handle2_seq_imap: node_id={} level={} indref={}",
m_state->node_id,
m_state->level,
m_state->indref);
4642 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_all(
RSEQIMAP));
4643 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
RKEY));
4644 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_any(
RVAL|
RNXT|
QMRK|
RKCL));
4645 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, 1 == has_all(
RVAL) + has_all(
RNXT) + has_all(
QMRK) + has_all(
RKCL));
4646 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, m_evt_handler->m_stack.size() >= 3);
4648 _handle_flow_skip_whitespace();
4649 csubstr rem =
m_state->line_contents.rem;
4655 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_any(
RVAL));
4656 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
RNXT));
4657 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
QMRK));
4658 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
RKCL));
4659 const char first = rem.str[0];
4660 _c4dbgpf(
"seqimap[RVAL]: '{}'", _c4prc(first));
4664 _c4dbgp(
"seqimap[RVAL]: scanning single-quoted scalar");
4665 sc = _scan_scalar_squot();
4666 csubstr maybe_filtered = _maybe_filter_val_scalar_squot(sc);
4667 m_evt_handler->set_val_scalar_squoted(maybe_filtered);
4668 m_evt_handler->end_map();
4669 goto seqimap_finish;
4671 else if(first ==
'"')
4673 _c4dbgp(
"seqimap[RVAL]: scanning double-quoted scalar");
4674 sc = _scan_scalar_dquot();
4675 csubstr maybe_filtered = _maybe_filter_val_scalar_dquot(sc);
4676 m_evt_handler->set_val_scalar_dquoted(maybe_filtered);
4677 m_evt_handler->end_map();
4678 goto seqimap_finish;
4681 else if(_scan_scalar_plain_map_flow(&sc))
4683 _c4dbgp(
"seqimap[RVAL]: it's a scalar.");
4684 csubstr maybe_filtered = _maybe_filter_val_scalar_plain(sc,
m_state->indref);
4685 m_evt_handler->set_val_scalar_plain(maybe_filtered);
4686 m_evt_handler->end_map();
4687 goto seqimap_finish;
4689 else if(first ==
'[')
4691 _c4dbgp(
"seqimap[RVAL]: start child seqflow");
4693 m_evt_handler->begin_seq_val_flow();
4695 _set_indentation(m_evt_handler->m_parent->indref);
4696 _line_progressed(1);
4697 goto seqimap_finish;
4699 else if(first ==
'{')
4701 _c4dbgp(
"seqimap[RVAL]: start child mapflow");
4703 m_evt_handler->begin_map_val_flow();
4705 _set_indentation(m_evt_handler->m_parent->indref);
4706 _line_progressed(1);
4707 goto seqimap_finish;
4709 else if(first ==
',' || first ==
']')
4711 _c4dbgp(
"seqimap[RVAL]: finish without val.");
4712 m_evt_handler->set_val_scalar_plain({});
4713 m_evt_handler->end_map();
4714 goto seqimap_finish;
4716 else if(first ==
'&')
4718 csubstr anchor = _scan_anchor();
4719 _c4dbgp(
"seqimap[RVAL]: anchor!");
4720 m_evt_handler->set_val_anchor(anchor);
4722 else if(first ==
'*')
4724 csubstr ref = _scan_ref_seq();
4725 _c4dbgp(
"seqimap[RVAL]: ref!");
4726 m_evt_handler->set_val_ref(ref);
4731 _c4err(
"parse error");
4734 else if(has_any(
RNXT))
4736 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_any(
RNXT));
4737 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
RVAL));
4738 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
QMRK));
4739 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
RKCL));
4740 const char first = rem.str[0];
4741 _c4dbgpf(
"seqimap[RNXT]: '{}'", _c4prc(first));
4742 if(first ==
',' || first ==
']')
4746 _c4dbgp(
"seqimap: done");
4747 m_evt_handler->end_map();
4748 goto seqimap_finish;
4752 _c4err(
"parse error");
4755 else if(has_any(
QMRK))
4757 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_any(
QMRK));
4758 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
RVAL));
4759 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
RNXT));
4760 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
RKCL));
4761 const char first = rem.str[0];
4762 _c4dbgpf(
"seqimap[QMRK]: '{}'", _c4prc(first));
4766 _c4dbgp(
"seqimap[QMRK]: scanning single-quoted scalar");
4767 sc = _scan_scalar_squot();
4768 csubstr maybe_filtered = _maybe_filter_key_scalar_squot(sc);
4769 m_evt_handler->set_key_scalar_squoted(maybe_filtered);
4773 else if(first ==
'"')
4775 _c4dbgp(
"seqimap[QMRK]: scanning double-quoted scalar");
4776 sc = _scan_scalar_dquot();
4777 csubstr maybe_filtered = _maybe_filter_key_scalar_dquot(sc);
4778 m_evt_handler->set_key_scalar_dquoted(maybe_filtered);
4783 else if(_scan_scalar_plain_map_flow(&sc))
4785 _c4dbgp(
"seqimap[QMRK]: it's a scalar.");
4786 csubstr maybe_filtered = _maybe_filter_key_scalar_plain(sc,
m_state->indref);
4787 m_evt_handler->set_key_scalar_plain(maybe_filtered);
4791 else if(first ==
'[')
4793 _c4dbgp(
"seqimap[QMRK]: start child seqflow");
4795 m_evt_handler->begin_seq_key_flow();
4797 _set_indentation(m_evt_handler->m_parent->indref);
4798 _line_progressed(1);
4799 goto seqimap_finish;
4801 else if(first ==
'{')
4803 _c4dbgp(
"seqimap[QMRK]: start child mapflow");
4805 m_evt_handler->begin_map_key_flow();
4807 _set_indentation(m_evt_handler->m_parent->indref);
4808 _line_progressed(1);
4809 goto seqimap_finish;
4811 else if(first ==
',' || first ==
']')
4813 _c4dbgp(
"seqimap[QMRK]: finish without key.");
4814 m_evt_handler->set_key_scalar_plain({});
4815 m_evt_handler->set_val_scalar_plain({});
4816 m_evt_handler->end_map();
4817 goto seqimap_finish;
4819 else if(first ==
'&')
4821 csubstr anchor = _scan_anchor();
4822 _c4dbgp(
"seqimap[QMRK]: anchor!");
4823 m_evt_handler->set_key_anchor(anchor);
4825 else if(first ==
'*')
4827 csubstr ref = _scan_ref_seq();
4828 _c4dbgp(
"seqimap[QMRK]: ref!");
4829 m_evt_handler->set_key_ref(ref);
4834 _c4err(
"parse error");
4837 else if(has_any(
RKCL))
4839 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
RVAL));
4840 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
RNXT));
4841 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
QMRK));
4842 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_any(
RKCL));
4843 const char first = rem.str[0];
4844 _c4dbgpf(
"seqimap[RKCL]: '{}'", _c4prc(first));
4847 _c4dbgp(
"seqimap[RKCL]: found ':'");
4849 _line_progressed(1);
4852 else if(first ==
',' || first ==
']')
4854 _c4dbgp(
"seqimap[RKCL]: found ','. finish without val");
4855 m_evt_handler->set_val_scalar_plain({});
4856 m_evt_handler->end_map();
4857 goto seqimap_finish;
4861 _c4err(
"parse error");
4866 _c4dbgt(
"seqimap: go again", 0);
4867 if(_finished_line())
4869 if(C4_LIKELY(!_finished_file()))
4877 _c4err(
"parse error");
4883 _c4dbgp(
"seqimap: finish");
4889 template<
class EventHandler>
4890 void ParseEngine<EventHandler>::_handle_seq_flow()
4893 _c4dbgpf(
"handle2_seq_flow: node_id={} level={} indentation={}",
m_state->node_id,
m_state->level,
m_state->indref);
4895 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
RKEY));
4896 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_all(
RSEQ));
4897 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_all(
FLOW));
4898 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_any(
RVAL|
RNXT));
4899 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_all(
RVAL) != has_all(
RNXT));
4900 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks,
m_state->indref !=
npos);
4902 _handle_flow_skip_whitespace();
4903 csubstr rem =
m_state->line_contents.rem;
4909 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
RNXT));
4910 const char first = rem.str[0];
4914 _c4dbgp(
"seqflow[RVAL]: scanning single-quoted scalar");
4915 sc = _scan_scalar_squot();
4916 csubstr maybe_filtered = _maybe_filter_val_scalar_squot(sc);
4917 m_evt_handler->set_val_scalar_squoted(maybe_filtered);
4920 else if(first ==
'"')
4922 _c4dbgp(
"seqflow[RVAL]: scanning double-quoted scalar");
4923 sc = _scan_scalar_dquot();
4924 csubstr maybe_filtered = _maybe_filter_val_scalar_dquot(sc);
4925 m_evt_handler->set_val_scalar_dquoted(maybe_filtered);
4929 else if(_scan_scalar_plain_seq_flow(&sc))
4931 _c4dbgp(
"seqflow[RVAL]: it's a scalar.");
4932 csubstr maybe_filtered = _maybe_filter_val_scalar_plain(sc,
m_state->indref);
4933 m_evt_handler->set_val_scalar_plain(maybe_filtered);
4936 else if(first ==
'[')
4938 _c4dbgp(
"seqflow[RVAL]: start child seqflow");
4940 m_evt_handler->begin_seq_val_flow();
4941 _set_indentation(m_evt_handler->m_parent->indref);
4943 _line_progressed(1);
4945 else if(first ==
'{')
4947 _c4dbgp(
"seqflow[RVAL]: start child mapflow");
4949 m_evt_handler->begin_map_val_flow();
4950 _set_indentation(m_evt_handler->m_parent->indref);
4952 _line_progressed(1);
4953 goto seqflow_finish;
4955 else if(first ==
']')
4957 _c4dbgp(
"seqflow[RVAL]: end!");
4958 _line_progressed(1);
4959 m_evt_handler->end_seq();
4960 goto seqflow_finish;
4962 else if(first ==
'*')
4964 csubstr ref = _scan_ref_seq();
4965 _c4dbgpf(
"seqflow[RVAL]: ref! [{}]~~~{}~~~", ref.len, ref);
4966 m_evt_handler->set_val_ref(ref);
4969 else if(first ==
'&')
4971 csubstr anchor = _scan_anchor();
4972 _c4dbgpf(
"seqflow[RVAL]: anchor! [{}]~~~{}~~~", anchor.len, anchor);
4973 m_evt_handler->set_val_anchor(anchor);
4974 if(_maybe_scan_following_comma())
4976 _c4dbgp(
"seqflow[RVAL]: empty scalar!");
4977 m_evt_handler->set_val_scalar_plain({});
4978 m_evt_handler->add_sibling();
4981 else if(first ==
'!')
4983 csubstr tag = _scan_tag();
4984 _c4dbgpf(
"seqflow[RVAL]: tag! [{}]~~~{}~~~", tag.len, tag);
4986 m_evt_handler->set_val_tag(tag);
4987 if(_maybe_scan_following_comma())
4989 _c4dbgp(
"seqflow[RVAL]: empty scalar!");
4990 m_evt_handler->set_val_scalar_plain({});
4991 m_evt_handler->add_sibling();
4994 else if(first ==
':')
4996 _c4dbgpf(
"seqflow[RVAL]: actually seqimap at node[{}], with empty key",
m_state->node_id);
4998 m_evt_handler->begin_map_val_flow();
4999 _set_indentation(m_evt_handler->m_parent->indref);
5000 m_evt_handler->set_key_scalar_plain({});
5002 _line_progressed(1);
5003 goto seqflow_finish;
5005 else if(first ==
'?')
5007 _c4dbgp(
"seqflow[RVAL]: start child mapflow, explicit key");
5009 m_was_inside_qmrk =
true;
5010 m_evt_handler->begin_map_val_flow();
5011 _set_indentation(m_evt_handler->m_parent->indref);
5013 _line_progressed(1);
5014 _maybe_skip_whitespace_tokens();
5015 goto seqflow_finish;
5019 _c4err(
"parse error");
5024 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_any(
RNXT));
5025 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
RVAL));
5026 const char first = rem.str[0];
5029 _c4dbgp(
"seqflow[RNXT]: expect next val");
5031 m_evt_handler->add_sibling();
5032 _line_progressed(1);
5034 else if(first ==
']')
5036 _c4dbgp(
"seqflow[RNXT]: end!");
5037 m_evt_handler->end_seq();
5038 _line_progressed(1);
5039 goto seqflow_finish;
5041 else if(first ==
':')
5043 _c4dbgpf(
"seqflow[RNXT]: actually seqimap at node[{}]",
m_state->node_id);
5044 m_evt_handler->actually_val_is_first_key_of_new_map_flow();
5045 _set_indentation(m_evt_handler->m_parent->indref);
5046 _line_progressed(1);
5048 goto seqflow_finish;
5052 _c4err(
"parse error");
5057 _c4dbgt(
"seqflow: go again", 0);
5058 if(_finished_line())
5060 if(C4_LIKELY(!_finished_file()))
5068 _c4err(
"missing terminating ]");
5074 _c4dbgp(
"seqflow: finish");
5080 template<
class EventHandler>
5081 void ParseEngine<EventHandler>::_handle_map_flow()
5084 _c4dbgpf(
"handle2_map_flow: node_id={} level={} indentation={}",
m_state->node_id,
m_state->level,
m_state->indref);
5086 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_all(
RMAP));
5087 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_all(
FLOW));
5089 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, 1 == (has_any(
RKEY) + has_any(
RKCL) + has_any(
RVAL) + has_any(
RNXT) + has_any(
QMRK)));
5091 _handle_flow_skip_whitespace();
5092 csubstr rem =
m_state->line_contents.rem;
5098 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
RKCL));
5099 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
RVAL));
5100 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
RNXT));
5101 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
QMRK));
5102 const char first = rem.str[0];
5103 _c4dbgpf(
"mapflow[RKEY]: '{}'", first);
5107 _c4dbgp(
"mapflow[RKEY]: scanning single-quoted scalar");
5108 sc = _scan_scalar_squot();
5109 csubstr maybe_filtered = _maybe_filter_key_scalar_squot(sc);
5110 m_evt_handler->set_key_scalar_squoted(maybe_filtered);
5113 else if(first ==
'"')
5115 _c4dbgp(
"mapflow[RKEY]: scanning double-quoted scalar");
5116 sc = _scan_scalar_dquot();
5117 csubstr maybe_filtered = _maybe_filter_key_scalar_dquot(sc);
5118 m_evt_handler->set_key_scalar_dquoted(maybe_filtered);
5122 else if(_scan_scalar_plain_map_flow(&sc))
5124 _c4dbgp(
"mapflow[RKEY]: plain scalar");
5125 csubstr maybe_filtered = _maybe_filter_key_scalar_plain(sc,
m_state->indref);
5126 m_evt_handler->set_key_scalar_plain(maybe_filtered);
5129 else if(first ==
'?')
5131 _c4dbgp(
"mapflow[RKEY]: explicit key");
5132 _line_progressed(1);
5134 _maybe_skip_whitespace_tokens();
5136 else if(first ==
':')
5138 _c4dbgp(
"mapflow[RKEY]: setting empty key");
5139 m_evt_handler->set_key_scalar_plain({});
5141 _line_progressed(1);
5142 _maybe_skip_whitespace_tokens();
5144 else if(first ==
'}')
5146 _c4dbgp(
"mapflow[RKEY]: end!");
5147 m_evt_handler->end_map();
5148 _line_progressed(1);
5149 goto mapflow_finish;
5151 else if(first ==
'&')
5153 csubstr anchor = _scan_anchor();
5154 _c4dbgpf(
"mapflow[RKEY]: key anchor! [{}]~~~{}~~~", anchor.len, anchor);
5155 m_evt_handler->set_key_anchor(anchor);
5157 else if(first ==
'*')
5159 csubstr ref = _scan_ref_map();
5160 _c4dbgpf(
"mapflow[RKEY]: key ref! [{}]~~~{}~~~", ref.len, ref);
5161 m_evt_handler->set_key_ref(ref);
5164 else if(first ==
'[')
5169 _c4dbgp(
"mapflow[RKEY]: start child seqflow (!)");
5171 m_evt_handler->begin_seq_key_flow();
5173 _set_indentation(m_evt_handler->m_parent->indref);
5174 _line_progressed(1);
5175 goto mapflow_finish;
5177 else if(first ==
'{')
5182 _c4dbgp(
"mapflow[RKEY]: start child mapflow (!)");
5184 m_evt_handler->begin_map_key_flow();
5186 _set_indentation(m_evt_handler->m_parent->indref);
5187 _line_progressed(1);
5190 else if(first ==
'!')
5192 csubstr tag = _scan_tag();
5193 _c4dbgpf(
"mapflow[RKEY]: tag! [{}]~~~{}~~~", tag.len, tag);
5195 m_evt_handler->set_key_tag(tag);
5199 _c4err(
"parse error");
5202 else if(has_any(
RKCL))
5204 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
RKEY));
5205 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
RVAL));
5206 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
RNXT));
5207 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
QMRK));
5208 const char first = rem.str[0];
5209 _c4dbgpf(
"mapflow[RKCL]: '{}'", first);
5212 _c4dbgp(
"mapflow[RKCL]: found the colon");
5214 _line_progressed(1);
5216 else if(first ==
'}')
5218 _c4dbgp(
"mapflow[RKCL]: end with missing val!");
5220 m_evt_handler->set_val_scalar_plain({});
5221 m_evt_handler->end_map();
5222 _line_progressed(1);
5223 goto mapflow_finish;
5225 else if(first ==
',')
5227 _c4dbgp(
"mapflow[RKCL]: got comma. val is missing");
5228 m_evt_handler->set_val_scalar_plain({});
5229 m_evt_handler->add_sibling();
5231 _line_progressed(1);
5235 _c4err(
"parse error");
5238 else if(has_any(
RVAL))
5240 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
RKEY));
5241 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
RKCL));
5242 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
RNXT));
5243 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
QMRK));
5244 const char first = rem.str[0];
5245 _c4dbgpf(
"mapflow[RVAL]: '{}'", first);
5249 _c4dbgp(
"mapflow[RVAL]: scanning single-quoted scalar");
5250 sc = _scan_scalar_squot();
5251 csubstr maybe_filtered = _maybe_filter_val_scalar_squot(sc);
5252 m_evt_handler->set_val_scalar_squoted(maybe_filtered);
5255 else if(first ==
'"')
5257 _c4dbgp(
"mapflow[RVAL]: scanning double-quoted scalar");
5258 sc = _scan_scalar_dquot();
5259 csubstr maybe_filtered = _maybe_filter_val_scalar_dquot(sc);
5260 m_evt_handler->set_val_scalar_dquoted(maybe_filtered);
5264 else if(_scan_scalar_plain_map_flow(&sc))
5266 _c4dbgp(
"mapflow[RVAL]: plain scalar.");
5267 csubstr maybe_filtered = _maybe_filter_val_scalar_plain(sc,
m_state->indref);
5268 m_evt_handler->set_val_scalar_plain(maybe_filtered);
5271 else if(first ==
'[')
5273 _c4dbgp(
"mapflow[RVAL]: start val seqflow");
5275 m_evt_handler->begin_seq_val_flow();
5276 _set_indentation(m_evt_handler->m_parent->indref);
5278 _line_progressed(1);
5279 goto mapflow_finish;
5281 else if(first ==
'{')
5283 _c4dbgp(
"mapflow[RVAL]: start val mapflow");
5285 m_evt_handler->begin_map_val_flow();
5286 _set_indentation(m_evt_handler->m_parent->indref);
5288 _line_progressed(1);
5291 else if(first ==
'}')
5293 _c4dbgp(
"mapflow[RVAL]: end!");
5294 m_evt_handler->set_val_scalar_plain({});
5295 m_evt_handler->end_map();
5296 _line_progressed(1);
5297 goto mapflow_finish;
5299 else if(first ==
'*')
5301 csubstr ref = _scan_ref_map();
5302 _c4dbgpf(
"mapflow[RVAL]: key ref! [{}]~~~{}~~~", ref.len, ref);
5303 m_evt_handler->set_val_ref(ref);
5306 else if(first ==
'&')
5308 csubstr anchor = _scan_anchor();
5309 _c4dbgpf(
"mapflow[RVAL]: key anchor! [{}]~~~{}~~~", anchor.len, anchor);
5310 m_evt_handler->set_val_anchor(anchor);
5312 else if(first ==
'!')
5314 csubstr tag = _scan_tag();
5315 _c4dbgpf(
"mapflow[RVAL]: tag! [{}]~~~{}~~~", tag.len, tag);
5317 m_evt_handler->set_val_tag(tag);
5321 _c4err(
"parse error");
5324 else if(has_any(
RNXT))
5326 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
RKEY));
5327 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
RKCL));
5328 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
RVAL));
5329 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
QMRK));
5330 _c4dbgpf(
"mapflow[RNXT]: '{}'", rem.str[0]);
5331 if(rem.begins_with(
','))
5333 _c4dbgp(
"mapflow[RNXT]: expect next keyval");
5334 m_evt_handler->add_sibling();
5336 _line_progressed(1);
5338 else if(rem.begins_with(
'}'))
5340 _c4dbgp(
"mapflow[RNXT]: end!");
5341 m_evt_handler->end_map();
5342 _line_progressed(1);
5343 goto mapflow_finish;
5347 _c4err(
"parse error");
5350 else if(has_any(
QMRK))
5352 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
RKEY));
5353 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
RKCL));
5354 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
RVAL));
5355 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
RNXT));
5356 const char first = rem.str[0];
5357 _c4dbgpf(
"mapflow[QMRK]: '{}'", first);
5361 _c4dbgp(
"mapflow[QMRK]: scanning single-quoted scalar");
5362 sc = _scan_scalar_squot();
5363 csubstr maybe_filtered = _maybe_filter_key_scalar_squot(sc);
5364 m_evt_handler->set_key_scalar_squoted(maybe_filtered);
5367 else if(first ==
'"')
5369 _c4dbgp(
"mapflow[QMRK]: scanning double-quoted scalar");
5370 sc = _scan_scalar_dquot();
5371 csubstr maybe_filtered = _maybe_filter_key_scalar_dquot(sc);
5372 m_evt_handler->set_key_scalar_dquoted(maybe_filtered);
5376 else if(_scan_scalar_plain_map_flow(&sc))
5378 _c4dbgp(
"mapflow[QMRK]: plain scalar");
5379 csubstr maybe_filtered = _maybe_filter_key_scalar_plain(sc,
m_state->indref);
5380 m_evt_handler->set_key_scalar_plain(maybe_filtered);
5383 else if(first ==
':')
5385 _c4dbgp(
"mapflow[QMRK]: setting empty key");
5386 m_evt_handler->set_key_scalar_plain({});
5388 _line_progressed(1);
5389 _maybe_skip_whitespace_tokens();
5391 else if(first ==
'}')
5393 _c4dbgp(
"mapflow[QMRK]: end!");
5394 m_evt_handler->set_key_scalar_plain({});
5395 m_evt_handler->set_val_scalar_plain({});
5396 m_evt_handler->end_map();
5397 _line_progressed(1);
5398 goto mapflow_finish;
5400 else if(first ==
'&')
5402 csubstr anchor = _scan_anchor();
5403 _c4dbgpf(
"mapflow[QMRK]: key anchor! [{}]~~~{}~~~", anchor.len, anchor);
5404 m_evt_handler->set_key_anchor(anchor);
5406 else if(first ==
'*')
5408 csubstr ref = _scan_ref_map();
5409 _c4dbgpf(
"mapflow[QMRK]: key ref! [{}]~~~{}~~~", ref.len, ref);
5410 m_evt_handler->set_key_ref(ref);
5413 else if(first ==
'[')
5418 _c4dbgp(
"mapflow[QMRK]: start child seqflow (!)");
5420 m_evt_handler->begin_seq_key_flow();
5422 _set_indentation(m_evt_handler->m_parent->indref);
5423 _line_progressed(1);
5424 goto mapflow_finish;
5426 else if(first ==
'{')
5431 _c4dbgp(
"mapflow[QMRK]: start child mapflow (!)");
5433 m_evt_handler->begin_map_key_flow();
5434 _set_indentation(m_evt_handler->m_parent->indref);
5436 _line_progressed(1);
5439 else if(first ==
'!')
5441 csubstr tag = _scan_tag();
5442 _c4dbgpf(
"mapflow[QMRK]: tag! [{}]~~~{}~~~", tag.len, tag);
5444 m_evt_handler->set_key_tag(tag);
5448 _c4err(
"parse error");
5453 _c4dbgt(
"mapflow: go again", 0);
5454 if(_finished_line())
5456 if(C4_LIKELY(!_finished_file()))
5464 _c4err(
"missing terminating }");
5470 _c4dbgp(
"mapflow: finish");
5476 template<
class EventHandler>
5477 void ParseEngine<EventHandler>::_handle_seq_block()
5480 _c4dbgpf(
"handle2_seq_block: seq_id={} node_id={} level={} indent={}", m_evt_handler->m_parent->node_id,
m_state->node_id,
m_state->level,
m_state->indref);
5482 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_all(
RSEQ));
5483 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_all(
BLCK));
5484 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_any(
RVAL|
RNXT));
5485 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, 1 == (has_any(
RVAL) + has_any(
RNXT)));
5487 _maybe_skip_comment();
5488 csubstr rem =
m_state->line_contents.rem;
5494 _c4dbgpf(
"seqblck[RVAL]: col={}",
m_state->pos.col);
5495 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
RNXT));
5496 if(
m_state->at_line_beginning())
5498 _c4dbgpf(
"seqblck[RVAL]: indref={} indentation={}",
m_state->indref,
m_state->line_contents.indentation);
5501 _c4dbgpf(
"seqblck[RVAL]: skip {} from indentation",
m_state->line_contents.indentation);
5502 _line_progressed(
m_state->line_contents.indentation);
5503 rem =
m_state->line_contents.rem;
5507 else if(
m_state->indentation_lt())
5509 _c4dbgp(
"seqblck[RVAL]: smaller indentation!");
5510 _handle_indentation_pop_from_block_seq();
5511 goto seqblck_finish;
5513 else if(
m_state->line_contents.indentation ==
npos)
5515 _c4dbgp(
"seqblck[RVAL]: empty line!");
5516 _line_progressed(
m_state->line_contents.rem.len);
5520 #ifdef RYML_NO_COVERAGE__TO_BE_DELETED
5528 if(rem.str[0] ==
' ')
5530 if(_handle_indentation_from_annotations())
5532 _c4dbgp(
"seqblck[RVAL]: annotations!");
5533 rem =
m_state->line_contents.rem;
5540 _RYML_CB_ASSERT(callbacks(), rem.len);
5541 _c4dbgpf(
"seqblck[RVAL]: '{}' node_id={}", rem.str[0],
m_state->node_id);
5542 const char first = rem.str[0];
5543 const size_t startline =
m_state->pos.line;
5546 const size_t startindent =
m_state->line_contents.current_col();
5550 _c4dbgp(
"seqblck[RVAL]: single-quoted scalar");
5551 sc = _scan_scalar_squot();
5552 if(!_maybe_scan_following_colon())
5554 _c4dbgp(
"seqblck[RVAL]: set as val");
5555 _handle_annotations_before_blck_val_scalar();
5556 csubstr maybe_filtered = _maybe_filter_val_scalar_squot(sc);
5557 m_evt_handler->set_val_scalar_squoted(maybe_filtered);
5562 _c4dbgp(
"seqblck[RVAL]: start mapblck, set scalar as key");
5564 _handle_annotations_before_start_mapblck(startline);
5565 m_evt_handler->begin_map_val_block();
5566 _handle_annotations_and_indentation_after_start_mapblck(startindent, startline);
5567 csubstr maybe_filtered = _maybe_filter_key_scalar_squot(sc);
5568 m_evt_handler->set_key_scalar_squoted(maybe_filtered);
5570 _maybe_skip_whitespace_tokens();
5571 goto seqblck_finish;
5574 else if(first ==
'"')
5576 _c4dbgp(
"seqblck[RVAL]: double-quoted scalar");
5577 sc = _scan_scalar_dquot();
5578 if(!_maybe_scan_following_colon())
5580 _c4dbgp(
"seqblck[RVAL]: set as val");
5581 _handle_annotations_before_blck_val_scalar();
5582 csubstr maybe_filtered = _maybe_filter_val_scalar_dquot(sc);
5583 m_evt_handler->set_val_scalar_dquoted(maybe_filtered);
5588 _c4dbgp(
"seqblck[RVAL]: start mapblck, set scalar as key");
5590 _handle_annotations_before_start_mapblck(startline);
5591 m_evt_handler->begin_map_val_block();
5592 _handle_annotations_and_indentation_after_start_mapblck(startindent, startline);
5593 csubstr maybe_filtered = _maybe_filter_key_scalar_dquot(sc);
5594 m_evt_handler->set_key_scalar_dquoted(maybe_filtered);
5596 _maybe_skip_whitespace_tokens();
5597 goto seqblck_finish;
5603 else if(first ==
'|')
5605 _c4dbgp(
"seqblck[RVAL]: block-literal scalar");
5607 _scan_block(&sb,
m_state->indref + 1);
5608 _handle_annotations_before_blck_val_scalar();
5609 csubstr maybe_filtered = _maybe_filter_val_scalar_literal(sb);
5610 m_evt_handler->set_val_scalar_literal(maybe_filtered);
5613 else if(first ==
'>')
5615 _c4dbgp(
"seqblck[RVAL]: block-folded scalar");
5617 _scan_block(&sb,
m_state->indref + 1);
5618 _handle_annotations_before_blck_val_scalar();
5619 csubstr maybe_filtered = _maybe_filter_val_scalar_folded(sb);
5620 m_evt_handler->set_val_scalar_folded(maybe_filtered);
5623 else if(_scan_scalar_plain_seq_blck(&sc))
5625 _c4dbgp(
"seqblck[RVAL]: plain scalar.");
5626 if(!_maybe_scan_following_colon())
5628 _c4dbgp(
"seqblck[RVAL]: set as val");
5629 _handle_annotations_before_blck_val_scalar();
5630 csubstr maybe_filtered = _maybe_filter_val_scalar_plain(sc,
m_state->indref);
5631 m_evt_handler->set_val_scalar_plain(maybe_filtered);
5636 if(startindent >
m_state->indref)
5638 _c4dbgp(
"seqblck[RVAL]: start mapblck, set scalar as key");
5640 _handle_annotations_before_start_mapblck(startline);
5641 m_evt_handler->begin_map_val_block();
5642 _handle_annotations_and_indentation_after_start_mapblck(startindent, startline);
5643 csubstr maybe_filtered = _maybe_filter_key_scalar_plain(sc,
m_state->indref);
5644 m_evt_handler->set_key_scalar_plain(maybe_filtered);
5646 _maybe_skip_whitespace_tokens();
5647 goto seqblck_finish;
5649 else if(m_evt_handler->m_parent && m_evt_handler->m_parent->indref == startindent && has_any(
RMAP|
BLCK, m_evt_handler->m_parent))
5651 _c4dbgp(
"seqblck[RVAL]: empty val + end indentless seq + set key");
5652 m_evt_handler->set_val_scalar_plain({});
5653 m_evt_handler->end_seq();
5654 m_evt_handler->add_sibling();
5655 csubstr maybe_filtered = _maybe_filter_key_scalar_plain(sc,
m_state->indref);
5656 m_evt_handler->set_key_scalar_plain(maybe_filtered);
5658 _maybe_skip_whitespace_tokens();
5659 goto seqblck_finish;
5663 _c4err(
"parse error");
5667 else if(first ==
'[')
5669 _c4dbgp(
"seqblck[RVAL]: start child seqflow");
5671 m_evt_handler->begin_seq_val_flow();
5673 _line_progressed(1);
5674 _set_indentation(m_evt_handler->m_parent->indref + 1u);
5675 goto seqblck_finish;
5677 else if(first ==
'{')
5679 _c4dbgp(
"seqblck[RVAL]: start child mapflow");
5681 _handle_annotations_before_blck_val_scalar();
5682 m_evt_handler->begin_map_val_flow();
5684 _line_progressed(1);
5685 _set_indentation(m_evt_handler->m_parent->indref + 1u);
5686 goto seqblck_finish;
5688 else if(first ==
'-')
5690 if(startindent ==
m_state->indref)
5692 _c4dbgp(
"seqblck[RVAL]: prev val was empty");
5693 _handle_annotations_before_blck_val_scalar();
5694 m_evt_handler->set_val_scalar_plain({});
5696 m_evt_handler->add_sibling();
5700 _c4dbgp(
"seqblck[RVAL]: start child seqblck");
5701 _RYML_CB_ASSERT(this->callbacks(), startindent >
m_state->indref);
5703 _handle_annotations_before_blck_val_scalar();
5704 m_evt_handler->begin_seq_val_block();
5706 _save_indentation();
5709 _line_progressed(1);
5710 _maybe_skip_whitespace_tokens();
5712 else if(first ==
':')
5714 _c4dbgp(
"seqblck[RVAL]: start child mapblck with empty key");
5716 _handle_annotations_before_start_mapblck(startline);
5717 m_evt_handler->begin_map_val_block();
5718 _handle_annotations_and_indentation_after_start_mapblck(startindent, startline);
5719 m_evt_handler->set_key_scalar_plain({});
5721 _line_progressed(1);
5722 _maybe_skip_whitespace_tokens();
5723 goto seqblck_finish;
5725 else if(first ==
'&')
5727 const csubstr anchor = _scan_anchor();
5728 _c4dbgpf(
"seqblck[RVAL]: anchor! [{}]~~~{}~~~", anchor.len, anchor);
5731 _add_annotation(&m_pending_anchors, anchor, startindent, startline);
5733 else if(first ==
'*')
5735 csubstr ref = _scan_ref_seq();
5736 _c4dbgpf(
"seqblck[RVAL]: ref! [{}]~~~{}~~~", ref.len, ref);
5737 if(!_maybe_scan_following_colon())
5739 _c4dbgp(
"seqblck[RVAL]: set ref as val!");
5740 _handle_annotations_before_blck_val_scalar();
5741 m_evt_handler->set_val_ref(ref);
5746 _c4dbgp(
"seqblck[RVAL]: ref is key of map");
5748 _handle_annotations_before_start_mapblck(startline);
5749 m_evt_handler->begin_map_val_block();
5750 _handle_annotations_and_indentation_after_start_mapblck(startindent, startline);
5751 m_evt_handler->set_key_ref(ref);
5753 _set_indentation(startindent);
5754 _maybe_skip_whitespace_tokens();
5755 goto seqblck_finish;
5758 else if(first ==
'!')
5760 csubstr tag = _scan_tag();
5761 _c4dbgpf(
"seqblck[RVAL]: val tag! [{}]~~~{}~~~", tag.len, tag);
5764 _add_annotation(&m_pending_tags, tag, startindent, startline);
5766 else if(first ==
'?')
5768 _c4dbgp(
"seqblck[RVAL]: start child mapblck, explicit key");
5770 m_was_inside_qmrk =
true;
5771 m_evt_handler->begin_map_val_block();
5773 _save_indentation();
5774 _line_progressed(1);
5775 _maybe_skip_whitespace_tokens();
5776 goto seqblck_finish;
5780 _c4err(
"parse error");
5785 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_any(
RNXT));
5786 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
RVAL));
5790 _c4dbgpf(
"seqblck[RNXT]: indref={} indentation={}",
m_state->indref,
m_state->line_contents.indentation);
5791 if(C4_UNLIKELY(!_at_line_begin()))
5792 _c4err(
"parse error");
5795 _c4dbgpf(
"seqblck[RNXT]: skip {} from indref",
m_state->indref);
5796 _line_progressed(
m_state->indref);
5797 _maybe_skip_whitespace_tokens();
5798 rem =
m_state->line_contents.rem;
5802 else if(
m_state->indentation_lt())
5804 _c4dbgp(
"seqblck[RNXT]: smaller indentation!");
5805 _handle_indentation_pop_from_block_seq();
5808 _c4dbgp(
"seqblck[RNXT]: still seqblck!");
5809 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_any(
RNXT));
5810 _line_progressed(
m_state->line_contents.indentation);
5811 rem =
m_state->line_contents.rem;
5817 _c4dbgp(
"seqblck[RNXT]: no longer seqblck!");
5818 goto seqblck_finish;
5821 else if(
m_state->line_contents.indentation ==
npos)
5823 _c4dbgpf(
"seqblck[RNXT]: blank line, len={}",
m_state->line_contents.rem);
5824 _line_progressed(
m_state->line_contents.rem.len);
5825 rem =
m_state->line_contents.rem;
5832 const char first = rem.str[0];
5833 _c4dbgpf(
"seqblck[RNXT]: '{}' node_id={}", first,
m_state->node_id);
5836 if(
m_state->indref > 0 ||
m_state->line_contents.indentation > 0 || !_is_doc_begin_token(rem))
5838 _c4dbgp(
"seqblck[RNXT]: expect next val");
5840 m_evt_handler->add_sibling();
5841 _line_progressed(1);
5842 _maybe_skip_whitespace_tokens();
5846 _c4dbgp(
"seqblck[RNXT]: start doc");
5847 _start_doc_suddenly();
5848 _line_progressed(3);
5849 _maybe_skip_whitespace_tokens();
5850 goto seqblck_finish;
5853 else if(first ==
':')
5859 auto const *C4_RESTRICT prev_state = m_evt_handler->m_parent;
5860 if(C4_LIKELY(prev_state && (prev_state->flags &
RMAP)))
5862 _c4dbgp(
"seqblck[RNXT]: actually this seq was '?' key of parent map");
5863 m_evt_handler->end_seq();
5864 goto seqblck_finish;
5868 _c4err(
"parse error");
5871 else if(first ==
'.')
5873 _c4dbgp(
"seqblck[RNXT]: maybe doc?");
5874 csubstr rs = rem.sub(1);
5875 if(rs ==
".." || rs.begins_with(
".. "))
5877 _c4dbgp(
"seqblck[RNXT]: end+start doc");
5878 _end_doc_suddenly();
5879 _line_progressed(3);
5880 _maybe_skip_whitespace_tokens();
5881 goto seqblck_finish;
5885 _c4err(
"parse error");
5894 for(
auto const& s : m_evt_handler->m_stack)
5896 _dbg_printf(
"state[{}]: ind={} node={} flags={}\n", s.level, s.indref, s.node_id, detail::_parser_flags_to_str(flagbuf_, s.flags));
5899 if(m_evt_handler->m_parent && has_all(
RMAP|
BLCK, m_evt_handler->m_parent) &&
m_state->indref == m_evt_handler->m_parent->indref)
5901 _c4dbgpf(
"seqblck[RNXT]: end indentless seq, go to parent={}. node={}", m_evt_handler->m_parent->node_id,
m_state->node_id);
5902 _RYML_CB_ASSERT(this->callbacks(),
m_state != m_evt_handler->m_parent);
5903 _handle_indentation_pop(m_evt_handler->m_parent);
5904 _RYML_CB_ASSERT(this->callbacks(), has_all(
RMAP|
BLCK));
5905 m_evt_handler->add_sibling();
5907 goto seqblck_finish;
5911 _c4err(
"parse error");
5917 _c4dbgt(
"seqblck: go again", 0);
5918 if(_finished_line())
5922 if(_finished_file())
5924 _c4dbgp(
"seqblck: finish!");
5926 goto seqblck_finish;
5933 _c4dbgp(
"seqblck: finish");
5939 template<
class EventHandler>
5940 void ParseEngine<EventHandler>::_handle_map_block()
5943 _c4dbgpf(
"handle2_map_block: map_id={} node_id={} level={} indref={}", m_evt_handler->m_parent->node_id,
m_state->node_id,
m_state->level,
m_state->indref);
5946 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_all(
RMAP));
5947 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_all(
BLCK));
5949 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, 1 == (has_any(
RKEY) + has_any(
RKCL) + has_any(
RVAL) + has_any(
RNXT) + has_any(
QMRK)));
5951 _maybe_skip_comment();
5952 csubstr rem =
m_state->line_contents.rem;
5958 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
RKCL));
5959 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
QMRK));
5960 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
RVAL));
5961 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
RNXT));
5965 if(
m_state->at_line_beginning())
5969 _c4dbgpf(
"mapblck[RKEY]: skip {} from indref",
m_state->indref);
5970 _line_progressed(
m_state->indref);
5971 rem =
m_state->line_contents.rem;
5975 else if(
m_state->indentation_lt())
5977 _c4dbgp(
"mapblck[RKEY]: smaller indentation!");
5978 _handle_indentation_pop_from_block_map();
5979 _line_progressed(
m_state->line_contents.indentation);
5982 _c4dbgp(
"mapblck[RKEY]: still mapblck!");
5983 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_any(
RKEY));
5984 rem =
m_state->line_contents.rem;
5990 _c4dbgp(
"mapblck[RKEY]: no longer mapblck!");
5991 goto mapblck_finish;
5996 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks,
m_state->indentation_gt());
5997 _c4err(
"invalid indentation");
6003 const char first = rem.str[0];
6004 const size_t startline =
m_state->pos.line;
6005 const size_t startindent =
m_state->line_contents.current_col();
6006 _c4dbgpf(
"mapblck[RKEY]: '{}'", first);
6010 _c4dbgp(
"mapblck[RKEY]: scanning single-quoted scalar");
6011 sc = _scan_scalar_squot();
6012 csubstr maybe_filtered = _maybe_filter_val_scalar_squot(sc);
6013 _handle_annotations_before_blck_key_scalar();
6014 m_evt_handler->set_key_scalar_squoted(maybe_filtered);
6016 if(!_maybe_scan_following_colon())
6017 _c4err(
"could not find ':' colon after key");
6018 _maybe_skip_whitespace_tokens();
6020 else if(first ==
'"')
6022 _c4dbgp(
"mapblck[RKEY]: scanning double-quoted scalar");
6023 sc = _scan_scalar_dquot();
6024 csubstr maybe_filtered = _maybe_filter_val_scalar_squot(sc);
6025 _handle_annotations_before_blck_key_scalar();
6026 m_evt_handler->set_key_scalar_dquoted(maybe_filtered);
6028 if(!_maybe_scan_following_colon())
6029 _c4err(
"could not find ':' colon after key");
6030 _maybe_skip_whitespace_tokens();
6034 else if(C4_UNLIKELY(first ==
'|'))
6036 _c4err(
"block literal keys must be enclosed in '?'");
6038 else if(C4_UNLIKELY(first ==
'>'))
6040 _c4err(
"block literal keys must be enclosed in '?'");
6042 else if(_scan_scalar_plain_map_blck(&sc))
6044 _c4dbgp(
"mapblck[RKEY]: plain scalar");
6045 csubstr maybe_filtered = _maybe_filter_val_scalar_plain(sc,
m_state->indref);
6046 _handle_annotations_before_blck_key_scalar();
6047 m_evt_handler->set_key_scalar_plain(maybe_filtered);
6049 if(!_maybe_scan_following_colon())
6050 _c4err(
"could not find ':' colon after key");
6051 _maybe_skip_whitespace_tokens();
6053 else if(first ==
'?')
6055 _c4dbgp(
"mapblck[RKEY]: key token!");
6057 _line_progressed(1);
6058 _maybe_skip_whitespace_tokens();
6059 m_was_inside_qmrk =
true;
6062 else if(first ==
':')
6064 _c4dbgp(
"mapblck[RKEY]: setting empty key");
6065 _handle_annotations_before_blck_key_scalar();
6066 m_evt_handler->set_key_scalar_plain({});
6068 _line_progressed(1);
6069 _maybe_skip_whitespace_tokens();
6071 else if(first ==
'*')
6073 csubstr ref = _scan_ref_map();
6074 _c4dbgpf(
"mapblck[RKEY]: key ref! [{}]~~~{}~~~", ref.len, ref);
6075 _handle_annotations_before_blck_key_scalar();
6076 m_evt_handler->set_key_ref(ref);
6078 if(!_maybe_scan_following_colon())
6079 _c4err(
"could not find ':' colon after key");
6080 _maybe_skip_whitespace_tokens();
6082 else if(first ==
'&')
6084 csubstr anchor = _scan_anchor();
6085 _c4dbgpf(
"mapblck[RKEY]: key anchor! [{}]~~~{}~~~", anchor.len, anchor);
6086 _add_annotation(&m_pending_anchors, anchor, startindent, startline);
6088 else if(first ==
'!')
6090 csubstr tag = _scan_tag();
6091 _c4dbgpf(
"mapblck[RKEY]: key tag! [{}]~~~{}~~~", tag.len, tag);
6092 _add_annotation(&m_pending_tags, tag, startindent, startline);
6094 else if(first ==
'[')
6099 _c4dbgp(
"mapblck[RKEY]: start child seqflow (!)");
6101 _handle_annotations_before_blck_key_scalar();
6102 m_evt_handler->begin_seq_key_flow();
6104 _line_progressed(1);
6105 _set_indentation(startindent);
6106 goto mapblck_finish;
6108 else if(first ==
'{')
6113 _c4dbgp(
"mapblck[RKEY]: start child mapflow (!)");
6115 _handle_annotations_before_blck_key_scalar();
6116 m_evt_handler->begin_map_key_flow();
6118 _line_progressed(1);
6119 _set_indentation(startindent);
6120 goto mapblck_finish;
6122 else if(first ==
'-')
6124 _c4dbgp(
"mapblck[RKEY]: maybe doc?");
6125 if(
m_state->line_contents.indentation == 0 && _is_doc_begin_token(rem))
6127 _c4dbgp(
"mapblck[RKEY]: end+start doc");
6128 _start_doc_suddenly();
6129 _line_progressed(3);
6130 _maybe_skip_whitespace_tokens();
6131 goto mapblck_finish;
6135 _c4err(
"parse error");
6138 else if(first ==
'.')
6140 _c4dbgp(
"mapblck[RKEY]: maybe end doc?");
6141 if(
m_state->line_contents.indentation == 0 && _is_doc_end_token(rem))
6143 _c4dbgp(
"mapblck[RKEY]: end doc");
6144 _end_doc_suddenly();
6145 _line_progressed(3);
6146 _maybe_skip_whitespace_tokens();
6147 goto mapblck_finish;
6151 _c4err(
"parse error");
6155 else if(first ==
'\t')
6157 _c4dbgp(
"mapblck[RKEY]: skip tabs");
6158 _maybe_skipchars(
'\t');
6162 _c4err(
"parse error");
6165 else if(has_any(
RKCL))
6167 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
RKEY));
6168 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
RVAL));
6169 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
RNXT));
6170 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
QMRK));
6174 if(
m_state->at_line_beginning())
6178 _c4dbgpf(
"mapblck[RKCL]: skip {} from indref",
m_state->indref);
6179 _line_progressed(
m_state->indref);
6180 rem =
m_state->line_contents.rem;
6184 else if(C4_UNLIKELY(
m_state->indentation_lt()))
6186 _c4err(
"invalid indentation");
6189 const char first = rem.str[0];
6190 _c4dbgpf(
"mapblck[RKCL]: '{}'", first);
6193 _c4dbgp(
"mapblck[RKCL]: found the colon");
6195 _line_progressed(1);
6196 _maybe_skip_whitespace_tokens();
6198 else if(first ==
'?')
6200 _c4dbgp(
"mapblck[RKCL]: got '?'. val was empty");
6201 _RYML_CB_CHECK(m_evt_handler->m_stack.m_callbacks, m_was_inside_qmrk);
6202 m_evt_handler->set_val_scalar_plain({});
6203 m_evt_handler->add_sibling();
6205 _line_progressed(1);
6206 _maybe_skip_whitespace_tokens();
6208 else if(first ==
'-')
6210 if(
m_state->indref == 0 ||
m_state->line_contents.indentation == 0 || _is_doc_begin_token(rem))
6212 _c4dbgp(
"mapblck[RKCL]: end+start doc");
6213 _RYML_CB_CHECK(m_evt_handler->m_stack.m_callbacks, _is_doc_begin_token(rem));
6214 _start_doc_suddenly();
6215 _line_progressed(3);
6216 _maybe_skip_whitespace_tokens();
6217 goto mapblck_finish;
6221 _c4err(
"parse error");
6224 else if(first ==
'.')
6226 _c4dbgp(
"mapblck[RKCL]: maybe end doc?");
6227 csubstr rs = rem.sub(1);
6228 if(rs ==
".." || rs.begins_with(
".. "))
6230 _c4dbgp(
"mapblck[RKCL]: end+start doc");
6231 _end_doc_suddenly();
6232 _line_progressed(3);
6233 goto mapblck_finish;
6237 _c4err(
"parse error");
6240 else if(m_was_inside_qmrk)
6242 _RYML_CB_CHECK(m_evt_handler->m_stack.m_callbacks,
m_state->indentation_eq());
6243 _c4dbgp(
"mapblck[RKCL]: missing :");
6244 m_evt_handler->set_val_scalar_plain({});
6245 m_evt_handler->add_sibling();
6246 m_was_inside_qmrk =
false;
6251 _c4err(
"parse error");
6254 else if(has_any(
RVAL))
6256 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
RKEY));
6257 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
RKCL));
6258 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
RNXT));
6259 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
QMRK));
6263 if(
m_state->at_line_beginning())
6265 _c4dbgpf(
"mapblck[RVAL]: indref={} indentation={}",
m_state->indref,
m_state->line_contents.indentation);
6266 m_state->more_indented =
false;
6269 _c4dbgpf(
"mapblck[RVAL]: setting indentation={}", m_evt_handler->m_parent->indref);
6270 _set_indentation(
m_state->line_contents.indentation);
6271 _line_progressed(
m_state->indref);
6272 rem =
m_state->line_contents.rem;
6276 else if(
m_state->indentation_eq())
6278 _c4dbgp(
"mapblck[RVAL]: skip indentation!");
6279 _line_progressed(
m_state->indref);
6280 rem =
m_state->line_contents.rem;
6308 else if(
m_state->indentation_gt())
6310 _c4dbgp(
"mapblck[RVAL]: more indented!");
6311 m_state->more_indented =
true;
6312 _line_progressed(
m_state->line_contents.indentation);
6313 rem =
m_state->line_contents.rem;
6317 else if(
m_state->indentation_lt())
6319 _c4dbgp(
"mapblck[RVAL]: smaller indentation!");
6320 _handle_indentation_pop_from_block_map();
6323 _c4dbgp(
"mapblck[RVAL]: still mapblck!");
6324 _line_progressed(
m_state->line_contents.indentation);
6329 _c4dbgp(
"mapblck[RVAL]: no longer mapblck!");
6330 goto mapblck_finish;
6333 else if(
m_state->line_contents.indentation ==
npos)
6335 _c4dbgp(
"mapblck[RVAL]: empty line!");
6336 _line_progressed(
m_state->line_contents.rem.len);
6343 const char first = rem.str[0];
6344 const size_t startline =
m_state->pos.line;
6345 const size_t startindent =
m_state->line_contents.current_col();
6346 _c4dbgpf(
"mapblck[RVAL]: '{}'", first);
6350 _c4dbgp(
"mapblck[RVAL]: scanning single-quoted scalar");
6351 sc = _scan_scalar_squot();
6352 if(!_maybe_scan_following_colon())
6354 _c4dbgp(
"mapblck[RVAL]: set as val");
6355 _handle_annotations_before_blck_val_scalar();
6356 csubstr maybe_filtered = _maybe_filter_val_scalar_squot(sc);
6357 m_evt_handler->set_val_scalar_squoted(maybe_filtered);
6362 if(startindent !=
m_state->indref)
6364 _c4dbgp(
"mapblck[RVAL]: start new block map, set scalar as key");
6365 _handle_annotations_before_start_mapblck(startline);
6367 m_evt_handler->begin_map_val_block();
6368 _handle_annotations_and_indentation_after_start_mapblck(startindent, startline);
6369 csubstr maybe_filtered = _maybe_filter_key_scalar_squot(sc);
6370 m_evt_handler->set_key_scalar_squoted(maybe_filtered);
6371 _maybe_skip_whitespace_tokens();
6372 _set_indentation(
m_state->line_contents.indentation);
6378 _c4dbgp(
"mapblck[RVAL]: prev val empty+this is a key");
6379 m_evt_handler->set_val_scalar_plain({});
6380 m_evt_handler->add_sibling();
6381 csubstr maybe_filtered = _maybe_filter_key_scalar_squot(sc);
6382 m_evt_handler->set_key_scalar_squoted(maybe_filtered);
6384 _maybe_skip_whitespace_tokens();
6388 else if(first ==
'"')
6390 _c4dbgp(
"mapblck[RVAL]: scanning double-quoted scalar");
6391 sc = _scan_scalar_dquot();
6392 if(!_maybe_scan_following_colon())
6394 _c4dbgp(
"mapblck[RVAL]: set as val");
6395 _handle_annotations_before_blck_val_scalar();
6396 csubstr maybe_filtered = _maybe_filter_val_scalar_dquot(sc);
6397 m_evt_handler->set_val_scalar_dquoted(maybe_filtered);
6402 if(startindent !=
m_state->indref)
6404 _c4dbgp(
"mapblck[RVAL]: start new block map, set scalar as key");
6405 _handle_annotations_before_start_mapblck(startline);
6407 m_evt_handler->begin_map_val_block();
6408 _handle_annotations_and_indentation_after_start_mapblck(startindent, startline);
6409 csubstr maybe_filtered = _maybe_filter_key_scalar_dquot(sc);
6410 m_evt_handler->set_key_scalar_dquoted(maybe_filtered);
6411 _maybe_skip_whitespace_tokens();
6412 _set_indentation(
m_state->line_contents.indentation);
6418 _c4dbgp(
"mapblck[RVAL]: prev val empty+this is a key");
6419 m_evt_handler->set_val_scalar_plain({});
6420 m_evt_handler->add_sibling();
6421 csubstr maybe_filtered = _maybe_filter_key_scalar_dquot(sc);
6422 m_evt_handler->set_key_scalar_dquoted(maybe_filtered);
6424 _maybe_skip_whitespace_tokens();
6430 else if(first ==
'|')
6432 _c4dbgp(
"mapblck[RVAL]: scanning block-literal scalar");
6434 _scan_block(&sb,
m_state->indref + 1);
6435 _handle_annotations_before_blck_val_scalar();
6436 csubstr maybe_filtered = _maybe_filter_val_scalar_literal(sb);
6437 m_evt_handler->set_val_scalar_literal(maybe_filtered);
6440 else if(first ==
'>')
6442 _c4dbgp(
"mapblck[RVAL]: scanning block-folded scalar");
6444 _scan_block(&sb,
m_state->indref + 1);
6445 _handle_annotations_before_blck_val_scalar();
6446 csubstr maybe_filtered = _maybe_filter_val_scalar_folded(sb);
6447 m_evt_handler->set_val_scalar_folded(maybe_filtered);
6450 else if(_scan_scalar_plain_map_blck(&sc))
6452 _c4dbgp(
"mapblck[RVAL]: plain scalar.");
6453 if(!_maybe_scan_following_colon())
6455 _c4dbgp(
"mapblck[RVAL]: set as val");
6456 _handle_annotations_before_blck_val_scalar();
6457 csubstr maybe_filtered = _maybe_filter_val_scalar_plain(sc,
m_state->indref);
6458 m_evt_handler->set_val_scalar_plain(maybe_filtered);
6463 if(startindent !=
m_state->indref)
6465 _c4dbgpf(
"mapblck[RVAL]: start new block map, set scalar as key {}",
m_state->indref);
6467 _handle_annotations_before_start_mapblck(startline);
6468 m_evt_handler->begin_map_val_block();
6469 _handle_annotations_and_indentation_after_start_mapblck(startindent, startline);
6470 csubstr maybe_filtered = _maybe_filter_key_scalar_plain(sc,
m_state->indref);
6471 m_evt_handler->set_key_scalar_plain(maybe_filtered);
6472 _maybe_skip_whitespace_tokens();
6473 _set_indentation(
m_state->line_contents.indentation);
6479 _c4dbgp(
"mapblck[RVAL]: prev val empty+this is a key");
6480 _handle_annotations_before_blck_val_scalar();
6481 m_evt_handler->set_val_scalar_plain({});
6482 m_evt_handler->add_sibling();
6483 csubstr maybe_filtered = _maybe_filter_key_scalar_plain(sc,
m_state->indref);
6484 m_evt_handler->set_key_scalar_plain(maybe_filtered);
6486 _maybe_skip_whitespace_tokens();
6490 else if(first ==
'-')
6494 _c4dbgp(
"mapblck[RVAL]: start val seqblck");
6496 _handle_annotations_before_blck_val_scalar();
6497 m_evt_handler->begin_seq_val_block();
6499 _set_indentation(startindent);
6500 _line_progressed(1);
6501 _maybe_skip_whitespace_tokens();
6502 goto mapblck_finish;
6504 else if(
m_state->indref == 0 ||
m_state->line_contents.indentation == 0 || _is_doc_begin_token(rem))
6506 _c4dbgp(
"mapblck[RVAL]: end+start doc");
6507 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, _is_doc_begin_token(rem));
6508 _start_doc_suddenly();
6509 _line_progressed(3);
6510 _maybe_skip_whitespace_tokens();
6511 goto mapblck_finish;
6515 _c4err(
"parse error");
6518 else if(first ==
'[')
6520 _c4dbgp(
"mapblck[RVAL]: start val seqflow");
6522 _handle_annotations_before_blck_val_scalar();
6523 m_evt_handler->begin_seq_val_flow();
6525 _set_indentation(
m_state->indref + 1u);
6526 _line_progressed(1);
6527 goto mapblck_finish;
6529 else if(first ==
'{')
6531 _c4dbgp(
"mapblck[RVAL]: start val mapflow");
6533 _handle_annotations_before_blck_val_scalar();
6534 m_evt_handler->begin_map_val_flow();
6537 _set_indentation(
m_state->indref + 1u);
6538 _line_progressed(1);
6539 goto mapblck_finish;
6541 else if(first ==
'*')
6543 csubstr ref = _scan_ref_map();
6544 _c4dbgpf(
"mapblck[RVAL]: ref! [{}]~~~{}~~~", ref.len, ref);
6545 if(startindent ==
m_state->indref)
6547 _c4dbgpf(
"mapblck[RVAL]: same indentation {}", startindent);
6548 m_evt_handler->set_val_ref(ref);
6553 _c4dbgpf(
"mapblck[RVAL]: larger indentation {}>{}", startindent,
m_state->indref);
6554 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, startindent >
m_state->indref);
6555 if(_maybe_scan_following_colon())
6557 _c4dbgp(
"mapblck[RVAL]: start child map, block");
6559 _handle_annotations_before_blck_val_scalar();
6560 m_evt_handler->begin_map_val_block();
6561 m_evt_handler->set_key_ref(ref);
6562 _set_indentation(startindent);
6568 _c4dbgp(
"mapblck[RVAL]: was val ref");
6569 _handle_annotations_before_blck_val_scalar();
6570 m_evt_handler->set_val_ref(ref);
6574 _maybe_skip_whitespace_tokens();
6576 else if(first ==
'&')
6578 csubstr anchor = _scan_anchor();
6579 _c4dbgpf(
"mapblck[RVAL]: anchor! [{}]~~~{}~~~", anchor.len, anchor);
6580 if(startindent ==
m_state->indref)
6582 _c4dbgp(
"mapblck[RVAL]: anchor for next key. val is missing!");
6583 m_evt_handler->set_val_scalar_plain({});
6584 m_evt_handler->add_sibling();
6589 _add_annotation(&m_pending_anchors, anchor, startindent, startline);
6591 else if(first ==
'!')
6593 csubstr tag = _scan_tag();
6594 _c4dbgpf(
"mapblck[RVAL]: tag! [{}]~~~{}~~~", tag.len, tag);
6595 if(startindent ==
m_state->indref)
6597 _c4dbgp(
"mapblck[RVAL]: tag for next key. val is missing!");
6598 _handle_annotations_before_blck_val_scalar();
6599 m_evt_handler->set_val_scalar_plain({});
6600 m_evt_handler->add_sibling();
6605 _add_annotation(&m_pending_tags, tag, startindent, startline);
6607 else if(first ==
'?')
6609 if(startindent ==
m_state->indref)
6611 _c4dbgp(
"mapblck[RVAL]: got '?'. val was empty");
6612 _handle_annotations_before_blck_val_scalar();
6613 m_evt_handler->set_val_scalar_plain({});
6614 m_evt_handler->add_sibling();
6617 else if(startindent >
m_state->indref)
6619 _c4dbgp(
"mapblck[RVAL]: start val mapblck");
6621 _handle_annotations_before_blck_val_scalar();
6622 m_evt_handler->begin_map_val_block();
6624 _set_indentation(startindent);
6628 _c4err(
"parse error");
6630 m_was_inside_qmrk =
true;
6631 _line_progressed(1);
6632 _maybe_skip_whitespace_tokens();
6635 else if(first ==
':')
6637 if(startindent ==
m_state->indref)
6639 _c4dbgp(
"mapblck[RVAL]: got ':'. val was empty, next key as well");
6640 m_evt_handler->set_val_scalar_plain({});
6641 m_evt_handler->add_sibling();
6642 m_evt_handler->set_key_scalar_plain({});
6643 _line_progressed(1);
6644 _maybe_skip_whitespace_tokens();
6649 _c4err(
"parse error");
6652 else if(first ==
'.')
6654 _c4dbgp(
"mapblck[RVAL]: maybe doc?");
6655 csubstr rs = rem.sub(1);
6656 if(rs ==
".." || rs.begins_with(
".. "))
6658 _c4dbgp(
"seqblck[RVAL]: end doc expl");
6659 _end_doc_suddenly();
6660 _line_progressed(3);
6661 _maybe_skip_whitespace_tokens();
6662 goto mapblck_finish;
6666 _c4err(
"parse error");
6670 else if(first ==
'\t')
6672 _c4dbgp(
"mapblck[RVAL]: skip tabs");
6673 _maybe_skipchars(
'\t');
6677 _c4err(
"parse error");
6680 else if(has_any(
RNXT))
6682 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
RKEY));
6683 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
RKCL));
6684 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
RVAL));
6685 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
QMRK));
6689 if(
m_state->at_line_beginning())
6691 _c4dbgpf(
"mapblck[RNXT]: indref={} indentation={}",
m_state->indref,
m_state->line_contents.indentation);
6694 _c4dbgpf(
"mapblck[RNXT]: skip {} from indref",
m_state->indref);
6695 _line_progressed(
m_state->indref);
6696 _c4dbgp(
"mapblck[RNXT]: speculatively expect next keyval");
6697 m_evt_handler->add_sibling();
6701 else if(
m_state->indentation_lt())
6703 _c4dbgp(
"mapblck[RNXT]: smaller indentation!");
6704 _handle_indentation_pop_from_block_map();
6707 _line_progressed(
m_state->line_contents.indentation);
6710 _c4dbgp(
"mapblck[RNXT]: speculatively expect next keyval");
6711 m_evt_handler->add_sibling();
6718 goto mapblck_finish;
6725 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, rem.len > 0);
6726 const char first = rem.str[0];
6727 _c4dbgpf(
"mapblck[RNXT]: '{}'", _c4prc(first));
6732 _c4dbgp(
"mapblck[RNXT]: start child block map");
6733 C4_NOT_IMPLEMENTED();
6735 _line_progressed(1);
6736 _set_indentation(
m_state->scalar_col);
6737 m_state->more_indented =
false;
6742 _c4err(
"parse error");
6745 else if(first ==
' ')
6747 _c4dbgp(
"mapblck[RNXT]: skip spaces");
6748 _maybe_skip_whitespace_tokens();
6752 _c4err(
"parse error");
6755 else if(has_any(
QMRK))
6757 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
RKEY));
6758 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
RKCL));
6759 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
RVAL));
6760 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
RNXT));
6764 if(
m_state->at_line_beginning())
6766 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks,
m_state->line_contents.indentation !=
npos);
6769 _c4dbgpf(
"mapblck[QMRK]: skip {} from indref",
m_state->indref);
6770 _line_progressed(
m_state->indref);
6771 rem =
m_state->line_contents.rem;
6775 else if(
m_state->indentation_lt())
6777 _c4dbgp(
"mapblck[QMRK]: smaller indentation!");
6778 _handle_indentation_pop_from_block_map();
6779 _line_progressed(
m_state->line_contents.indentation);
6782 _c4dbgp(
"mapblck[QMRK]: still mapblck!");
6783 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_any(
QMRK));
6784 rem =
m_state->line_contents.rem;
6790 _c4dbgp(
"mapblck[QMRK]: no longer mapblck!");
6791 goto mapblck_finish;
6797 _c4dbgp(
"mapblck[QMRK]: larger indentation !");
6798 _line_progressed(
m_state->line_contents.indentation);
6799 rem =
m_state->line_contents.rem;
6807 const char first = rem.str[0];
6808 const size_t startline =
m_state->pos.line;
6809 const size_t startindent =
m_state->line_contents.current_col();
6810 _c4dbgpf(
"mapblck[QMRK]: '{}'", first);
6814 _c4dbgp(
"mapblck[QMRK]: scanning single-quoted scalar");
6815 sc = _scan_scalar_squot();
6816 csubstr maybe_filtered = _maybe_filter_key_scalar_squot(sc);
6817 if(!_maybe_scan_following_colon())
6819 _c4dbgp(
"mapblck[QMRK]: set as key");
6820 _handle_annotations_before_blck_key_scalar();
6821 m_evt_handler->set_key_scalar_squoted(maybe_filtered);
6826 _c4dbgp(
"mapblck[QMRK]: start new block map as key (!), set scalar as key");
6828 _handle_annotations_before_start_mapblck_as_key();
6829 m_evt_handler->begin_map_key_block();
6830 _handle_annotations_and_indentation_after_start_mapblck(startindent, startline);
6831 m_evt_handler->set_key_scalar_squoted(maybe_filtered);
6832 _maybe_skip_whitespace_tokens();
6833 _set_indentation(startindent);
6838 else if(first ==
'"')
6840 _c4dbgp(
"mapblck[QMRK]: scanning double-quoted scalar");
6841 sc = _scan_scalar_dquot();
6842 csubstr maybe_filtered = _maybe_filter_key_scalar_dquot(sc);
6843 if(!_maybe_scan_following_colon())
6845 _c4dbgp(
"mapblck[QMRK]: set as key");
6846 _handle_annotations_before_blck_key_scalar();
6847 m_evt_handler->set_key_scalar_dquoted(maybe_filtered);
6852 _c4dbgp(
"mapblck[QMRK]: start new block map as key (!), set scalar as key");
6854 _handle_annotations_before_start_mapblck_as_key();
6855 m_evt_handler->begin_map_key_block();
6856 _handle_annotations_and_indentation_after_start_mapblck(startindent, startline);
6857 m_evt_handler->set_key_scalar_dquoted(maybe_filtered);
6858 _maybe_skip_whitespace_tokens();
6859 _set_indentation(startindent);
6864 else if(first ==
'|')
6866 _c4dbgp(
"mapblck[QMRK]: scanning block-literal scalar");
6868 _scan_block(&sb,
m_state->indref + 1);
6869 csubstr maybe_filtered = _maybe_filter_key_scalar_literal(sb);
6870 _handle_annotations_before_blck_key_scalar();
6871 m_evt_handler->set_key_scalar_literal(maybe_filtered);
6874 else if(first ==
'>')
6876 _c4dbgp(
"mapblck[QMRK]: scanning block-literal scalar");
6878 _scan_block(&sb,
m_state->indref + 1);
6879 csubstr maybe_filtered = _maybe_filter_key_scalar_folded(sb);
6880 _handle_annotations_before_blck_key_scalar();
6881 m_evt_handler->set_key_scalar_folded(maybe_filtered);
6884 else if(_scan_scalar_plain_map_blck(&sc))
6886 _c4dbgp(
"mapblck[QMRK]: plain scalar");
6887 csubstr maybe_filtered = _maybe_filter_key_scalar_plain(sc,
m_state->indref);
6888 if(!_maybe_scan_following_colon())
6890 _c4dbgp(
"mapblck[QMRK]: set as key");
6891 _handle_annotations_before_blck_key_scalar();
6892 m_evt_handler->set_key_scalar_plain(maybe_filtered);
6897 _c4dbgp(
"mapblck[QMRK]: start new block map as key (!), set scalar as key");
6899 _handle_annotations_before_start_mapblck_as_key();
6900 m_evt_handler->begin_map_key_block();
6901 _handle_annotations_and_indentation_after_start_mapblck(startindent, startline);
6902 m_evt_handler->set_key_scalar_plain(maybe_filtered);
6903 _maybe_skip_whitespace_tokens();
6904 _set_indentation(startindent);
6909 else if(first ==
':')
6911 if(startindent ==
m_state->indref)
6913 _c4dbgp(
"mapblck[QMRK]: empty key");
6915 _handle_annotations_before_blck_key_scalar();
6916 m_evt_handler->set_key_scalar_plain({});
6917 _line_progressed(1);
6918 _maybe_skip_whitespace_tokens();
6922 _c4dbgp(
"mapblck[QMRK]: start new block map as key (!), empty key");
6924 _handle_annotations_before_start_mapblck_as_key();
6925 m_evt_handler->begin_map_key_block();
6926 _handle_annotations_and_indentation_after_start_mapblck(startindent, startline);
6927 m_evt_handler->set_key_scalar_plain({});
6928 _line_progressed(1);
6929 _maybe_skip_whitespace_tokens();
6930 _set_indentation(startindent);
6935 else if(first ==
'*')
6937 csubstr ref = _scan_ref_map();
6938 _c4dbgpf(
"mapblck[QMRK]: key ref! [{}]~~~{}~~~", ref.len, ref);
6939 if(!_maybe_scan_following_colon())
6941 _c4dbgp(
"mapblck[QMRK]: set ref as key");
6942 _handle_annotations_before_blck_key_scalar();
6943 m_evt_handler->set_key_ref(ref);
6948 _c4dbgp(
"mapblck[QMRK]: start new block map as key (!), set ref as key");
6950 _handle_annotations_before_blck_key_scalar();
6951 m_evt_handler->begin_map_key_block();
6952 m_evt_handler->set_key_ref(ref);
6953 _set_indentation(startindent);
6957 _maybe_skip_whitespace_tokens();
6959 else if(first ==
'&')
6961 csubstr anchor = _scan_anchor();
6962 _c4dbgpf(
"mapblck[QMRK]: key anchor! [{}]~~~{}~~~", anchor.len, anchor);
6963 _add_annotation(&m_pending_anchors, anchor, startindent, startline);
6965 else if(first ==
'!')
6967 csubstr tag = _scan_tag();
6968 _c4dbgpf(
"mapblck[QMRK]: key tag! [{}]~~~{}~~~", tag.len, tag);
6969 _add_annotation(&m_pending_tags, tag, startindent, startline);
6971 else if(first ==
'-')
6973 _c4dbgp(
"mapblck[QMRK]: maybe doc?");
6974 csubstr rs = rem.sub(1);
6975 if(rs ==
"--" || rs.begins_with(
"-- "))
6977 _c4dbgp(
"mapblck[QMRK]: end+start doc");
6978 _start_doc_suddenly();
6979 _line_progressed(3);
6983 _c4dbgp(
"mapblck[QMRK]: start child seqblck (!)");
6985 m_evt_handler->begin_seq_key_block();
6987 _set_indentation(startindent);
6988 _line_progressed(1);
6990 _maybe_skip_whitespace_tokens();
6991 goto mapblck_finish;
6993 else if(first ==
'[')
6995 _c4dbgp(
"mapblck[QMRK]: start child seqflow (!)");
6997 m_evt_handler->begin_seq_key_flow();
6999 _set_indentation(m_evt_handler->m_parent->indref);
7000 _line_progressed(1);
7001 goto mapblck_finish;
7003 else if(first ==
'{')
7005 _c4dbgp(
"mapblck[QMRK]: start child mapblck (!)");
7007 m_evt_handler->begin_map_key_flow();
7009 _set_indentation(m_evt_handler->m_parent->indref);
7010 _line_progressed(1);
7011 goto mapblck_finish;
7013 else if(first ==
'?')
7015 _c4dbgp(
"mapblck[QMRK]: another QMRK '?'");
7016 m_evt_handler->set_key_scalar_plain({});
7017 m_evt_handler->set_val_scalar_plain({});
7018 m_evt_handler->add_sibling();
7019 _line_progressed(1);
7021 else if(first ==
'.')
7023 _c4dbgp(
"mapblck[QMRK]: maybe end doc?");
7024 csubstr rs = rem.sub(1);
7025 if(rs ==
".." || rs.begins_with(
".. "))
7027 _c4dbgp(
"mapblck[QMRK]: end+start doc");
7028 _end_doc_suddenly();
7029 _line_progressed(3);
7030 goto mapblck_finish;
7034 _c4err(
"parse error");
7039 _c4err(
"parse error");
7044 _c4dbgt(
"mapblck: again", 0);
7045 if(_finished_line())
7049 if(_finished_file())
7051 _c4dbgp(
"mapblck: file finished!");
7053 goto mapblck_finish;
7060 _c4dbgp(
"mapblck: finish");
7066 template<
class EventHandler>
7067 void ParseEngine<EventHandler>::_handle_unk_json()
7069 _c4dbgpf(
"handle_unk_json indref={} target={}",
m_state->indref,
m_state->node_id);
7071 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
RNXT|
RSEQ|
RMAP));
7072 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_all(
RTOP));
7074 _maybe_skip_comment();
7075 csubstr rem =
m_state->line_contents.rem;
7079 size_t pos = rem.first_not_of(
" \t");
7082 pos = pos !=
npos ? pos : rem.len;
7083 _c4dbgpf(
"skipping indentation of {}", pos);
7084 _line_progressed(pos);
7085 rem =
m_state->line_contents.rem;
7088 _c4dbgpf(
"rem is now [{}]~~~{}~~~", rem.len, rem);
7091 if(rem.begins_with(
'['))
7093 _c4dbgp(
"it's a seq");
7094 m_evt_handler->check_trailing_doc_token();
7096 m_evt_handler->begin_seq_val_flow();
7098 _set_indentation(
m_state->line_contents.current_col(rem));
7099 m_doc_empty =
false;
7100 _line_progressed(1);
7102 else if(rem.begins_with(
'{'))
7104 _c4dbgp(
"it's a map");
7105 m_evt_handler->check_trailing_doc_token();
7107 m_evt_handler->begin_map_val_flow();
7109 m_doc_empty =
false;
7110 _set_indentation(
m_state->line_contents.current_col(rem));
7111 _line_progressed(1);
7115 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, ! has_any(
SSCL));
7116 _maybe_skip_whitespace_tokens();
7117 csubstr s =
m_state->line_contents.rem;
7120 const size_t startindent =
m_state->line_contents.indentation;
7121 const char first = s.str[0];
7125 _c4dbgp(
"runk_json: scanning double-quoted scalar");
7126 m_evt_handler->check_trailing_doc_token();
7129 m_doc_empty =
false;
7130 sc = _scan_scalar_dquot();
7131 csubstr maybe_filtered = _maybe_filter_val_scalar_dquot(sc);
7132 if(!_maybe_scan_following_colon())
7134 _c4dbgp(
"runk_json: set as val");
7135 _handle_annotations_before_blck_val_scalar();
7136 m_evt_handler->set_val_scalar_dquoted(maybe_filtered);
7140 _c4err(
"parse error");
7143 else if(_scan_scalar_plain_unk(&sc))
7145 _c4dbgp(
"runk_json: got a plain scalar");
7146 m_evt_handler->check_trailing_doc_token();
7149 m_doc_empty =
false;
7150 if(!_maybe_scan_following_colon())
7152 _c4dbgp(
"runk_json: set as val");
7153 _handle_annotations_before_blck_val_scalar();
7154 csubstr maybe_filtered = _maybe_filter_val_scalar_plain(sc, startindent);
7155 m_evt_handler->set_val_scalar_plain(maybe_filtered);
7159 _c4err(
"parse error");
7164 _c4err(
"parse error");
7172 template<
class EventHandler>
7173 void ParseEngine<EventHandler>::_handle_unk()
7175 _c4dbgpf(
"handle_unk indref={} target={}",
m_state->indref,
m_state->node_id);
7177 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
RNXT|
RSEQ|
RMAP));
7178 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_all(
RTOP));
7180 _maybe_skip_comment();
7181 csubstr rem =
m_state->line_contents.rem;
7185 size_t pos = rem.first_not_of(
" \t");
7188 pos = pos !=
npos ? pos : rem.len;
7189 _c4dbgpf(
"skipping {} whitespace characters", pos);
7190 _line_progressed(pos);
7191 rem =
m_state->line_contents.rem;
7194 _c4dbgpf(
"rem is now [{}]~~~{}~~~", rem.len, rem);
7197 if(
m_state->line_contents.indentation == 0u && _at_line_begin())
7199 const char first = rem.str[0];
7200 _c4dbgp(
"rtop: zero indent + at line begin");
7203 _c4dbgp(
"rtop: suspecting doc");
7204 if(_is_doc_begin_token(rem))
7206 _c4dbgp(
"rtop: begin doc");
7209 _set_indentation(0);
7211 _line_progressed(3u);
7212 _maybe_skip_whitespace_tokens();
7216 else if(first ==
'.')
7218 _c4dbgp(
"rtop: suspecting doc end");
7219 if(_is_doc_end_token(rem))
7221 _c4dbgp(
"rtop: end doc");
7228 _c4dbgp(
"rtop: ignore end doc");
7231 _line_progressed(3u);
7232 _maybe_skip_whitespace_tokens();
7236 else if(first ==
'%')
7238 _c4dbgpf(
"directive: {}", rem);
7239 if(C4_UNLIKELY(!m_doc_empty && has_none(
NDOC)))
7240 _RYML_CB_ERR(m_evt_handler->m_stack.m_callbacks,
"need document footer before directives");
7241 _handle_directive(rem);
7247 char first = rem.str[0];
7251 m_evt_handler->check_trailing_doc_token();
7253 m_doc_empty =
false;
7254 const size_t startindent =
m_state->line_contents.current_col(rem);
7255 if(C4_LIKELY( ! _annotations_require_key_container()))
7257 _c4dbgp(
"it's a seq, flow");
7258 _handle_annotations_before_blck_val_scalar();
7259 m_evt_handler->begin_seq_val_flow();
7261 _set_indentation(startindent);
7265 _c4dbgp(
"start new block map, set flow seq as key (!)");
7266 _handle_annotations_before_start_mapblck(
m_state->pos.line);
7267 m_evt_handler->begin_map_val_block();
7269 _handle_annotations_and_indentation_after_start_mapblck(startindent,
m_state->pos.line);
7270 m_evt_handler->begin_seq_key_flow();
7272 _set_indentation(startindent);
7274 _line_progressed(1);
7276 else if(first ==
'{')
7278 m_evt_handler->check_trailing_doc_token();
7280 m_doc_empty =
false;
7281 const size_t startindent =
m_state->line_contents.current_col(rem);
7282 if(C4_LIKELY( ! _annotations_require_key_container()))
7284 _c4dbgp(
"it's a map, flow");
7285 _handle_annotations_before_blck_val_scalar();
7286 m_evt_handler->begin_map_val_flow();
7288 _set_indentation(startindent);
7292 _c4dbgp(
"start new block map, set flow map as key (!)");
7293 _handle_annotations_before_start_mapblck(
m_state->pos.line);
7294 m_evt_handler->begin_map_val_block();
7296 _handle_annotations_and_indentation_after_start_mapblck(startindent,
m_state->pos.line);
7297 m_evt_handler->begin_map_key_flow();
7299 _set_indentation(startindent);
7301 _line_progressed(1);
7303 else if(first ==
'-' && _is_blck_token(rem))
7305 _c4dbgp(
"it's a seq, block");
7306 m_evt_handler->check_trailing_doc_token();
7308 _handle_annotations_before_blck_val_scalar();
7309 m_evt_handler->begin_seq_val_block();
7311 m_doc_empty =
false;
7312 _set_indentation(
m_state->line_contents.current_col(rem));
7313 _line_progressed(1);
7314 _maybe_skip_whitespace_tokens();
7316 else if(first ==
'?' && _is_blck_token(rem))
7318 _c4dbgp(
"it's a map + this key is complex");
7319 m_evt_handler->check_trailing_doc_token();
7321 _handle_annotations_before_blck_val_scalar();
7322 m_evt_handler->begin_map_val_block();
7324 m_doc_empty =
false;
7325 m_was_inside_qmrk =
true;
7326 _save_indentation();
7327 _line_progressed(1);
7328 _maybe_skip_whitespace_tokens();
7330 else if(first ==
':' && _is_blck_token(rem))
7334 _c4dbgp(
"it's a map with an empty key");
7335 m_evt_handler->check_trailing_doc_token();
7337 _handle_annotations_before_blck_val_scalar();
7338 m_evt_handler->begin_map_val_block();
7339 m_evt_handler->set_key_scalar_plain({});
7340 m_doc_empty =
false;
7341 _save_indentation();
7345 _c4dbgp(
"actually prev val is a key!");
7346 size_t prev_indentation =
m_state->indref;
7347 m_evt_handler->actually_val_is_first_key_of_new_map_block();
7348 _set_indentation(prev_indentation);
7351 _line_progressed(1);
7352 _maybe_skip_whitespace_tokens();
7354 else if(first ==
'&')
7356 csubstr anchor = _scan_anchor();
7357 _c4dbgpf(
"anchor! [{}]~~~{}~~~", anchor.len, anchor);
7358 m_evt_handler->check_trailing_doc_token();
7360 const size_t indentation =
m_state->line_contents.current_col(rem);
7361 const size_t line =
m_state->pos.line;
7362 _add_annotation(&m_pending_anchors, anchor, indentation, line);
7363 _set_indentation(
m_state->line_contents.current_col(rem));
7364 m_doc_empty =
false;
7366 else if(first ==
'*')
7368 csubstr ref = _scan_ref_map();
7369 _c4dbgpf(
"ref! [{}]~~~{}~~~", ref.len, ref);
7370 m_evt_handler->check_trailing_doc_token();
7372 m_doc_empty =
false;
7373 if(!_maybe_scan_following_colon())
7375 _c4dbgp(
"runk: set val ref");
7376 _handle_annotations_before_blck_val_scalar();
7377 m_evt_handler->set_val_ref(ref);
7381 _c4dbgp(
"runk: start new block map, set ref as key");
7382 const size_t startindent =
m_state->line_contents.indentation;
7383 const size_t startline =
m_state->pos.line;
7384 _handle_annotations_before_start_mapblck(startline);
7385 m_evt_handler->begin_map_val_block();
7386 _handle_annotations_and_indentation_after_start_mapblck(startindent, startline);
7387 m_evt_handler->set_key_ref(ref);
7388 _maybe_skip_whitespace_tokens();
7389 _set_indentation(startindent);
7393 else if(first ==
'!')
7395 csubstr tag = _scan_tag();
7396 _c4dbgpf(
"unk: val tag! [{}]~~~{}~~~", tag.len, tag);
7399 const size_t indentation =
m_state->line_contents.current_col(rem);
7400 const size_t line =
m_state->pos.line;
7401 _add_annotation(&m_pending_tags, tag, indentation, line);
7405 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, ! has_any(
SSCL));
7406 _maybe_skip_whitespace_tokens();
7407 csubstr s =
m_state->line_contents.rem;
7410 const size_t startindent =
m_state->line_contents.indentation;
7411 const size_t startline =
m_state->pos.line;
7416 _c4dbgp(
"runk: scanning single-quoted scalar");
7417 m_evt_handler->check_trailing_doc_token();
7420 m_doc_empty =
false;
7421 sc = _scan_scalar_squot();
7422 if(!_maybe_scan_following_colon())
7424 _c4dbgp(
"runk: set as val");
7425 _handle_annotations_before_blck_val_scalar();
7426 csubstr maybe_filtered = _maybe_filter_val_scalar_squot(sc);
7427 m_evt_handler->set_val_scalar_squoted(maybe_filtered);
7431 _c4dbgp(
"runk: start new block map, set scalar as key");
7432 _handle_annotations_before_start_mapblck(startline);
7433 m_evt_handler->begin_map_val_block();
7434 _handle_annotations_and_indentation_after_start_mapblck(startindent, startline);
7435 csubstr maybe_filtered = _maybe_filter_key_scalar_squot(sc);
7436 m_evt_handler->set_key_scalar_squoted(maybe_filtered);
7437 _maybe_skip_whitespace_tokens();
7438 _set_indentation(startindent);
7442 else if(first ==
'"')
7444 _c4dbgp(
"runk: scanning double-quoted scalar");
7445 m_evt_handler->check_trailing_doc_token();
7448 m_doc_empty =
false;
7449 sc = _scan_scalar_dquot();
7450 if(!_maybe_scan_following_colon())
7452 _c4dbgp(
"runk: set as val");
7453 _handle_annotations_before_blck_val_scalar();
7454 csubstr maybe_filtered = _maybe_filter_val_scalar_dquot(sc);
7455 m_evt_handler->set_val_scalar_dquoted(maybe_filtered);
7459 _c4dbgp(
"runk: start new block map, set double-quoted scalar as key");
7460 _handle_annotations_before_start_mapblck(startline);
7461 m_evt_handler->begin_map_val_block();
7462 _handle_annotations_and_indentation_after_start_mapblck(startindent, startline);
7463 csubstr maybe_filtered = _maybe_filter_key_scalar_dquot(sc);
7464 m_evt_handler->set_key_scalar_dquoted(maybe_filtered);
7465 _maybe_skip_whitespace_tokens();
7466 _set_indentation(startindent);
7470 else if(first ==
'|')
7472 _c4dbgp(
"runk: scanning block-literal scalar");
7473 m_evt_handler->check_trailing_doc_token();
7476 m_doc_empty =
false;
7478 _scan_block(&sb, startindent);
7479 if(C4_LIKELY(!_maybe_scan_following_colon()))
7481 _c4dbgp(
"runk: set as val");
7482 _handle_annotations_before_blck_val_scalar();
7483 csubstr maybe_filtered = _maybe_filter_val_scalar_literal(sb);
7484 m_evt_handler->set_val_scalar_literal(maybe_filtered);
7488 _c4err(
"block literal keys must be enclosed in '?'");
7491 else if(first ==
'>')
7493 _c4dbgp(
"runk: scanning block-folded scalar");
7494 m_evt_handler->check_trailing_doc_token();
7497 m_doc_empty =
false;
7499 _scan_block(&sb, startindent);
7500 if(C4_LIKELY(!_maybe_scan_following_colon()))
7502 _c4dbgp(
"runk: set as val");
7503 _handle_annotations_before_blck_val_scalar();
7504 csubstr maybe_filtered = _maybe_filter_val_scalar_folded(sb);
7505 m_evt_handler->set_val_scalar_folded(maybe_filtered);
7509 _c4err(
"block folded keys must be enclosed in '?'");
7512 else if(_scan_scalar_plain_unk(&sc))
7514 _c4dbgp(
"runk: got a plain scalar");
7515 m_evt_handler->check_trailing_doc_token();
7518 m_doc_empty =
false;
7519 if(!_maybe_scan_following_colon())
7521 _c4dbgp(
"runk: set as val");
7522 _handle_annotations_before_blck_val_scalar();
7523 csubstr maybe_filtered = _maybe_filter_val_scalar_plain(sc, startindent);
7524 m_evt_handler->set_val_scalar_plain(maybe_filtered);
7528 _c4dbgp(
"runk: start new block map, set scalar as key");
7529 _handle_annotations_before_start_mapblck(startline);
7530 m_evt_handler->begin_map_val_block();
7531 _handle_annotations_and_indentation_after_start_mapblck(startindent, startline);
7532 csubstr maybe_filtered = _maybe_filter_key_scalar_plain(sc, startindent);
7533 m_evt_handler->set_key_scalar_plain(maybe_filtered);
7534 _maybe_skip_whitespace_tokens();
7535 _set_indentation(startindent);
7545 template<
class EventHandler>
7546 C4_COLD
void ParseEngine<EventHandler>::_handle_usty()
7548 _c4dbgpf(
"handle_usty target={}",
m_state->indref,
m_state->node_id);
7550 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_none(
BLCK|
FLOW));
7552 #ifdef RYML_NO_COVERAGE__TO_BE_DELETED
7555 _c4dbgp(
"usty[RNXT]: finishing!");
7560 _maybe_skip_comment();
7561 csubstr rem =
m_state->line_contents.rem;
7565 size_t pos = rem.first_not_of(
" \t");
7568 pos = pos !=
npos ? pos : rem.len;
7569 _c4dbgpf(
"skipping indentation of {}", pos);
7570 _line_progressed(pos);
7571 rem =
m_state->line_contents.rem;
7574 _c4dbgpf(
"rem is now [{}]~~~{}~~~", rem.len, rem);
7577 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, rem.len > 0);
7578 size_t startindent =
m_state->line_contents.indentation;
7579 char first = rem.str[0];
7582 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, ! has_any(
RMAP));
7583 _c4dbgpf(
"usty[RSEQ]: first='{}'", _c4prc(first));
7586 _c4dbgp(
"usty[RSEQ]: it's a flow seq. merging it");
7588 m_evt_handler->_push();
7590 _set_indentation(startindent);
7591 _line_progressed(1);
7592 _maybe_skip_whitespace_tokens();
7594 else if(first ==
'-' && _is_blck_token(rem))
7596 _c4dbgp(
"usty[RSEQ]: it's a block seq. merging it");
7598 m_evt_handler->_push();
7600 _set_indentation(startindent);
7601 _line_progressed(1);
7602 _maybe_skip_whitespace_tokens();
7606 _c4err(
"can only parse a seq into an existing seq");
7609 else if(has_any(
RMAP))
7611 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, ! has_any(
RSEQ));
7612 _c4dbgpf(
"usty[RMAP]: first='{}'", _c4prc(first));
7615 _c4dbgp(
"usty[RMAP]: it's a flow map. merging it");
7617 _handle_annotations_before_blck_val_scalar();
7618 m_evt_handler->_push();
7620 _set_indentation(startindent);
7621 _line_progressed(1);
7622 _maybe_skip_whitespace_tokens();
7624 else if(first ==
'?' && _is_blck_token(rem))
7626 _c4dbgp(
"usty[RMAP]: it's a block map + this key is complex");
7628 _handle_annotations_before_blck_val_scalar();
7629 m_evt_handler->_push();
7631 m_was_inside_qmrk =
true;
7632 _save_indentation();
7633 _line_progressed(1);
7634 _maybe_skip_whitespace_tokens();
7636 else if(first ==
':' && _is_blck_token(rem))
7638 _c4dbgp(
"usty[RMAP]: it's a map with an empty key");
7640 _handle_annotations_before_blck_val_scalar();
7641 m_evt_handler->_push();
7642 m_evt_handler->set_key_scalar_plain({});
7644 _save_indentation();
7645 _line_progressed(1);
7646 _maybe_skip_whitespace_tokens();
7648 else if(rem.begins_with(
'&'))
7650 csubstr anchor = _scan_anchor();
7651 _c4dbgpf(
"usty[RMAP]: anchor! [{}]~~~{}~~~", anchor.len, anchor);
7652 const size_t indentation =
m_state->line_contents.current_col(rem);
7653 const size_t line =
m_state->pos.line;
7654 _add_annotation(&m_pending_anchors, anchor, indentation, line);
7655 _set_indentation(
m_state->line_contents.current_col(rem));
7657 else if(first ==
'*')
7659 csubstr ref = _scan_ref_map();
7660 _c4dbgpf(
"usty[RMAP]: ref! [{}]~~~{}~~~", ref.len, ref);
7661 if(!_maybe_scan_following_colon())
7663 _c4err(
"cannot read a VAL to a map");
7667 _c4dbgp(
"usty[RMAP]: start new block map, set ref as key");
7668 const size_t startline =
m_state->pos.line;
7670 _handle_annotations_before_start_mapblck(startline);
7671 m_evt_handler->_push();
7672 _handle_annotations_and_indentation_after_start_mapblck(startindent, startline);
7673 m_evt_handler->set_key_ref(ref);
7674 _maybe_skip_whitespace_tokens();
7675 _set_indentation(startindent);
7679 else if(first ==
'!')
7681 csubstr tag = _scan_tag();
7682 _c4dbgpf(
"usty[RMAP]: val tag! [{}]~~~{}~~~", tag.len, tag);
7685 const size_t indentation =
m_state->line_contents.current_col(rem);
7686 const size_t line =
m_state->pos.line;
7687 _add_annotation(&m_pending_tags, tag, indentation, line);
7689 else if(first ==
'[' || (first ==
'-' && _is_blck_token(rem)))
7691 _c4err(
"cannot parse a seq into an existing map");
7695 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, ! has_any(
SSCL));
7696 startindent =
m_state->line_contents.indentation;
7697 const size_t startline =
m_state->pos.line;
7699 _c4dbgpf(
"usty[RMAP]: maybe scalar. first='{}'", _c4prc(first));
7702 _c4dbgp(
"usty[RMAP]: scanning single-quoted scalar");
7703 sc = _scan_scalar_squot();
7704 if(!_maybe_scan_following_colon())
7706 _c4err(
"cannot read a VAL to a map");
7710 _c4dbgp(
"usty[RMAP]: start new block map, set scalar as key");
7712 _handle_annotations_before_start_mapblck(startline);
7713 m_evt_handler->_push();
7714 _handle_annotations_and_indentation_after_start_mapblck(startindent, startline);
7715 csubstr maybe_filtered = _maybe_filter_key_scalar_squot(sc);
7716 m_evt_handler->set_key_scalar_squoted(maybe_filtered);
7717 _set_indentation(startindent);
7719 _maybe_skip_whitespace_tokens();
7722 else if(first ==
'"')
7724 _c4dbgp(
"usty[RMAP]: scanning double-quoted scalar");
7725 sc = _scan_scalar_dquot();
7726 if(!_maybe_scan_following_colon())
7728 _c4err(
"cannot read a VAL to a map");
7732 _c4dbgp(
"usty[RMAP]: start new block map, set double-quoted scalar as key");
7734 _handle_annotations_before_start_mapblck(startline);
7735 m_evt_handler->_push();
7736 _handle_annotations_and_indentation_after_start_mapblck(startindent, startline);
7737 csubstr maybe_filtered = _maybe_filter_key_scalar_dquot(sc);
7738 m_evt_handler->set_key_scalar_dquoted(maybe_filtered);
7739 _set_indentation(startindent);
7741 _maybe_skip_whitespace_tokens();
7744 else if(first ==
'|')
7746 _c4err(
"block literal keys must be enclosed in '?'");
7748 else if(first ==
'>')
7750 _c4err(
"block literal keys must be enclosed in '?'");
7752 else if(_scan_scalar_plain_unk(&sc))
7754 _c4dbgp(
"usty[RMAP]: got a plain scalar");
7755 if(!_maybe_scan_following_colon())
7757 _c4err(
"cannot read a VAL to a map");
7761 _c4dbgp(
"usty[RMAP]: start new block map, set scalar as key");
7763 _handle_annotations_before_start_mapblck(startline);
7764 m_evt_handler->_push();
7765 _handle_annotations_and_indentation_after_start_mapblck(startindent, startline);
7766 csubstr maybe_filtered = _maybe_filter_key_scalar_plain(sc, startindent);
7767 m_evt_handler->set_key_scalar_plain(maybe_filtered);
7768 _set_indentation(startindent);
7770 _maybe_skip_whitespace_tokens();
7775 _c4err(
"parse error");
7781 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, ! has_any(
RSEQ));
7782 _c4dbgpf(
"usty[UNK]: first='{}'", _c4prc(first));
7785 _c4dbgp(
"usty[UNK]: it's a flow seq");
7787 _handle_annotations_before_blck_val_scalar();
7788 m_evt_handler->begin_seq_val_flow();
7790 _set_indentation(startindent);
7791 _line_progressed(1);
7792 _maybe_skip_whitespace_tokens();
7794 else if(first ==
'-' && _is_blck_token(rem))
7796 _c4dbgp(
"usty[UNK]: it's a block seq");
7798 _handle_annotations_before_blck_val_scalar();
7799 m_evt_handler->begin_seq_val_block();
7801 _set_indentation(startindent);
7802 _line_progressed(1);
7803 _maybe_skip_whitespace_tokens();
7805 else if(first ==
'{')
7807 _c4dbgp(
"usty[UNK]: it's a flow map");
7809 _handle_annotations_before_blck_val_scalar();
7810 m_evt_handler->begin_map_val_flow();
7812 _set_indentation(startindent);
7813 _line_progressed(1);
7814 _maybe_skip_whitespace_tokens();
7816 else if(first ==
'?' && _is_blck_token(rem))
7818 _c4dbgp(
"usty[UNK]: it's a map + this key is complex");
7820 _handle_annotations_before_blck_val_scalar();
7821 m_evt_handler->begin_map_val_block();
7823 m_was_inside_qmrk =
true;
7824 _save_indentation();
7825 _line_progressed(1);
7826 _maybe_skip_whitespace_tokens();
7828 else if(first ==
':' && _is_blck_token(rem))
7830 _c4dbgp(
"usty[UNK]: it's a map with an empty key");
7832 _handle_annotations_before_blck_val_scalar();
7833 m_evt_handler->begin_map_val_block();
7834 m_evt_handler->set_key_scalar_plain({});
7836 _save_indentation();
7837 _line_progressed(1);
7838 _maybe_skip_whitespace_tokens();
7840 else if(first ==
'&')
7842 csubstr anchor = _scan_anchor();
7843 _c4dbgpf(
"usty[UNK]: anchor! [{}]~~~{}~~~", anchor.len, anchor);
7844 const size_t indentation =
m_state->line_contents.current_col(rem);
7845 const size_t line =
m_state->pos.line;
7846 _add_annotation(&m_pending_anchors, anchor, indentation, line);
7847 _set_indentation(
m_state->line_contents.current_col(rem));
7849 else if(first ==
'*')
7851 csubstr ref = _scan_ref_map();
7852 _c4dbgpf(
"usty[UNK]: ref! [{}]~~~{}~~~", ref.len, ref);
7853 if(!_maybe_scan_following_colon())
7855 _c4dbgp(
"usty[UNK]: set val ref");
7856 _handle_annotations_before_blck_val_scalar();
7857 m_evt_handler->set_val_ref(ref);
7861 _c4dbgp(
"usty[UNK]: start new block map, set ref as key");
7862 const size_t startline =
m_state->pos.line;
7864 _handle_annotations_before_start_mapblck(startline);
7865 m_evt_handler->begin_map_val_block();
7866 _handle_annotations_and_indentation_after_start_mapblck(startindent, startline);
7867 m_evt_handler->set_key_ref(ref);
7868 _maybe_skip_whitespace_tokens();
7869 _set_indentation(startindent);
7873 else if(first ==
'!')
7875 csubstr tag = _scan_tag();
7876 _c4dbgpf(
"usty[UNK]: val tag! [{}]~~~{}~~~", tag.len, tag);
7879 const size_t indentation =
m_state->line_contents.current_col(rem);
7880 const size_t line =
m_state->pos.line;
7881 _add_annotation(&m_pending_tags, tag, indentation, line);
7885 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, ! has_any(
SSCL));
7886 startindent =
m_state->line_contents.indentation;
7887 const size_t startline =
m_state->pos.line;
7890 _c4dbgpf(
"usty[UNK]: maybe scalar. first='{}'", _c4prc(first));
7893 _c4dbgp(
"usty[UNK]: scanning single-quoted scalar");
7894 sc = _scan_scalar_squot();
7895 if(!_maybe_scan_following_colon())
7897 _c4dbgp(
"usty[UNK]: set as val");
7898 _handle_annotations_before_blck_val_scalar();
7899 csubstr maybe_filtered = _maybe_filter_val_scalar_squot(sc);
7900 m_evt_handler->set_val_scalar_squoted(maybe_filtered);
7905 _c4dbgp(
"usty[UNK]: start new block map, set scalar as key");
7907 _handle_annotations_before_start_mapblck(startline);
7908 m_evt_handler->begin_map_val_block();
7909 _handle_annotations_and_indentation_after_start_mapblck(startindent, startline);
7910 csubstr maybe_filtered = _maybe_filter_key_scalar_squot(sc);
7911 m_evt_handler->set_key_scalar_squoted(maybe_filtered);
7912 _set_indentation(startindent);
7914 _maybe_skip_whitespace_tokens();
7917 else if(first ==
'"')
7919 _c4dbgp(
"usty[UNK]: scanning double-quoted scalar");
7920 sc = _scan_scalar_dquot();
7921 if(!_maybe_scan_following_colon())
7923 _c4dbgp(
"usty[UNK]: set as val");
7924 _handle_annotations_before_blck_val_scalar();
7925 csubstr maybe_filtered = _maybe_filter_val_scalar_dquot(sc);
7926 m_evt_handler->set_val_scalar_dquoted(maybe_filtered);
7931 _c4dbgp(
"usty[UNK]: start new block map, set double-quoted scalar as key");
7933 _handle_annotations_before_start_mapblck(startline);
7934 m_evt_handler->begin_map_val_block();
7935 _handle_annotations_and_indentation_after_start_mapblck(startindent, startline);
7936 csubstr maybe_filtered = _maybe_filter_key_scalar_dquot(sc);
7937 m_evt_handler->set_key_scalar_dquoted(maybe_filtered);
7938 _set_indentation(startindent);
7940 _maybe_skip_whitespace_tokens();
7943 else if(first ==
'|')
7945 _c4dbgp(
"usty[UNK]: scanning block-literal scalar");
7947 _scan_block(&sb, startindent);
7948 _c4dbgp(
"usty[UNK]: set as val");
7949 _handle_annotations_before_blck_val_scalar();
7950 csubstr maybe_filtered = _maybe_filter_val_scalar_literal(sb);
7951 m_evt_handler->set_val_scalar_literal(maybe_filtered);
7954 else if(first ==
'>')
7956 _c4dbgp(
"usty[UNK]: scanning block-folded scalar");
7958 _scan_block(&sb, startindent);
7959 _c4dbgp(
"usty[UNK]: set as val");
7960 _handle_annotations_before_blck_val_scalar();
7961 csubstr maybe_filtered = _maybe_filter_val_scalar_folded(sb);
7962 m_evt_handler->set_val_scalar_folded(maybe_filtered);
7965 else if(_scan_scalar_plain_unk(&sc))
7967 _c4dbgp(
"usty[UNK]: got a plain scalar");
7968 if(!_maybe_scan_following_colon())
7970 _c4dbgp(
"usty[UNK]: set as val");
7971 _handle_annotations_before_blck_val_scalar();
7972 csubstr maybe_filtered = _maybe_filter_val_scalar_plain(sc, startindent);
7973 m_evt_handler->set_val_scalar_plain(maybe_filtered);
7978 _c4dbgp(
"usty[UNK]: start new block map, set scalar as key");
7980 _handle_annotations_before_start_mapblck(startline);
7981 m_evt_handler->begin_map_val_block();
7982 _handle_annotations_and_indentation_after_start_mapblck(startindent, startline);
7983 csubstr maybe_filtered = _maybe_filter_key_scalar_plain(sc, startindent);
7984 m_evt_handler->set_key_scalar_plain(maybe_filtered);
7985 _set_indentation(startindent);
7987 _maybe_skip_whitespace_tokens();
7992 _c4err(
"parse error");
8001 template<
class EventHandler>
8004 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, m_evt_handler->m_stack.size() >= 1);
8008 m_evt_handler->start_parse(filename.str, &_s_relocate_arena,
this);
8009 m_evt_handler->begin_stream();
8010 while( ! _finished_file())
8013 while( ! _finished_line())
8016 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, ! m_evt_handler->m_curr->line_contents.rem.empty());
8021 else if(has_any(
RMAP))
8025 else if(has_any(
RUNK))
8031 _c4err(
"internal error");
8034 if(_finished_file())
8039 m_evt_handler->finish_parse();
8045 template<
class EventHandler>
8048 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, m_evt_handler->m_stack.size() >= 1);
8052 m_evt_handler->start_parse(filename.str, &_s_relocate_arena,
this);
8053 m_evt_handler->begin_stream();
8054 while( ! _finished_file())
8057 while( ! _finished_line())
8060 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, ! m_evt_handler->m_curr->line_contents.rem.empty());
8071 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_all(
RMAP));
8080 else if(has_any(
BLCK))
8084 _handle_seq_block();
8088 _RYML_CB_ASSERT(m_evt_handler->m_stack.m_callbacks, has_all(
RMAP));
8089 _handle_map_block();
8092 else if(has_any(
RUNK))
8096 else if(has_any(
USTY))
8102 _c4err(
"internal error");
8105 if(_finished_file())
8110 m_evt_handler->finish_parse();
8118 #undef _addrem_flags2
8121 #if defined(_MSC_VER)
8122 # pragma warning(pop)
8123 #elif defined(__clang__)
8124 # pragma clang diagnostic pop
8125 #elif defined(__GNUC__)
8126 # pragma GCC diagnostic pop
Lightweight generic type-safe wrappers for converting individual values to/from strings.
Holds a pointer to an existing tree, and a node id.
Tree const * tree() const noexcept
id_type id() const noexcept
bool readable() const noexcept
because a ConstNodeRef cannot be used to write to the tree, readable() has the same meaning as !...
This is the main driver of parsing logic: it scans the YAML or JSON source for tokens,...
Location location(Tree const &tree, id_type node_id) const
Get the location of a node of the last tree to be parsed by this parser.
FilterResult filter_scalar_plain(csubstr scalar, substr dst, size_t indentation)
filter a plain scalar
csubstr location_contents(Location const &loc) const
Get the string starting at a particular location, to the end of the parsed source buffer.
FilterResult filter_scalar_squoted(csubstr scalar, substr dst)
filter a single-quoted scalar
ParseEngine(EventHandler *evt_handler, ParserOptions opts={})
FilterResult filter_scalar_dquoted(csubstr scalar, substr dst)
filter a double-quoted scalar
void parse_json_in_place_ev(csubstr filename, substr src)
parse JSON in place, emitting events to the current handler
Location val_location(const char *val) const
Given a pointer to a buffer position, get the location.
FilterResult filter_scalar_plain_in_place(substr scalar, size_t cap, size_t indentation)
filter a plain scalar in place
FilterResult filter_scalar_squoted_in_place(substr scalar, size_t cap)
filter a single-quoted scalar in place
FilterResultExtending filter_scalar_dquoted_in_place(substr scalar, size_t cap)
filter a double-quoted scalar in place
void parse_in_place_ev(csubstr filename, substr src)
parse YAML in place, emitting events to the current handler
FilterResult filter_scalar_block_literal_in_place(substr scalar, size_t cap, size_t indentation, BlockChomp_e chomp)
filter a block-literal scalar in place
FilterResult filter_scalar_block_literal(csubstr scalar, substr dst, size_t indentation, BlockChomp_e chomp)
filter a block-literal scalar
FilterResult filter_scalar_block_folded_in_place(substr scalar, size_t cap, size_t indentation, BlockChomp_e chomp)
filter a block-folded scalar in place
ParseEngine & operator=(ParseEngine &&)
FilterResult filter_scalar_block_folded(csubstr scalar, substr dst, size_t indentation, BlockChomp_e chomp)
filter a block-folded scalar
NodeType type(id_type node) const
id_type prev_sibling(id_type node) const
bool has_key(id_type node) const
id_type parent(id_type node) const
id_type next_sibling(id_type node) const
csubstr const & key(id_type node) const
bool has_val(id_type node) const
csubstr const & val(id_type node) const
bool is_container(id_type node) const
#define RYML_ERRMSG_SIZE
size for the error message buffer
#define RYML_LOCATIONS_SMALL_THRESHOLD
threshold at which a location search will revert from linear to binary search.
bool atou(csubstr str, T *v) noexcept
Convert a trimmed string to an unsigned integral value.
@ NOTYPE
no node type or style is set
bool read_hex(csubstr s, I *v) noexcept
read an hexadecimal integer from a string.
size_t to_chars(substr buf, uint8_t v) noexcept
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
size_t _find_last_newline_and_larger_indentation(csubstr s, size_t indentation) noexcept
@ RTOP
reading at top level
@ BLCK
reading in block mode
@ RSET
the (implicit) map being read is a !!set.
@ RNXT
read next val or keyval
@ FLOW
reading is inside explicit flow chars: [] or {}
@ RUNK
reading unknown state (when starting): must determine whether scalar, map or seq
@ RKEY
reading a scalar as key
@ RKCL
reading the key colon (ie the : after the key in the map)
@ NDOC
no document mode. a document has ended and another has not started yet.
@ QSCL
stored scalar was quoted
@ USTY
reading in unknown style mode - must determine FLOW or BLCK reading an implicit map nested in an expl...
@ QMRK
reading an explicit key (? key)
@ SSCL
there's a stored scalar
@ RVAL
reading a scalar as val
int ParserFlag_t
data type for ParserState_e
#define _RYML_WITHOUT_TAB_TOKENS(...)
#define _ryml_relocate(s)
#define _c4dbgfsq(fmt,...)
#define _RYML_WITH_OR_WITHOUT_TAB_TOKENS(with, without)
#define _RYML_WITH_TAB_TOKENS(...)
#define _c4dbgfps(fmt,...)
#define _addrem_flags2(on, off)
Filters an input string into a different output string.
size_t offset
number of bytes from the beginning of the source buffer
Options to give to the parser to control its behavior.