302 , m_has_directives(that.m_has_directives)
303 , m_doc_empty(that.m_doc_empty)
305 , m_prev_val_end(
npos)
307 , m_newline_offsets(that.m_newline_offsets)
308 , m_newline_offsets_size(that.m_newline_offsets_size)
309 , m_newline_offsets_capacity(that.m_newline_offsets_capacity)
314template<
class EventHandler>
316 : m_options(that.m_options)
317 , m_evt_handler(that.m_evt_handler)
318 , m_pending_anchors(that.m_pending_anchors)
319 , m_pending_tags(that.m_pending_tags)
320 , m_has_directives_yaml(that.m_has_directives_yaml)
321 , m_has_directives(that.m_has_directives)
322 , m_doc_empty(that.m_doc_empty)
324 , m_prev_val_end(
npos)
326 , m_newline_offsets()
327 , m_newline_offsets_size()
328 , m_newline_offsets_capacity()
330 if(that.m_newline_offsets_capacity)
332 _resize_locations(that.m_newline_offsets_capacity);
333 RYML_CHECK_BASIC_CB_(m_evt_handler->m_stack.m_callbacks, m_newline_offsets_capacity == that.m_newline_offsets_capacity);
334 memcpy(m_newline_offsets, that.m_newline_offsets, that.m_newline_offsets_size * sizeof(size_t));
335 m_newline_offsets_size = that.m_newline_offsets_size;
339template<
class EventHandler>
343 m_options = (that.m_options);
344 m_evt_handler = that.m_evt_handler;
345 m_pending_anchors = that.m_pending_anchors;
346 m_pending_tags = that.m_pending_tags;
347 m_has_directives_yaml = that.m_has_directives_yaml;
348 m_has_directives = that.m_has_directives;
349 m_doc_empty = that.m_doc_empty;
350 m_prev_colon = that.m_prev_colon;
351 m_prev_val_end = that.m_prev_val_end;
352 m_encoding = that.m_encoding;
353 m_newline_offsets = (that.m_newline_offsets);
354 m_newline_offsets_size = (that.m_newline_offsets_size);
355 m_newline_offsets_capacity = (that.m_newline_offsets_capacity);
360template<
class EventHandler>
366 m_options = (that.m_options);
367 m_evt_handler = that.m_evt_handler;
368 m_pending_anchors = that.m_pending_anchors;
369 m_pending_tags = that.m_pending_tags;
370 m_has_directives_yaml = that.m_has_directives_yaml;
371 m_has_directives = that.m_has_directives;
372 m_doc_empty = that.m_doc_empty;
373 m_prev_colon = that.m_prev_colon;
374 m_prev_val_end = that.m_prev_val_end;
375 m_encoding = that.m_encoding;
376 if(that.m_newline_offsets_capacity > m_newline_offsets_capacity)
377 _resize_locations(that.m_newline_offsets_capacity);
378 RYML_CHECK_BASIC_CB_(m_evt_handler->m_stack.m_callbacks, m_newline_offsets_capacity >= that.m_newline_offsets_capacity);
379 RYML_CHECK_BASIC_CB_(m_evt_handler->m_stack.m_callbacks, m_newline_offsets_capacity >= that.m_newline_offsets_size);
380 memcpy(m_newline_offsets, that.m_newline_offsets, that.m_newline_offsets_size *
sizeof(
size_t));
381 m_newline_offsets_size = that.m_newline_offsets_size;
386template<
class EventHandler>
387void ParseEngine<EventHandler>::_clr()
391 m_pending_anchors = {};
393 m_has_directives_yaml =
false;
394 m_has_directives =
false;
397 m_prev_val_end =
npos;
399 m_newline_offsets = {};
400 m_newline_offsets_size = {};
401 m_newline_offsets_capacity = {};
404template<
class EventHandler>
405void ParseEngine<EventHandler>::_free()
407 if(m_newline_offsets)
409 RYML_CB_FREE_(m_evt_handler->m_stack.m_callbacks, m_newline_offsets,
size_t, m_newline_offsets_capacity);
410 m_newline_offsets =
nullptr;
411 m_newline_offsets_size = 0u;
412 m_newline_offsets_capacity = 0u;
419template<
class EventHandler>
420void ParseEngine<EventHandler>::_reset()
422 m_pending_anchors = {};
424 m_has_directives_yaml =
false;
425 m_has_directives =
false;
428 m_prev_val_end =
npos;
432 if(m_options.locations())
434 _prepare_locations();
441template<
class EventHandler>
442void ParseEngine<EventHandler>::_relocate_arena(
csubstr prev_arena,
substr next_arena,
substr *other)
444 _c4dbgp(
"relocate to new arena");
445 const char *pb = prev_arena.str;
446 const char *pe = prev_arena.str + prev_arena.len;
447 #define _ryml_relocate(s) \
448 if((s).str >= pb && (s).str <= pe) \
450 (s).str = next_arena.str + ((s).str - pb); \
459 for(
size_t i = 0; i < m_pending_tags.num_entries; ++i)
464 for(
size_t i = 0; i < m_pending_anchors.num_entries; ++i)
471 for(
size_t i = 0, sz = tds.size(); i < sz; ++i)
478 TagCache &tch = m_evt_handler->tag_cache();
479 for(
id_type i = 0, sz = tch.m_entries.size(); i < sz; ++i)
489 #undef _ryml_relocate
493template<
class EventHandler>
496 csubstr prev = m_evt_handler->arena();
497 substr out = m_evt_handler->alloc_arena(len);
498 substr curr = m_evt_handler->arena();
499 if(curr.str != prev.str)
500 _relocate_arena(prev, curr, other);
509template<
class EventHandler>
510template<
class DumpFn>
513 ParserState const *
const C4_RESTRICT st = m_evt_handler->m_curr;
520 csubstr m_file = m_evt_handler->m_curr->pos.name;
523 dbg_dump_(std::forward<DumpFn>(dumpfn),
"{}:", m_file);
524 offs += m_file.len + 1;
526 dbg_dump_(std::forward<DumpFn>(dumpfn),
"{}:{}: ", st->pos.line, st->pos.col);
527 csubstr maybe_full_content = (contents.len < 80u ? contents : contents.first(80u));
529 dbg_dump_(std::forward<DumpFn>(dumpfn),
"{}{} (size={})\n",
escaped_scalar(maybe_full_content,
true), maybe_ellipsis, contents.len);
531 size_t firstcol = (size_t)(lc.rem.str - lc.full.str);
532 size_t lastcol = firstcol + lc.rem.len;
535 for(
size_t i = 0; i < offs + firstcol_adj; ++i)
536 std::forward<DumpFn>(dumpfn)(
" ");
537 std::forward<DumpFn>(dumpfn)(
"^");
538 for(
size_t i = 1, e = (len < 80u ? len : 80u); i < e; ++i)
539 std::forward<DumpFn>(dumpfn)(
"~");
540 dbg_dump_(std::forward<DumpFn>(dumpfn),
"{} (cols {}-{})\n", maybe_ellipsis, firstcol+1, lastcol+1);
544 std::forward<DumpFn>(dumpfn)(
"\n");
549 dbg_dump_(std::forward<DumpFn>(dumpfn),
"top state: {}\n", detail::_parser_flags_to_str(flagbuf_, m_evt_handler->m_curr->flags));
553template<
class EventHandler>
559 dbg_printf_(
"state[{}]: ind={} node={} flags={}\n", s.level, s.indref, s.node_id, detail::_parser_flags_to_str(buf, s.flags));
563template<
class EventHandler>
567 _print_state_stack(buf);
574template<
class EventHandler>
575template<
class ...Args>
576C4_NORETURN C4_NO_INLINE
void ParseEngine<EventHandler>::_err(
Location const& cpploc,
Location const& ymlloc,
const char* fmt, Args
const& ...args)
const
578 m_evt_handler->cancel_parse();
582template<
class EventHandler>
583template<
class ...Args>
584C4_NORETURN C4_NO_INLINE
void ParseEngine<EventHandler>::_err(
Location const& cpploc,
const char *fmt, Args
const& ...args)
const
586 m_evt_handler->cancel_parse();
587 err_parse(m_evt_handler->m_stack.m_callbacks,
ErrorDataParse{cpploc, m_evt_handler->m_curr->pos}, fmt, args...);
593template<
class EventHandler>
594template<
class ...Args>
599 dbg_printf_(fmt, args...);
601 _fmt_msg(dbg_dumper_);
608template<
class EventHandler>
609bool ParseEngine<EventHandler>::_finished_file()
const
611 bool ret = m_evt_handler->m_curr->pos.offset >= _buf().len;
615 _c4dbgp(
"finished file!!!");
621template<
class EventHandler>
622C4_HOT C4_ALWAYS_INLINE
bool ParseEngine<EventHandler>::_finished_line() const
624 return m_evt_handler->m_curr->line_contents.rem.empty();
630template<
class EventHandler>
631void ParseEngine<EventHandler>::_maybe_skip_whitespace_tokens()
633 if(m_evt_handler->m_curr->line_contents.rem.len && (m_evt_handler->m_curr->line_contents.rem.str[0] ==
' ' RYML_WITH_TAB_TOKENS_(|| m_evt_handler->m_curr->line_contents.rem.str[0] ==
'\t')))
637 pos = m_evt_handler->m_curr->line_contents.rem.len;
638 _c4dbgpf(
"skip {} whitespace characters", pos);
639 _line_progressed(pos);
643template<
class EventHandler>
644void ParseEngine<EventHandler>::_maybe_skipchars(
char c)
646 if(m_evt_handler->m_curr->line_contents.rem.len && m_evt_handler->m_curr->line_contents.rem.str[0] == c)
648 size_t pos = m_evt_handler->m_curr->line_contents.rem.first_not_of(c);
650 pos = m_evt_handler->m_curr->line_contents.rem.len;
651 _c4dbgpf(
"skip {}x'{}'", pos, _c4prc(c));
652 _line_progressed(pos);
656template<
class EventHandler>
658void ParseEngine<EventHandler>::_skipchars(
const char (&chars)[N])
660 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, m_evt_handler->m_curr->line_contents.rem.begins_with_any(chars), m_evt_handler->m_curr->pos);
661 size_t pos = m_evt_handler->m_curr->line_contents.rem.first_not_of(chars);
663 pos = m_evt_handler->m_curr->line_contents.rem.len;
664 _c4dbgpf(
"skip {} characters", pos);
665 _line_progressed(pos);
668template<
class EventHandler>
669void ParseEngine<EventHandler>::_skip_comment()
671 LineContents const& C4_RESTRICT lc = m_evt_handler->m_curr->line_contents;
672 const size_t col = m_evt_handler->m_curr->pos.col - 1u;
673 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, lc.rem.begins_with(
'#'), m_evt_handler->m_curr->pos);
674 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, lc.rem.is_sub(lc.full), m_evt_handler->m_curr->pos);
675 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, m_evt_handler->m_curr->pos.col >= 1, m_evt_handler->m_curr->pos);
676 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, col == ((
size_t)(lc.rem.str - lc.full.str)), m_evt_handler->m_curr->pos);
678 if(lc.rem.str != lc.full.str)
680 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, col > 0, m_evt_handler->m_curr->pos);
681 const char prev = lc.full.str[col - 1u];
682 if C4_UNLIKELY(prev !=
' ' && prev !=
'\t')
683 _c4err(
"comment not preceded by whitespace");
685 _c4dbgpf(
"comment was '{}'", m_evt_handler->m_curr->line_contents.rem);
686 _line_progressed(m_evt_handler->m_curr->line_contents.rem.len);
689template<class EventHandler>
690void ParseEngine<EventHandler>::_maybe_skip_comment_strict()
692 size_t pos = m_evt_handler->m_curr->line_contents.rem.first_not_of(
" \t");
695 if(
'#' == m_evt_handler->m_curr->line_contents.rem[pos])
697 _line_progressed(pos);
703template<
class EventHandler>
704void ParseEngine<EventHandler>::_maybe_skip_comment()
706 size_t pos = m_evt_handler->m_curr->line_contents.rem.first_not_of(
" \t");
709 if(
'#' == m_evt_handler->m_curr->line_contents.rem[pos])
711 _line_progressed(pos);
717 _line_progressed(m_evt_handler->m_curr->line_contents.rem.len);
721template<
class EventHandler>
722bool ParseEngine<EventHandler>::_maybe_scan_following_colon() noexcept
724 size_t pos = m_evt_handler->m_curr->line_contents.rem.first_not_of(
" \t");
727 if(
':' == m_evt_handler->m_curr->line_contents.rem[pos])
731 if(++pos < m_evt_handler->m_curr->line_contents.rem.len)
733 const char next = m_evt_handler->m_curr->line_contents.rem.str[pos];
739 _line_progressed(pos);
745 _line_progressed(m_evt_handler->m_curr->line_contents.rem.len);
753template<
class EventHandler>
754csubstr ParseEngine<EventHandler>::_scan_anchor()
756 csubstr s = m_evt_handler->m_curr->line_contents.rem;
757 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, s.begins_with(
'&'), m_evt_handler->m_curr->pos);
759 _line_progressed(1u + anchor.len);
760 _maybe_skipchars(
' ');
764template<
class EventHandler>
765csubstr ParseEngine<EventHandler>::_scan_ref_seq()
767 csubstr s = m_evt_handler->m_curr->line_contents.rem;
768 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, s.begins_with(
'*'), m_evt_handler->m_curr->pos);
769 _set_first(s, s.first_of(
" ,]\t"));
770 _line_progressed(s.len);
774template<
class EventHandler>
775csubstr ParseEngine<EventHandler>::_scan_ref_map()
777 csubstr s = m_evt_handler->m_curr->line_contents.rem;
778 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, s.begins_with(
'*'), m_evt_handler->m_curr->pos);
779 _set_first(s, s.first_of(
" ,}\t"));
780 _line_progressed(s.len);
784template<
class EventHandler>
785csubstr ParseEngine<EventHandler>::_scan_tag()
787 csubstr t = m_evt_handler->m_curr->line_contents.rem;
788 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, t.begins_with(
'!'), m_evt_handler->m_curr->pos);
789 if(!t.begins_with(
"!<"))
791 _c4dbgp(
"begins with '!'");
792 _set_first(t, t.first_of(
" ,]}\t"));
793 if C4_UNLIKELY(t.first_of(
"[{") !=
npos)
795 _line_progressed(t.len);
796 if(m_options.resolve_tags_all() || (m_options.resolve_tags() &&
is_custom_tag(t)))
801 _c4dbgp(
"begins with '!<'");
802 size_t pos = t.find(
'>');
803 if C4_UNLIKELY(pos ==
npos)
805 _set_first_strict(t, pos+1);
806 _line_progressed(t.len);
809 _maybe_skip_whitespace_tokens();
813template<
class EventHandler>
816 csubstr t = m_evt_handler->m_curr->line_contents.rem;
817 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, t.begins_with(
'!'), m_evt_handler->m_curr->pos);
818 if(!t.begins_with(
"!<"))
820 _c4dbgp(
"begins with '!'");
821 _set_first(t, t.first_of(
" ,\t"));
822 if C4_UNLIKELY(t.first_of(
"[{") !=
npos)
824 _line_progressed(t.len);
826 if(m_options.resolve_tags_all() || (m_options.resolve_tags() &&
is_custom_tag(t)))
831 _c4dbgp(
"begins with '!<'");
832 size_t pos = t.find(
'>');
833 if C4_UNLIKELY(pos ==
npos)
835 _set_first_strict(t, pos+1);
836 _line_progressed(t.len);
840 _maybe_skip_whitespace_tokens();
847template<
class EventHandler>
848bool ParseEngine<EventHandler>::_is_valid_start_scalar_plain_flow_check_block_token(
csubstr s)
850 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, s.len > 0, m_evt_handler->m_curr->pos);
851 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, s.begins_with_any(
":-"), m_evt_handler->m_curr->pos);
852 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, s.count(
'\n') == 0, m_evt_handler->m_curr->pos);
853 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, s.count(
'\r') == 0, m_evt_handler->m_curr->pos);
865 _c4dbgpf(
"not a scalar: found non-scalar token '{}{}'", s.str[0], s.str[1]);
875 _c4err(
"invalid token \":{}\"", _c4prc(s.str[1]));
890template<
class EventHandler>
891bool ParseEngine<EventHandler>::_is_valid_start_scalar_plain_flow_check_qmrk(
csubstr s)
893 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, s.len > 0, m_evt_handler->m_curr->pos);
894 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, s[0] ==
'?', m_evt_handler->m_curr->pos);
895 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, s.count(
'\n') == 0, m_evt_handler->m_curr->pos);
896 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, s.count(
'\r') == 0, m_evt_handler->m_curr->pos);
903 _c4dbgpf(
"not a scalar: found non-scalar token '?{}'", _c4prc(s.str[1]));
909 _c4err(
"invalid token \"?{}\"", _c4prc(s.str[1]));
923template<
class EventHandler>
924bool ParseEngine<EventHandler>::_is_valid_start_scalar_plain_flow(
csubstr s)
926 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, !s.empty(), m_evt_handler->m_curr->pos);
942 _c4dbgpf(
"not a scalar: found non-scalar token '{}'", _c4prc(s.str[0]));
947 _c4dbgpf(
"suspicious token='{}' len={}", _c4prc(s.str[0]), s.len);
948 return _is_valid_start_scalar_plain_flow_check_block_token(s);
950 _c4dbgpf(
"qmrk='{}' len={}", _c4prc(s.str[0]), s.len);
951 return _is_valid_start_scalar_plain_flow_check_qmrk(s);
959template<
class EventHandler>
960bool ParseEngine<EventHandler>::_scan_scalar_plain_handle_newline(
csubstr s,
size_t offs)
962 _c4dbgpf(
"newl[PLAIN]: found '\\n'. offs={} line={} sofar={}", offs, m_evt_handler->m_curr->pos.line, prs_(s.first(offs),
true));
965 _c4dbgp(
"newl[PLAIN]: buffer continues");
967 size_t next_line_indentation = next_line.
first_not_of(
' ');
968 if(next_line_indentation !=
npos)
970 _c4dbgpf(
"newl[PLAIN]: line={} indentation={} indref={}", m_evt_handler->m_curr->pos.line + 1, next_line_indentation, m_evt_handler->m_curr->indref);
971 next_line = next_line.first(next_line.first_of(
"\n\r"));
972 _c4dbgpf(
"newl[PLAIN]: has indentation. next_line={}", prs_(next_line));
973 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, next_line_indentation <= next_line.len, m_evt_handler->m_curr->pos);
974 if C4_LIKELY(next_line_indentation >= m_evt_handler->m_curr->indref)
976 _c4dbgp(
"newl[PLAIN]: larger indentation");
977 next_line = next_line.sub(next_line_indentation);
979 else if C4_UNLIKELY(next_line.len && next_line.triml(
' ').len)
981 _c4dbgp(
"newl[PLAIN]: err, smaller indentation");
982 _line_progressed(m_evt_handler->m_curr->line_contents.rem.len);
985 if(m_evt_handler->m_curr->line_contents.indentation !=
npos)
986 _line_progressed(m_evt_handler->m_curr->line_contents.indentation);
989 _c4dbgpf(
"newl[PLAIN]: next_line.len={}", next_line.len);
992 size_t fno = next_line.first_not_of(
" \t");
996 switch(next_line.str[fno])
998 case ',':
case ']':
case '#':
999 _c4dbgpf(
"newl[PLAIN]: found terminating character beginning next line: '{}'", next_line.str[fno]);
1002 _c4dbgp(
"newl[PLAIN]: found :");
1003 if(fno + 1 == next_line.len || _is_blck_token(next_line.sub(fno)))
1005 _c4dbgpf(
"newl[PLAIN]: found terminating character beginning next line: '{}'", next_line.str[fno]);
1014 _line_progressed(m_evt_handler->m_curr->line_contents.rem.len);
1020template<
class EventHandler>
1021bool ParseEngine<EventHandler>::_scan_scalar_plain_seq_flow(ScannedScalar *C4_RESTRICT sc)
1023 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RMAP), m_evt_handler->m_curr->pos);
1024 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RBLCK), m_evt_handler->m_curr->pos);
1025 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_any(
RSEQ|
RSEQIMAP), m_evt_handler->m_curr->pos);
1026 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_any(
RFLOW), m_evt_handler->m_curr->pos);
1027 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_any(
RVAL), m_evt_handler->m_curr->pos);
1029 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, !m_evt_handler->m_curr->line_contents.rem.begins_with(
' '), m_evt_handler->m_curr->pos);
1030 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, !m_evt_handler->m_curr->line_contents.rem.begins_with(
'\n'), m_evt_handler->m_curr->pos);
1032 if(!m_evt_handler->m_curr->line_contents.rem.len || !_is_valid_start_scalar_plain_flow(m_evt_handler->m_curr->line_contents.rem))
1035 substr s = _buf().
sub(m_evt_handler->m_curr->pos.offset);
1036 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, s.begins_with(m_evt_handler->m_curr->line_contents.rem), m_evt_handler->m_curr->pos);
1038 _c4dbgp(
"scanning seqflow scalar...");
1040 bool needs_filter =
false;
1043 for( ; offs < s.len; ++offs, ++col)
1045 const char c = s.str[offs];
1050 _c4dbgpf(
"found terminating character at {}: '{}'", offs, c);
1051 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, offs > 0, m_evt_handler->m_curr->pos);
1054 _c4dbgpf(
"found '\\n' at col={}", col);
1055 if(!_scan_scalar_plain_handle_newline(s, offs))
1058 needs_filter =
true;
1062 needs_filter =
true;
1065 _c4dbgp(
"found suspicious ':'");
1066 if(s.len > offs + 1)
1068 char next = s.str[offs + 1];
1069 _c4dbgpf(
"next char is '{}'", _c4prc(next));
1075 next = after.str[0];
1076 _c4dbgpf(
"skip \\r to '{}'", _c4prc(next));
1080 if(next ==
' ' RYML_WITH_TAB_TOKENS_(|| next ==
'\t') || next ==
',' || next ==
'\n' || next ==
']')
1082 _c4dbgp(
"map starting!");
1087 _c4dbgp(
"':' nothing to see here");
1092 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, s.len == offs + 1, m_evt_handler->m_curr->pos);
1093 _line_progressed(col);
1094 _c4err(
"missing termination: '{}'", c);
1099 _c4dbgp(
"found suspicious '#'");
1100 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, offs > 0, m_evt_handler->m_curr->pos);
1101 char prev = s.str[offs - 1];
1104 _c4dbgpf(
"found terminating character at {}: '{}'", offs, c);
1112 _line_progressed(col);
1113 _c4err(
"invalid character: '{}'", c);
1116 _c4dbgpf(
"doc token character: '{}', offs={}", c, offs);
1117 if(offs == 0 && m_evt_handler->m_curr->at_line_beginning())
1119 _c4dbgp(
"at line beginning");
1120 if(s.len >= 3 && s.str[1] == c && s.str[2] == c)
1133 _line_progressed(col);
1134 _set_first(s, offs);
1136 sc->needs_filter = needs_filter;
1138 _c4prscalar(
"scanned plain scalar", sc->scalar,
true);
1143template<
class EventHandler>
1144bool ParseEngine<EventHandler>::_scan_scalar_plain_map_flow(ScannedScalar *C4_RESTRICT sc)
1146 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RSEQ) || has_any(
RSEQIMAP), m_evt_handler->m_curr->pos);
1147 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RBLCK), m_evt_handler->m_curr->pos);
1148 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_any(
RMAP|
RSEQIMAP), m_evt_handler->m_curr->pos);
1149 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_any(
RFLOW), m_evt_handler->m_curr->pos);
1150 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_any(
RKEY|
RVAL|
QMRK), m_evt_handler->m_curr->pos);
1152 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, !m_evt_handler->m_curr->line_contents.rem.begins_with(
' '), m_evt_handler->m_curr->pos);
1153 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, !m_evt_handler->m_curr->line_contents.rem.begins_with(
'\n'), m_evt_handler->m_curr->pos);
1155 if(!m_evt_handler->m_curr->line_contents.rem.len || !_is_valid_start_scalar_plain_flow(m_evt_handler->m_curr->line_contents.rem))
1158 substr s = _buf().
sub(m_evt_handler->m_curr->pos.offset);
1159 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, s.begins_with(m_evt_handler->m_curr->line_contents.rem), m_evt_handler->m_curr->pos);
1161 _c4dbgp(
"scanning mapflow scalar...");
1163 bool needs_filter =
false;
1166 for( ; offs < s.len; ++offs, ++col)
1168 const char c = s.str[offs];
1173 _c4dbgpf(
"found terminating character at {}: '{}'", offs, c);
1174 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, offs > 0, m_evt_handler->m_curr->pos);
1177 _c4dbgpf(
"found '\\n' at col={}", col);
1178 if(!_scan_scalar_plain_handle_newline(s, offs))
1181 needs_filter =
true;
1185 needs_filter =
true;
1188 _c4dbgpf(
"found ':'", c);
1192 const char next = s.str[offs+1];
1193 _c4dbgpf(
"next='{}'", c);
1194 if(next ==
' ' || next ==
',' || next ==
'}' || next ==
'\n' || next ==
'\r' RYML_WITH_TAB_TOKENS_(|| next ==
'\t'))
1196 _c4dbgpf(
"found terminating character: '{}'", c);
1203 _line_progressed(col);
1204 _c4err(
"invalid character: '{}'", c);
1207 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_any(
RSEQIMAP), m_evt_handler->m_curr->pos);
1216 _line_progressed(col);
1219 sc->needs_filter = needs_filter;
1221 _c4prscalar(
"scanned plain scalar", sc->scalar,
true);
1223 return sc->scalar.len > 0u;
1226template<
class EventHandler>
1227bool ParseEngine<EventHandler>::_scan_scalar_seq_json(ScannedScalar *C4_RESTRICT sc)
1229 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RMAP), m_evt_handler->m_curr->pos);
1230 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RBLCK), m_evt_handler->m_curr->pos);
1231 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_any(
RSEQ), m_evt_handler->m_curr->pos);
1232 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_any(
RFLOW), m_evt_handler->m_curr->pos);
1234 substr s = m_evt_handler->m_curr->line_contents.rem;
1235 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, !s.begins_with(
' '), m_evt_handler->m_curr->pos);
1236 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, s.len > 0, m_evt_handler->m_curr->pos);
1238 _c4dbgp(
"seq_json: scanning scalar...");
1245 _c4dbgp(
"seq_json: not a scalar.");
1250 const size_t len = _begins_with_special_json_scalar(s);
1253 char c = s.len > len ? s.str[len] :
',';
1254 if(c ==
',' || c ==
']' || c ==
' ' || c ==
'\n' || c ==
'\t' || c ==
'\r')
1256 sc->scalar = s.first(len);
1257 sc->needs_filter =
false;
1258 _c4dbgpf(
"seq_json: special scalar: '{}'", sc->scalar);
1259 _line_progressed(len);
1271 for( ; i < s.len; ++i)
1273 const char c = s.str[i];
1280 _c4dbgpf(
"seq_json: found terminating character: '{}'", c);
1289 _line_progressed(i);
1290 sc->scalar = s.first(i);
1291 sc->needs_filter =
false;
1292 _c4dbgpf(
"seq_json: scalar was {}", prs_(sc->scalar,
true));
1297template<
class EventHandler>
1298bool ParseEngine<EventHandler>::_scan_scalar_map_json(ScannedScalar *C4_RESTRICT sc)
1300 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RSEQ), m_evt_handler->m_curr->pos);
1301 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RBLCK), m_evt_handler->m_curr->pos);
1302 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_any(
RMAP), m_evt_handler->m_curr->pos);
1303 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_any(
RFLOW), m_evt_handler->m_curr->pos);
1304 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_any(
RKEY|
RVAL), m_evt_handler->m_curr->pos);
1306 substr s = m_evt_handler->m_curr->line_contents.rem;
1307 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, !s.begins_with(
' '), m_evt_handler->m_curr->pos);
1308 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, s.len > 0, m_evt_handler->m_curr->pos);
1310 _c4dbgp(
"scanning scalar...");
1313 const size_t len = _begins_with_special_json_scalar(s);
1316 char c = s.len > len ? s.str[len] :
',';
1317 _c4dbgpf(
"begins with special scalar: {} next='{}'", s.first(len), _c4prc(c));
1318 if(c ==
',' || c ==
'}' || c ==
' ' || c ==
'\n' || c ==
'\t' || c ==
'\r')
1320 sc->scalar = s.first(len);
1321 sc->needs_filter =
false;
1322 _c4dbgpf(
"special json scalar: '{}'", prs_(sc->scalar));
1323 _line_progressed(len);
1335 for( ; i < s.len; ++i)
1337 const char c = s.str[i];
1344 _c4dbgpf(
"found terminating character: '{}'", c);
1355 _line_progressed(i);
1356 sc->scalar = s.first(i);
1357 sc->needs_filter =
false;
1358 _c4dbgpf(
"scalar was {}", prs_(sc->scalar));
1365template<
class EventHandler>
1366bool ParseEngine<EventHandler>::_is_doc_begin(
csubstr s)
1368 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, s[0] ==
'-', m_evt_handler->m_curr->pos);
1369 return (m_evt_handler->m_curr->line_contents.indentation == 0u && m_evt_handler->m_curr->at_line_beginning() && _is_doc_begin_token(s));
1372template<
class EventHandler>
1373bool ParseEngine<EventHandler>::_is_doc_end(
csubstr s)
1375 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, s[0] ==
'.', m_evt_handler->m_curr->pos);
1376 return (m_evt_handler->m_curr->line_contents.indentation == 0u && m_evt_handler->m_curr->at_line_beginning() && _is_doc_end_token(s));
1379template<
class EventHandler>
1380bool ParseEngine<EventHandler>::_scan_scalar_plain_blck(ScannedScalar *C4_RESTRICT sc,
size_t indentation)
1382 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RFLOW), m_evt_handler->m_curr->pos);
1383 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RSEQIMAP), m_evt_handler->m_curr->pos);
1384 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_any(
RBLCK|
RUNK|
USTY), m_evt_handler->m_curr->pos);
1386 substr s = m_evt_handler->m_curr->line_contents.rem;
1387 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, !s.begins_with(
' '), m_evt_handler->m_curr->pos);
1388 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, s.len > 0, m_evt_handler->m_curr->pos);
1393 if(_is_blck_token(s))
1397 else if(_is_doc_begin(s))
1399 _c4dbgp(
"token is doc start");
1405 if(_is_blck_token(s))
1420 _c4dbgp(
"token is doc end");
1426 _c4dbgpf(
"plain scalar! indentation={}", indentation);
1428 const size_t start_offset = m_evt_handler->m_curr->pos.offset;
1429 const size_t start_line = m_evt_handler->m_curr->pos.line;
1431 bool needs_filter =
false;
1434 _c4dbgpf(
"plain scalar line: {}", prs_(s));
1435 for(
size_t i = 0; i < s.len; ++i)
1437 const char curr = s.str[i];
1442 _c4dbgpf(
"[{}]: got suspicious ':'", i);
1446 _c4dbgpf(
"followed by '{}'", i+1 == s.len ?
csubstr(
"\\n") : _c4prc(s.str[i+1]));
1447 _line_progressed(i);
1449 if C4_LIKELY(m_evt_handler->m_curr->pos.line == start_line)
1451 _c4dbgp(
"start line. scalar ends here");
1456 _c4err(
"multiline scalars cannot be used as keys");
1462 while(j + 1 < s.len && s.str[j+1] ==
':')
1464 _c4dbgp(
"skip colon");
1467 i = j > i ? j-1 : i;
1468 _c4dbgp(
"nothing to see here");
1472 _c4dbgp(
"got suspicious '#'");
1473 if(!i || (s.str[i-1] ==
' ' || s.str[i-1] ==
'\t'))
1475 _c4dbgp(
"comment! scalar ends here");
1476 _line_progressed(i);
1481 _c4dbgp(
"nothing to see here");
1486 _line_progressed(s.len);
1487 csubstr next_peeked = _peek_next_line(m_evt_handler->m_curr->pos.offset);
1488 next_peeked = next_peeked.trimr(
"\n\r");
1489 const size_t next_indentation = next_peeked.first_not_of(
' ');
1490 _c4dbgpf(
"indentation curr={} next={}", indentation, next_indentation);
1491 if(next_indentation < indentation)
1493 _c4dbgp(
"smaller indentation! scalar ended");
1496 else if(next_indentation == 0 && next_peeked.len > 0)
1498 const char first = next_peeked.str[0];
1502 _c4dbgpf(
"doc begin? peeked={}", prs_(next_peeked,
size_t(3)));
1503 if(_is_doc_begin_token(next_peeked))
1505 _c4dbgp(
"doc begin! scalar ended");
1510 _c4dbgpf(
"doc end? peeked={}", prs_(next_peeked,
size_t(3)));
1511 if(_is_doc_end_token(next_peeked))
1513 _c4dbgp(
"doc end! scalar ended");
1520 _c4dbgp(
"next line!");
1521 if(!_finished_file())
1523 _c4dbgp(
"next line!");
1529 _c4dbgp(
"file finished!");
1532 s = m_evt_handler->m_curr->line_contents.rem;
1533 needs_filter =
true;
1538 sc->scalar = _buf().range(start_offset, m_evt_handler->m_curr->pos.offset).trimr(
" \n\r\t");
1539 sc->needs_filter = needs_filter;
1541 _c4dbgpf(
"scalar was {}", prs_(sc->scalar));
1546template<
class EventHandler>
1547C4_ALWAYS_INLINE
bool ParseEngine<EventHandler>::_scan_scalar_plain_seq_blck(ScannedScalar *C4_RESTRICT sc)
1549 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RMAP), m_evt_handler->m_curr->pos);
1550 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RFLOW), m_evt_handler->m_curr->pos);
1551 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RSEQIMAP), m_evt_handler->m_curr->pos);
1552 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_any(
RSEQ), m_evt_handler->m_curr->pos);
1553 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_any(
RBLCK), m_evt_handler->m_curr->pos);
1554 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_any(
RVAL), m_evt_handler->m_curr->pos);
1555 return _scan_scalar_plain_blck(sc, m_evt_handler->m_curr->indref + 1u);
1558template<
class EventHandler>
1559C4_ALWAYS_INLINE
bool ParseEngine<EventHandler>::_scan_scalar_plain_map_blck(ScannedScalar *C4_RESTRICT sc)
1561 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RSEQ), m_evt_handler->m_curr->pos);
1562 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RFLOW), m_evt_handler->m_curr->pos);
1563 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_any(
RMAP), m_evt_handler->m_curr->pos);
1564 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_any(
RBLCK), m_evt_handler->m_curr->pos);
1565 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_any(
RKEY|
RVAL|
QMRK), m_evt_handler->m_curr->pos);
1566 return _scan_scalar_plain_blck(sc, m_evt_handler->m_curr->indref + 1u);
1569template<
class EventHandler>
1570C4_ALWAYS_INLINE
bool ParseEngine<EventHandler>::_scan_scalar_plain_unk(ScannedScalar *C4_RESTRICT sc)
1572 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_any(
RUNK|
USTY), m_evt_handler->m_curr->pos);
1573 return _scan_scalar_plain_blck(sc, m_evt_handler->m_curr->indref);
1579template<
class EventHandler>
1580substr ParseEngine<EventHandler>::_peek_next_line(
size_t pos)
const
1584 pos = pos ==
npos ? m_evt_handler->m_curr->pos.offset : pos;
1585 if(pos >= _buf().len)
1589 rem = _from_next_line(_buf().sub(pos));
1594 nlpos = rem.first_of(
"\r\n");
1596 nlpos += _extend_from_combined_newline(rem[nlpos], rem[nlpos+1]);
1597 rem = rem.left_of(nlpos,
true);
1599 _c4dbgpf(
"peek next line @ {}: (len={})'{}'", pos, rem.len, rem.trimr(
"\r\n"));
1603 _c4dbgpf(
"peek next line @ {}: (len=0)''", pos);
1609template<
class EventHandler>
1610void ParseEngine<EventHandler>::_scan_line()
1612 if C4_LIKELY(m_evt_handler->m_curr->pos.offset < _buf().len)
1613 m_evt_handler->m_curr->line_contents.reset_with_next_line(_buf(), m_evt_handler->m_curr->pos.offset);
1615 m_evt_handler->m_curr->line_contents.reset_with_next_line(_buf().last(0), 0);
1618template<
class EventHandler>
1619void ParseEngine<EventHandler>::_line_progressed(
size_t ahead)
1621 _c4dbgpf(
"line[{}] ({} cols) progressed by {}: col {}-->{} offset {}-->{}",
1622 m_evt_handler->m_curr->pos.line,
1623 m_evt_handler->m_curr->line_contents.full.len,
1624 ahead, m_evt_handler->m_curr->pos.col,
1625 m_evt_handler->m_curr->pos.col+ahead,
1626 m_evt_handler->m_curr->pos.offset,
1627 m_evt_handler->m_curr->pos.offset+ahead);
1628 m_evt_handler->m_curr->pos.offset += ahead;
1629 m_evt_handler->m_curr->pos.col += ahead;
1630 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, m_evt_handler->m_curr->pos.col <= m_evt_handler->m_curr->line_contents.num_cols+1, m_evt_handler->m_curr->pos);
1631 m_evt_handler->m_curr->line_contents.rem = m_evt_handler->m_curr->line_contents.rem.sub(ahead);
1634template<
class EventHandler>
1635void ParseEngine<EventHandler>::_line_ended()
1637 _c4dbgpf(
"line[{}] ({} cols) ended! offset {}-->{} / col {}-->{}",
1638 m_evt_handler->m_curr->pos.line,
1639 m_evt_handler->m_curr->line_contents.full.len,
1640 m_evt_handler->m_curr->pos.offset, m_evt_handler->m_curr->pos.offset + m_evt_handler->m_curr->line_contents.full.len - m_evt_handler->m_curr->line_contents.num_cols,
1641 m_evt_handler->m_curr->pos.col, 1);
1642 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, m_evt_handler->m_curr->pos.col == m_evt_handler->m_curr->line_contents.num_cols + 1, m_evt_handler->m_curr->pos);
1643 m_evt_handler->m_curr->pos.offset += m_evt_handler->m_curr->line_contents.full.len - m_evt_handler->m_curr->line_contents.num_cols;
1644 ++m_evt_handler->m_curr->pos.line;
1645 m_evt_handler->m_curr->pos.col = 1;
1648template<
class EventHandler>
1649void ParseEngine<EventHandler>::_line_ended_undo()
1651 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, m_evt_handler->m_curr->pos.col == 1u, m_evt_handler->m_curr->pos);
1652 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, m_evt_handler->m_curr->pos.line > 0u, m_evt_handler->m_curr->pos);
1653 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, m_evt_handler->m_curr->pos.offset >= m_evt_handler->m_curr->line_contents.full.len - m_evt_handler->m_curr->line_contents.num_cols, m_evt_handler->m_curr->pos);
1654 const size_t delta = m_evt_handler->m_curr->line_contents.full.len - m_evt_handler->m_curr->line_contents.num_cols;
1655 _c4dbgpf(
"line[{}] undo ended! line {}-->{}, offset {}-->{}", m_evt_handler->m_curr->pos.line, m_evt_handler->m_curr->pos.line, m_evt_handler->m_curr->pos.line - 1, m_evt_handler->m_curr->pos.offset, m_evt_handler->m_curr->pos.offset - delta);
1656 m_evt_handler->m_curr->pos.offset -= delta;
1657 --m_evt_handler->m_curr->pos.line;
1658 m_evt_handler->m_curr->pos.col = m_evt_handler->m_curr->line_contents.num_cols + 1u;
1661 m_evt_handler->m_curr->line_contents.rem = _buf().sub(m_evt_handler->m_curr->pos.offset, 0);
1666template<
class EventHandler>
1667void ParseEngine<EventHandler>::_set_indentation(
size_t indentation)
noexcept
1669 m_evt_handler->m_curr->indref = indentation;
1670 _c4dbgpf(
"state[{}]: saving indentation: {}", m_evt_handler->m_curr->level, m_evt_handler->m_curr->indref);
1673template<
class EventHandler>
1674void ParseEngine<EventHandler>::_save_indentation()
1676 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, m_evt_handler->m_curr->line_contents.rem.is_sub(m_evt_handler->m_curr->line_contents.full), m_evt_handler->m_curr->pos);
1677 m_evt_handler->m_curr->indref = m_evt_handler->m_curr->line_contents.current_col();
1678 _c4dbgpf(
"state[{}]: saving indentation: {}", m_evt_handler->m_curr->level, m_evt_handler->m_curr->indref);
1681template<
class EventHandler>
1682void ParseEngine<EventHandler>::_mark_seqflow_val_end() noexcept
1684 _c4dbgpf(
"SEQFLOW. mark val end at line={}", m_evt_handler->m_curr->pos.line);
1685 m_prev_val_end = m_evt_handler->m_curr->pos.line;
1691template<
class EventHandler>
1692void ParseEngine<EventHandler>::_flow_container_was_a_key(
size_t orig_indent)
1694 _c4dbgpf(
"flow container is followed by colon! orig_indent={}", orig_indent);
1695 m_evt_handler->actually_val_is_first_key_of_new_map_block();
1697 _set_indentation(orig_indent);
1698 _maybe_skip_whitespace_tokens();
1701template<
class EventHandler>
1702void ParseEngine<EventHandler>::_end_flow_container(
size_t orig_indent,
bool multiline)
1708 _c4dbgp(
"flow container: end as vanilla block map key!");
1709 if C4_UNLIKELY(multiline)
1710 _c4err(
"multiline key is invalid");
1711 if C4_UNLIKELY(!_maybe_scan_following_colon())
1712 _c4err(
"could not find ':' colon after key");
1713 _maybe_skip_whitespace_tokens();
1716 else if(has_none(
RFLOW))
1718 _c4dbgp(
"end_flow_container: now not in flow!");
1719 if(has_any(
RUNK|
RSEQ|
RKCL) && _maybe_scan_following_colon())
1721 if C4_UNLIKELY(multiline)
1722 _c4err(
"multiline key is invalid");
1723 _flow_container_was_a_key(orig_indent);
1727 _c4dbgp(
"end_flow_container: end map as key!");
1730 else if(has_any(
RSEQ))
1732 _c4dbgp(
"end_flow_container: now in a flow seq");
1733 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_any(
RFLOW), m_evt_handler->m_curr->pos);
1734 _mark_seqflow_val_end();
1738template<
class EventHandler>
1739void ParseEngine<EventHandler>::_end_map_flow()
1741 bool multiline = m_evt_handler->m_parent->pos.line < m_evt_handler->m_curr->pos.line;
1742 size_t orig_indent = m_evt_handler->m_curr->indref;
1743 _c4dbgpf(
"mapflow: end, multiline={}", multiline);
1744 m_evt_handler->end_map_flow(multiline && m_options.detect_flow_ml(), m_options.flow_ml_style().m_bits);
1745 _end_flow_container(orig_indent, multiline);
1748template<
class EventHandler>
1749void ParseEngine<EventHandler>::_end_seq_flow()
1751 bool multiline = m_evt_handler->m_parent->pos.line < m_evt_handler->m_curr->pos.line;
1752 size_t orig_indent = m_evt_handler->m_curr->indref;
1753 _c4dbgpf(
"seqflow: end, multiline={}", multiline);
1754 m_evt_handler->end_seq_flow(multiline && m_options.detect_flow_ml(), m_options.flow_ml_style().m_bits);
1755 _end_flow_container(orig_indent, multiline);
1758template<
class EventHandler>
1759void ParseEngine<EventHandler>::_end_map_blck()
1761 _c4dbgp(
"mapblck: end");
1764 _c4dbgp(
"mapblck: set missing val");
1765 _handle_annotations_before_blck_val_scalar();
1766 m_evt_handler->set_val_scalar_plain_empty();
1768 else if(has_any(
QMRK))
1770 _c4dbgp(
"mapblck: set missing keyval");
1771 _handle_annotations_before_blck_key_scalar();
1772 m_evt_handler->set_key_scalar_plain_empty();
1773 _handle_annotations_before_blck_val_scalar();
1774 m_evt_handler->set_val_scalar_plain_empty();
1776 m_evt_handler->end_map_block();
1779template<
class EventHandler>
1780void ParseEngine<EventHandler>::_end_seq_blck()
1784 _c4dbgp(
"seqblck: set missing val");
1785 _handle_annotations_before_blck_val_scalar();
1786 m_evt_handler->set_val_scalar_plain_empty();
1788 m_evt_handler->end_seq_block();
1791template<
class EventHandler>
1792void ParseEngine<EventHandler>::_end2_map()
1794 _c4dbgp(
"map: end");
1795 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_any(
RMAP), m_evt_handler->m_curr->pos);
1802 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RFLOW), m_evt_handler->m_curr->pos);
1803 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_any(
USTY), m_evt_handler->m_curr->pos);
1804 m_evt_handler->_pop();
1808template<
class EventHandler>
1809void ParseEngine<EventHandler>::_end2_seq()
1811 _c4dbgp(
"seq: end");
1812 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_any(
RSEQ), m_evt_handler->m_curr->pos);
1819 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RFLOW), m_evt_handler->m_curr->pos);
1820 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_any(
USTY), m_evt_handler->m_curr->pos);
1821 m_evt_handler->_pop();
1825template<
class EventHandler>
1826void ParseEngine<EventHandler>::_begin2_doc()
1828 _c4dbgp(
"begin_doc");
1829 m_has_directives_yaml =
false;
1830 m_has_directives =
false;
1833 m_evt_handler->begin_doc();
1834 m_evt_handler->m_curr->indref = 0;
1837template<
class EventHandler>
1838void ParseEngine<EventHandler>::_begin2_doc_expl()
1840 _c4dbgp(
"begin_doc_expl");
1841 m_has_directives_yaml =
false;
1842 m_has_directives =
false;
1845 m_evt_handler->begin_doc_expl();
1846 m_evt_handler->m_curr->indref = 0;
1849template<
class EventHandler>
1850void ParseEngine<EventHandler>::_end2_doc()
1852 _c4dbgp(
"doc: end");
1853 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_any(
RDOC), m_evt_handler->m_curr->pos);
1854 if(m_doc_empty || (m_pending_tags.num_entries || m_pending_anchors.num_entries))
1856 _c4dbgp(
"doc was empty; add empty val");
1857 _handle_annotations_before_blck_val_scalar();
1858 m_evt_handler->set_val_scalar_plain_empty();
1860 m_evt_handler->end_doc();
1864template<
class EventHandler>
1865void ParseEngine<EventHandler>::_end2_doc_expl()
1867 _c4dbgp(
"doc: end");
1868 if(m_doc_empty || (m_pending_tags.num_entries || m_pending_anchors.num_entries))
1870 _c4dbgp(
"doc: no children; add empty val");
1871 _handle_annotations_before_blck_val_scalar();
1872 m_evt_handler->set_val_scalar_plain_empty();
1874 m_evt_handler->end_doc_expl();
1878template<
class EventHandler>
1879void ParseEngine<EventHandler>::_maybe_begin_doc()
1883 _c4dbgp(
"doc must be started");
1887template<
class EventHandler>
1888void ParseEngine<EventHandler>::_maybe_end_doc()
1892 _c4dbgp(
"doc must be finished");
1895 else if(m_doc_empty && (m_pending_tags.num_entries || m_pending_anchors.num_entries))
1897 _c4dbgp(
"no doc to finish, but pending annotations");
1898 m_evt_handler->begin_doc();
1899 _handle_annotations_before_blck_val_scalar();
1900 m_evt_handler->set_val_scalar_plain_empty();
1901 m_evt_handler->end_doc();
1905template<
class EventHandler>
1906void ParseEngine<EventHandler>::_end_doc_suddenly__pop()
1908 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, m_evt_handler->m_stack.size() >= 1, m_evt_handler->m_curr->pos);
1909 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, m_evt_handler->m_stack[0].flags &
RDOC, m_evt_handler->m_curr->pos);
1910 _c4dbgp(
"root is RDOC");
1911 if(m_evt_handler->m_curr->level != 0)
1912 _handle_indentation_pop(&m_evt_handler->m_stack[0]);
1913 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_any(
RDOC), m_evt_handler->m_curr->pos);
1918template<
class EventHandler>
1919void ParseEngine<EventHandler>::_check_trailing_doc_token()
1921 const bool is_root = (m_evt_handler->m_stack.size() == 1u);
1922 const bool isndoc = (m_evt_handler->m_curr->flags &
NDOC) != 0;
1923 const bool suspicious = m_evt_handler->template has_any_<MAP|SEQ|VAL>();
1924 _c4dbgpf(
"target={} isroot={} suspicious={} ndoc={}", m_evt_handler->m_curr->node_id, is_root, suspicious, isndoc);
1925 if((is_root || m_evt_handler->template has_any_<DOC>()) && suspicious && !isndoc)
1929template<
class EventHandler>
1930void ParseEngine<EventHandler>::_end_doc_suddenly()
1932 _c4dbgp(
"end doc suddenly");
1933 _end_doc_suddenly__pop();
1938template<
class EventHandler>
1939void ParseEngine<EventHandler>::_check_doc_end_tokens()
const
1941 csubstr rem = m_evt_handler->m_curr->line_contents.rem;
1942 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, !rem.begins_with_any(
". \t"), m_evt_handler->m_curr->pos);
1943 if C4_UNLIKELY(rem.len && !rem.begins_with(
'#'))
1949template<
class EventHandler>
1950void ParseEngine<EventHandler>::_start_doc_suddenly()
1952 _c4dbgp(
"start doc suddenly");
1953 _end_doc_suddenly__pop();
1958template<
class EventHandler>
1959void ParseEngine<EventHandler>::_end_stream()
1961 _c4dbgpf(
"end_stream, level={} node_id={}", m_evt_handler->m_curr->level, m_evt_handler->m_curr->node_id);
1963 _c4err(
"missing terminating ]");
1964 else if C4_UNLIKELY(has_all(
RMAP|
RFLOW))
1965 _c4err(
"missing terminating }");
1966 if(m_evt_handler->m_stack.size() > 1)
1967 _handle_indentation_pop(m_evt_handler->m_stack.begin());
1974 if(m_pending_anchors.num_entries || m_pending_tags.num_entries)
1978 m_evt_handler->begin_doc();
1979 _handle_annotations_before_blck_val_scalar();
1980 m_evt_handler->set_val_scalar_plain_empty();
1981 m_evt_handler->end_doc();
1985 m_evt_handler->end_stream();
1986 if C4_UNLIKELY(m_has_directives)
1987 _c4err(
"directives cannot be used without a document");
1991template<
class EventHandler>
1992void ParseEngine<EventHandler>::_handle_indentation_pop(
ParserState const* popto)
1994 _c4dbgpf(
"popping {} level{}: from level {}(@ind={}) to level {}(@ind={})", m_evt_handler->m_curr->level - popto->level, (((m_evt_handler->m_curr->level - popto->level) > 1) ?
"s" :
""), m_evt_handler->m_curr->level, m_evt_handler->m_curr->indref, popto->level, popto->indref);
1995 while(m_evt_handler->m_curr != popto)
1999 _c4dbgpf(
"popping seq at level {} (indentation={},addr={})", m_evt_handler->m_curr->level, m_evt_handler->m_curr->indref, m_evt_handler->m_curr);
2002 else if(has_any(
RMAP))
2004 _c4dbgpf(
"popping map at level {} (indentation={},addr={})", m_evt_handler->m_curr->level, m_evt_handler->m_curr->indref, m_evt_handler->m_curr);
2012 _c4dbgpf(
"current level is {} (indentation={})", m_evt_handler->m_curr->level, m_evt_handler->m_curr->indref);
2015template<
class EventHandler>
2016void ParseEngine<EventHandler>::_handle_indentation_pop_from_block_seq()
2019 using state_type =
typename EventHandler::state;
2020 state_type
const* popto =
nullptr;
2021 auto &stack = m_evt_handler->m_stack;
2022 RYML_ASSERT_PARSE_CB_(stack.m_callbacks, stack.is_contiguous(), m_evt_handler->m_curr->pos);
2023 RYML_ASSERT_PARSE_CB_(stack.m_callbacks, m_evt_handler->m_curr >= stack.begin() && m_evt_handler->m_curr < stack.end(), m_evt_handler->m_curr->pos);
2024 const size_t ind = m_evt_handler->m_curr->line_contents.indentation;
2026 _print_state_stack();
2028 for(state_type
const* s = m_evt_handler->m_curr-1; s >= stack.begin(); --s)
2030 _c4dbgpf(
"searching for state with indentation {}. curr={} (level={},node={})", ind, s->indref, s->level, s->node_id);
2031 if(s->indref == ind)
2033 _c4dbgpf(
"gotit!!! level={} node={}", s->level, s->node_id);
2038 if(!popto || popto >= m_evt_handler->m_curr || popto->level >= m_evt_handler->m_curr->level)
2040 _c4err(
"parse error: incorrect indentation?");
2042 _handle_indentation_pop(popto);
2045template<
class EventHandler>
2046void ParseEngine<EventHandler>::_handle_indentation_pop_from_block_map()
2049 using state_type =
typename EventHandler::state;
2050 auto &stack = m_evt_handler->m_stack;
2051 RYML_ASSERT_PARSE_CB_(stack.m_callbacks, stack.is_contiguous(), m_evt_handler->m_curr->pos);
2052 RYML_ASSERT_PARSE_CB_(stack.m_callbacks, m_evt_handler->m_curr >= stack.begin() && m_evt_handler->m_curr < stack.end(), m_evt_handler->m_curr->pos);
2053 const size_t ind = m_evt_handler->m_curr->line_contents.indentation;
2054 state_type
const* popto =
nullptr;
2057 _print_state_stack(flagbuf_);
2059 for(state_type
const* s = m_evt_handler->m_curr-1; s > stack.begin(); --s)
2061 _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));
2066 else if(s->indref == ind)
2068 _c4dbgpf(
"same indentation!!! level={} node={}", s->level, s->node_id);
2069 if(popto && has_any(
RTOP, s) && has_none(
RMAP|
RSEQ, s))
2076 csubstr rem = m_evt_handler->m_curr->line_contents.rem;
2078 RYML_ASSERT_PARSE_CB_(stack.m_callbacks, first == ind || first ==
npos, m_evt_handler->m_curr->pos);
2079 rem = rem.right_of(first,
true);
2080 _c4dbgpf(
"indentless? rem='{}' first={}", rem, first);
2081 if(rem.begins_with(
'-') && _is_blck_token(rem))
2083 _c4dbgp(
"parent was indentless seq");
2089 if(!popto || popto >= m_evt_handler->m_curr || popto->level >= m_evt_handler->m_curr->level)
2091 _c4err(
"parse error: incorrect indentation?");
2093 _handle_indentation_pop(popto);
2098template<
class EventHandler>
2099void ParseEngine<EventHandler>::_check_valid_newline_in_quoted_scalar()
2103 _c4err(
"multiline quoted keys are invalid");
2107 const size_t minindent = m_evt_handler->m_curr->indref + ((has_any(
RMAP|
RSEQ) && has_any(
RBLCK)));
2108 _c4dbgpf(
"indent={} vs minindent={} indref={}", m_evt_handler->m_curr->line_contents.indentation, minindent, m_evt_handler->m_curr->indref);
2109 if(m_evt_handler->m_curr->line_contents.indentation < minindent)
2111 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks,
2112 m_evt_handler->m_curr->line_contents.indentation == m_evt_handler->m_curr->line_contents.rem.first_not_of(
' '),
2113 m_evt_handler->m_curr->pos);
2114 csubstr trimmed = m_evt_handler->m_curr->line_contents.rem.
sub(m_evt_handler->m_curr->line_contents.indentation);
2115 _c4dbgpf(
"trimmed.len={} line={}", trimmed.len, prs_(m_evt_handler->m_curr->line_contents.rem,
true));
2116 if C4_UNLIKELY(!!trimmed.len)
2118 _c4err(
"bad indentation");
2126template<
class EventHandler>
2127ScannedScalar ParseEngine<EventHandler>::_scan_scalar_squot()
2132 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, _buf().sub(m_evt_handler->m_curr->pos.offset).begins_with(
'\''), m_evt_handler->m_curr->pos);
2135 substr s = _buf().
sub(m_evt_handler->m_curr->pos.offset + 1);
2136 _line_progressed(1);
2137 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, !m_evt_handler->m_curr->at_line_beginning(), m_evt_handler->m_curr->pos);
2139 bool needs_filter =
false;
2141 while( ! _finished_file())
2143 const csubstr line = m_evt_handler->m_curr->line_contents.rem;
2144 _c4dbgpf(
"scanning single quoted scalar @ line[{}]: {}", m_evt_handler->m_curr->pos.line, prs_(line));
2145 if C4_UNLIKELY(m_evt_handler->m_curr->at_line_beginning() && _is_doc_token(line))
2146 _c4err(
"token can not appear at line begin");
2147 for(
size_t i = 0; i < line.len; ++i)
2149 const char curr = line.str[i];
2152 const char next = i+1 < line.len ? line.str[i+1] :
'~';
2155 _line_progressed(i + 1);
2156 pos = i + (size_t)(line.str - s.str);
2161 needs_filter =
true;
2167 needs_filter =
true;
2168 _line_progressed(line.len);
2171 _check_valid_newline_in_quoted_scalar();
2174 _c4err(
"reached end of file while looking for closing quote");
2178 _c4dbgpf(
"found closing quote at: {}", pos);
2179 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, pos !=
npos, m_evt_handler->m_curr->pos);
2180 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, pos >= 0, m_evt_handler->m_curr->pos);
2181 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, s.end() >= _buf().begin() && s.end() <= _buf().end(), m_evt_handler->m_curr->pos);
2182 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, s.end() == _buf().end() || *s.end() ==
'\'', m_evt_handler->m_curr->pos);
2183 _set_first_strict(s, pos);
2185 _c4prscalar(
"scanned squoted scalar", s,
true);
2187 return ScannedScalar { s, needs_filter };
2192template<
class EventHandler>
2193ScannedScalar ParseEngine<EventHandler>::_scan_scalar_dquot()
2198 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, _buf().sub(m_evt_handler->m_curr->pos.offset).begins_with(
'"'), m_evt_handler->m_curr->pos);
2201 substr s = _buf().
sub(m_evt_handler->m_curr->pos.offset + 1);
2202 _line_progressed(1);
2203 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, !m_evt_handler->m_curr->at_line_beginning(), m_evt_handler->m_curr->pos);
2205 bool needs_filter =
false;
2207 while( ! _finished_file())
2209 #if defined(__GNUC__) && (__GNUC__ == 13)
2210 C4_DONT_OPTIMIZE(m_evt_handler->m_curr->line_contents.rem);
2212 csubstr rem = m_evt_handler->m_curr->line_contents.rem;
2213 _c4dbgpf(
"scanning double quoted scalar @ line[{}]: line='{}'", m_evt_handler->m_curr->pos.line, rem);
2214 if C4_UNLIKELY(m_evt_handler->m_curr->at_line_beginning() && _is_doc_token(rem))
2215 _c4err(
"token can not appear at line begin");
2216 for(
size_t i = 0; i < rem.len; ++i)
2218 const char curr = rem.str[i];
2222 const char next = i+1 < rem.len ? rem.str[i+1] :
'~';
2223 needs_filter =
true;
2224 if(next ==
'"' || next ==
'\\')
2227 else if(curr ==
'"')
2229 _line_progressed(i + 1);
2230 pos = i + (size_t)(rem.str - s.str);
2236 needs_filter =
true;
2237 _line_progressed(rem.len);
2240 _check_valid_newline_in_quoted_scalar();
2243 _c4err(
"reached end of file while looking for closing quote");
2247 _c4dbgpf(
"found closing quote at: {}", pos);
2248 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, pos !=
npos, m_evt_handler->m_curr->pos);
2249 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, pos >= 0, m_evt_handler->m_curr->pos);
2250 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, s.end() >= _buf().begin() && s.end() <= _buf().end(), m_evt_handler->m_curr->pos);
2251 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, s.end() == _buf().end() || *s.end() ==
'"', m_evt_handler->m_curr->pos);
2252 _set_first_strict(s, pos);
2254 _c4prscalar(
"scanned dquoted scalar", s,
true);
2256 return ScannedScalar{s, needs_filter};
2261template<
class EventHandler>
2262void ParseEngine<EventHandler>::_scan_block(ScannedBlock *C4_RESTRICT sb,
size_t indref)
2264 _c4dbgpf(
"blck: indref={}", indref);
2265 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, indref !=
npos, m_evt_handler->m_curr->pos);
2268 csubstr s = m_evt_handler->m_curr->line_contents.rem;
2269 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, s.begins_with(
'|') || s.begins_with(
'>'), m_evt_handler->m_curr->pos);
2271 _c4dbgpf(
"blck: specs={}", prs_(s));
2274 BlockChomp_e chomp = CHOMP_CLIP;
2275 size_t indentation =
npos;
2278 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, s.begins_with_any(
"|>"), m_evt_handler->m_curr->pos);
2280 _c4dbgpf(
"blck: spec is multichar: {}", prs_(t));
2281 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, t.len >= 1, m_evt_handler->m_curr->pos);
2282 size_t pos = t.first_of(
"-+");
2283 _c4dbgpf(
"blck: spec chomp char: pos={}", pos);
2286 _c4dbgpf(
"blck: spec chomp char: {}", _c4prc(t[pos]));
2289 _c4dbgp(
"blck: chomp=STRIP");
2290 chomp = CHOMP_STRIP;
2292 else if(t[pos] ==
'+')
2294 _c4dbgp(
"blck: chomp=KEEP");
2301 _c4dbgpf(
"blck: spec is now: {}", prs_(t));
2304 pos = t.first_not_of(
"0123456789");
2308 _c4dbgpf(
"blck: parse indentation digits: {}", prs_(rest));
2309 if C4_UNLIKELY(rest.len > 1)
2310 _c4err(
"parse error: invalid indentation");
2311 if C4_UNLIKELY( ! c4::
atou(rest, &indentation))
2312 _c4err(
"parse error: could not read indentation as decimal");
2313 if C4_UNLIKELY( ! indentation)
2314 _c4err(
"parse error: null indentation");
2315 _c4dbgpf(
"blck: indentation specified: {}. add {} from curr state -> {}", indentation, m_evt_handler->m_curr->indref, indentation+indref);
2316 indentation += m_evt_handler->m_curr->indref;
2320 rest = t.triml(
" \t");
2321 _c4dbgpf(
"blck: digits empty. t={} trimmed={} iscomm={} t.iscomm={}", prs_(t), prs_(rest), rest.begins_with(
'#'), t.begins_with(
'#'));
2322 if C4_UNLIKELY(rest.len && (rest.str[0] !=
'#' || t.str[0] ==
'#'))
2323 _c4err(
"parse error: invalid token");
2327 _c4dbgpf(
"blck: style={} chomp={} indentation={}", s.begins_with(
'>') ?
"fold" :
"literal", chomp==CHOMP_CLIP ?
"clip" : (chomp==CHOMP_STRIP ?
"strip" :
"keep"), indentation);
2330 _line_progressed(s.len);
2335 substr raw_block(_buf().data() + m_evt_handler->m_curr->pos.offset,
size_t(0));
2336 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, raw_block.begin() == m_evt_handler->m_curr->line_contents.full.str, m_evt_handler->m_curr->pos);
2344 size_t num_lines = 0;
2345 size_t first = m_evt_handler->m_curr->pos.line;
2346 size_t provisional_indentation =
npos;
2348 while(( ! _finished_file()))
2352 #
if defined(__GNUC__) && (__GNUC__ == 12 || __GNUC__ == 13)
2353 C4_DONT_OPTIMIZE(lc.rem);
2355 _c4dbgpf(
"blck: peeking at {}", prs_(lc.rem.trimr(
"\r\n"),
true));
2357 if(indentation !=
npos)
2359 _c4dbgpf(
"blck: indentation={}", indentation);
2361 if(lc.indentation < indentation && ( ! lc.rem.trim(
" \t").empty()))
2365 _c4dbgpf(
"blck: indentation decreased ref={} thisline={}", indentation, lc.indentation);
2369 _c4err(
"indentation decreased without any scalar");
2373 else if(indentation == 0)
2375 _c4dbgpf(
"blck: noindent. lc.rem={}", prs_(lc.rem));
2376 if(_is_doc_token(lc.rem))
2378 _c4dbgp(
"blck: stop. indentation=0 and doc ended");
2385 const size_t fns = lc.rem.first_not_of(
' ');
2386 _c4dbgpf(
"blck: indentation ref not set. firstnonws={}", fns);
2389 _c4dbgpf(
"blck: line not empty. indref={} indprov={} indentation={}", indref, provisional_indentation, lc.indentation);
2390 if C4_UNLIKELY(lc.full.begins_with(
'\t'))
2392 if(provisional_indentation ==
npos)
2394 if(lc.indentation < indref)
2396 _c4dbgpf(
"blck: block terminated indentation={} < indref={}", lc.indentation, indref);
2397 if(raw_block.len == 0)
2399 _c4dbgp(
"blck: was empty, undo next line");
2404 else if(lc.indentation == m_evt_handler->m_curr->indref)
2408 _c4dbgpf(
"blck: block terminated. reading container and indentation={}==indref={}", lc.indentation, m_evt_handler->m_curr->indref);
2412 _c4dbgpf(
"blck: set indentation ref from this line: ref={}", lc.indentation);
2413 indentation = lc.indentation;
2417 if(lc.indentation >= provisional_indentation)
2419 _c4dbgpf(
"blck: set indentation ref from provisional indentation: provisional_ref={}, thisline={}", provisional_indentation, lc.indentation);
2421 indentation = lc.indentation;
2425 if(lc.indentation >= indref)
2426 _c4err(
"parse error: first non-empty block line should have at least the original indentation");
2427 _c4dbgp(
"blck: finished");
2434 _c4dbgpf(
"blck: line empty or {} spaces. line_indentation={} prov_indentation={}", lc.rem.len, lc.indentation, provisional_indentation);
2435 if(provisional_indentation !=
npos)
2437 if(lc.rem.len >= provisional_indentation)
2439 _c4dbgpf(
"blck: increase provisional_ref {} -> {}", provisional_indentation, lc.rem.len);
2440 provisional_indentation = lc.rem.len;
2445 provisional_indentation = lc.indentation ? lc.indentation : has_any(
RSEQ|
RVAL);
2446 _c4dbgpf(
"blck: initialize provisional_ref={}", provisional_indentation);
2447 if(provisional_indentation ==
npos)
2449 provisional_indentation = lc.rem.len ? lc.rem.len : has_any(
RSEQ|
RVAL);
2450 _c4dbgpf(
"blck: initialize provisional_ref={}", provisional_indentation);
2452 if(provisional_indentation < indref)
2454 provisional_indentation = indref;
2455 _c4dbgpf(
"blck: initialize provisional_ref={}", provisional_indentation);
2461 m_evt_handler->m_curr->line_contents = lc;
2462 _c4dbgpf(
"blck: append '{}'", m_evt_handler->m_curr->line_contents.rem);
2463 raw_block.len += m_evt_handler->m_curr->line_contents.full.len;
2464 _line_progressed(m_evt_handler->m_curr->line_contents.rem.len);
2468 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, m_evt_handler->m_curr->pos.line == (first + num_lines) || (raw_block.len == 0), m_evt_handler->m_curr->pos);
2469 C4_UNUSED(num_lines);
2472 if(indentation ==
npos)
2474 _c4dbgpf(
"blck: set indentation from provisional: {}", provisional_indentation);
2475 indentation = provisional_indentation;
2481 _c4prscalar(
"scanned block", raw_block,
true);
2483 sb->scalar = raw_block;
2484 sb->indentation = indentation;
2496#define _c4dbgfws(fmt, ...) _c4dbgpf("filt_ws[{}->{}]: " fmt, proc.rpos, proc.wpos, __VA_ARGS__)
2498#define _c4dbgfws(...)
2501template<
class EventHandler>
2502template<
class FilterProcessor>
2505 _c4dbgfws(
"found whitespace '{}'", _c4prc(proc.curr()));
2506 RYML_ASSERT_PARSE_CB_(this->callbacks(), proc.curr() ==
' ' || proc.curr() ==
'\t', m_evt_handler->m_curr->pos);
2508 const size_t first_pos = proc.rpos > 0 ? proc.src.first_not_of(
" \t", proc.rpos) : proc.src.first_not_of(
' ', proc.rpos);
2509 if(first_pos !=
npos)
2511 const char first_char = proc.src[first_pos];
2512 _c4dbgfws(
"firstnonws='{}'@{}", _c4prc(first_char), first_pos);
2513 if(first_char ==
'\n' || first_char ==
'\r')
2515 _c4dbgfws(
"whitespace is trailing on line",
"");
2516 proc.skip(first_pos - proc.rpos);
2521 _c4dbgfws(
"legit whitespace. sofar={}", prs_(proc.sofar()));
2525 _c4dbgfws(
"whitespace is trailing on line",
"");
2529template<
class EventHandler>
2530template<
class FilterProcessor>
2533 if(!_filter_ws_handle_to_first_non_space(proc))
2535 _c4dbgfws(
"... everything else is trailing whitespace - copy {} chars", proc.src.len - proc.rpos);
2536 proc.copy(proc.src.len - proc.rpos);
2540template<
class EventHandler>
2541template<
class FilterProcessor>
2544 if(!_filter_ws_handle_to_first_non_space(proc))
2546 _c4dbgfws(
"... everything else is trailing whitespace - skip {} chars", proc.src.len - proc.rpos);
2547 proc.skip(proc.src.len - proc.rpos);
2561#define _c4dbgfps(fmt, ...) _c4dbgpf("filt_plain[{}->{}]: " fmt, proc.rpos, proc.wpos, __VA_ARGS__)
2563#define _c4dbgfps(fmt, ...)
2566template<
class EventHandler>
2567template<
class FilterProcessor>
2570 RYML_ASSERT_PARSE_CB_(this->callbacks(), proc.curr() ==
'\n', m_evt_handler->m_curr->pos);
2572 _c4dbgfps(
"found newline. sofar={}", prs_(proc.sofar()));
2573 size_t ii = proc.rpos;
2574 const size_t numnl_following = _count_following_newlines(proc.src, &ii, indentation);
2577 proc.set(
'\n', numnl_following);
2578 _c4dbgfps(
"{} consecutive (empty) lines {}. totalws={}", 1+numnl_following, ii < proc.src.len ?
"in the middle" :
"at the end", proc.rpos-ii);
2582 const size_t ret = proc.src.first_not_of(
" \t", proc.rpos+1);
2586 _c4dbgfps(
"single newline. convert to space. ret={}/{}. sofar={}", ii, proc.src.len, prs_(proc.sofar()));
2590 _c4dbgfps(
"last newline, everything else is whitespace. ii={}/{}", ii, proc.src.len);
2597template<
class EventHandler>
2598template<
class FilterProcessor>
2601 RYML_ASSERT_PARSE_CB_(this->callbacks(), indentation !=
npos, m_evt_handler->m_curr->pos);
2602 _c4dbgfps(
"before={}", prs_(proc.src));
2604 while(proc.has_more_chars())
2606 const char curr = proc.curr();
2607 _c4dbgfps(
"'{}', sofar={}", _c4prc(curr), prs_(proc.sofar()));
2612 _c4dbgfps(
"whitespace", curr);
2613 _filter_ws_skip_trailing(proc);
2616 _c4dbgfps(
"newline", curr);
2617 _filter_nl_plain(proc, indentation);
2620 _c4dbgfps(
"carriage return, ignore", curr);
2629 _c4dbgfps(
"after={}", prs_(proc.sofar()));
2631 return proc.result();
2637template<
class EventHandler>
2641 return _filter_plain(proc, indentation);
2644template<
class EventHandler>
2648 return _filter_plain(proc, indentation);
2659#define _c4dbgfsq(fmt, ...) _c4dbgpf("filt_squo[{}->{}]: " fmt, proc.rpos, proc.wpos, __VA_ARGS__)
2661#define _c4dbgfsq(fmt, ...)
2664template<
class EventHandler>
2665template<
class FilterProcessor>
2668 RYML_ASSERT_PARSE_CB_(this->callbacks(), proc.curr() ==
'\n', m_evt_handler->m_curr->pos);
2670 _c4dbgfsq(
"found newline. sofar={}", prs_(proc.sofar()));
2671 size_t ii = proc.rpos;
2672 const size_t numnl_following = _count_following_newlines(proc.src, &ii);
2675 proc.set(
'\n', numnl_following);
2676 _c4dbgfsq(
"{} consecutive (empty) lines {}. totalws={}", 1+numnl_following, ii < proc.src.len ?
"in the middle" :
"at the end", proc.rpos-ii);
2680 const size_t ret = proc.src.first_not_of(
" \t", proc.rpos+1);
2684 _c4dbgfsq(
"single newline. convert to space. ret={}/{}. sofar={}", ii, proc.src.len, prs_(proc.sofar()));
2689 _c4dbgfsq(
"single newline. convert to space. ii={}/{}. sofar={}", ii, proc.src.len, prs_(proc.sofar()));
2695template<
class EventHandler>
2696template<
class FilterProcessor>
2699 _c4dbgfsq(
"before={}", prs_(proc.src));
2703 while(proc.has_more_chars())
2705 const char curr = proc.curr();
2706 _c4dbgfsq(
"'{}', sofar={}", _c4prc(curr), prs_(proc.sofar()));
2711 _c4dbgfsq(
"whitespace", curr);
2712 _filter_ws_copy_trailing(proc);
2715 _c4dbgfsq(
"newline", curr);
2716 _filter_nl_squoted(proc);
2719 _c4dbgfsq(
"skip cr", curr);
2723 _c4dbgfsq(
"squote", curr);
2724 if(proc.next() ==
'\'')
2726 _c4dbgfsq(
"two consecutive squotes", curr);
2741 _c4dbgfsq(
": #filteredchars={} after={}", proc.src.len-proc.sofar().len, prs_(proc.sofar()));
2743 return proc.result();
2748template<
class EventHandler>
2752 return _filter_squoted(proc);
2755template<
class EventHandler>
2759 return _filter_squoted(proc);
2770#define _c4dbgfdq(fmt, ...) _c4dbgpf("filt_dquo[{}->{}]: " fmt, proc.rpos, proc.wpos, __VA_ARGS__)
2772#define _c4dbgfdq(...)
2775template<
class EventHandler>
2776template<
class FilterProcessor>
2779 RYML_ASSERT_PARSE_CB_(this->callbacks(), proc.curr() ==
'\n', m_evt_handler->m_curr->pos);
2781 _c4dbgfdq(
"found newline. sofar={}", prs_(proc.sofar()));
2782 size_t ii = proc.rpos;
2783 const size_t numnl_following = _count_following_newlines(proc.src, &ii);
2786 proc.set(
'\n', numnl_following);
2787 _c4dbgfdq(
"{} consecutive (empty) lines {}. totalws={}", 1+numnl_following, ii < proc.src.len ?
"in the middle" :
"at the end", proc.rpos-ii);
2791 const size_t ret = proc.src.first_not_of(
" \t", proc.rpos+1);
2795 _c4dbgfdq(
"single newline. convert to space. ret={}/{}. sofar={}", ii, proc.src.len, prs_(proc.sofar()));
2800 _c4dbgfdq(
"single newline. convert to space. ii={}/{}. sofar={}", ii, proc.src.len, prs_(proc.sofar()));
2802 if(ii < proc.src.len && proc.src.str[ii] ==
'\\')
2804 _c4dbgfdq(
"backslash at [{}]", ii);
2805 const char next = ii+1 < proc.src.len ? proc.src.str[ii+1] :
'\0';
2806 if(next ==
' ' || next ==
'\t')
2808 _c4dbgfdq(
"extend skip to backslash",
"");
2816template<
class EventHandler>
2817template<
class FilterProcessor>
2820 const size_t szp1 = sz + 1u;
2821 if C4_UNLIKELY(proc.rpos + szp1 >= proc.src.len)
2822 _c4err(
"codepoint requires {} hex digits. scalar pos={}", sz, proc.rpos);
2824 csubstr codepoint = proc.src.sub(proc.rpos + 2u, sz);
2825 _c4dbgfdq(
"utf8 ~~~{}~~~ rpos={} rem=~~~{}~~~", codepoint, proc.rpos, proc.src.sub(proc.rpos));
2826 uint32_t codepoint_val = {};
2827 if C4_UNLIKELY(!
read_hex(codepoint, &codepoint_val))
2828 _c4err(
"failed to parse codepoint. scalar pos={}", proc.rpos);
2829 const size_t numbytes =
decode_code_point((uint8_t*)readbuf,
sizeof(readbuf), codepoint_val);
2830 if C4_UNLIKELY(numbytes == 0)
2831 _c4err(
"failed to decode code point={}", proc.rpos);
2832 RYML_ASSERT_PARSE_CB_(callbacks(), numbytes <= 4, m_evt_handler->m_curr->pos);
2833 proc.translate_esc_bulk(readbuf, numbytes, szp1);
2834 _c4dbgfdq(
"utf8 after rpos={} rem=~~~{}~~~", proc.rpos, proc.src.sub(proc.rpos));
2837template<class EventHandler>
2838template<class FilterProcessor>
2839void ParseEngine<EventHandler>::_filter_dquoted_backslash(FilterProcessor &C4_RESTRICT proc)
2841 char next = proc.next();
2842 _c4dbgfdq(
"backslash, next='{}'", _c4prc(next));
2845 if(proc.rpos+2 < proc.src.len && proc.src.str[proc.rpos+2] ==
'\n')
2849 _c4dbgfdq(
"[{}]: was \\r\\n, now next='\\n'", proc.rpos);
2855 size_t ii = proc.rpos + 2;
2856 for( ; ii < proc.src.len; ++ii)
2859 if(proc.src.str[ii] ==
' ' || proc.src.str[ii] ==
'\t')
2864 proc.skip(ii - proc.rpos);
2866 else if(next ==
'"' || next ==
'/' || next ==
' ' || next ==
'\t')
2869 proc.translate_esc(next);
2870 _c4dbgfdq(
"here, used '{}'", _c4prc(next));
2872 else if(next ==
'\r')
2876 else if(next ==
'n')
2878 proc.translate_esc(
'\n');
2880 else if(next ==
'r')
2882 proc.translate_esc(
'\r');
2884 else if(next ==
't')
2886 proc.translate_esc(
'\t');
2888 else if(next ==
'\\')
2890 proc.translate_esc(
'\\');
2892 else if(next ==
'x')
2894 _filter_dquoted_backslash_decode(proc, 2u);
2896 else if(next ==
'u')
2898 _filter_dquoted_backslash_decode(proc, 4u);
2900 else if(next ==
'U')
2902 _filter_dquoted_backslash_decode(proc, 8u);
2905 else if(next ==
'0')
2907 proc.translate_esc(
'\0');
2909 else if(next ==
'b')
2911 proc.translate_esc(
'\b');
2913 else if(next ==
'f')
2915 proc.translate_esc(
'\f');
2917 else if(next ==
'a')
2919 proc.translate_esc(
'\a');
2921 else if(next ==
'v')
2923 proc.translate_esc(
'\v');
2925 else if(next ==
'e')
2927 proc.translate_esc(
'\x1b');
2929 else if(next ==
'_')
2932 const char payload[] = {
2933 RYML_CHCONST_(-0x3e, 0xc2),
2934 RYML_CHCONST_(-0x60, 0xa0),
2936 proc.translate_esc_bulk(payload, 2, 1);
2938 else if(next ==
'N')
2941 const char payload[] = {
2942 RYML_CHCONST_(-0x3e, 0xc2),
2943 RYML_CHCONST_(-0x7b, 0x85),
2945 proc.translate_esc_bulk(payload, 2, 1);
2947 else if(next ==
'L')
2950 const char payload[] = {
2951 RYML_CHCONST_(-0x1e, 0xe2),
2952 RYML_CHCONST_(-0x80, 0x80),
2953 RYML_CHCONST_(-0x58, 0xa8),
2955 proc.translate_esc_extending(payload, 3, 1);
2957 else if(next ==
'P')
2960 const char payload[] = {
2961 RYML_CHCONST_(-0x1e, 0xe2),
2962 RYML_CHCONST_(-0x80, 0x80),
2963 RYML_CHCONST_(-0x57, 0xa9),
2965 proc.translate_esc_extending(payload, 3, 1);
2967 else if(next ==
'\0')
2973 _c4err(
"unknown character '{}' after '\\' pos={}", _c4prc(next), proc.rpos);
2975 _c4dbgfdq(
"backslash...sofar={}", prs_(proc.sofar()));
2979template<
class EventHandler>
2980template<
class FilterProcessor>
2983 _c4dbgfdq(
"before={}", prs_(proc.src));
2986 while(proc.has_more_chars())
2988 const char curr = proc.curr();
2989 _c4dbgfdq(
"'{}' sofar={}", _c4prc(curr), prs_(proc.sofar()));
2995 _c4dbgfdq(
"whitespace", curr);
2996 _filter_ws_copy_trailing(proc);
3001 _c4dbgfdq(
"newline", curr);
3002 _filter_nl_dquoted(proc);
3007 _c4dbgfdq(
"carriage return, ignore", curr);
3013 _filter_dquoted_backslash(proc);
3023 _c4dbgfdq(
"after={}", prs_(proc.sofar()));
3024 return proc.result();
3030template<
class EventHandler>
3034 return _filter_dquoted(proc);
3037template<
class EventHandler>
3041 return _filter_dquoted(proc);
3050template<
class EventHandler>
3051template<
class FilterProcessor>
3054 RYML_ASSERT_PARSE_CB_(this->callbacks(), chomp == CHOMP_CLIP || chomp == CHOMP_KEEP || chomp == CHOMP_STRIP, m_evt_handler->m_curr->pos);
3055 RYML_ASSERT_PARSE_CB_(this->callbacks(), proc.rem().first_not_of(
" \n\r") ==
npos, m_evt_handler->m_curr->pos);
3059 #define _c4dbgchomp(fmt, ...) _c4dbgpf("chomp[{}->{}]: " fmt, proc.rpos, proc.wpos, __VA_ARGS__)
3061 #define _c4dbgchomp(...)
3066 size_t last = _find_last_newline_and_larger_indentation(proc.rem(), indentation);
3069 _c4dbgchomp(
"found newline and larger indentation. last={}", last);
3070 last = proc.rpos + last + size_t(1) + indentation;
3071 RYML_ASSERT_PARSE_CB_(this->callbacks(), last <= proc.src.len, m_evt_handler->m_curr->pos);
3073 while((proc.rpos < last) && proc.has_more_chars())
3075 const char curr = proc.curr();
3076 _c4dbgchomp(
"curr='{}'", _c4prc(curr));
3081 _c4dbgchomp(
"newline! remlen={}", proc.rem().len);
3084 csubstr at_next_line = proc.rem();
3085 if(at_next_line.begins_with(
' '))
3087 _c4dbgchomp(
"next line begins with spaces. indentation={}", indentation);
3089 size_t first_non_space = at_next_line.first_not_of(
' ');
3090 _c4dbgchomp(
"first_non_space={}", first_non_space);
3091 if(first_non_space ==
npos)
3093 _c4dbgchomp(
"{} spaces, to the end", at_next_line.len);
3094 first_non_space = at_next_line.len;
3096 if(first_non_space <= indentation)
3098 _c4dbgchomp(
"skip spaces={}<=indentation={}", first_non_space, indentation);
3099 proc.skip(first_non_space);
3103 _c4dbgchomp(
"skip indentation={}<spaces={}", indentation, first_non_space);
3104 proc.skip(indentation);
3106 _c4dbgchomp(
"copy {}={}-{} spaces", first_non_space - indentation, first_non_space, indentation);
3107 proc.copy(first_non_space - indentation);
3125 bool had_one =
false;
3126 while(proc.has_more_chars())
3128 const char curr = proc.curr();
3129 _c4dbgchomp(
"CLIP: '{}'", _c4prc(curr));
3134 _c4dbgchomp(
"copy newline!", curr);
3142 _c4dbgchomp(
"skip!", curr);
3149 _c4dbgchomp(
"chomp=CLIP: add missing newline @{}", proc.wpos);
3156 _c4dbgchomp(
"chomp=KEEP: copy all remaining new lines of {} characters", proc.rem().len);
3157 while(proc.has_more_chars())
3159 const char curr = proc.curr();
3160 _c4dbgchomp(
"KEEP: '{}'", _c4prc(curr));
3164 _c4dbgchomp(
"copy newline!", curr);
3169 _c4dbgchomp(
"skip!", curr);
3178 _c4dbgchomp(
"chomp=STRIP: strip {} characters", proc.rem().len);
3190#define _c4dbgfb(fmt, ...) _c4dbgpf("filt_block[{}->{}]: " fmt, proc.rpos, proc.wpos, __VA_ARGS__)
3192#define _c4dbgfb(...)
3195template<
class EventHandler>
3196template<
class FilterProcessor>
3202 size_t first = rem.first_not_of(
' ');
3205 _c4dbgfb(
"{} spaces follow before next nonws character", first);
3206 if(first < indentation)
3208 _c4dbgfb(
"skip {}<{} spaces from indentation", first, indentation);
3213 _c4dbgfb(
"skip {} spaces from indentation", indentation);
3214 proc.skip(indentation);
3217 #ifdef RYML_NO_COVERAGE__TO_BE_DELETED
3220 _c4dbgfb(
"all spaces to the end: {} spaces", first);
3224 if(first < indentation)
3226 _c4dbgfb(
"skip everything", first);
3227 proc.skip(proc.src.len - proc.rpos);
3231 _c4dbgfb(
"skip {} spaces from indentation", indentation);
3232 proc.skip(indentation);
3240template<
class EventHandler>
3241template<
class FilterProcessor>
3245 _c4dbgfb(
"ws: contents_len={} wslen={}", contents.len, proc.src.len-contents.len);
3248 _c4dbgfb(
"ws: all whitespace: len={}", proc.src.len);
3249 if(chomp == CHOMP_KEEP && proc.src.len)
3251 _c4dbgfb(
"ws: chomp=KEEP all {} newlines", proc.src.count(
'\n'));
3252 while(proc.has_more_chars())
3254 const char curr = proc.curr();
3266 return contents.len;
3269template<
class EventHandler>
3270template<
class FilterProcessor>
3273 _c4dbgfb(
"contents_len={}", contents_len);
3275 RYML_ASSERT_PARSE_CB_(this->callbacks(), contents_len > 0u, m_evt_handler->m_curr->pos);
3279 size_t firstnewl = proc.src.first_of(
'\n', contents_len);
3280 if(firstnewl !=
npos)
3282 contents_len = firstnewl;
3283 _c4dbgfb(
"contents_len={} <--- firstnewl={}", contents_len, firstnewl);
3287 contents_len = proc.src.len;
3288 _c4dbgfb(
"contents_len={} <--- src.len={}", contents_len, proc.src.len);
3291 return contents_len;
3303#define _c4dbgfbl(fmt, ...) _c4dbgpf("filt_block_lit[{}->{}]: " fmt, proc.rpos, proc.wpos, __VA_ARGS__)
3305#define _c4dbgfbl(...)
3308template<
class EventHandler>
3309template<
class FilterProcessor>
3312 _c4dbgfbl(
"indentation={} before={}", indentation, prs_(proc.src));
3314 size_t contents_len = _handle_all_whitespace(proc, chomp);
3316 return proc.result();
3318 contents_len = _extend_to_chomp(proc, contents_len);
3320 _c4dbgfbl(
"to filter={}", prs_(proc.src.first(contents_len)));
3322 _filter_block_indentation(proc, indentation);
3325 while(proc.has_more_chars(contents_len))
3327 const char curr = proc.curr();
3328 _c4dbgfbl(
"'{}' sofar={}", _c4prc(curr), prs_(proc.sofar()));
3333 _c4dbgfbl(
"found newline. skip indentation on the next line", curr);
3335 _filter_block_indentation(proc, indentation);
3347 _c4dbgfbl(
"before chomp: #tochomp={} sofar={}", proc.rem().len, prs_(proc.sofar()));
3349 _filter_chomp(proc, chomp, indentation);
3351 _c4dbgfbl(
"final={}", prs_(proc.sofar()));
3353 return proc.result();
3358template<
class EventHandler>
3362 return _filter_block_literal(proc, indentation, chomp);
3365template<
class EventHandler>
3369 return _filter_block_literal(proc, indentation, chomp);
3379#define _c4dbgfbf(fmt, ...) _c4dbgpf("filt_block_folded[{}->{}]: " fmt, proc.rpos, proc.wpos, __VA_ARGS__)
3381#define _c4dbgfbf(...)
3385template<
class EventHandler>
3386template<
class FilterProcessor>
3389 _filter_block_indentation(proc, indentation);
3390 while(proc.has_more_chars(len))
3392 const char curr = proc.curr();
3393 _c4dbgfbf(
"'{}' sofar={}", _c4prc(curr), prs_(proc.sofar()));
3397 _c4dbgfbf(
"newline.", curr);
3399 _filter_block_indentation(proc, indentation);
3407 size_t first = proc.rem().first_not_of(
" \t");
3408 _c4dbgfbf(
"space. first={}", first);
3410 first = proc.rem().len;
3411 _c4dbgfbf(
"... indentation increased to {}", first);
3412 _filter_block_folded_indented_block(proc, indentation, len, first);
3416 _c4dbgfbf(
"newl leading: not space, not newline. stop.", 0);
3422template<
class EventHandler>
3423template<
class FilterProcessor>
3429 _c4dbgfbf(
"... this is the first newline. turn into space. wpos={}", proc.wpos);
3430 wpos_at_first_newl = proc.wpos;
3435 _c4dbgfbf(
"... this is the second newline. prev space (at wpos={}) must be newline", wpos_at_first_newl);
3436 RYML_ASSERT_PARSE_CB_(this->callbacks(), wpos_at_first_newl !=
npos, m_evt_handler->m_curr->pos);
3437 RYML_ASSERT_PARSE_CB_(this->callbacks(), proc.sofar()[wpos_at_first_newl] ==
' ', m_evt_handler->m_curr->pos);
3438 RYML_ASSERT_PARSE_CB_(this->callbacks(), wpos_at_first_newl + 1u == proc.wpos, m_evt_handler->m_curr->pos);
3440 proc.set_at(wpos_at_first_newl,
'\n');
3441 RYML_ASSERT_PARSE_CB_(this->callbacks(), proc.sofar()[wpos_at_first_newl] ==
'\n', m_evt_handler->m_curr->pos);
3444 _c4dbgfbf(
"... subsequent newline (num_newl={}). copy", num_newl);
3448 return wpos_at_first_newl;
3451template<
class EventHandler>
3452template<
class FilterProcessor>
3455 RYML_ASSERT_PARSE_CB_(this->callbacks(), proc.curr() ==
'\n', m_evt_handler->m_curr->pos);
3456 size_t num_newl = 0;
3457 size_t wpos_at_first_newl =
npos;
3458 while(proc.has_more_chars(len))
3460 const char curr = proc.curr();
3461 _c4dbgfbf(
"'{}' sofar={}", _c4prc(curr), prs_(proc.sofar()));
3466 _c4dbgfbf(
"newline. sofar={}", num_newl);
3502 wpos_at_first_newl = _filter_block_folded_newlines_compress(proc, ++num_newl, wpos_at_first_newl);
3503 _filter_block_indentation(proc, indentation);
3509 size_t first = proc.rem().first_not_of(
" \t");
3510 _c4dbgfbf(
"space. first={}", first);
3512 first = proc.rem().len;
3513 _c4dbgfbf(
"... indentation increased to {}", first);
3516 _c4dbgfbf(
"... prev space (at wpos={}) must be newline", wpos_at_first_newl);
3517 proc.set_at(wpos_at_first_newl,
'\n');
3521 _c4dbgfbf(
"... add missing newline", wpos_at_first_newl);
3524 _filter_block_folded_indented_block(proc, indentation, len, first);
3526 wpos_at_first_newl =
npos;
3533 _c4dbgfbf(
"not space, not newline. stop.", 0);
3540template<
class EventHandler>
3541template<
class FilterProcessor>
3544 RYML_ASSERT_PARSE_CB_(this->callbacks(), (proc.rem().first_not_of(
" \t") == curr_indentation) || (proc.rem().first_not_of(
" \t") ==
npos), m_evt_handler->m_curr->pos);
3545 if(curr_indentation)
3546 proc.copy(curr_indentation);
3547 while(proc.has_more_chars(len))
3549 const char curr = proc.curr();
3550 _c4dbgfbf(
"'{}' sofar={}", _c4prc(curr), prs_(proc.sofar()));
3556 _filter_block_indentation(proc, indentation);
3559 _c4dbgfbf(
"newline. firstns={}", first);
3562 const char c = rem[first];
3563 _c4dbgfbf(
"firstns={}='{}'", first, _c4prc(c));
3564 if(c !=
'\n' && c !=
'\r')
3566 _c4dbgfbf(
"done with indented block", first);
3570 else if(first !=
npos)
3573 _c4dbgfbf(
"copy all {} spaces", first);
3591template<
class EventHandler>
3592template<
class FilterProcessor>
3595 _c4dbgfbf(
"indentation={} before={}", indentation, prs_(proc.src));
3597 size_t contents_len = _handle_all_whitespace(proc, chomp);
3599 return proc.result();
3601 contents_len = _extend_to_chomp(proc, contents_len);
3603 _c4dbgfbf(
"to filter={}", prs_(proc.src.first(contents_len)));
3605 _filter_block_folded_newlines_leading(proc, indentation, contents_len);
3608 while(proc.has_more_chars(contents_len))
3610 const char curr = proc.curr();
3611 _c4dbgfbf(
"'{}' sofar={}", _c4prc(curr), prs_(proc.sofar()));
3616 _c4dbgfbf(
"found newline", curr);
3617 _filter_block_folded_newlines(proc, indentation, contents_len);
3629 _c4dbgfbf(
"before chomp: #tochomp={} sofar={}", proc.rem().len, prs_(proc.sofar()));
3631 _filter_chomp(proc, chomp, indentation);
3633 _c4dbgfbf(
"final={}", proc.sofar().len, prs_(proc.sofar()));
3635 return proc.result();
3640template<
class EventHandler>
3644 return _filter_block_folded(proc, indentation, chomp);
3647template<
class EventHandler>
3651 return _filter_block_folded(proc, indentation, chomp);
3659template<
class EventHandler>
3662 _c4dbgpf(
"filtering plain scalar: s={}", prs_(s));
3663 FilterResult r = this->filter_scalar_plain_in_place(s, s.len, indentation);
3664 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, r.valid(), m_evt_handler->m_curr->pos);
3665 _c4dbgpf(
"filtering plain scalar: success! s={}", prs_(r.get()));
3671template<
class EventHandler>
3674 _c4dbgpf(
"filtering squo scalar: s={}", prs_(s));
3675 FilterResult r = this->filter_scalar_squoted_in_place(s, s.len);
3676 RYML_ASSERT_PARSE_CB_(this->callbacks(), r.valid(), m_evt_handler->m_curr->pos);
3677 _c4dbgpf(
"filtering squo scalar: success! s={}", prs_(r.get()));
3684template<
class EventHandler>
3687 _c4dbgpf(
"filtering dquo scalar: s={}", prs_(s));
3689 if C4_LIKELY(r.valid())
3691 _c4dbgpf(
"filtering dquo scalar: success! s={}", prs_(r.get()));
3696 const size_t len = r.required_len();
3697 _c4dbgpf(
"filtering dquo scalar: not enough space: needs {}, have {}", len, s.len);
3698 substr dst = _alloc_arena(len, &s);
3699 _c4dbgpf(
"filtering dquo scalar: dst.len={}", dst.len);
3702 RYML_ASSERT_PARSE_CB_(this->callbacks(), dst.len == len, m_evt_handler->m_curr->pos);
3703 FilterResult rsd = this->filter_scalar_dquoted(s, dst);
3704 _c4dbgpf(
"filtering dquo scalar: ... result now needs {} was {}", rsd.required_len(), len);
3705 RYML_ASSERT_PARSE_CB_(this->callbacks(), rsd.required_len() <= len, m_evt_handler->m_curr->pos);
3706 RYML_CHECK_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, rsd.valid(), m_evt_handler->m_curr->pos);
3707 _c4dbgpf(
"filtering dquo scalar: success! s={}", prs_(rsd.get()));
3717template<
class EventHandler>
3720 if(s.is_sub(_buf()))
3722 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, s.str > _buf().str, m_evt_handler->m_curr->pos);
3723 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, s.str-1 >= _buf().str, m_evt_handler->m_curr->pos);
3725 memmove(s.str - 1, s.str, s.len);
3727 s.str[s.len] =
'\n';
3733 substr dst = _alloc_arena(s.len + 1, &s);
3735 memcpy(dst.str, s.str, s.len);
3741template<
class EventHandler>
3744 _c4dbgpf(
"filtering block literal scalar: s={}", prs_(s));
3745 FilterResult r = this->filter_scalar_block_literal_in_place(s, s.len, indentation, chomp);
3747 if C4_LIKELY(r.valid())
3753 _c4dbgpf(
"filtering block literal scalar: not enough space: needs {}, have {}", r.required_len(), s.len);
3754 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, r.required_len() == s.len + 1, m_evt_handler->m_curr->pos);
3757 result = _move_scalar_left_and_add_newline(s);
3759 _c4dbgpf(
"filtering block literal scalar: success! s={}", prs_(result));
3765template<
class EventHandler>
3768 _c4dbgpf(
"filtering block folded scalar: s={}", prs_(s));
3769 FilterResult r = this->filter_scalar_block_folded_in_place(s, s.len, indentation, chomp);
3771 if C4_LIKELY(r.valid())
3777 _c4dbgpf(
"filtering block folded scalar: not enough space: needs {}, have {}", r.required_len(), s.len);
3778 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, r.required_len() == s.len + 1, m_evt_handler->m_curr->pos);
3781 result = _move_scalar_left_and_add_newline(s);
3783 _c4dbgpf(
"filtering block folded scalar: success! s={}", prs_(result));
3790template<
class EventHandler>
3795 if(m_options.scalar_filtering())
3797 return _filter_scalar_plain(sc.scalar, indentation);
3801 _c4dbgp(
"plain scalar left unfiltered");
3802 m_evt_handler->mark_key_scalar_unfiltered();
3807 _c4dbgp(
"plain scalar doesn't need filtering");
3812template<
class EventHandler>
3817 if(m_options.scalar_filtering())
3819 return _filter_scalar_plain(sc.scalar, indentation);
3823 _c4dbgp(
"plain scalar left unfiltered");
3824 m_evt_handler->mark_val_scalar_unfiltered();
3829 _c4dbgp(
"plain scalar doesn't need filtering");
3837template<
class EventHandler>
3842 if(m_options.scalar_filtering())
3844 return _filter_scalar_squot(sc.scalar);
3848 _c4dbgp(
"squo key scalar left unfiltered");
3849 m_evt_handler->mark_key_scalar_unfiltered();
3854 _c4dbgp(
"squo key scalar doesn't need filtering");
3859template<
class EventHandler>
3864 if(m_options.scalar_filtering())
3866 return _filter_scalar_squot(sc.scalar);
3870 _c4dbgp(
"squo val scalar left unfiltered");
3871 m_evt_handler->mark_val_scalar_unfiltered();
3876 _c4dbgp(
"squo val scalar doesn't need filtering");
3884template<
class EventHandler>
3889 if(m_options.scalar_filtering())
3891 return _filter_scalar_dquot(sc.scalar);
3895 _c4dbgp(
"dquo scalar left unfiltered");
3896 m_evt_handler->mark_key_scalar_unfiltered();
3901 _c4dbgp(
"dquo scalar doesn't need filtering");
3906template<
class EventHandler>
3911 if(m_options.scalar_filtering())
3913 return _filter_scalar_dquot(sc.scalar);
3917 _c4dbgp(
"dquo scalar left unfiltered");
3918 m_evt_handler->mark_val_scalar_unfiltered();
3923 _c4dbgp(
"dquo scalar doesn't need filtering");
3931template<
class EventHandler>
3934 if(m_options.scalar_filtering())
3936 return _filter_scalar_literal(sb.scalar, sb.indentation, sb.chomp);
3940 _c4dbgp(
"literal scalar left unfiltered");
3941 m_evt_handler->mark_key_scalar_unfiltered();
3946template<
class EventHandler>
3949 if(m_options.scalar_filtering())
3951 return _filter_scalar_literal(sb.scalar, sb.indentation, sb.chomp);
3955 _c4dbgp(
"literal scalar left unfiltered");
3956 m_evt_handler->mark_val_scalar_unfiltered();
3964template<
class EventHandler>
3967 if(m_options.scalar_filtering())
3969 return _filter_scalar_folded(sb.scalar, sb.indentation, sb.chomp);
3973 _c4dbgp(
"folded scalar left unfiltered");
3974 m_evt_handler->mark_key_scalar_unfiltered();
3979template<
class EventHandler>
3982 if(m_options.scalar_filtering())
3984 return _filter_scalar_folded(sb.scalar, sb.indentation, sb.chomp);
3988 _c4dbgp(
"folded scalar left unfiltered");
3989 m_evt_handler->mark_val_scalar_unfiltered();
4001template<
class EventHandler>
4002void ParseEngine<EventHandler>::add_flags(
ParserFlag_t on)
4005 char buf1_[64], buf2_[64], buf3_[64];
4006 csubstr buf1 = detail::_parser_flags_to_str(buf1_, on);
4007 csubstr buf2 = detail::_parser_flags_to_str(buf2_, s->flags);
4008 csubstr buf3 = detail::_parser_flags_to_str(buf3_, s->flags|on);
4009 _c4dbgpf(
"state[{}]: add {}: before={} after={}", s->level, buf1, buf2, buf3);
4013template<
class EventHandler>
4017 char buf1_[64], buf2_[64], buf3_[64], buf4_[64];
4018 csubstr buf1 = detail::_parser_flags_to_str(buf1_, on);
4019 csubstr buf2 = detail::_parser_flags_to_str(buf2_, off);
4020 csubstr buf3 = detail::_parser_flags_to_str(buf3_, s->flags);
4021 csubstr buf4 = detail::_parser_flags_to_str(buf4_, (~off)&((s->flags|on)));
4022 _c4dbgpf(
"state[{}]: add {} / rem {}: before={} after={}", s->level, buf1, buf2, buf3, buf4);
4028template<
class EventHandler>
4029void ParseEngine<EventHandler>::rem_flags(
ParserFlag_t off)
4032 char buf1_[64], buf2_[64], buf3_[64];
4033 csubstr buf1 = detail::_parser_flags_to_str(buf1_, off);
4034 csubstr buf2 = detail::_parser_flags_to_str(buf2_, s->flags);
4035 csubstr buf3 = detail::_parser_flags_to_str(buf3_, s->flags&(~off));
4036 _c4dbgpf(
"state[{}]: rem {}: before={} after={}", s->level, buf1, buf2, buf3);
4043 bool gotone =
false;
4045 #define _prflag(fl) \
4046 if((flags & fl) == (fl)) \
4050 if(pos + 1 < buf.len) \
4054 csubstr fltxt = #fl; \
4055 if(pos + fltxt.len <= buf.len) \
4056 memcpy(buf.str + pos, fltxt.str, fltxt.len); \
4086 RYML_CHECK_BASIC_(pos <= buf.len);
4088 return buf.first(pos);
4098template<
class EventHandler>
4101 RYML_ASSERT_BASIC_CB_(m_evt_handler->m_stack.m_callbacks, loc.offset < _buf().len);
4102 return _buf().sub(loc.offset);
4105template<
class EventHandler>
4108 if C4_UNLIKELY(val ==
nullptr)
4109 return {m_evt_handler->m_curr->pos.
name, 0, 0, 0};
4110 RYML_CHECK_BASIC_CB_(m_evt_handler->m_stack.m_callbacks, m_options.locations());
4113 RYML_ASSERT_BASIC_CB_(m_evt_handler->m_stack.m_callbacks, m_options.locations());
4114 RYML_ASSERT_BASIC_CB_(m_evt_handler->m_stack.m_callbacks, !_locations_dirty());
4115 RYML_ASSERT_BASIC_CB_(m_evt_handler->m_stack.m_callbacks, m_newline_offsets !=
nullptr);
4116 RYML_ASSERT_BASIC_CB_(m_evt_handler->m_stack.m_callbacks, m_newline_offsets_size > 0);
4119 RYML_CHECK_BASIC_CB_(m_evt_handler->m_stack.m_callbacks, val !=
nullptr || src.str ==
nullptr);
4120 RYML_CHECK_BASIC_CB_(m_evt_handler->m_stack.m_callbacks, (val >= src.begin() && val <= src.end()) || (src.str ==
nullptr && val ==
nullptr));
4122 using lineptr_type =
size_t const* C4_RESTRICT;
4123 lineptr_type lineptr =
nullptr;
4124 size_t offset = (size_t)(val - src.begin());
4128 for(lineptr_type curr = m_newline_offsets, last = m_newline_offsets + m_newline_offsets_size; curr < last; ++curr)
4143 size_t count = m_newline_offsets_size;
4144 lineptr = m_newline_offsets;
4147 size_t step = count >> 1;
4148 lineptr_type it = lineptr + step;
4160 RYML_ASSERT_BASIC_CB_(m_evt_handler->m_stack.m_callbacks, lineptr);
4161 RYML_ASSERT_BASIC_CB_(m_evt_handler->m_stack.m_callbacks, lineptr >= m_newline_offsets);
4162 RYML_ASSERT_BASIC_CB_(m_evt_handler->m_stack.m_callbacks, lineptr <= m_newline_offsets + m_newline_offsets_size);
4163 RYML_ASSERT_BASIC_CB_(m_evt_handler->m_stack.m_callbacks, lineptr && (*lineptr > offset));
4165 loc.
name = m_evt_handler->m_curr->pos.name;
4166 loc.offset = offset;
4167 loc.line = (size_t)(lineptr - m_newline_offsets);
4168 if(lineptr > m_newline_offsets)
4169 loc.col = (offset - *(lineptr-1) - 1u);
4175template<
class EventHandler>
4176void ParseEngine<EventHandler>::_prepare_locations()
4179 size_t numnewlines = 1u + src.count(
'\n');
4180 _resize_locations(numnewlines);
4181 m_newline_offsets_size = 0;
4182 for(
size_t i = 0; i < src.len; i++)
4183 if(src.str[i] ==
'\n')
4184 m_newline_offsets[m_newline_offsets_size++] = i;
4185 m_newline_offsets[m_newline_offsets_size++] = src.len;
4186 RYML_ASSERT_BASIC_CB_(m_evt_handler->m_stack.m_callbacks, m_newline_offsets_size == numnewlines);
4189template<
class EventHandler>
4190void ParseEngine<EventHandler>::_resize_locations(
size_t numnewlines)
4192 numnewlines = numnewlines >= 16 ? numnewlines : 16;
4193 if(numnewlines > m_newline_offsets_capacity)
4195 if(m_newline_offsets)
4196 RYML_CB_FREE_(m_evt_handler->m_stack.m_callbacks, m_newline_offsets,
size_t, m_newline_offsets_capacity);
4197 m_newline_offsets = RYML_CB_ALLOC_HINT_(m_evt_handler->m_stack.m_callbacks,
size_t, numnewlines, m_newline_offsets);
4198 m_newline_offsets_capacity = numnewlines;
4202template<
class EventHandler>
4203bool ParseEngine<EventHandler>::_locations_dirty()
const
4205 return !m_newline_offsets_size;
4213template<
class EventHandler>
4214void ParseEngine<EventHandler>::_handle_flow_skip_whitespace()
4217 if(m_evt_handler->m_curr->line_contents.rem.len > 0)
4219 if(m_evt_handler->m_curr->line_contents.rem.str[0] ==
' ' || m_evt_handler->m_curr->line_contents.rem.str[0] ==
'\t')
4221 _c4dbgpf(
"starts with whitespace: '{}'", _c4prc(m_evt_handler->m_curr->line_contents.rem.str[0]));
4225 if(m_evt_handler->m_curr->line_contents.rem.begins_with(
'#'))
4227 _c4dbgpf(
"it's a comment: {}", m_evt_handler->m_curr->line_contents.rem);
4228 _line_progressed(m_evt_handler->m_curr->line_contents.rem.len);
4234template<
class EventHandler>
4235void ParseEngine<EventHandler>::_handle_flow_line_beginning()
4237 _c4dbgpf(
"flow: indref={} indentation={}", m_evt_handler->m_curr->indref, m_evt_handler->m_curr->line_contents.indentation);
4238 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, m_evt_handler->m_curr->at_line_beginning(), m_evt_handler->m_curr->pos);
4239 if C4_UNLIKELY(m_evt_handler->m_curr->indentation_lt())
4241 csubstr trimmed = m_evt_handler->m_curr->line_contents.rem.
sub(m_evt_handler->m_curr->line_contents.indentation);
4242 _c4dbgpf(
"flow: after indentation={}", prs_(trimmed));
4243 if(trimmed.len && trimmed.triml(
" \t").len)
4245 _line_progressed(m_evt_handler->m_curr->line_contents.indentation);
4246 _c4err(
"bad indentation");
4251template<
class EventHandler>
4252size_t ParseEngine<EventHandler>::_handle_block_skip_leading_whitespace()
4254 const size_t mark = m_evt_handler->m_curr->pos.offset;
4255 const size_t firstpos = m_evt_handler->m_curr->line_contents.rem.first_not_of(
" \t");
4256 _c4dbgpf(
"block: mark={} firstpos={}", mark, firstpos);
4257 if(firstpos !=
npos)
4259 _c4dbgp(
"block: non empty line");
4260 _line_progressed(firstpos);
4265 _c4dbgp(
"block: rest of line is whitespace");
4266 _line_progressed(m_evt_handler->m_curr->line_contents.rem.len);
4271template<
class EventHandler>
4272void ParseEngine<EventHandler>::_handle_block_check_leading_tabs(
size_t start_mark,
size_t end_mark)
4274 _c4dbgpf(
"block: start_mark={} end_mark={}", start_mark, end_mark);
4275 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, end_mark >= start_mark, m_evt_handler->m_curr->pos);
4276 if(end_mark != start_mark)
4279 _c4dbgpf(
"block: leading[{}-{}]={}", start_mark, end_mark, prs_(leading,
true));
4280 size_t pos = leading.find(
'\t');
4283 size_t fno = leading.first_not_of(
" \t");
4284 if(fno ==
npos || pos < fno)
4285 _c4err(
"invalid tab character to the left");
4295template<
class EventHandler>
4296void ParseEngine<EventHandler>::_handle_colon()
4298 size_t curr = m_evt_handler->m_curr->pos.line;
4299 if C4_UNLIKELY(m_prev_colon !=
npos && curr == m_prev_colon)
4301 _c4dbgpf(
"colon: prevline={} currline={}", m_prev_colon, curr);
4302 _c4err(
"two colons on same line");
4304 _c4dbgpf(
"colon: set prevline={}->{}", m_prev_colon, curr);
4305 m_prev_colon = curr;
4308template<
class EventHandler>
4309void ParseEngine<EventHandler>::_add_annotation(Annotation *C4_RESTRICT dst,
csubstr str)
4311 _c4dbgpf(
"store annotation[{}]: {}", dst->num_entries, prs_(str));
4312 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, dst->num_entries < C4_COUNTOF(dst->annotations), m_evt_handler->m_curr->pos);
4313 dst->annotations[dst->num_entries].str = str;
4314 dst->annotations[dst->num_entries].indentation = {};
4315 dst->annotations[dst->num_entries].line = {};
4316 dst->annotations[dst->num_entries].orig = {};
4320template<
class EventHandler>
4321void ParseEngine<EventHandler>::_add_annotation(Annotation *C4_RESTRICT dst,
csubstr str,
size_t indentation,
size_t line)
4323 _c4dbgpf(
"store annotation[{}]: '{}' indentation={} line={}", dst->num_entries, maybe_null_str_(str), indentation, line);
4324 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, dst->num_entries < C4_COUNTOF(dst->annotations), m_evt_handler->m_curr->pos);
4325 if C4_UNLIKELY(dst->num_entries && dst->annotations[0].line == line)
4329 dst->annotations[dst->num_entries].str = str;
4330 dst->annotations[dst->num_entries].indentation = indentation;
4331 dst->annotations[dst->num_entries].line = line;
4332 dst->annotations[dst->num_entries].orig = {};
4336template<
class EventHandler>
4337void ParseEngine<EventHandler>::_add_annotation(Annotation *C4_RESTRICT dst,
csubstr str,
size_t indentation,
size_t line,
csubstr orig)
4339 _c4dbgpf(
"store annotation[{}]: '{}'->'{}' indentation={} line={}", dst->num_entries, orig, maybe_null_str_(str), indentation, line);
4340 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, dst->num_entries < C4_COUNTOF(dst->annotations), m_evt_handler->m_curr->pos);
4341 if C4_UNLIKELY(dst->num_entries && dst->annotations[0].line == line)
4345 dst->annotations[dst->num_entries].str = str;
4346 dst->annotations[dst->num_entries].indentation = indentation;
4347 dst->annotations[dst->num_entries].line = line;
4348 dst->annotations[dst->num_entries].orig = orig;
4352template<
class EventHandler>
4353bool ParseEngine<EventHandler>::_annotations_require_key_container()
const
4355 return m_pending_tags.num_entries > 1 || m_pending_anchors.num_entries > 1;
4358template<
class EventHandler>
4359bool ParseEngine<EventHandler>::_handle_annotations_before_unexpected_flow_token_rkey()
4361 if(!(m_pending_tags.num_entries | m_pending_anchors.num_entries))
4363 _c4dbgpf(
"handle_annotations_before_unexpected_flow_comma_rkey, node={}", m_evt_handler->m_curr->node_id);
4364 if(m_pending_tags.num_entries)
4366 _c4dbgpf(
"handle_annotations_before_unexpected_flow_comma_rkey, #tags={}", m_pending_tags.num_entries);
4367 if C4_LIKELY(m_pending_tags.num_entries == 1)
4369 m_evt_handler->set_key_tag(m_pending_tags.annotations[0].str);
4370 _clear_annotations(&m_pending_tags);
4377 if(m_pending_anchors.num_entries)
4379 _c4dbgpf(
"handle_annotations_before_unexpected_flow_comma, #anchors={}", m_pending_tags.num_entries);
4380 if C4_LIKELY(m_pending_anchors.num_entries == 1)
4382 m_evt_handler->set_key_anchor(m_pending_anchors.annotations[0].str);
4383 _clear_annotations(&m_pending_anchors);
4387 _c4err(
"too many anchors");
4390 m_evt_handler->set_key_scalar_plain_empty();
4391 m_evt_handler->set_val_scalar_plain_empty();
4395template<
class EventHandler>
4396void ParseEngine<EventHandler>::_handle_annotations_before_blck_key_scalar()
4398 _c4dbgpf(
"annotations_before_blck_key_scalar, node={}", m_evt_handler->m_curr->node_id);
4399 if(m_pending_tags.num_entries)
4401 _c4dbgpf(
"annotations_before_blck_key_scalar, #tags={}", m_pending_tags.num_entries);
4402 if C4_LIKELY(m_pending_tags.num_entries == 1)
4404 m_evt_handler->set_key_tag(m_pending_tags.annotations[0].str);
4405 _clear_annotations(&m_pending_tags);
4412 if(m_pending_anchors.num_entries)
4414 _c4dbgpf(
"annotations_before_blck_key_scalar, #anchors={}", m_pending_anchors.num_entries);
4415 if C4_LIKELY(m_pending_anchors.num_entries == 1)
4417 m_evt_handler->set_key_anchor(m_pending_anchors.annotations[0].str);
4418 _clear_annotations(&m_pending_anchors);
4422 _c4err(
"too many anchors");
4427template<
class EventHandler>
4428void ParseEngine<EventHandler>::_handle_annotations_before_blck_val_scalar()
4430 _c4dbgpf(
"annotations_before_blck_val_scalar, node={}", m_evt_handler->m_curr->node_id);
4431 if(m_pending_tags.num_entries)
4433 _c4dbgpf(
"annotations_before_blck_val_scalar, #tags={}", m_pending_tags.num_entries);
4434 if C4_LIKELY(m_pending_tags.num_entries == 1)
4436 m_evt_handler->set_val_tag(m_pending_tags.annotations[0].str);
4437 _clear_annotations(&m_pending_tags);
4444 if(m_pending_anchors.num_entries)
4446 _c4dbgpf(
"annotations_before_blck_val_scalar, #anchors={}", m_pending_anchors.num_entries);
4447 if C4_LIKELY(m_pending_anchors.num_entries == 1)
4449 m_evt_handler->set_val_anchor(m_pending_anchors.annotations[0].str);
4450 _clear_annotations(&m_pending_anchors);
4454 _c4err(
"too many anchors");
4459template<
class EventHandler>
4460void ParseEngine<EventHandler>::_handle_annotations_before_start_mapblck(
size_t current_line)
4462 _c4dbgpf(
"annotations_before_start_mapblck, current_line={}", current_line);
4463 if(m_pending_tags.num_entries == 2)
4465 _c4dbgp(
"2 tags, setting entry 0");
4466 m_evt_handler->set_val_tag(m_pending_tags.annotations[0].str);
4468 else if(m_pending_tags.num_entries == 1)
4470 _c4dbgpf(
"1 tag. line={}, curr={}", m_pending_tags.annotations[0].line, current_line);
4471 if(m_pending_tags.annotations[0].line < current_line)
4473 _c4dbgp(
"...tag is for the map. setting it.");
4474 m_evt_handler->set_val_tag(m_pending_tags.annotations[0].str);
4475 _clear_annotations(&m_pending_tags);
4479 if(m_pending_anchors.num_entries == 2)
4481 _c4dbgp(
"2 anchors, setting entry 0");
4482 m_evt_handler->set_val_anchor(m_pending_anchors.annotations[0].str);
4484 else if(m_pending_anchors.num_entries == 1)
4486 _c4dbgpf(
"1 anchor. line={}, curr={}", m_pending_anchors.annotations[0].line, current_line);
4487 if(m_pending_anchors.annotations[0].line < current_line)
4489 _c4dbgp(
"...anchor is for the map. setting it.");
4490 m_evt_handler->set_val_anchor(m_pending_anchors.annotations[0].str);
4491 _clear_annotations(&m_pending_anchors);
4496template<
class EventHandler>
4497void ParseEngine<EventHandler>::_handle_annotations_before_start_mapblck_as_key()
4499 _c4dbgp(
"annotations_before_start_mapblck_as_key");
4500 switch(m_pending_tags.num_entries)
4503 _c4dbgpf(
"annotations_after_start_mapblck_as_key: 1 tag={} line={} currline=", prs_(m_pending_tags.annotations[0].str), m_pending_tags.annotations[0].line, m_evt_handler->m_curr->pos.line);
4504 if(m_pending_tags.annotations[0].line != m_evt_handler->m_curr->pos.line)
4506 _c4dbgp(
"annotations_after_start_mapblck_as_key: is map tag");
4507 m_evt_handler->set_key_tag(m_pending_tags.annotations[0].str);
4508 _clear_annotations(&m_pending_tags);
4512 _c4dbgpf(
"annotations_after_start_mapblck_as_key: 2 tags: {} -> {}", prs_(m_pending_tags.annotations[0].str), prs_(m_pending_tags.annotations[1].str));
4513 m_evt_handler->set_key_tag(m_pending_tags.annotations[0].str);
4516 switch(m_pending_anchors.num_entries)
4519 _c4dbgpf(
"annotations_after_start_mapblck_as_key: 1 anchor={} line={} currline=", m_pending_anchors.annotations[0].str, m_pending_anchors.annotations[0].line, m_evt_handler->m_curr->pos.line);
4520 if(m_pending_anchors.annotations[0].line != m_evt_handler->m_curr->pos.line)
4522 _c4dbgp(
"annotations_after_start_mapblck_as_key: is map anchor");
4523 m_evt_handler->set_key_anchor(m_pending_anchors.annotations[0].str);
4524 _clear_annotations(&m_pending_anchors);
4528 _c4dbgpf(
"annotations_after_start_mapblck_as_key: 2 anchors: {} -> {}", m_pending_anchors.annotations[0].str, m_pending_anchors.annotations[1].str);
4529 m_evt_handler->set_key_anchor(m_pending_anchors.annotations[0].str);
4534template<
class EventHandler>
4535void ParseEngine<EventHandler>::_handle_annotations_and_indentation_after_start_mapblck(
size_t key_indentation,
size_t key_line)
4537 _c4dbgp(
"annotations_after_start_mapblck");
4538 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, m_pending_tags.num_entries <= 2, m_evt_handler->m_curr->pos);
4539 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, m_pending_anchors.num_entries <= 2, m_evt_handler->m_curr->pos);
4540 if(m_pending_anchors.num_entries || m_pending_tags.num_entries)
4542 key_indentation = _select_indentation_from_annotations(key_indentation, key_line);
4543 switch(m_pending_tags.num_entries)
4546 _c4dbgpf(
"annotations_after_start_mapblck: 1 tag: {}", prs_(m_pending_tags.annotations[0].str));
4547 m_evt_handler->set_key_tag(m_pending_tags.annotations[0].str);
4548 _clear_annotations(&m_pending_tags);
4551 _c4dbgpf(
"annotations_after_start_mapblck: 2 tags: {} -> {}", prs_(m_pending_tags.annotations[0].str), prs_(m_pending_tags.annotations[1].str));
4552 m_evt_handler->set_key_tag(m_pending_tags.annotations[1].str);
4553 _clear_annotations(&m_pending_tags);
4556 switch(m_pending_anchors.num_entries)
4559 _c4dbgpf(
"annotations_after_start_mapblck: 1 anchors: {} -> {}", m_pending_anchors.annotations[0].str);
4560 m_evt_handler->set_key_anchor(m_pending_anchors.annotations[0].str);
4561 _clear_annotations(&m_pending_anchors);
4564 _c4dbgpf(
"annotations_after_start_mapblck: 2 anchors: {} -> {}", m_pending_anchors.annotations[0].str, m_pending_anchors.annotations[1].str);
4565 m_evt_handler->set_key_anchor(m_pending_anchors.annotations[1].str);
4566 _clear_annotations(&m_pending_anchors);
4570 _set_indentation(key_indentation);
4573template<
class EventHandler>
4574size_t ParseEngine<EventHandler>::_select_indentation_from_annotations(
size_t val_indentation,
size_t val_line)
4576 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, m_pending_tags.num_entries | m_pending_anchors.num_entries, m_evt_handler->m_curr->pos);
4578 auto const *C4_RESTRICT curr = m_pending_anchors.num_entries ? &m_pending_anchors.annotations[0] : &m_pending_tags.annotations[0];
4579 for(
size_t i = 0; i < m_pending_anchors.num_entries; ++i)
4581 auto const& C4_RESTRICT ann = m_pending_anchors.annotations[i];
4582 if(ann.line > curr->line)
4584 else if(ann.indentation < curr->indentation)
4587 for(
size_t j = 0; j < m_pending_tags.num_entries; ++j)
4589 auto const& C4_RESTRICT ann = m_pending_tags.annotations[j];
4590 if(ann.line > curr->line)
4592 else if(ann.indentation < curr->indentation)
4595 return curr->line < val_line ? val_indentation : curr->indentation;
4598template<
class EventHandler>
4599void ParseEngine<EventHandler>::_handle_keyref(
csubstr alias)
4601 if C4_LIKELY(!(m_pending_anchors.num_entries | m_pending_tags.num_entries))
4602 m_evt_handler->set_key_ref(alias);
4604 _c4err(
"aliases cannot have anchors or tags");
4607template<class EventHandler>
4610 if C4_LIKELY(!(m_pending_anchors.num_entries | m_pending_tags.num_entries))
4611 m_evt_handler->set_val_ref(alias);
4613 _c4err(
"aliases cannot have anchors or tags");
4616template<class EventHandler>
4619 _c4dbgpf(
"resolving tag: {} curr_doc={}", prs_(tag), m_evt_handler->m_curr_doc);
4624 _c4dbgpf(
"resolving tag: found in cache[{}]: {}", ret.pos, prs_(ret.resolved));
4625 return ret.resolved;
4627 _c4dbgpf(
"resolving tag: not in cache: {} curr_doc={}", prs_(tag), m_evt_handler->m_curr_doc);
4629 substr buf = m_evt_handler->arena_rem();
4630 TagDirectives const& C4_RESTRICT tds = m_evt_handler->tag_directives();
4631 csubstr ttag = tds.resolve(buf, &bufsz, tag, m_evt_handler->m_curr_doc,
4632 m_evt_handler->m_curr->pos,
4633 m_evt_handler->m_stack.m_callbacks);
4634 _c4dbgpf(
"resolving tag: bufsz={} ttag.len={} !!ttag.str={}", bufsz, ttag.len, !!ttag.str);
4635 _c4assert((bufsz > buf.len) == (!ttag.str));
4636 _c4assert(!!bufsz == (ttag.len == bufsz));
4640 _c4dbgpf(
"tag requires arena, but it was small. arena.len={} arena.slack={} tag.required={}", m_evt_handler->arena_rem().len, m_evt_handler->arena().len, ttag.len);
4642 buf = _alloc_arena(bufsz, &tag);
4645 ttag = tds.resolve(buf, &bufsz, tag, m_evt_handler->m_curr_doc,
4646 m_evt_handler->m_curr->pos,
4647 m_evt_handler->m_stack.m_callbacks);
4650 _c4assert(!ttag.str || ttag.is_sub(m_evt_handler->arena()));
4654 _c4dbgp(
"tag required arena. update size");
4657 (void)_alloc_arena(bufsz);
4659 C4_SUPPRESS_WARNING_MSVC_WITH_PUSH(4127)
4660 if C4_IF_CONSTEXPR (EventHandler::requires_strings_on_buffers)
4662 _c4dbgpf(
"handler requires tags in buffers. !!ttag.str={} in_arena={} in_src={}", !!ttag.str, ttag.is_sub(m_evt_handler->arena()), ttag.is_sub(_buf()));
4664 if(ttag.str && !ttag.is_sub(m_evt_handler->arena()) && !ttag.is_sub(_buf()))
4666 _c4dbgpf(
"copying resolved tag to arena: slack={} required={}", m_evt_handler->arena_rem().len, ttag.len);
4667 buf = _alloc_arena(ttag.len, &tag);
4669 memcpy(buf.str, ttag.str, ttag.len);
4671 _c4assert(!ttag.str || ttag.is_sub(m_evt_handler->arena()));
4674 C4_SUPPRESS_WARNING_MSVC_POP
4675 _c4dbgpf(
"resolved tag: {} --> [{}]~~~{}~~~", prs_(tag), ttag.len, maybe_null_str_(ttag));
4678 m_evt_handler->tag_cache().add(tag, ttag, m_evt_handler->m_curr_doc, ret.pos);
4682template<
class EventHandler>
4683bool ParseEngine<EventHandler>::_validate_directive_yaml(
csubstr *C4_RESTRICT directive,
csubstr *C4_RESTRICT
version)
const
4685 _c4assert(directive->begins_with(
"%YAML"));
4686 size_t version_start = directive->first_not_of(
" \t", 5);
4687 if(version_start !=
npos)
4689 csubstr digits =
"0123456789";
4690 size_t major_end = directive->
first_not_of(digits, version_start);
4691 if(major_end !=
npos && directive->str[major_end] ==
'.')
4693 size_t minor_end = directive->first_not_of(digits, major_end + 1);
4694 if(minor_end ==
npos)
4695 minor_end = directive->len;
4696 _set_first_strict(*directive, minor_end);
4697 *
version = directive->range(version_start, minor_end);
4698 _c4dbgpf(
"%YAML: version={} full={}", *
version, prs_(*directive,
true));
4705template<
class EventHandler>
4706bool ParseEngine<EventHandler>::_validate_directive_tag(
csubstr *C4_RESTRICT directive,
csubstr *C4_RESTRICT handle,
csubstr *C4_RESTRICT prefix)
const
4708 _c4assert(directive->begins_with(
"%TAG"));
4710 size_t handle_start = directive->
first_not_of(whitespace, 4);
4711 if(handle_start !=
npos && directive->str[handle_start] ==
'!')
4713 size_t handle_end = directive->first_of(whitespace, handle_start);
4714 if(handle_end !=
npos)
4716 size_t prefix_start = directive->first_not_of(whitespace, handle_end);
4717 if(prefix_start !=
npos)
4719 size_t prefix_end = directive->first_of(whitespace, prefix_start);
4720 if(prefix_end ==
npos)
4721 prefix_end = directive->len;
4722 _set_first_strict(*directive, prefix_end);
4723 *handle = directive->range(handle_start, handle_end);
4724 *prefix = directive->range(prefix_start, prefix_end);
4725 _c4dbgpf(
"%TAG: handle={} prefix={} full={}", *handle, *prefix, prs_(*directive,
true));
4734template<
class EventHandler>
4735void ParseEngine<EventHandler>::_handle_directive(
csubstr directive)
4737 _c4dbgpf(
"handle_directive: rem={}", prs_(directive,
true));
4738 _c4assert(m_evt_handler->m_curr->line_contents.rem.begins_with(
'%'));
4739 _c4assert(directive.str == m_evt_handler->m_curr->line_contents.rem.str);
4740 const char *err =
nullptr;
4744 if(str.begins_with(dir))
4747 return (!rest.len || rest.str[0] ==
' ' || rest.str[0] ==
'\t');
4751 if(isdirective(directive,
"%TAG"))
4755 if C4_UNLIKELY(!_validate_directive_tag(&directive, &handle, &prefix))
4757 err =
"invalid %TAG directive";
4758 goto directive_error;
4760 m_evt_handler->add_directive_tag(handle, prefix);
4762 else if(isdirective(directive,
"%YAML"))
4765 if C4_UNLIKELY(!_validate_directive_yaml(&directive, &
version))
4767 err =
"invalid %YAML directive";
4768 goto directive_error;
4770 if C4_UNLIKELY(m_has_directives_yaml)
4772 err =
"multiple %YAML directives";
4773 goto directive_error;
4775 m_has_directives_yaml =
true;
4776 m_evt_handler->add_directive_yaml(
version);
4778 m_has_directives =
true;
4779 rem = m_evt_handler->m_curr->line_contents.rem;
4781 pos = pos !=
npos ? pos : rem.len;
4782 _line_progressed(pos);
4784 _c4dbgpf(
"handle_directive: rest={}", prs_(rem));
4785 if C4_UNLIKELY(rem.len && !rem.begins_with(
'#'))
4787 err =
"invalid tokens after directive";
4788 goto directive_error;
4791 if C4_UNLIKELY(err !=
nullptr)
4795template<class EventHandler>
4798 const csubstr rem = m_evt_handler->m_curr->line_contents.rem;
4801 const csubstr rest = rem.sub(1);
4803 #define _rymlisascii(c) ((c) >
'\0' && (c) <=
'\x7f')
4804 if(rem.begins_with(csubstr{
"\x00\x00\xfe\xff", 4})
4806 || (rem.begins_with(
csubstr{
"\x00\x00\x00", 3}) && rem.len >= 4u && _rymlisascii(rem.str[3])))
4808 _c4err(
"UTF32BE not supported");
4810 else if(rem.begins_with(
csubstr{
"\xff\xfe\x00\x00", 4})
4812 || (rest.begins_with(
csubstr{
"\x00\x00\x00", 3}) && rem.len >= 4u && _rymlisascii(rem.str[0])))
4814 _c4err(
"UTF32LE not supported");
4816 else if(rem.begins_with(
"\xfe\xff") || (rem.begins_with(
'\x00') && rem.len >= 2u && _rymlisascii(rem.str[1])))
4818 _c4err(
"UTF16BE not supported");
4820 else if(rem.begins_with(
"\xff\xfe") || (rest.begins_with(
'\x00') && rem.len >= 2u && _rymlisascii(rem.str[0])))
4822 _c4err(
"UTF16LE not supported");
4824 else if(rem.begins_with(
"\xef\xbb\xbf"))
4826 _c4dbgp(
"byte order mark: UTF8");
4828 _line_progressed(3);
4837template<
class EventHandler>
4838void ParseEngine<EventHandler>::_handle_bom(
Encoding_e enc)
4840 if(m_encoding ==
NOBOM)
4842 if(enc ==
UTF8 || (m_evt_handler->m_curr->line_contents.rem.str == _buf().str))
4845 _c4err(
"non-UTF8 byte order mark can appear only at the beginning of the file");
4847 else if(enc != m_encoding)
4849 _c4err(
"byte order mark can only be set once");
4856template<
class EventHandler>
4857void ParseEngine<EventHandler>::_handle_seq_json()
4860 _c4dbgpf(
"handle2_seq_json: node_id={} level={} indentation={}", m_evt_handler->m_curr->node_id, m_evt_handler->m_curr->level, m_evt_handler->m_curr->indref);
4862 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RKEY), m_evt_handler->m_curr->pos);
4863 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_all(
RSEQ), m_evt_handler->m_curr->pos);
4864 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_all(
RFLOW), m_evt_handler->m_curr->pos);
4865 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_any(
RVAL|
RNXT), m_evt_handler->m_curr->pos);
4866 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_all(
RVAL) != has_all(
RNXT), m_evt_handler->m_curr->pos);
4868 _handle_flow_skip_whitespace();
4869 csubstr rem = m_evt_handler->m_curr->line_contents.rem;
4875 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RNXT), m_evt_handler->m_curr->pos);
4876 const char first = rem.str[0];
4877 _c4dbgpf(
"mapjson[RVAL]: '{}'", first);
4882 _c4dbgp(
"seqjson[RVAL]: scanning double-quoted scalar");
4883 ScannedScalar sc = _scan_scalar_dquot();
4884 csubstr maybe_filtered = _maybe_filter_val_scalar_dquot(sc);
4885 m_evt_handler->set_val_scalar_dquoted(maybe_filtered);
4891 _c4dbgp(
"seqjson[RVAL]: start child seqjson");
4893 m_evt_handler->begin_seq_val_flow();
4895 _line_progressed(1);
4900 _c4dbgp(
"seqjson[RVAL]: start child mapjson");
4902 m_evt_handler->begin_map_val_flow();
4904 _line_progressed(1);
4905 goto seqjson_finish;
4909 _c4dbgp(
"seqjson[RVAL]: end!");
4912 _line_progressed(1);
4914 goto seqjson_finish;
4920 if(_scan_scalar_seq_json(&sc))
4922 _c4dbgp(
"seqjson[RVAL]: it's a plain scalar.");
4923 csubstr maybe_filtered = _maybe_filter_val_scalar_plain(sc, m_evt_handler->m_curr->indref);
4924 m_evt_handler->set_val_scalar_plain(maybe_filtered);
4936 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_any(
RNXT), m_evt_handler->m_curr->pos);
4937 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RVAL), m_evt_handler->m_curr->pos);
4938 const char first = rem.str[0];
4939 _c4dbgpf(
"mapjson[RNXT]: '{}'", first);
4944 _c4dbgp(
"seqjson[RNXT]: expect next val");
4946 m_evt_handler->add_sibling();
4947 _line_progressed(1);
4952 _c4dbgp(
"seqjson[RNXT]: end!");
4954 _line_progressed(1);
4955 goto seqjson_finish;
4963 _c4dbgt(
"seqjson: go again", 0);
4964 if(_finished_line())
4966 if C4_LIKELY(!_finished_file())
4974 _c4err(
"missing terminating ]");
4980 _c4dbgp(
"seqjson: finish");
4986template<
class EventHandler>
4987void ParseEngine<EventHandler>::_handle_map_json()
4990 _c4dbgpf(
"handle2_map_json: node_id={} level={} indentation={}", m_evt_handler->m_curr->node_id, m_evt_handler->m_curr->level, m_evt_handler->m_curr->indref);
4992 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_all(
RMAP), m_evt_handler->m_curr->pos);
4993 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_all(
RFLOW), m_evt_handler->m_curr->pos);
4994 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
QMRK), m_evt_handler->m_curr->pos);
4995 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_any(
RKEY|
RKCL|
RVAL|
RNXT), m_evt_handler->m_curr->pos);
4996 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, 1 == (has_any(
RKEY) + has_any(
RKCL) + has_any(
RVAL) + has_any(
RNXT)), m_evt_handler->m_curr->pos);
4998 _handle_flow_skip_whitespace();
4999 csubstr rem = m_evt_handler->m_curr->line_contents.rem;
5005 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RKCL), m_evt_handler->m_curr->pos);
5006 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RVAL), m_evt_handler->m_curr->pos);
5007 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RNXT), m_evt_handler->m_curr->pos);
5008 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
QMRK), m_evt_handler->m_curr->pos);
5009 const char first = rem.str[0];
5010 _c4dbgpf(
"mapjson[RKEY]: '{}'", first);
5015 _c4dbgp(
"mapjson[RKEY]: scanning double-quoted scalar");
5016 ScannedScalar sc = _scan_scalar_dquot();
5017 csubstr maybe_filtered = _maybe_filter_key_scalar_dquot(sc);
5018 m_evt_handler->set_key_scalar_dquoted(maybe_filtered);
5024 _c4dbgp(
"mapjson[RKEY]: end!");
5026 _line_progressed(1);
5027 goto mapjson_finish;
5033 else if(has_any(
RVAL))
5035 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RKEY), m_evt_handler->m_curr->pos);
5036 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RKCL), m_evt_handler->m_curr->pos);
5037 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RNXT), m_evt_handler->m_curr->pos);
5038 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
QMRK), m_evt_handler->m_curr->pos);
5039 const char first = rem.str[0];
5040 _c4dbgpf(
"mapjson[RVAL]: '{}'", first);
5045 _c4dbgp(
"mapjson[RVAL]: scanning double-quoted scalar");
5046 ScannedScalar sc = _scan_scalar_dquot();
5047 csubstr maybe_filtered = _maybe_filter_val_scalar_dquot(sc);
5048 m_evt_handler->set_val_scalar_dquoted(maybe_filtered);
5054 _c4dbgp(
"mapjson[RVAL]: start val seqjson");
5056 m_evt_handler->begin_seq_val_flow();
5057 _set_indentation(m_evt_handler->m_parent->indref);
5059 _line_progressed(1);
5060 goto mapjson_finish;
5064 _c4dbgp(
"mapjson[RVAL]: start val mapjson");
5066 m_evt_handler->begin_map_val_flow();
5067 _set_indentation(m_evt_handler->m_parent->indref);
5069 _line_progressed(1);
5076 if(_scan_scalar_map_json(&sc))
5078 _c4dbgp(
"mapjson[RVAL]: plain scalar.");
5079 csubstr maybe_filtered = _maybe_filter_val_scalar_plain(sc, m_evt_handler->m_curr->indref);
5080 m_evt_handler->set_val_scalar_plain(maybe_filtered);
5091 else if(has_any(
RKCL))
5093 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RKEY), m_evt_handler->m_curr->pos);
5094 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RVAL), m_evt_handler->m_curr->pos);
5095 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RNXT), m_evt_handler->m_curr->pos);
5096 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
QMRK), m_evt_handler->m_curr->pos);
5097 const char first = rem.str[0];
5098 _c4dbgpf(
"mapjson[RKCL]: '{}'", first);
5101 _c4dbgp(
"mapjson[RKCL]: found the colon");
5103 _line_progressed(1);
5110 else if(has_any(
RNXT))
5112 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RKEY), m_evt_handler->m_curr->pos);
5113 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RKCL), m_evt_handler->m_curr->pos);
5114 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RVAL), m_evt_handler->m_curr->pos);
5115 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
QMRK), m_evt_handler->m_curr->pos);
5116 _c4dbgpf(
"mapjson[RNXT]: '{}'", rem.str[0]);
5117 if(rem.begins_with(
','))
5119 _c4dbgp(
"mapjson[RNXT]: expect next keyval");
5120 m_evt_handler->add_sibling();
5122 _line_progressed(1);
5124 else if(rem.begins_with(
'}'))
5126 _c4dbgp(
"mapjson[RNXT]: end!");
5128 _line_progressed(1);
5129 goto mapjson_finish;
5138 _c4dbgt(
"mapjson: go again", 0);
5139 if(_finished_line())
5141 if C4_LIKELY(!_finished_file())
5149 _c4err(
"missing terminating }");
5155 _c4dbgp(
"mapjson: finish");
5161template<
class EventHandler>
5162void ParseEngine<EventHandler>::_handle_seq_imap()
5165 _c4dbgpf(
"handle2_seq_imap: node_id={} level={} indref={}", m_evt_handler->m_curr->node_id, m_evt_handler->m_curr->level, m_evt_handler->m_curr->indref);
5167 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_all(
RSEQIMAP), m_evt_handler->m_curr->pos);
5168 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RKEY), m_evt_handler->m_curr->pos);
5169 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_any(
RVAL|
RNXT|
QMRK|
RKCL), m_evt_handler->m_curr->pos);
5170 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, 1 == has_all(
RVAL) + has_all(
RNXT) + has_all(
QMRK) + has_all(
RKCL), m_evt_handler->m_curr->pos);
5171 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, m_evt_handler->m_stack.size() >= 3, m_evt_handler->m_curr->pos);
5173 _handle_flow_skip_whitespace();
5174 csubstr rem = m_evt_handler->m_curr->line_contents.rem;
5180 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_any(
RVAL), m_evt_handler->m_curr->pos);
5181 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RNXT), m_evt_handler->m_curr->pos);
5182 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
QMRK), m_evt_handler->m_curr->pos);
5183 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RKCL), m_evt_handler->m_curr->pos);
5184 const char first = rem.str[0];
5185 _c4dbgpf(
"seqimap[RVAL]: '{}'", _c4prc(first));
5189 _c4dbgp(
"seqimap[RVAL]: scanning single-quoted scalar");
5190 sc = _scan_scalar_squot();
5191 csubstr maybe_filtered = _maybe_filter_val_scalar_squot(sc);
5192 _handle_annotations_before_blck_val_scalar();
5193 m_evt_handler->set_val_scalar_squoted(maybe_filtered);
5195 goto seqimap_finish;
5197 else if(first ==
'"')
5199 _c4dbgp(
"seqimap[RVAL]: scanning double-quoted scalar");
5200 sc = _scan_scalar_dquot();
5201 csubstr maybe_filtered = _maybe_filter_val_scalar_dquot(sc);
5202 _handle_annotations_before_blck_val_scalar();
5203 m_evt_handler->set_val_scalar_dquoted(maybe_filtered);
5205 goto seqimap_finish;
5208 else if(_scan_scalar_plain_map_flow(&sc))
5210 _c4dbgp(
"seqimap[RVAL]: it's a scalar.");
5211 csubstr maybe_filtered = _maybe_filter_val_scalar_plain(sc, m_evt_handler->m_curr->indref);
5212 _handle_annotations_before_blck_val_scalar();
5213 m_evt_handler->set_val_scalar_plain(maybe_filtered);
5215 goto seqimap_finish;
5217 else if(first ==
'[')
5219 _c4dbgp(
"seqimap[RVAL]: start child seqflow");
5221 _handle_annotations_before_blck_val_scalar();
5222 m_evt_handler->begin_seq_val_flow();
5224 _set_indentation(m_evt_handler->m_parent->indref);
5225 _line_progressed(1);
5226 goto seqimap_finish;
5228 else if(first ==
'{')
5230 _c4dbgp(
"seqimap[RVAL]: start child mapflow");
5232 _handle_annotations_before_blck_val_scalar();
5233 m_evt_handler->begin_map_val_flow();
5235 _set_indentation(m_evt_handler->m_parent->indref);
5236 _line_progressed(1);
5237 goto seqimap_finish;
5239 else if(first ==
',' || first ==
']')
5241 _c4dbgp(
"seqimap[RVAL]: finish without val.");
5242 _handle_annotations_before_blck_val_scalar();
5243 m_evt_handler->set_val_scalar_plain_empty();
5245 goto seqimap_finish;
5247 else if(first ==
'*')
5249 csubstr ref = _scan_ref_seq();
5250 _c4dbgpf(
"seqimap[RVAL]: ref! {}", prs_(ref));
5251 _handle_valref(ref);
5254 else if(first ==
'&')
5256 csubstr anchor = _scan_anchor();
5257 _c4dbgpf(
"seqimap[RVAL]: anchor! {}", prs_(anchor));
5258 _add_annotation(&m_pending_anchors, anchor);
5260 else if(first ==
'!')
5263 _c4dbgpf(
"seqimap[RVAL]: tag! {}", prs_(tag));
5264 _add_annotation(&m_pending_tags, tag);
5271 else if(has_any(
RNXT))
5273 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_any(
RNXT), m_evt_handler->m_curr->pos);
5274 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RVAL), m_evt_handler->m_curr->pos);
5275 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
QMRK), m_evt_handler->m_curr->pos);
5276 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RKCL), m_evt_handler->m_curr->pos);
5277 const char first = rem.str[0];
5278 _c4dbgpf(
"seqimap[RNXT]: '{}'", _c4prc(first));
5279 if(first ==
',' || first ==
']')
5283 _c4dbgp(
"seqimap: done");
5285 goto seqimap_finish;
5292 else if(has_any(
QMRK))
5294 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_any(
QMRK), m_evt_handler->m_curr->pos);
5295 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RVAL), m_evt_handler->m_curr->pos);
5296 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RNXT), m_evt_handler->m_curr->pos);
5297 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RKCL), m_evt_handler->m_curr->pos);
5298 const char first = rem.str[0];
5299 _c4dbgpf(
"seqimap[QMRK]: '{}'", _c4prc(first));
5303 _c4dbgp(
"seqimap[QMRK]: scanning single-quoted scalar");
5304 sc = _scan_scalar_squot();
5305 csubstr maybe_filtered = _maybe_filter_key_scalar_squot(sc);
5306 m_evt_handler->set_key_scalar_squoted(maybe_filtered);
5310 else if(first ==
'"')
5312 _c4dbgp(
"seqimap[QMRK]: scanning double-quoted scalar");
5313 sc = _scan_scalar_dquot();
5314 csubstr maybe_filtered = _maybe_filter_key_scalar_dquot(sc);
5315 m_evt_handler->set_key_scalar_dquoted(maybe_filtered);
5320 else if(_scan_scalar_plain_map_flow(&sc))
5322 _c4dbgp(
"seqimap[QMRK]: it's a scalar.");
5323 csubstr maybe_filtered = _maybe_filter_key_scalar_plain(sc, m_evt_handler->m_curr->indref);
5324 m_evt_handler->set_key_scalar_plain(maybe_filtered);
5328 else if(first ==
'[')
5330 _c4dbgp(
"seqimap[QMRK]: start child seqflow");
5332 m_evt_handler->begin_seq_key_flow();
5334 _set_indentation(m_evt_handler->m_parent->indref);
5335 _line_progressed(1);
5336 goto seqimap_finish;
5338 else if(first ==
'{')
5340 _c4dbgp(
"seqimap[QMRK]: start child mapflow");
5342 m_evt_handler->begin_map_key_flow();
5344 _set_indentation(m_evt_handler->m_parent->indref);
5345 _line_progressed(1);
5346 goto seqimap_finish;
5348 else if(first ==
',' || first ==
']')
5350 _c4dbgp(
"seqimap[QMRK]: finish without key.");
5351 m_evt_handler->set_key_scalar_plain_empty();
5352 m_evt_handler->set_val_scalar_plain_empty();
5354 goto seqimap_finish;
5356 else if(first ==
'&')
5358 csubstr anchor = _scan_anchor();
5359 _c4dbgp(
"seqimap[QMRK]: anchor!");
5360 m_evt_handler->set_key_anchor(anchor);
5362 else if(first ==
'*')
5364 csubstr ref = _scan_ref_seq();
5365 _c4dbgp(
"seqimap[QMRK]: ref!");
5366 _handle_keyref(ref);
5374 else if(has_any(
RKCL))
5376 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RVAL), m_evt_handler->m_curr->pos);
5377 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RNXT), m_evt_handler->m_curr->pos);
5378 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
QMRK), m_evt_handler->m_curr->pos);
5379 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_any(
RKCL), m_evt_handler->m_curr->pos);
5380 const char first = rem.str[0];
5381 _c4dbgpf(
"seqimap[RKCL]: '{}'", _c4prc(first));
5384 _c4dbgp(
"seqimap[RKCL]: found ':'");
5386 _line_progressed(1);
5389 else if(first ==
',' || first ==
']')
5391 _c4dbgp(
"seqimap[RKCL]: found ','. finish without val");
5392 m_evt_handler->set_val_scalar_plain_empty();
5394 goto seqimap_finish;
5403 _c4dbgt(
"seqimap: go again", 0);
5404 if(_finished_line())
5406 if C4_LIKELY(!_finished_file())
5420 _c4dbgp(
"seqimap: finish");
5426template<
class EventHandler>
5427void ParseEngine<EventHandler>::_handle_seq_flow()
5430 _c4dbgpf(
"handle_seq_flow: node_id={} level={} indentation={}", m_evt_handler->m_curr->node_id, m_evt_handler->m_curr->level, m_evt_handler->m_curr->indref);
5432 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RKEY), m_evt_handler->m_curr->pos);
5433 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_all(
RSEQ), m_evt_handler->m_curr->pos);
5434 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_all(
RFLOW), m_evt_handler->m_curr->pos);
5435 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_any(
RVAL|
RNXT), m_evt_handler->m_curr->pos);
5436 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_all(
RVAL) != has_all(
RNXT), m_evt_handler->m_curr->pos);
5437 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, m_evt_handler->m_curr->indref !=
npos, m_evt_handler->m_curr->pos);
5439 if(m_evt_handler->m_curr->at_line_beginning())
5441 _handle_flow_line_beginning();
5444 _handle_flow_skip_whitespace();
5445 if(!m_evt_handler->m_curr->line_contents.rem.len)
5450 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RNXT), m_evt_handler->m_curr->pos);
5451 const char first = m_evt_handler->m_curr->line_contents.rem.str[0];
5455 _c4dbgp(
"seqflow[RVAL]: scanning single-quoted scalar");
5456 sc = _scan_scalar_squot();
5457 csubstr maybe_filtered = _maybe_filter_val_scalar_squot(sc);
5458 _handle_annotations_before_blck_val_scalar();
5459 m_evt_handler->set_val_scalar_squoted(maybe_filtered);
5461 _mark_seqflow_val_end();
5463 else if(first ==
'"')
5465 _c4dbgp(
"seqflow[RVAL]: scanning double-quoted scalar");
5466 sc = _scan_scalar_dquot();
5467 csubstr maybe_filtered = _maybe_filter_val_scalar_dquot(sc);
5468 _handle_annotations_before_blck_val_scalar();
5469 m_evt_handler->set_val_scalar_dquoted(maybe_filtered);
5471 _mark_seqflow_val_end();
5474 else if(_scan_scalar_plain_seq_flow(&sc))
5476 _c4dbgp(
"seqflow[RVAL]: it's a scalar.");
5477 csubstr maybe_filtered = _maybe_filter_val_scalar_plain(sc, m_evt_handler->m_curr->indref);
5478 _handle_annotations_before_blck_val_scalar();
5479 m_evt_handler->set_val_scalar_plain(maybe_filtered);
5481 _mark_seqflow_val_end();
5483 else if(first ==
'[')
5485 _c4dbgp(
"seqflow[RVAL]: start child seqflow");
5487 _handle_annotations_before_blck_val_scalar();
5488 m_evt_handler->begin_seq_val_flow();
5489 _set_indentation(m_evt_handler->m_parent->indref);
5491 _line_progressed(1);
5493 else if(first ==
'{')
5495 _c4dbgp(
"seqflow[RVAL]: start child mapflow");
5497 _handle_annotations_before_blck_val_scalar();
5498 m_evt_handler->begin_map_val_flow();
5499 _set_indentation(m_evt_handler->m_parent->indref);
5501 _line_progressed(1);
5502 goto seqflow_finish;
5504 else if(first ==
']')
5506 _c4dbgp(
"seqflow[RVAL]: end!");
5507 if(m_pending_anchors.num_entries | m_pending_tags.num_entries)
5509 _c4dbgp(
"seqflow[RVAL]: add pending annotations");
5510 _handle_annotations_before_blck_val_scalar();
5511 m_evt_handler->set_val_scalar_plain_empty();
5513 _line_progressed(1);
5515 goto seqflow_finish;
5517 else if(first ==
'*')
5519 csubstr ref = _scan_ref_seq();
5520 _c4dbgpf(
"seqflow[RVAL]: ref! {}", prs_(ref));
5521 _handle_valref(ref);
5524 else if(first ==
'&')
5526 csubstr anchor = _scan_anchor();
5527 _c4dbgpf(
"seqflow[RVAL]: anchor! {}", prs_(anchor));
5528 _add_annotation(&m_pending_anchors, anchor);
5530 else if(first ==
'!')
5533 _c4dbgpf(
"seqflow[RVAL]: tag! {}", prs_(tag));
5534 _add_annotation(&m_pending_tags, tag);
5536 else if(first ==
':')
5538 _c4dbgpf(
"seqflow[RVAL]: actually seqimap at node[{}], with empty key", m_evt_handler->m_curr->node_id);
5540 m_evt_handler->begin_map_val_flow();
5541 _set_indentation(m_evt_handler->m_parent->indref);
5542 _handle_annotations_before_blck_key_scalar();
5543 m_evt_handler->set_key_scalar_plain_empty();
5545 _line_progressed(1);
5546 goto seqflow_finish;
5548 else if(first ==
'?')
5550 _c4dbgp(
"seqflow[RVAL]: start child mapflow, explicit key");
5552 m_evt_handler->begin_map_val_flow();
5553 _set_indentation(m_evt_handler->m_parent->indref);
5555 _line_progressed(1);
5556 _maybe_skip_whitespace_tokens();
5557 goto seqflow_finish;
5559 else if(first ==
',')
5561 if(m_pending_anchors.num_entries || m_pending_tags.num_entries)
5563 _c4dbgp(
"seqflow[RVAL]: add pending annotations");
5564 _handle_annotations_before_blck_val_scalar();
5565 m_evt_handler->set_val_scalar_plain_empty();
5567 _mark_seqflow_val_end();
5581 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_any(
RNXT), m_evt_handler->m_curr->pos);
5582 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RVAL), m_evt_handler->m_curr->pos);
5583 const char first = m_evt_handler->m_curr->line_contents.rem.str[0];
5586 _c4dbgp(
"seqflow[RNXT]: expect next val");
5588 m_evt_handler->add_sibling();
5589 _line_progressed(1);
5590 if(m_evt_handler->m_curr->line_contents.rem.begins_with(
'#'))
5592 _c4err(
"parse error: invalid comment after comma");
5594 _mark_seqflow_val_end();
5596 else if(first ==
']')
5598 _c4dbgp(
"seqflow[RNXT]: end!");
5599 _line_progressed(1);
5601 goto seqflow_finish;
5603 else if(first ==
':')
5605 _c4dbgpf(
"seqflow[RNXT]: line@valend={} line@now={}", m_prev_val_end, m_evt_handler->m_curr->pos.line);
5606 if(m_prev_val_end !=
NONE && m_evt_handler->m_curr->pos.line == m_prev_val_end)
5608 _c4dbgpf(
"seqflow[RNXT]: actually seqimap at node[{}]", m_evt_handler->m_curr->node_id);
5609 m_evt_handler->actually_val_is_first_key_of_new_map_flow();
5610 _set_indentation(m_evt_handler->m_parent->indref);
5611 _line_progressed(1);
5613 goto seqflow_finish;
5627 _c4dbgt(
"seqflow: go again", 0);
5628 if(_finished_line())
5630 if C4_LIKELY(!_finished_file())
5638 _c4err(
"missing terminating ]");
5644 _c4dbgp(
"seqflow: finish");
5650template<
class EventHandler>
5651void ParseEngine<EventHandler>::_handle_map_flow()
5654 _c4dbgpf(
"handle_map_flow: node_id={} level={} indentation={}", m_evt_handler->m_curr->node_id, m_evt_handler->m_curr->level, m_evt_handler->m_curr->indref);
5656 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_all(
RMAP), m_evt_handler->m_curr->pos);
5657 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_all(
RFLOW), m_evt_handler->m_curr->pos);
5658 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_any(
RKEY|
RKCL|
RVAL|
RNXT|
QMRK), m_evt_handler->m_curr->pos);
5659 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, 1 == (has_any(
RKEY) + has_any(
RKCL) + has_any(
RVAL) + has_any(
RNXT) + has_any(
QMRK)), m_evt_handler->m_curr->pos);
5661 if(m_evt_handler->m_curr->at_line_beginning())
5663 _handle_flow_line_beginning();
5666 _handle_flow_skip_whitespace();
5667 if(!m_evt_handler->m_curr->line_contents.rem.len)
5672 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RKCL), m_evt_handler->m_curr->pos);
5673 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RVAL), m_evt_handler->m_curr->pos);
5674 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RNXT), m_evt_handler->m_curr->pos);
5675 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
QMRK), m_evt_handler->m_curr->pos);
5676 const char first = m_evt_handler->m_curr->line_contents.rem.str[0];
5677 _c4dbgpf(
"mapflow[RKEY]: '{}'", first);
5681 _c4dbgp(
"mapflow[RKEY]: scanning single-quoted scalar");
5682 sc = _scan_scalar_squot();
5683 csubstr maybe_filtered = _maybe_filter_key_scalar_squot(sc);
5684 _handle_annotations_before_blck_key_scalar();
5685 m_evt_handler->set_key_scalar_squoted(maybe_filtered);
5688 else if(first ==
'"')
5690 _c4dbgp(
"mapflow[RKEY]: scanning double-quoted scalar");
5691 sc = _scan_scalar_dquot();
5692 csubstr maybe_filtered = _maybe_filter_key_scalar_dquot(sc);
5693 _handle_annotations_before_blck_key_scalar();
5694 m_evt_handler->set_key_scalar_dquoted(maybe_filtered);
5698 else if(_scan_scalar_plain_map_flow(&sc))
5700 _c4dbgp(
"mapflow[RKEY]: plain scalar");
5701 csubstr maybe_filtered = _maybe_filter_key_scalar_plain(sc, m_evt_handler->m_curr->indref);
5702 _handle_annotations_before_blck_key_scalar();
5703 m_evt_handler->set_key_scalar_plain(maybe_filtered);
5706 else if(first ==
'?')
5708 _c4dbgp(
"mapflow[RKEY]: explicit key");
5709 _handle_annotations_before_blck_key_scalar();
5711 _line_progressed(1);
5712 _maybe_skip_whitespace_tokens();
5714 else if(first ==
':')
5716 _c4dbgp(
"mapflow[RKEY]: setting empty key");
5717 _handle_annotations_before_blck_key_scalar();
5718 m_evt_handler->set_key_scalar_plain_empty();
5720 _line_progressed(1);
5721 _maybe_skip_whitespace_tokens();
5723 else if(first ==
',')
5725 _c4dbgp(
"mapflow[RKEY]: comma!");
5726 if(!_handle_annotations_before_unexpected_flow_token_rkey())
5727 _c4err(
"unexpected comma");
5731 else if(first ==
'}')
5733 _c4dbgp(
"mapflow[RKEY]: end!");
5734 (void)_handle_annotations_before_unexpected_flow_token_rkey();
5735 _line_progressed(1);
5737 goto mapflow_finish;
5739 else if(first ==
'&')
5741 csubstr anchor = _scan_anchor();
5742 _c4dbgpf(
"mapflow[RKEY]: key anchor! {}", prs_(anchor));
5743 _add_annotation(&m_pending_anchors, anchor);
5745 else if(first ==
'!')
5748 _c4dbgpf(
"mapflow[RKEY]: tag! {}", prs_(tag));
5749 _add_annotation(&m_pending_tags, tag);
5751 else if(first ==
'*')
5753 csubstr ref = _scan_ref_map();
5754 _c4dbgpf(
"mapflow[RKEY]: key ref! {}", prs_(ref));
5755 _handle_keyref(ref);
5758 else if(first ==
'[')
5763 _c4dbgp(
"mapflow[RKEY]: start child seqflow (!)");
5764 _handle_annotations_before_blck_key_scalar();
5766 m_evt_handler->begin_seq_key_flow();
5768 _set_indentation(m_evt_handler->m_parent->indref);
5769 _line_progressed(1);
5770 goto mapflow_finish;
5772 else if(first ==
'{')
5777 _c4dbgp(
"mapflow[RKEY]: start child mapflow (!)");
5778 _handle_annotations_before_blck_key_scalar();
5780 m_evt_handler->begin_map_key_flow();
5782 _set_indentation(m_evt_handler->m_parent->indref);
5783 _line_progressed(1);
5791 else if(has_any(
RKCL))
5793 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RKEY), m_evt_handler->m_curr->pos);
5794 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RVAL), m_evt_handler->m_curr->pos);
5795 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RNXT), m_evt_handler->m_curr->pos);
5796 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
QMRK), m_evt_handler->m_curr->pos);
5797 const char first = m_evt_handler->m_curr->line_contents.rem.str[0];
5798 _c4dbgpf(
"mapflow[RKCL]: '{}'", first);
5801 _c4dbgp(
"mapflow[RKCL]: found the colon");
5803 _line_progressed(1);
5805 else if(first ==
'}')
5807 _c4dbgp(
"mapflow[RKCL]: end with missing val!");
5809 m_evt_handler->set_val_scalar_plain_empty();
5810 _line_progressed(1);
5812 goto mapflow_finish;
5814 else if(first ==
',')
5816 _c4dbgp(
"mapflow[RKCL]: got comma. val is missing");
5817 m_evt_handler->set_val_scalar_plain_empty();
5818 m_evt_handler->add_sibling();
5820 _line_progressed(1);
5821 if(m_evt_handler->m_curr->line_contents.rem.begins_with(
'#'))
5823 _c4err(
"parse error: invalid comment after comma");
5831 else if(has_any(
RVAL))
5833 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RKEY), m_evt_handler->m_curr->pos);
5834 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RKCL), m_evt_handler->m_curr->pos);
5835 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RNXT), m_evt_handler->m_curr->pos);
5836 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
QMRK), m_evt_handler->m_curr->pos);
5837 const char first = m_evt_handler->m_curr->line_contents.rem.str[0];
5838 _c4dbgpf(
"mapflow[RVAL]: '{}'", first);
5842 _c4dbgp(
"mapflow[RVAL]: scanning single-quoted scalar");
5843 sc = _scan_scalar_squot();
5844 csubstr maybe_filtered = _maybe_filter_val_scalar_squot(sc);
5845 _handle_annotations_before_blck_val_scalar();
5846 m_evt_handler->set_val_scalar_squoted(maybe_filtered);
5849 else if(first ==
'"')
5851 _c4dbgp(
"mapflow[RVAL]: scanning double-quoted scalar");
5852 sc = _scan_scalar_dquot();
5853 csubstr maybe_filtered = _maybe_filter_val_scalar_dquot(sc);
5854 _handle_annotations_before_blck_val_scalar();
5855 m_evt_handler->set_val_scalar_dquoted(maybe_filtered);
5859 else if(_scan_scalar_plain_map_flow(&sc))
5861 _c4dbgp(
"mapflow[RVAL]: plain scalar.");
5862 csubstr maybe_filtered = _maybe_filter_val_scalar_plain(sc, m_evt_handler->m_curr->indref);
5863 _handle_annotations_before_blck_val_scalar();
5864 m_evt_handler->set_val_scalar_plain(maybe_filtered);
5867 else if(first ==
'[')
5869 _c4dbgp(
"mapflow[RVAL]: start val seqflow");
5871 _handle_annotations_before_blck_val_scalar();
5872 m_evt_handler->begin_seq_val_flow();
5873 _set_indentation(m_evt_handler->m_parent->indref);
5875 _line_progressed(1);
5876 goto mapflow_finish;
5878 else if(first ==
'{')
5880 _c4dbgp(
"mapflow[RVAL]: start val mapflow");
5882 _handle_annotations_before_blck_val_scalar();
5883 m_evt_handler->begin_map_val_flow();
5884 _set_indentation(m_evt_handler->m_parent->indref);
5886 _line_progressed(1);
5889 else if(first ==
'}')
5891 _c4dbgp(
"mapflow[RVAL]: end!");
5892 _handle_annotations_before_blck_val_scalar();
5893 m_evt_handler->set_val_scalar_plain_empty();
5894 _line_progressed(1);
5896 goto mapflow_finish;
5898 else if(first ==
',')
5900 _c4dbgp(
"mapflow[RVAL]: empty val!");
5901 _handle_annotations_before_blck_val_scalar();
5902 m_evt_handler->set_val_scalar_plain_empty();
5906 else if(first ==
'*')
5908 csubstr ref = _scan_ref_map();
5909 _c4dbgpf(
"mapflow[RVAL]: key ref! {}", prs_(ref));
5910 _handle_valref(ref);
5913 else if(first ==
'&')
5915 csubstr anchor = _scan_anchor();
5916 _c4dbgpf(
"mapflow[RVAL]: key anchor! {}", prs_(anchor));
5917 _add_annotation(&m_pending_anchors, anchor);
5919 else if(first ==
'!')
5922 _c4dbgpf(
"mapflow[RVAL]: tag! {}", prs_(tag));
5923 _add_annotation(&m_pending_tags, tag);
5930 else if(has_any(
RNXT))
5932 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RKEY), m_evt_handler->m_curr->pos);
5933 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RKCL), m_evt_handler->m_curr->pos);
5934 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RVAL), m_evt_handler->m_curr->pos);
5935 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
QMRK), m_evt_handler->m_curr->pos);
5936 _c4dbgpf(
"mapflow[RNXT]: '{}'", m_evt_handler->m_curr->line_contents.rem.str[0]);
5937 if(m_evt_handler->m_curr->line_contents.rem.begins_with(
','))
5939 _c4dbgp(
"mapflow[RNXT]: expect next keyval");
5940 m_evt_handler->add_sibling();
5942 _line_progressed(1);
5943 if(m_evt_handler->m_curr->line_contents.rem.begins_with(
'#'))
5945 _c4err(
"parse error: invalid comment after comma");
5948 else if(m_evt_handler->m_curr->line_contents.rem.begins_with(
'}'))
5950 _c4dbgp(
"mapflow[RNXT]: end!");
5951 _line_progressed(1);
5953 goto mapflow_finish;
5960 else if(has_any(
QMRK))
5962 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RKEY), m_evt_handler->m_curr->pos);
5963 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RKCL), m_evt_handler->m_curr->pos);
5964 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RVAL), m_evt_handler->m_curr->pos);
5965 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RNXT), m_evt_handler->m_curr->pos);
5966 const char first = m_evt_handler->m_curr->line_contents.rem.str[0];
5967 _c4dbgpf(
"mapflow[QMRK]: '{}'", first);
5971 _c4dbgp(
"mapflow[QMRK]: scanning single-quoted scalar");
5972 sc = _scan_scalar_squot();
5973 csubstr maybe_filtered = _maybe_filter_key_scalar_squot(sc);
5974 _handle_annotations_before_blck_key_scalar();
5975 m_evt_handler->set_key_scalar_squoted(maybe_filtered);
5978 else if(first ==
'"')
5980 _c4dbgp(
"mapflow[QMRK]: scanning double-quoted scalar");
5981 sc = _scan_scalar_dquot();
5982 csubstr maybe_filtered = _maybe_filter_key_scalar_dquot(sc);
5983 _handle_annotations_before_blck_key_scalar();
5984 m_evt_handler->set_key_scalar_dquoted(maybe_filtered);
5988 else if(_scan_scalar_plain_map_flow(&sc))
5990 _c4dbgp(
"mapflow[QMRK]: plain scalar");
5991 csubstr maybe_filtered = _maybe_filter_key_scalar_plain(sc, m_evt_handler->m_curr->indref);
5992 _handle_annotations_before_blck_key_scalar();
5993 m_evt_handler->set_key_scalar_plain(maybe_filtered);
5996 else if(first ==
':')
5998 _c4dbgp(
"mapflow[QMRK]: setting empty key");
5999 _handle_annotations_before_blck_key_scalar();
6000 m_evt_handler->set_key_scalar_plain_empty();
6002 _line_progressed(1);
6003 _maybe_skip_whitespace_tokens();
6005 else if(first ==
'}')
6007 _c4dbgp(
"mapflow[QMRK]: end!");
6008 _handle_annotations_before_blck_key_scalar();
6009 m_evt_handler->set_key_scalar_plain_empty();
6010 m_evt_handler->set_val_scalar_plain_empty();
6012 _line_progressed(1);
6013 goto mapflow_finish;
6015 else if(first ==
',')
6017 _c4dbgp(
"mapflow[QMRK]: empty key+val!");
6018 _handle_annotations_before_blck_key_scalar();
6019 m_evt_handler->set_key_scalar_plain_empty();
6020 m_evt_handler->set_val_scalar_plain_empty();
6023 else if(first ==
'&')
6025 csubstr anchor = _scan_anchor();
6026 _c4dbgpf(
"mapflow[QMRK]: key anchor! {}", prs_(anchor));
6027 _add_annotation(&m_pending_anchors, anchor);
6029 else if(first ==
'*')
6031 csubstr ref = _scan_ref_map();
6032 _c4dbgpf(
"mapflow[QMRK]: key ref! {}", prs_(ref));
6033 _handle_keyref(ref);
6036 else if(first ==
'[')
6041 _c4dbgp(
"mapflow[QMRK]: start child seqflow (!)");
6043 _handle_annotations_before_blck_key_scalar();
6044 m_evt_handler->begin_seq_key_flow();
6046 _set_indentation(m_evt_handler->m_parent->indref);
6047 _line_progressed(1);
6048 goto mapflow_finish;
6050 else if(first ==
'{')
6055 _c4dbgp(
"mapflow[QMRK]: start child mapflow (!)");
6057 _handle_annotations_before_blck_key_scalar();
6058 m_evt_handler->begin_map_key_flow();
6059 _set_indentation(m_evt_handler->m_parent->indref);
6061 _line_progressed(1);
6064 else if(first ==
'!')
6067 _c4dbgpf(
"mapflow[QMRK]: tag! {}", prs_(tag));
6068 _add_annotation(&m_pending_tags, tag);
6077 _c4dbgt(
"mapflow: go again", 0);
6078 if(_finished_line())
6080 if C4_LIKELY(!_finished_file())
6088 _c4err(
"missing terminating }");
6094 _c4dbgp(
"mapflow: finish");
6100template<
class EventHandler>
6101void ParseEngine<EventHandler>::_handle_seq_block()
6104 _c4dbgpf(
"handle_seq_block: seq_id={} node_id={} level={} indent={}", m_evt_handler->m_parent->node_id, m_evt_handler->m_curr->node_id, m_evt_handler->m_curr->level, m_evt_handler->m_curr->indref);
6106 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_all(
RSEQ), m_evt_handler->m_curr->pos);
6107 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_all(
RBLCK), m_evt_handler->m_curr->pos);
6108 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_any(
RVAL|
RNXT), m_evt_handler->m_curr->pos);
6109 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, 1 == (has_any(
RVAL) + has_any(
RNXT)), m_evt_handler->m_curr->pos);
6111 _maybe_skip_comment_strict();
6112 if(!m_evt_handler->m_curr->line_contents.rem.len)
6117 _c4dbgpf(
"seqblck[RVAL]: col={}", m_evt_handler->m_curr->pos.col);
6118 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RNXT), m_evt_handler->m_curr->pos);
6119 if(m_evt_handler->m_curr->at_line_beginning())
6121 _c4dbgpf(
"seqblck[RVAL]: indref={} indentation={}", m_evt_handler->m_curr->indref+1, m_evt_handler->m_curr->line_contents.indentation);
6122 if(m_evt_handler->m_curr->indentation_ge_extra())
6124 _c4dbgpf(
"seqblck[RVAL]: skip {} from indentation", m_evt_handler->m_curr->line_contents.indentation);
6125 _line_progressed(m_evt_handler->m_curr->line_contents.indentation);
6126 if(!m_evt_handler->m_curr->line_contents.rem.len)
6129 else if(m_evt_handler->m_curr->indentation_lt_extra())
6131 _c4dbgp(
"seqblck[RVAL]: smaller indentation than RVAL!");
6132 if(m_evt_handler->m_curr->indentation_eq())
6134 _c4dbgp(
"seqblck[RVAL]: smaller indentation than RVAL!");
6135 _handle_annotations_before_blck_val_scalar();
6136 m_evt_handler->set_val_scalar_plain_empty();
6142 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, m_evt_handler->m_curr->indentation_lt(), m_evt_handler->m_curr->pos);
6143 _c4dbgp(
"seqblck[RVAL]: smaller indentation!");
6144 _handle_indentation_pop_from_block_seq();
6145 goto seqblck_finish;
6148 else if(m_evt_handler->m_curr->line_contents.indentation ==
npos)
6150 _c4dbgp(
"seqblck[RVAL]: empty line!");
6151 _line_progressed(m_evt_handler->m_curr->line_contents.rem.len);
6155 RYML_ASSERT_PARSE_CB_(callbacks(), m_evt_handler->m_curr->line_contents.rem.len, m_evt_handler->m_curr->pos);
6156 const size_t startmark = _handle_block_skip_leading_whitespace();
6157 _c4dbgpf(
"seqblck[RVAL]: startmark={}", startmark);
6158 if(startmark ==
npos)
6160 _c4dbgp(
"seqblck[RVAL]: whitespace only");
6163 const size_t tabmark = _handle_block_get_whitespace_mark();
6164 const char first = m_evt_handler->m_curr->line_contents.rem.str[0];
6165 _c4dbgpf(
"seqblck[RVAL]: first='{}' currcol={}", first, m_evt_handler->m_curr->pos.col - 1);
6166 const size_t startline = m_evt_handler->m_curr->pos.line;
6167 _c4assert(m_evt_handler->m_curr->line_contents.current_col() >= m_bom_len);
6168 const size_t startindent = m_evt_handler->m_curr->line_contents.current_col() - m_bom_len;
6172 _c4dbgp(
"seqblck[RVAL]: single-quoted scalar");
6173 sc = _scan_scalar_squot();
6174 if(!_maybe_scan_following_colon())
6176 _c4dbgp(
"seqblck[RVAL]: set as val");
6177 _handle_annotations_before_blck_val_scalar();
6178 csubstr maybe_filtered = _maybe_filter_val_scalar_squot(sc);
6179 m_evt_handler->set_val_scalar_squoted(maybe_filtered);
6184 _c4dbgp(
"seqblck[RVAL]: start mapblck, set scalar as key");
6185 _handle_block_check_leading_tabs(startmark);
6187 _handle_annotations_before_start_mapblck(startline);
6189 m_evt_handler->begin_map_val_block();
6190 _handle_annotations_and_indentation_after_start_mapblck(startindent, startline);
6191 csubstr maybe_filtered = _maybe_filter_key_scalar_squot(sc);
6192 m_evt_handler->set_key_scalar_squoted(maybe_filtered);
6194 _maybe_skip_whitespace_tokens();
6195 goto seqblck_finish;
6198 else if(first ==
'"')
6200 _c4dbgp(
"seqblck[RVAL]: double-quoted scalar");
6201 sc = _scan_scalar_dquot();
6202 if(!_maybe_scan_following_colon())
6204 _c4dbgp(
"seqblck[RVAL]: set as val");
6205 _handle_annotations_before_blck_val_scalar();
6206 csubstr maybe_filtered = _maybe_filter_val_scalar_dquot(sc);
6207 m_evt_handler->set_val_scalar_dquoted(maybe_filtered);
6212 _c4dbgp(
"seqblck[RVAL]: start mapblck, set scalar as key");
6214 _handle_block_check_leading_tabs(startmark);
6215 _handle_annotations_before_start_mapblck(startline);
6217 m_evt_handler->begin_map_val_block();
6218 _handle_annotations_and_indentation_after_start_mapblck(startindent, startline);
6219 csubstr maybe_filtered = _maybe_filter_key_scalar_dquot(sc);
6220 m_evt_handler->set_key_scalar_dquoted(maybe_filtered);
6222 _maybe_skip_whitespace_tokens();
6223 goto seqblck_finish;
6229 else if(first ==
'|')
6231 _c4dbgp(
"seqblck[RVAL]: block-literal scalar");
6233 _scan_block(&sb, m_evt_handler->m_curr->indref + 1);
6234 _handle_annotations_before_blck_val_scalar();
6235 csubstr maybe_filtered = _maybe_filter_val_scalar_literal(sb);
6236 m_evt_handler->set_val_scalar_literal(maybe_filtered);
6239 else if(first ==
'>')
6241 _c4dbgp(
"seqblck[RVAL]: block-folded scalar");
6243 _scan_block(&sb, m_evt_handler->m_curr->indref + 1);
6244 _handle_annotations_before_blck_val_scalar();
6245 csubstr maybe_filtered = _maybe_filter_val_scalar_folded(sb);
6246 m_evt_handler->set_val_scalar_folded(maybe_filtered);
6249 else if(_scan_scalar_plain_seq_blck(&sc))
6251 _c4dbgp(
"seqblck[RVAL]: plain scalar.");
6252 if(!_maybe_scan_following_colon())
6254 _c4dbgp(
"seqblck[RVAL]: set as val");
6255 _handle_annotations_before_blck_val_scalar();
6256 csubstr maybe_filtered = _maybe_filter_val_scalar_plain(sc, m_evt_handler->m_curr->indref);
6257 m_evt_handler->set_val_scalar_plain(maybe_filtered);
6262 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, m_evt_handler->m_curr->indref !=
npos, m_evt_handler->m_curr->pos);
6263 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, startindent > m_evt_handler->m_curr->indref, m_evt_handler->m_curr->pos);
6264 _c4dbgp(
"seqblck[RVAL]: start mapblck, set scalar as key");
6265 _handle_block_check_leading_tabs(startmark, tabmark);
6267 _handle_annotations_before_start_mapblck(startline);
6269 m_evt_handler->begin_map_val_block();
6270 _handle_annotations_and_indentation_after_start_mapblck(startindent, startline);
6271 csubstr maybe_filtered = _maybe_filter_key_scalar_plain(sc, m_evt_handler->m_curr->indref);
6272 m_evt_handler->set_key_scalar_plain(maybe_filtered);
6274 _maybe_skip_whitespace_tokens();
6275 goto seqblck_finish;
6278 else if(first ==
'[')
6280 _c4dbgp(
"seqblck[RVAL]: start child seqflow");
6282 _handle_annotations_before_blck_val_scalar();
6283 m_evt_handler->begin_seq_val_flow();
6285 _line_progressed(1);
6286 _set_indentation(m_evt_handler->m_parent->indref + 1u);
6287 goto seqblck_finish;
6289 else if(first ==
'{')
6291 _c4dbgp(
"seqblck[RVAL]: start child mapflow");
6293 _handle_annotations_before_blck_val_scalar();
6294 m_evt_handler->begin_map_val_flow();
6296 _line_progressed(1);
6297 _set_indentation(m_evt_handler->m_parent->indref + 1u);
6298 goto seqblck_finish;
6300 else if(first ==
'-')
6302 _c4dbgp(
"seqblck[RVAL]: dash");
6303 _handle_block_check_leading_tabs(startmark);
6304 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, m_evt_handler->m_curr->indref !=
npos, m_evt_handler->m_curr->pos);
6305 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, startindent > m_evt_handler->m_curr->indref, m_evt_handler->m_curr->pos);
6306 _c4dbgp(
"seqblck[RVAL]: start child seqblck");
6307 RYML_ASSERT_PARSE_CB_(this->callbacks(), startindent > m_evt_handler->m_curr->indref, m_evt_handler->m_curr->pos);
6309 _handle_annotations_before_blck_val_scalar();
6310 m_evt_handler->begin_seq_val_block();
6312 _set_indentation(startindent);
6314 _line_progressed(1);
6316 else if(first ==
':')
6318 _c4dbgp(
"seqblck[RVAL]: start child mapblck with empty key");
6320 _handle_annotations_before_start_mapblck(startline);
6322 m_evt_handler->begin_map_val_block();
6323 _handle_annotations_and_indentation_after_start_mapblck(startindent, startline);
6324 m_evt_handler->set_key_scalar_plain_empty();
6326 _line_progressed(1);
6327 _maybe_skip_whitespace_tokens();
6328 goto seqblck_finish;
6330 else if(first ==
'&')
6332 const csubstr anchor = _scan_anchor();
6333 _c4dbgpf(
"seqblck[RVAL]: anchor! {}", prs_(anchor));
6336 _add_annotation(&m_pending_anchors, anchor, startindent, startline);
6338 else if(first ==
'*')
6340 csubstr ref = _scan_ref_seq();
6341 _c4dbgpf(
"seqblck[RVAL]: ref! {}", prs_(ref));
6342 if(!_maybe_scan_following_colon())
6344 _c4dbgp(
"seqblck[RVAL]: set ref as val!");
6345 _handle_valref(ref);
6350 _c4dbgp(
"seqblck[RVAL]: ref is key of map");
6352 _handle_annotations_before_start_mapblck(startline);
6353 m_evt_handler->begin_map_val_block();
6354 _handle_annotations_and_indentation_after_start_mapblck(startindent, startline);
6355 _handle_keyref(ref);
6357 _set_indentation(startindent);
6358 _maybe_skip_whitespace_tokens();
6359 goto seqblck_finish;
6362 else if(first ==
'!')
6365 _c4dbgpf(
"seqblck[RVAL]: val tag! {}", prs_(tag));
6368 _add_annotation(&m_pending_tags, tag, startindent, startline);
6370 else if(first ==
'?')
6372 _c4dbgp(
"seqblck[RVAL]: start child mapblck, explicit key");
6374 m_evt_handler->begin_map_val_block();
6376 _set_indentation(startindent);
6377 _line_progressed(1);
6378 _maybe_skipchars(
' ');
6379 if(_is_blck_seq_token_maybe(m_evt_handler->m_curr->line_contents.rem))
6381 _c4dbgp(
"seqblck[RVAL]: seqblck starts after ?");
6383 m_evt_handler->begin_seq_key_block();
6385 _save_indentation();
6386 _line_progressed(1);
6387 _maybe_skipchars(
' ');
6389 goto seqblck_finish;
6398 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_any(
RNXT), m_evt_handler->m_curr->pos);
6399 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RVAL), m_evt_handler->m_curr->pos);
6403 _c4dbgpf(
"seqblck[RNXT]: indref={} indentation={}", m_evt_handler->m_curr->indref, m_evt_handler->m_curr->line_contents.indentation);
6404 if C4_LIKELY(m_evt_handler->m_curr->at_line_beginning())
6406 _c4dbgp(
"seqblck[RNXT]: at line begin");
6407 if(m_evt_handler->m_curr->indentation_ge())
6409 _c4dbgpf(
"seqblck[RNXT]: skip {} from indref", m_evt_handler->m_curr->indref);
6410 _line_progressed(m_evt_handler->m_curr->indref);
6411 if(!m_evt_handler->m_curr->line_contents.rem.len)
6414 else if(m_evt_handler->m_curr->indentation_lt())
6416 _c4dbgp(
"seqblck[RNXT]: smaller indentation!");
6417 _handle_indentation_pop_from_block_seq();
6420 _c4dbgp(
"seqblck[RNXT]: still seqblck!");
6421 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_any(
RNXT), m_evt_handler->m_curr->pos);
6422 _line_progressed(m_evt_handler->m_curr->line_contents.indentation);
6423 if(!m_evt_handler->m_curr->line_contents.rem.len)
6428 _c4dbgp(
"seqblck[RNXT]: no longer seqblck!");
6429 goto seqblck_finish;
6432 else if(m_evt_handler->m_curr->line_contents.indentation ==
npos)
6434 _c4dbgpf(
"seqblck[RNXT]: blank line, len={}", m_evt_handler->m_curr->line_contents.rem);
6435 _line_progressed(m_evt_handler->m_curr->line_contents.rem.len);
6436 if(!m_evt_handler->m_curr->line_contents.rem.len)
6442 _c4dbgp(
"seqblck[RNXT]: NOT at line begin");
6443 if(!m_evt_handler->m_curr->line_contents.rem.begins_with_any(
" \t"))
6450 if(!m_evt_handler->m_curr->line_contents.rem.len)
6452 _c4dbgp(
"seqblck[RNXT]: again");
6460 _c4assert(m_evt_handler->m_curr->line_contents.rem.len > 0);
6461 const char first = m_evt_handler->m_curr->line_contents.rem.str[0];
6462 _c4dbgpf(
"seqblck[RNXT]: '{}' node_id={}", _c4prc(first), m_evt_handler->m_curr->node_id);
6465 if(m_evt_handler->m_curr->indref > 0
6466 || m_evt_handler->m_curr->line_contents.indentation > 0
6467 || !_is_doc_begin_token(m_evt_handler->m_curr->line_contents.rem))
6469 if C4_LIKELY(_is_blck_seq_token_maybe(m_evt_handler->m_curr->line_contents.rem))
6471 _c4dbgp(
"seqblck[RNXT]: expect next val");
6473 m_evt_handler->add_sibling();
6474 _line_progressed(1);
6483 _c4dbgp(
"seqblck[RNXT]: start doc");
6484 _start_doc_suddenly();
6485 _line_progressed(3);
6486 _maybe_skip_whitespace_tokens();
6487 goto seqblck_finish;
6490 else if(first ==
':')
6496 if C4_LIKELY(m_evt_handler->m_parent && (m_evt_handler->m_parent->flags &
RMAP))
6498 _c4dbgp(
"seqblck[RNXT]: actually this seq was '?' key of parent map");
6499 m_evt_handler->end_seq_block();
6500 goto seqblck_finish;
6507 else if(first ==
'.')
6509 _c4dbgp(
"seqblck[RNXT]: maybe doc?");
6510 if(_is_doc_end_token(m_evt_handler->m_curr->line_contents.rem))
6512 _c4dbgp(
"seqblck[RNXT]: end doc");
6513 _end_doc_suddenly();
6514 _line_progressed(3);
6515 _maybe_skip_whitespace_tokens();
6516 _check_doc_end_tokens();
6517 goto seqblck_finish;
6528 _print_state_stack();
6530 if(m_evt_handler->m_parent
6531 && has_all(
RMAP|
RBLCK, m_evt_handler->m_parent)
6532 && m_evt_handler->m_curr->indref == m_evt_handler->m_parent->indref)
6534 _c4dbgpf(
"seqblck[RNXT]: end indentless seq, go to parent={}. node={}", m_evt_handler->m_parent->node_id, m_evt_handler->m_curr->node_id);
6535 RYML_ASSERT_PARSE_CB_(this->callbacks(), m_evt_handler->m_curr != m_evt_handler->m_parent, m_evt_handler->m_curr->pos);
6536 _handle_indentation_pop(m_evt_handler->m_parent);
6537 RYML_ASSERT_PARSE_CB_(this->callbacks(), has_all(
RMAP|
RBLCK), m_evt_handler->m_curr->pos);
6538 m_evt_handler->add_sibling();
6540 goto seqblck_finish;
6542 else if(first ==
'\t')
6544 size_t pos = m_evt_handler->m_curr->line_contents.rem.first_not_of(
'\t');
6547 _line_progressed(m_evt_handler->m_curr->line_contents.rem.len);
6556 _c4dbgt(
"seqblck: go again", 0);
6557 if(_finished_line())
6562 if(_finished_file())
6564 _c4dbgp(
"seqblck: finish!");
6566 goto seqblck_finish;
6573 _c4dbgp(
"seqblck: finish");
6579template<
class EventHandler>
6580void ParseEngine<EventHandler>::_handle_map_block()
6583 _c4dbgpf(
"handle_map_block: map_id={} node_id={} level={} indref={}", m_evt_handler->m_parent->node_id, m_evt_handler->m_curr->node_id, m_evt_handler->m_curr->level, m_evt_handler->m_curr->indref);
6587 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_all(
RMAP), m_evt_handler->m_curr->pos);
6588 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_all(
RBLCK), m_evt_handler->m_curr->pos);
6589 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_any(
RKEY|
RKCL|
RVAL|
RNXT|
QMRK), m_evt_handler->m_curr->pos);
6590 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, 1 == (has_any(
RKEY) + has_any(
RKCL) + has_any(
RVAL) + has_any(
RNXT) + has_any(
QMRK)), m_evt_handler->m_curr->pos);
6592 _maybe_skip_comment();
6593 if(!m_evt_handler->m_curr->line_contents.rem.len)
6598 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RKCL), m_evt_handler->m_curr->pos);
6599 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
QMRK), m_evt_handler->m_curr->pos);
6600 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RVAL), m_evt_handler->m_curr->pos);
6601 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RNXT), m_evt_handler->m_curr->pos);
6605 if(m_evt_handler->m_curr->at_line_beginning())
6607 if(m_evt_handler->m_curr->indentation_eq())
6609 _c4dbgpf(
"mapblck[RKEY]: skip {} from indref", m_evt_handler->m_curr->indref);
6610 _line_progressed(m_evt_handler->m_curr->indref);
6611 if(!m_evt_handler->m_curr->line_contents.rem.len)
6614 else if(m_evt_handler->m_curr->indentation_lt())
6616 _c4dbgp(
"mapblck[RKEY]: smaller indentation!");
6617 _handle_indentation_pop_from_block_map();
6618 _line_progressed(m_evt_handler->m_curr->line_contents.indentation);
6621 _c4dbgp(
"mapblck[RKEY]: still mapblck!");
6622 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_any(
RKEY), m_evt_handler->m_curr->pos);
6623 if(!m_evt_handler->m_curr->line_contents.rem.len)
6628 _c4dbgp(
"mapblck[RKEY]: no longer mapblck!");
6629 goto mapblck_finish;
6634 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, m_evt_handler->m_curr->indentation_gt(), m_evt_handler->m_curr->pos);
6635 _c4err(
"invalid indentation");
6641 const char first = m_evt_handler->m_curr->line_contents.rem.str[0];
6642 const size_t startline = m_evt_handler->m_curr->pos.line;
6643 const size_t startindent = m_evt_handler->m_curr->line_contents.current_col();
6644 _c4dbgpf(
"mapblck[RKEY]: '{}'", _c4prc(first));
6648 _c4dbgp(
"mapblck[RKEY]: scanning single-quoted scalar");
6649 sc = _scan_scalar_squot();
6650 csubstr maybe_filtered = _maybe_filter_val_scalar_squot(sc);
6651 _handle_annotations_before_blck_key_scalar();
6652 m_evt_handler->set_key_scalar_squoted(maybe_filtered);
6654 if(!_maybe_scan_following_colon())
6655 _c4err(
"could not find ':' colon after key");
6657 _maybe_skip_whitespace_tokens();
6659 else if(first ==
'"')
6661 _c4dbgp(
"mapblck[RKEY]: scanning double-quoted scalar");
6662 sc = _scan_scalar_dquot();
6663 csubstr maybe_filtered = _maybe_filter_val_scalar_dquot(sc);
6664 _handle_annotations_before_blck_key_scalar();
6665 m_evt_handler->set_key_scalar_dquoted(maybe_filtered);
6667 if(!_maybe_scan_following_colon())
6668 _c4err(
"could not find ':' colon after key");
6670 _maybe_skip_whitespace_tokens();
6674 else if C4_UNLIKELY(first ==
'|')
6676 _c4err(
"block map: literal keys must be enclosed in '?'");
6678 else if C4_UNLIKELY(first ==
'>')
6680 _c4err(
"block map: folded keys must be enclosed in '?'");
6682 else if(_scan_scalar_plain_map_blck(&sc))
6684 _c4dbgp(
"mapblck[RKEY]: plain scalar");
6685 csubstr maybe_filtered = _maybe_filter_val_scalar_plain(sc, m_evt_handler->m_curr->indref);
6686 _handle_annotations_before_blck_key_scalar();
6687 m_evt_handler->set_key_scalar_plain(maybe_filtered);
6689 if(!_maybe_scan_following_colon())
6690 _c4err(
"could not find ':' colon after key");
6692 _maybe_skip_whitespace_tokens();
6694 else if(first ==
'?')
6696 _c4dbgp(
"mapblck[RKEY]: key token!");
6698 _line_progressed(1);
6699 _maybe_skipchars(
' ');
6700 if(_is_blck_seq_token_maybe(m_evt_handler->m_curr->line_contents.rem))
6702 _c4dbgp(
"mapblck[RKEY]: seqblck starts after ?");
6704 m_evt_handler->begin_seq_key_block();
6706 _save_indentation();
6707 _line_progressed(1);
6708 _maybe_skipchars(
' ');
6709 goto mapblck_finish;
6713 else if(first ==
':')
6715 _c4dbgp(
"mapblck[RKEY]: setting empty key");
6716 _handle_annotations_before_blck_key_scalar();
6717 m_evt_handler->set_key_scalar_plain_empty();
6719 _line_progressed(1);
6721 _maybe_skip_whitespace_tokens();
6723 else if(first ==
'*')
6725 csubstr ref = _scan_ref_map();
6726 _c4dbgpf(
"mapblck[RKEY]: key ref! {}", prs_(ref));
6727 _handle_keyref(ref);
6729 if(!_maybe_scan_following_colon())
6730 _c4err(
"could not find ':' colon after key");
6732 _maybe_skip_whitespace_tokens();
6734 else if(first ==
'&')
6736 csubstr anchor = _scan_anchor();
6737 _c4dbgpf(
"mapblck[RKEY]: key anchor! {}", prs_(anchor));
6738 _add_annotation(&m_pending_anchors, anchor, startindent, startline);
6740 else if(first ==
'!')
6743 _c4dbgpf(
"mapblck[RKEY]: key tag! {}", prs_(tag));
6744 _add_annotation(&m_pending_tags, tag, startindent, startline);
6746 else if(first ==
'[')
6751 _c4dbgp(
"mapblck[RKEY]: start child seqflow (!)");
6752 _handle_annotations_before_blck_key_scalar();
6753 m_evt_handler->begin_seq_key_flow();
6755 _line_progressed(1);
6756 _set_indentation(startindent);
6757 goto mapblck_finish;
6759 else if(first ==
'{')
6764 _c4dbgp(
"mapblck[RKEY]: start child mapflow (!)");
6765 _handle_annotations_before_blck_key_scalar();
6766 m_evt_handler->begin_map_key_flow();
6768 _line_progressed(1);
6769 _set_indentation(startindent);
6770 goto mapblck_finish;
6772 else if(first ==
'-')
6774 _c4dbgp(
"mapblck[RKEY]: maybe doc?");
6775 if(m_evt_handler->m_curr->line_contents.indentation == 0 && _is_doc_begin_token(m_evt_handler->m_curr->line_contents.rem))
6777 _c4dbgp(
"mapblck[RKEY]: end+start doc");
6778 _start_doc_suddenly();
6779 _line_progressed(3);
6780 _maybe_skip_whitespace_tokens();
6781 goto mapblck_finish;
6788 else if(first ==
'.')
6790 _c4dbgp(
"mapblck[RKEY]: maybe end doc?");
6791 if(m_evt_handler->m_curr->line_contents.indentation == 0 && _is_doc_end_token(m_evt_handler->m_curr->line_contents.rem))
6793 _c4dbgp(
"mapblck[RKEY]: end doc");
6794 _end_doc_suddenly();
6795 _line_progressed(3);
6796 _maybe_skip_whitespace_tokens();
6797 _check_doc_end_tokens();
6798 goto mapblck_finish;
6810 else if(has_any(
RVAL))
6812 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RKEY), m_evt_handler->m_curr->pos);
6813 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RKCL), m_evt_handler->m_curr->pos);
6814 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RNXT), m_evt_handler->m_curr->pos);
6815 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
QMRK), m_evt_handler->m_curr->pos);
6819 if(m_evt_handler->m_curr->at_line_beginning())
6821 _c4dbgpf(
"mapblck[RVAL]: indref={} indentation={}", m_evt_handler->m_curr->indref+1, m_evt_handler->m_curr->line_contents.indentation);
6822 m_evt_handler->m_curr->more_indented =
false;
6823 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, m_evt_handler->m_curr->indref !=
npos, m_evt_handler->m_curr->pos);
6824 if(m_evt_handler->m_curr->indentation_eq_extra())
6826 _c4dbgp(
"mapblck[RVAL]: skip indentation!");
6827 _line_progressed(m_evt_handler->m_curr->indref + 1);
6828 if(!m_evt_handler->m_curr->line_contents.rem.len)
6831 else if(m_evt_handler->m_curr->indentation_gt_extra())
6833 _c4dbgp(
"mapblck[RVAL]: more indented!");
6834 m_evt_handler->m_curr->more_indented =
true;
6835 _line_progressed(m_evt_handler->m_curr->line_contents.indentation);
6836 if(!m_evt_handler->m_curr->line_contents.rem.len)
6839 else if(m_evt_handler->m_curr->indentation_lt_extra())
6841 if(m_evt_handler->m_curr->indentation_eq())
6843 _c4dbgp(
"mapblck[RVAL]: smaller indentation than RVAL!");
6845 if(!_is_blck_seq_token_maybe(m_evt_handler->m_curr->line_contents.rem.sub(m_evt_handler->m_curr->line_contents.indentation)))
6847 _c4dbgp(
"mapblck[RVAL]: smaller indentation than RVAL!");
6848 _handle_annotations_before_blck_val_scalar();
6849 m_evt_handler->set_val_scalar_plain_empty();
6856 _c4dbgp(
"mapblck[RVAL]: smaller indentation than RKEY!");
6857 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, m_evt_handler->m_curr->indentation_lt(), m_evt_handler->m_curr->pos);
6858 _handle_indentation_pop_from_block_map();
6861 _c4dbgp(
"mapblck[RVAL]: still mapblck!");
6862 _line_progressed(m_evt_handler->m_curr->line_contents.indentation);
6865 _c4dbgp(
"mapblck[RVAL]: speculatively expect next keyval");
6866 m_evt_handler->add_sibling();
6873 _c4dbgp(
"mapblck[RVAL]: no longer mapblck!");
6874 goto mapblck_finish;
6879 const size_t startcol = _handle_block_skip_leading_whitespace();
6880 if(startcol ==
npos)
6882 _c4dbgp(
"mapblck[RVAL]: whitespace only");
6885 const size_t tabmark = _handle_block_get_whitespace_mark();
6889 _c4assert(m_evt_handler->m_curr->line_contents.rem.len);
6890 const char first = m_evt_handler->m_curr->line_contents.rem.str[0];
6891 const size_t startline = m_evt_handler->m_curr->pos.line;
6892 const size_t startindent = m_evt_handler->m_curr->line_contents.current_col();
6893 _c4dbgpf(
"mapblck[RVAL]: '{}'", _c4prc(first));
6897 _c4dbgp(
"mapblck[RVAL]: scanning single-quoted scalar");
6898 sc = _scan_scalar_squot();
6899 if(!_maybe_scan_following_colon())
6901 _c4dbgp(
"mapblck[RVAL]: set as val");
6902 _handle_annotations_before_blck_val_scalar();
6903 csubstr maybe_filtered = _maybe_filter_val_scalar_squot(sc);
6904 m_evt_handler->set_val_scalar_squoted(maybe_filtered);
6910 _c4assert(startindent > m_evt_handler->m_curr->indref);
6911 _c4dbgp(
"mapblck[RVAL]: start new block map, set scalar as key");
6912 _handle_block_check_leading_tabs(startcol);
6913 _handle_annotations_before_start_mapblck(startline);
6916 m_evt_handler->begin_map_val_block();
6917 _handle_annotations_and_indentation_after_start_mapblck(startindent, startline);
6918 csubstr maybe_filtered = _maybe_filter_key_scalar_squot(sc);
6919 m_evt_handler->set_key_scalar_squoted(maybe_filtered);
6920 _maybe_skip_whitespace_tokens();
6925 else if(first ==
'"')
6927 _c4dbgp(
"mapblck[RVAL]: scanning double-quoted scalar");
6928 sc = _scan_scalar_dquot();
6929 if(!_maybe_scan_following_colon())
6931 _c4dbgp(
"mapblck[RVAL]: set as val");
6932 _handle_annotations_before_blck_val_scalar();
6933 csubstr maybe_filtered = _maybe_filter_val_scalar_dquot(sc);
6934 m_evt_handler->set_val_scalar_dquoted(maybe_filtered);
6940 _c4assert(startindent > m_evt_handler->m_curr->indref);
6941 _c4dbgp(
"mapblck[RVAL]: start new block map, set scalar as key");
6942 _handle_block_check_leading_tabs(startcol);
6943 _handle_annotations_before_start_mapblck(startline);
6946 m_evt_handler->begin_map_val_block();
6947 _handle_annotations_and_indentation_after_start_mapblck(startindent, startline);
6948 csubstr maybe_filtered = _maybe_filter_key_scalar_dquot(sc);
6949 m_evt_handler->set_key_scalar_dquoted(maybe_filtered);
6950 _maybe_skip_whitespace_tokens();
6957 else if(first ==
'|')
6959 _c4dbgp(
"mapblck[RVAL]: scanning block-literal scalar");
6961 _scan_block(&sb, m_evt_handler->m_curr->indref + 1);
6962 _handle_annotations_before_blck_val_scalar();
6963 csubstr maybe_filtered = _maybe_filter_val_scalar_literal(sb);
6964 m_evt_handler->set_val_scalar_literal(maybe_filtered);
6967 else if(first ==
'>')
6969 _c4dbgp(
"mapblck[RVAL]: scanning block-folded scalar");
6971 _scan_block(&sb, m_evt_handler->m_curr->indref + 1);
6972 _handle_annotations_before_blck_val_scalar();
6973 csubstr maybe_filtered = _maybe_filter_val_scalar_folded(sb);
6974 m_evt_handler->set_val_scalar_folded(maybe_filtered);
6977 else if(_scan_scalar_plain_map_blck(&sc))
6979 _c4dbgp(
"mapblck[RVAL]: plain scalar.");
6980 if(!_maybe_scan_following_colon())
6982 _c4dbgp(
"mapblck[RVAL]: set as val");
6983 _handle_annotations_before_blck_val_scalar();
6984 csubstr maybe_filtered = _maybe_filter_val_scalar_plain(sc, m_evt_handler->m_curr->indref);
6985 m_evt_handler->set_val_scalar_plain(maybe_filtered);
6991 _c4assert(startindent > m_evt_handler->m_curr->indref);
6992 _c4dbgpf(
"mapblck[RVAL]: start new block map, set scalar as key {}", m_evt_handler->m_curr->indref);
6993 _handle_block_check_leading_tabs(startcol, tabmark);
6995 _handle_annotations_before_start_mapblck(startline);
6997 m_evt_handler->begin_map_val_block();
6998 _handle_annotations_and_indentation_after_start_mapblck(startindent, startline);
6999 csubstr maybe_filtered = _maybe_filter_key_scalar_plain(sc, m_evt_handler->m_curr->indref);
7000 m_evt_handler->set_key_scalar_plain(maybe_filtered);
7001 _maybe_skip_whitespace_tokens();
7006 else if(first ==
'-' && _is_blck_seq_token_maybe(m_evt_handler->m_curr->line_contents.rem))
7008 if C4_UNLIKELY(!m_evt_handler->m_curr->at_first_token())
7010 _c4dbgp(
"mapblck[RVAL]: start val seqblck");
7011 _handle_block_check_leading_tabs(startcol);
7013 _handle_annotations_before_blck_val_scalar();
7014 m_evt_handler->begin_seq_val_block();
7016 _set_indentation(startindent);
7017 _line_progressed(1);
7018 _maybe_skip_whitespace_tokens();
7019 goto mapblck_finish;
7021 else if(first ==
'[')
7023 _c4dbgp(
"mapblck[RVAL]: start val seqflow");
7025 _handle_annotations_before_blck_val_scalar();
7026 m_evt_handler->begin_seq_val_flow();
7028 _set_indentation(m_evt_handler->m_parent->indref + 1u);
7029 _line_progressed(1);
7030 goto mapblck_finish;
7032 else if(first ==
'{')
7034 _c4dbgp(
"mapblck[RVAL]: start val mapflow");
7036 _handle_annotations_before_blck_val_scalar();
7037 m_evt_handler->begin_map_val_flow();
7039 m_evt_handler->m_curr->scalar_col = m_evt_handler->m_curr->line_contents.indentation;
7040 _set_indentation(m_evt_handler->m_parent->indref + 1u);
7041 _line_progressed(1);
7042 goto mapblck_finish;
7044 else if(first ==
'*')
7046 csubstr ref = _scan_ref_map();
7047 _c4dbgpf(
"mapblck[RVAL]: ref! {}", prs_(ref));
7048 if(_maybe_scan_following_colon())
7050 _c4dbgp(
"mapblck[RVAL]: start child map, block");
7052 _handle_annotations_before_blck_val_scalar();
7053 m_evt_handler->begin_map_val_block();
7054 _handle_keyref(ref);
7055 _set_indentation(startindent);
7061 _c4dbgp(
"mapblck[RVAL]: was val ref");
7062 _handle_valref(ref);
7065 _maybe_skip_whitespace_tokens();
7067 else if(first ==
'&')
7069 csubstr anchor = _scan_anchor();
7070 _c4dbgpf(
"mapblck[RVAL]: anchor! {}", prs_(anchor));
7073 _add_annotation(&m_pending_anchors, anchor, startindent, startline);
7075 else if(first ==
'!')
7078 _c4dbgpf(
"mapblck[RVAL]: tag! {}", prs_(tag));
7081 _add_annotation(&m_pending_tags, tag, startindent, startline);
7083 else if(first ==
'?')
7085 if C4_UNLIKELY(!m_evt_handler->m_curr->at_first_token())
7087 _c4dbgp(
"mapblck[RVAL]: start val mapblck");
7089 _handle_annotations_before_blck_val_scalar();
7090 m_evt_handler->begin_map_val_block();
7092 _set_indentation(startindent);
7093 _line_progressed(1);
7094 _maybe_skipchars(
' ');
7095 if(_is_blck_seq_token_maybe(m_evt_handler->m_curr->line_contents.rem))
7097 _c4dbgp(
"mapblck[RVAL]: seqblck starts after ?");
7099 m_evt_handler->begin_seq_key_block();
7101 _save_indentation();
7102 _line_progressed(1);
7103 _maybe_skipchars(
' ');
7104 goto mapblck_finish;
7108 else if(first ==
':')
7110 _c4dbgp(
"mapblck[RVAL]: start val mapblck");
7112 _handle_annotations_before_start_mapblck(startline);
7114 m_evt_handler->begin_map_val_block();
7115 _handle_annotations_and_indentation_after_start_mapblck(startindent, startline);
7116 m_evt_handler->set_key_scalar_plain_empty();
7119 _line_progressed(1);
7120 _maybe_skip_whitespace_tokens();
7128 else if(has_any(
RNXT))
7130 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RKEY), m_evt_handler->m_curr->pos);
7131 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RKCL), m_evt_handler->m_curr->pos);
7132 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RVAL), m_evt_handler->m_curr->pos);
7133 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
QMRK), m_evt_handler->m_curr->pos);
7137 if(m_evt_handler->m_curr->at_line_beginning())
7139 _c4dbgpf(
"mapblck[RNXT]: indref={} indentation={}", m_evt_handler->m_curr->indref, m_evt_handler->m_curr->line_contents.indentation);
7140 if(m_evt_handler->m_curr->indentation_eq())
7142 _c4dbgpf(
"mapblck[RNXT]: skip {} from indref", m_evt_handler->m_curr->indref);
7143 _line_progressed(m_evt_handler->m_curr->indref);
7144 _c4dbgp(
"mapblck[RNXT]: speculatively expect next keyval");
7145 m_evt_handler->add_sibling();
7149 else if(m_evt_handler->m_curr->indentation_lt())
7151 _c4dbgp(
"mapblck[RNXT]: smaller indentation!");
7152 _handle_indentation_pop_from_block_map();
7155 _line_progressed(m_evt_handler->m_curr->line_contents.indentation);
7158 _c4dbgp(
"mapblck[RNXT]: speculatively expect next keyval");
7159 m_evt_handler->add_sibling();
7166 goto mapblck_finish;
7172 _c4dbgp(
"mapblck[RNXT]: NOT at line begin");
7173 if(!m_evt_handler->m_curr->line_contents.rem.begins_with_any(
" \t"))
7180 if(!m_evt_handler->m_curr->line_contents.rem.len)
7182 _c4dbgp(
"seqblck[RNXT]: again");
7190 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, m_evt_handler->m_curr->line_contents.rem.len > 0, m_evt_handler->m_curr->pos);
7191 const char first = m_evt_handler->m_curr->line_contents.rem.str[0];
7192 _c4dbgpf(
"mapblck[RNXT]: '{}'", _c4prc(first));
7195 _c4dbgp(
"mapblck[RNXT]: skip spaces");
7196 _maybe_skip_whitespace_tokens();
7203 else if(has_any(
QMRK))
7205 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RKEY), m_evt_handler->m_curr->pos);
7206 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RKCL), m_evt_handler->m_curr->pos);
7207 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RVAL), m_evt_handler->m_curr->pos);
7208 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RNXT), m_evt_handler->m_curr->pos);
7209 if(_handle_map_block_qmrk())
7212 goto mapblck_finish;
7214 else if(has_any(
RKCL))
7216 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RKEY), m_evt_handler->m_curr->pos);
7217 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RVAL), m_evt_handler->m_curr->pos);
7218 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RNXT), m_evt_handler->m_curr->pos);
7219 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
QMRK), m_evt_handler->m_curr->pos);
7220 if(_handle_map_block_rkcl())
7223 goto mapblck_finish;
7227 _c4dbgt(
"mapblck: again", 0);
7228 if(_finished_line())
7232 if(_finished_file())
7234 _c4dbgp(
"mapblck: file finished!");
7236 goto mapblck_finish;
7243 _c4dbgp(
"mapblck: finish");
7250template<
class EventHandler>
7251bool ParseEngine<EventHandler>::_handle_map_block_qmrk()
7256 if(m_evt_handler->m_curr->at_line_beginning())
7258 _c4dbgpf(
"mapblck[QMRK]: at line beginning. ind={} indref={}", m_evt_handler->m_curr->line_contents.indentation, m_evt_handler->m_curr->indref);
7259 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, m_evt_handler->m_curr->line_contents.indentation !=
npos, m_evt_handler->m_curr->pos);
7260 if(m_evt_handler->m_curr->indentation_eq_extra())
7262 _c4dbgpf(
"mapblck[QMRK]: skip {} from indref", m_evt_handler->m_curr->indref + 1);
7263 _line_progressed(m_evt_handler->m_curr->indref + 1);
7264 if(!m_evt_handler->m_curr->line_contents.rem.len)
7268 else if(m_evt_handler->m_curr->indentation_gt_extra())
7270 _c4dbgp(
"mapblck[QMRK]: larger indentation !");
7271 _line_progressed(m_evt_handler->m_curr->line_contents.indentation);
7272 if(!m_evt_handler->m_curr->line_contents.rem.len)
7277 _c4dbgp(
"mapblck[QMRK]: smaller indentation!");
7278 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, m_evt_handler->m_curr->indentation_lt_extra(), m_evt_handler->m_curr->pos);
7279 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, m_evt_handler->m_curr->line_contents.rem.len > 0, m_evt_handler->m_curr->pos);
7280 if(m_evt_handler->m_curr->indentation_eq()
7282 && m_evt_handler->m_curr->line_contents.rem.str[0] !=
'-')
7284 _c4dbgp(
"mapblck[QMRK]: QMRK finished!");
7285 _handle_annotations_before_blck_key_scalar();
7286 m_evt_handler->set_key_scalar_plain_empty();
7290 else if(m_evt_handler->m_curr->indentation_lt())
7292 _c4dbgp(
"mapblck[QMRK]: indentation pop!");
7293 _handle_indentation_pop_from_block_map();
7294 _line_progressed(m_evt_handler->m_curr->line_contents.indentation);
7297 _c4dbgp(
"mapblck[QMRK]: still mapblck!");
7302 _c4dbgp(
"mapblck[QMRK]: no longer mapblck!");
7311 _c4assert(m_evt_handler->m_curr->line_contents.rem.len);
7312 const char first = m_evt_handler->m_curr->line_contents.rem.str[0];
7313 const size_t startline = m_evt_handler->m_curr->pos.line;
7314 const size_t startindent = m_evt_handler->m_curr->line_contents.current_col();
7315 _c4dbgpf(
"mapblck[QMRK]: '{}'", first);
7319 _c4dbgp(
"mapblck[QMRK]: scanning single-quoted scalar");
7320 sc = _scan_scalar_squot();
7321 csubstr maybe_filtered = _maybe_filter_key_scalar_squot(sc);
7323 if(!_maybe_scan_following_colon())
7325 _c4dbgp(
"mapblck[QMRK]: set as key");
7326 _handle_annotations_before_blck_key_scalar();
7327 m_evt_handler->set_key_scalar_squoted(maybe_filtered);
7331 _c4dbgp(
"mapblck[QMRK]: start new block map as key (!), set scalar as key");
7332 _handle_annotations_before_start_mapblck_as_key();
7333 m_evt_handler->begin_map_key_block();
7334 _handle_annotations_and_indentation_after_start_mapblck(startindent, startline);
7335 m_evt_handler->set_key_scalar_squoted(maybe_filtered);
7336 _maybe_skip_whitespace_tokens();
7337 _set_indentation(startindent);
7342 else if(first ==
'"')
7344 _c4dbgp(
"mapblck[QMRK]: scanning double-quoted scalar");
7345 sc = _scan_scalar_dquot();
7346 csubstr maybe_filtered = _maybe_filter_key_scalar_dquot(sc);
7348 if(!_maybe_scan_following_colon())
7350 _c4dbgp(
"mapblck[QMRK]: set as key");
7351 _handle_annotations_before_blck_key_scalar();
7352 m_evt_handler->set_key_scalar_dquoted(maybe_filtered);
7356 _c4dbgp(
"mapblck[QMRK]: start new block map as key (!), set scalar as key");
7357 _handle_annotations_before_start_mapblck_as_key();
7358 m_evt_handler->begin_map_key_block();
7359 _handle_annotations_and_indentation_after_start_mapblck(startindent, startline);
7360 m_evt_handler->set_key_scalar_dquoted(maybe_filtered);
7361 _maybe_skip_whitespace_tokens();
7362 _set_indentation(startindent);
7367 else if(first ==
'|')
7369 _c4dbgp(
"mapblck[QMRK]: scanning block-literal scalar");
7371 _scan_block(&sb, m_evt_handler->m_curr->indref + 1);
7372 csubstr maybe_filtered = _maybe_filter_key_scalar_literal(sb);
7373 _handle_annotations_before_blck_key_scalar();
7374 m_evt_handler->set_key_scalar_literal(maybe_filtered);
7377 else if(first ==
'>')
7379 _c4dbgp(
"mapblck[QMRK]: scanning block-literal scalar");
7381 _scan_block(&sb, m_evt_handler->m_curr->indref + 1);
7382 csubstr maybe_filtered = _maybe_filter_key_scalar_folded(sb);
7383 _handle_annotations_before_blck_key_scalar();
7384 m_evt_handler->set_key_scalar_folded(maybe_filtered);
7387 else if(_scan_scalar_plain_map_blck(&sc))
7389 _c4dbgp(
"mapblck[QMRK]: plain scalar");
7390 csubstr maybe_filtered = _maybe_filter_key_scalar_plain(sc, m_evt_handler->m_curr->indref);
7392 if(!_maybe_scan_following_colon())
7394 _c4dbgp(
"mapblck[QMRK]: set as key");
7395 _handle_annotations_before_blck_key_scalar();
7396 m_evt_handler->set_key_scalar_plain(maybe_filtered);
7400 _c4dbgp(
"mapblck[QMRK]: start new block map as key (!), set scalar as key");
7401 _handle_annotations_before_start_mapblck_as_key();
7402 m_evt_handler->begin_map_key_block();
7403 _handle_annotations_and_indentation_after_start_mapblck(startindent, startline);
7404 m_evt_handler->set_key_scalar_plain(maybe_filtered);
7405 _maybe_skip_whitespace_tokens();
7406 _set_indentation(startindent);
7411 else if(first ==
':')
7413 _c4dbgp(
"mapblck[QMRK]: start new block map as key (!), empty key");
7415 _handle_annotations_before_start_mapblck_as_key();
7416 m_evt_handler->begin_map_key_block();
7417 _handle_annotations_and_indentation_after_start_mapblck(startindent, startline);
7418 m_evt_handler->set_key_scalar_plain_empty();
7419 _line_progressed(1);
7420 _maybe_skip_whitespace_tokens();
7421 _set_indentation(startindent);
7425 else if(first ==
'*')
7427 csubstr ref = _scan_ref_map();
7428 _c4dbgpf(
"mapblck[QMRK]: key ref! {}", prs_(ref));
7430 if(!_maybe_scan_following_colon())
7432 _c4dbgp(
"mapblck[QMRK]: set ref as key");
7433 _handle_keyref(ref);
7437 _c4dbgp(
"mapblck[QMRK]: start new block map as key (!), set ref as key");
7438 _handle_annotations_before_start_mapblck_as_key();
7439 m_evt_handler->begin_map_key_block();
7440 _handle_annotations_and_indentation_after_start_mapblck(startindent, startline);
7441 _handle_keyref(ref);
7442 _set_indentation(startindent);
7446 _maybe_skip_whitespace_tokens();
7448 else if(first ==
'&')
7450 csubstr anchor = _scan_anchor();
7451 _c4dbgpf(
"mapblck[QMRK]: key anchor! {}", prs_(anchor));
7452 _add_annotation(&m_pending_anchors, anchor, startindent, startline);
7454 else if(first ==
'!')
7457 _c4dbgpf(
"mapblck[QMRK]: key tag! {}", prs_(tag));
7458 _add_annotation(&m_pending_tags, tag, startindent, startline);
7460 else if(first ==
'-')
7462 _c4dbgp(
"mapblck[QMRK]: maybe seq or doc?");
7463 if(_is_blck_seq_token_maybe(m_evt_handler->m_curr->line_contents.rem))
7465 _c4dbgp(
"mapblck[QMRK]: start child seqblck (!)");
7467 _handle_annotations_before_blck_key_scalar();
7468 m_evt_handler->begin_seq_key_block();
7470 _set_indentation(startindent);
7471 _line_progressed(1);
7475 _c4dbgp(
"mapblck[QMRK]: end+start doc");
7476 _c4assert(_is_doc_begin_token(m_evt_handler->m_curr->line_contents.rem));
7477 _start_doc_suddenly();
7478 _line_progressed(3);
7480 _maybe_skip_whitespace_tokens();
7483 else if(first ==
'[')
7485 _c4dbgp(
"mapblck[QMRK]: start child seqflow (!)");
7487 _handle_annotations_before_blck_key_scalar();
7488 m_evt_handler->begin_seq_key_flow();
7490 _set_indentation(m_evt_handler->m_parent->indref + 1);
7491 _line_progressed(1);
7494 else if(first ==
'{')
7496 _c4dbgp(
"mapblck[QMRK]: start child mapflow (!)");
7498 _handle_annotations_before_blck_key_scalar();
7499 m_evt_handler->begin_map_key_flow();
7501 _set_indentation(m_evt_handler->m_parent->indref + 1);
7502 _line_progressed(1);
7505 else if(first ==
'?')
7507 _c4dbgpf(
"mapblck[QMRK]: another QMRK '?'. ind={} indref={}", startindent, m_evt_handler->m_curr->indref);
7508 RYML_ASSERT_PARSE_CB_(callbacks(), startindent > m_evt_handler->m_curr->indref, m_evt_handler->m_curr->pos);
7509 _c4dbgp(
"mapblck[QMRK]: ? indent gt - start child mapblck (!)");
7511 _handle_annotations_before_blck_key_scalar();
7512 m_evt_handler->begin_map_key_block();
7514 _set_indentation(startindent);
7516 _line_progressed(1);
7517 _maybe_skipchars(
' ');
7518 if(_is_blck_seq_token_maybe(m_evt_handler->m_curr->line_contents.rem))
7520 _c4dbgp(
"mapblck[RVAL]: seqblck starts after ?");
7522 m_evt_handler->begin_seq_key_block();
7524 _save_indentation();
7525 _line_progressed(1);
7526 _maybe_skipchars(
' ');
7541template<
class EventHandler>
7542bool ParseEngine<EventHandler>::_handle_map_block_rkcl()
7547 if(m_evt_handler->m_curr->at_line_beginning())
7549 if(m_evt_handler->m_curr->indentation_eq())
7551 _c4dbgpf(
"mapblck[RKCL]: skip {} from indref", m_evt_handler->m_curr->indref);
7552 _line_progressed(m_evt_handler->m_curr->indref);
7553 if(!m_evt_handler->m_curr->line_contents.rem.len)
7556 else if C4_UNLIKELY(m_evt_handler->m_curr->indentation_lt())
7558 _c4err(
"invalid indentation");
7561 const char first = m_evt_handler->m_curr->line_contents.rem.str[0];
7562 _c4dbgpf(
"mapblck[RKCL]: '{}'", first);
7565 _c4dbgp(
"mapblck[RKCL]: found the colon");
7566 _line_progressed(1);
7567 _maybe_skipchars(
' ');
7568 #if defined(__GNUC__) && ( \
7569 ((__GNUC__ >= 12) && ((C4_WORDSIZE == 4) || defined(C4_CPU_S390_X) || defined(C4_CPU_PPC64))) \
7571 (__GNUC__ == 16 && defined(C4_CPU_X86_64)))
7572 C4_DONT_OPTIMIZE(m_evt_handler->m_curr->line_contents.rem);
7575 if(!_is_blck_seq_token_maybe(m_evt_handler->m_curr->line_contents.rem))
7582 _c4dbgp(
"mapblck[RKCL]: start val seqblck");
7584 m_evt_handler->begin_seq_val_block();
7586 _save_indentation();
7587 _line_progressed(1);
7588 _maybe_skipchars(
' ');
7592 else if(first ==
'?')
7594 _c4dbgp(
"mapblck[RKCL]: got '?'. val was empty");
7595 m_evt_handler->set_val_scalar_plain_empty();
7596 m_evt_handler->add_sibling();
7598 _line_progressed(1);
7599 _maybe_skipchars(
' ');
7600 if(_is_blck_seq_token_maybe(m_evt_handler->m_curr->line_contents.rem))
7602 _c4dbgp(
"mapblck[RKCL]: seqblck starts after ?");
7604 m_evt_handler->begin_seq_key_block();
7606 _save_indentation();
7607 _line_progressed(1);
7608 _maybe_skipchars(
' ');
7612 else if(first ==
'-')
7614 if(m_evt_handler->m_curr->indref == 0 || m_evt_handler->m_curr->line_contents.indentation == 0 || _is_doc_begin_token(m_evt_handler->m_curr->line_contents.rem))
7616 _c4dbgp(
"mapblck[RKCL]: end+start doc");
7617 RYML_CHECK_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, _is_doc_begin_token(m_evt_handler->m_curr->line_contents.rem), m_evt_handler->m_curr->pos);
7618 _start_doc_suddenly();
7619 _line_progressed(3);
7620 _maybe_skip_whitespace_tokens();
7628 else if(first ==
'.')
7630 _c4dbgp(
"mapblck[RKCL]: maybe end doc?");
7631 csubstr rs = m_evt_handler->m_curr->line_contents.rem.
sub(1);
7632 if(rs ==
".." || rs.begins_with(
".. "))
7634 _c4dbgp(
"mapblck[RKCL]: end+start doc");
7635 _end_doc_suddenly();
7636 _line_progressed(3);
7637 _maybe_skip_whitespace_tokens();
7638 _check_doc_end_tokens();
7648 _c4dbgp(
"mapblck[RKCL]: missing :");
7649 if C4_UNLIKELY(!m_evt_handler->m_curr->indentation_eq())
7651 m_evt_handler->set_val_scalar_plain_empty();
7652 m_evt_handler->add_sibling();
7661template<class EventHandler>
7664 _c4dbgpf(
"handle_unk_json indref={} target={}", m_evt_handler->m_curr->indref, m_evt_handler->m_curr->node_id);
7666 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RNXT|
RSEQ|
RMAP), m_evt_handler->m_curr->pos);
7667 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_all(
RTOP), m_evt_handler->m_curr->pos);
7669 _maybe_skip_comment();
7670 csubstr rem = m_evt_handler->m_curr->line_contents.rem;
7677 pos = pos !=
npos ? pos : rem.len;
7678 _c4dbgpf(
"skipping indentation of {}", pos);
7679 _line_progressed(pos);
7680 rem = m_evt_handler->m_curr->line_contents.rem;
7683 _c4dbgpf(
"rem is now {}", prs_(rem));
7686 if(rem.begins_with(
'['))
7688 _c4dbgp(
"it's a seq");
7689 _check_trailing_doc_token();
7691 m_evt_handler->begin_seq_val_flow();
7693 _set_indentation(m_evt_handler->m_curr->line_contents.current_col(rem));
7694 m_doc_empty =
false;
7695 _line_progressed(1);
7697 else if(rem.begins_with(
'{'))
7699 _c4dbgp(
"it's a map");
7700 _check_trailing_doc_token();
7702 m_evt_handler->begin_map_val_flow();
7704 m_doc_empty =
false;
7705 _set_indentation(m_evt_handler->m_curr->line_contents.current_col(rem));
7706 _line_progressed(1);
7708 else if(_handle_bom())
7710 _c4dbgp(
"byte order mark");
7714 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, ! has_any(
SSCL), m_evt_handler->m_curr->pos);
7715 _maybe_skip_whitespace_tokens();
7716 csubstr s = m_evt_handler->m_curr->line_contents.rem;
7719 const size_t startindent = m_evt_handler->m_curr->line_contents.indentation;
7720 const char first = s.
str[0];
7724 _c4dbgp(
"runk_json: scanning double-quoted scalar");
7725 _check_trailing_doc_token();
7728 m_doc_empty =
false;
7729 sc = _scan_scalar_dquot();
7730 csubstr maybe_filtered = _maybe_filter_val_scalar_dquot(sc);
7731 if(!_maybe_scan_following_colon())
7733 _c4dbgp(
"runk_json: set as val");
7734 _handle_annotations_before_blck_val_scalar();
7735 m_evt_handler->set_val_scalar_dquoted(maybe_filtered);
7742 else if(_scan_scalar_plain_unk(&sc))
7744 _c4dbgp(
"runk_json: got a plain scalar");
7745 _check_trailing_doc_token();
7748 m_doc_empty =
false;
7749 if(!_maybe_scan_following_colon())
7751 _c4dbgp(
"runk_json: set as val");
7752 _handle_annotations_before_blck_val_scalar();
7753 csubstr maybe_filtered = _maybe_filter_val_scalar_plain(sc, startindent);
7754 m_evt_handler->set_val_scalar_plain(maybe_filtered);
7771template<
class EventHandler>
7772void ParseEngine<EventHandler>::_handle_unk()
7774 _c4dbgpf(
"handle_unk indref={} target={}", m_evt_handler->m_curr->indref, m_evt_handler->m_curr->node_id);
7776 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RNXT|
RSEQ|
RMAP), m_evt_handler->m_curr->pos);
7777 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_all(
RTOP), m_evt_handler->m_curr->pos);
7779 _maybe_skipchars(
' ');
7780 _maybe_skip_comment();
7782 if(!m_evt_handler->m_curr->line_contents.rem.len)
7785 _c4dbgpf(
"runk: rem is now {}", prs_(m_evt_handler->m_curr->line_contents.rem));
7787 if(m_evt_handler->m_curr->line_contents.indentation == 0u && (m_evt_handler->m_curr->at_line_beginning() || (m_bom_len && (m_evt_handler->m_curr->pos.line == m_bom_line))))
7789 _c4dbgpf(
"runk: rtop: zero indent + at line begin. offset={}", m_evt_handler->m_curr->pos.offset);
7790 _c4dbgp(
"runk: check BOM");
7793 m_bom_line = m_evt_handler->m_curr->pos.line;
7794 _c4dbgpf(
"runk: byte order mark! line={} offset={}", m_bom_line, m_evt_handler->m_curr->pos.offset);
7797 const char first = m_evt_handler->m_curr->line_contents.rem.str[0];
7798 _c4dbgpf(
"runk: rtop: first={}", _c4prc(first));
7801 _c4dbgp(
"runk: rtop: suspecting doc");
7802 if(_is_doc_begin_token(m_evt_handler->m_curr->line_contents.rem))
7804 _c4dbgp(
"runk: rtop: begin doc");
7807 _set_indentation(0);
7809 _line_progressed(3u);
7810 _maybe_skip_whitespace_tokens();
7814 else if(first ==
'.')
7816 _c4dbgp(
"runk: rtop: suspecting doc end");
7817 if(_is_doc_end_token(m_evt_handler->m_curr->line_contents.rem))
7819 _c4dbgp(
"runk: rtop: end doc");
7826 _c4dbgp(
"runk: rtop: ignore end doc");
7829 _line_progressed(3u);
7830 _maybe_skip_whitespace_tokens();
7831 _check_doc_end_tokens();
7835 else if(first ==
'%')
7837 _c4dbgpf(
"directive: {}", m_evt_handler->m_curr->line_contents.rem);
7838 if C4_UNLIKELY(has_any(
RDOC) || (!m_doc_empty && has_none(
NDOC)))
7839 _c4err(
"need document footer before directives");
7840 _handle_directive(m_evt_handler->m_curr->line_contents.rem);
7847 size_t startindent = m_evt_handler->m_curr->line_contents.indentation;
7848 size_t remindent = m_evt_handler->m_curr->line_contents.current_col(m_evt_handler->m_curr->line_contents.rem);
7851 _c4dbgpf(
"runk: prev BOMlen={}", m_bom_len);
7852 if(m_evt_handler->m_curr->pos.line == m_bom_line)
7854 _c4dbgpf(
"runk: BOM remindent={} offset={}", remindent, m_evt_handler->m_curr->pos.offset);
7855 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, remindent >= m_bom_len, m_evt_handler->m_curr->pos);
7856 remindent -= m_bom_len;
7864 size_t startcol = _handle_block_skip_leading_whitespace();
7865 const char first = m_evt_handler->m_curr->line_contents.rem.str[0];
7869 _c4dbgp(
"runk: flow seq?");
7870 _handle_unk_begin_doc();
7871 if C4_LIKELY( ! _annotations_require_key_container())
7873 _c4dbgp(
"runk: it's a seq, flow");
7874 _handle_annotations_before_blck_val_scalar();
7875 m_evt_handler->begin_seq_val_flow();
7877 _set_indentation(0);
7881 _c4dbgp(
"runk: start new block map, set flow seq as key (!)");
7882 _handle_annotations_before_start_mapblck(m_evt_handler->m_curr->pos.line);
7883 m_evt_handler->begin_map_val_block();
7885 _handle_annotations_and_indentation_after_start_mapblck(remindent, m_evt_handler->m_curr->pos.line);
7886 m_evt_handler->begin_seq_key_flow();
7888 _set_indentation(0);
7890 _line_progressed(1);
7892 else if(first ==
'{')
7894 _c4dbgp(
"runk: flow map?");
7895 _handle_unk_begin_doc();
7896 if C4_LIKELY( ! _annotations_require_key_container())
7898 _c4dbgp(
"runk: it's a map, flow");
7899 _handle_annotations_before_blck_val_scalar();
7900 m_evt_handler->begin_map_val_flow();
7902 _set_indentation(0);
7906 _c4dbgp(
"runk: start new block map, set flow map as key (!)");
7907 _handle_annotations_before_start_mapblck(m_evt_handler->m_curr->pos.line);
7908 m_evt_handler->begin_map_val_block();
7910 _handle_annotations_and_indentation_after_start_mapblck(remindent, m_evt_handler->m_curr->pos.line);
7911 m_evt_handler->begin_map_key_flow();
7913 _set_indentation(0);
7915 _line_progressed(1);
7917 else if(first ==
'-' && _is_blck_token(m_evt_handler->m_curr->line_contents.rem))
7919 _c4dbgp(
"runk: it's a seq, block");
7920 if C4_UNLIKELY(!m_evt_handler->m_curr->at_first_token())
7921 startindent = _handle_unk_check_left_tokens(startindent, m_evt_handler->m_curr->pos.col, false);
7922 _handle_unk_begin_doc();
7923 _handle_annotations_before_blck_val_scalar();
7924 m_evt_handler->begin_seq_val_block();
7926 _set_indentation(startindent);
7927 _line_progressed(1);
7928 _maybe_skipchars(
' ');
7930 else if(first ==
'?' && _is_blck_token(m_evt_handler->m_curr->line_contents.rem))
7932 _c4dbgp(
"runk: it's a map + this key is complex");
7933 if C4_UNLIKELY(!m_evt_handler->m_curr->at_first_token())
7934 startindent = _handle_unk_check_left_tokens(startindent, m_evt_handler->m_curr->pos.col, false);
7935 _handle_block_check_leading_tabs(startcol);
7936 _handle_unk_begin_doc();
7937 _handle_annotations_before_blck_val_scalar();
7938 m_evt_handler->begin_map_val_block();
7940 _set_indentation(startindent);
7941 _line_progressed(1);
7942 _maybe_skipchars(
' ');
7943 if(_is_blck_seq_token_maybe(m_evt_handler->m_curr->line_contents.rem))
7945 _c4dbgp(
"runk: seqblck key starts after ?");
7947 m_evt_handler->begin_seq_key_block();
7949 _save_indentation();
7950 _line_progressed(1);
7951 _maybe_skipchars(
' ');
7954 else if(first ==
':' && _is_blck_token(m_evt_handler->m_curr->line_contents.rem))
7956 if(m_doc_empty || (m_pending_anchors.num_entries | m_pending_tags.num_entries))
7958 _c4dbgp(
"runk: it's a map with an empty key");
7959 if C4_UNLIKELY(!m_evt_handler->m_curr->at_first_token())
7960 startindent = _handle_unk_check_left_tokens(startindent, m_evt_handler->m_curr->pos.col);
7961 _handle_block_check_leading_tabs(startcol);
7962 const
size_t startline = m_evt_handler->m_curr->pos.line;
7963 _handle_unk_begin_doc();
7964 _handle_annotations_before_start_mapblck(startline);
7966 m_evt_handler->begin_map_val_block();
7967 _handle_annotations_and_indentation_after_start_mapblck(startindent, startline);
7968 m_evt_handler->set_key_scalar_plain_empty();
7969 _set_indentation(startindent);
7973 _c4err(
"block colon cannot occur on a new line unless ? is used");
7976 _line_progressed(1);
7977 _maybe_skip_whitespace_tokens();
7979 else if(first ==
'&')
7981 csubstr anchor = _scan_anchor();
7982 _c4dbgpf(
"anchor! {}", prs_(anchor));
7983 const size_t line = m_evt_handler->m_curr->pos.line;
7984 _handle_unk_begin_doc();
7985 _add_annotation(&m_pending_anchors, anchor, remindent, line);
7986 _set_indentation(0);
7988 else if(first ==
'*')
7990 csubstr ref = _scan_ref_map();
7991 _c4dbgpf(
"runk: ref! {}", prs_(ref));
7992 _handle_unk_begin_doc();
7993 if(!_maybe_scan_following_colon())
7995 _c4dbgp(
"runk: set val ref");
7996 _handle_valref(ref);
8000 _c4dbgp(
"runk: start new block map, set ref as key");
8001 _handle_block_check_leading_tabs(startcol);
8002 const size_t startline = m_evt_handler->m_curr->pos.line;
8003 _handle_annotations_before_start_mapblck(startline);
8004 m_evt_handler->begin_map_val_block();
8005 _handle_keyref(ref);
8006 _maybe_skip_whitespace_tokens();
8007 _set_indentation(0);
8011 else if(first ==
'!')
8014 csubstr tag = _scan_tag(&tag_orig);
8015 _c4dbgpf(
"runk: val tag! {}", prs_(tag));
8018 const size_t indentation = m_evt_handler->m_curr->line_contents.current_col(m_evt_handler->m_curr->line_contents.rem);
8019 const size_t line = m_evt_handler->m_curr->pos.line;
8020 _add_annotation(&m_pending_tags, tag, indentation, line, tag_orig);
8024 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, ! has_any(
SSCL), m_evt_handler->m_curr->pos);
8025 const size_t startscalar = _handle_block_get_whitespace_mark();
8026 const size_t startline = m_evt_handler->m_curr->pos.line;
8027 auto beginmap = [&](
size_t startindent_){
8028 if C4_UNLIKELY(m_evt_handler->m_curr->pos.line > startline)
8029 _c4err(
"multiline scalars cannot be used as implicit keys");
8030 _handle_block_check_leading_tabs(startcol, startscalar);
8031 _handle_annotations_before_start_mapblck(startline);
8033 m_evt_handler->begin_map_val_block();
8034 _handle_annotations_and_indentation_after_start_mapblck(startindent_, startline);
8036 auto after_beginmap = [&](
size_t startindent_){
8037 _maybe_skip_whitespace_tokens();
8038 _set_indentation(startindent_);
8043 _c4dbgp(
"runk: block-literal scalar");
8044 _handle_unk_begin_doc();
8046 _scan_block(&sb, startindent);
8047 _handle_annotations_before_blck_val_scalar();
8048 csubstr maybe_filtered = _maybe_filter_val_scalar_literal(sb);
8049 m_evt_handler->set_val_scalar_literal(maybe_filtered);
8051 else if(first ==
'>')
8053 _c4dbgp(
"runk: block-folded scalar");
8054 _handle_unk_begin_doc();
8056 _scan_block(&sb, startindent);
8057 _handle_annotations_before_blck_val_scalar();
8058 csubstr maybe_filtered = _maybe_filter_val_scalar_folded(sb);
8059 m_evt_handler->set_val_scalar_folded(maybe_filtered);
8061 else if(first ==
'\'')
8063 _c4dbgp(
"runk: single-quoted scalar");
8064 _handle_unk_begin_doc();
8065 bool firsttoken = m_evt_handler->m_curr->at_first_token();
8066 size_t col = m_evt_handler->m_curr->pos.col;
8067 ScannedScalar sc = _scan_scalar_squot();
8068 if(!_maybe_scan_following_colon())
8070 _c4dbgp(
"runk: set as val");
8071 _handle_annotations_before_blck_val_scalar();
8072 csubstr maybe_filtered = _maybe_filter_val_scalar_squot(sc);
8073 m_evt_handler->set_val_scalar_squoted(maybe_filtered);
8077 _c4dbgp(
"runk: start new block map, set single-quoted scalar as key");
8078 if C4_UNLIKELY(m_evt_handler->m_curr->pos.line > startline)
8081 startindent = _handle_unk_check_left_tokens(startindent, col);
8082 beginmap(startindent);
8083 csubstr maybe_filtered = _maybe_filter_val_scalar_squot(sc);
8084 m_evt_handler->set_key_scalar_squoted(maybe_filtered);
8085 after_beginmap(startindent);
8088 else if(first ==
'"')
8090 _c4dbgp(
"runk: double-quoted scalar");
8091 _handle_unk_begin_doc();
8092 bool firsttoken = m_evt_handler->m_curr->at_first_token();
8093 size_t col = m_evt_handler->m_curr->pos.col;
8094 ScannedScalar sc = _scan_scalar_dquot();
8095 if(!_maybe_scan_following_colon())
8097 _c4dbgp(
"runk: set as val");
8098 _handle_annotations_before_blck_val_scalar();
8099 csubstr maybe_filtered = _maybe_filter_val_scalar_dquot(sc);
8100 m_evt_handler->set_val_scalar_dquoted(maybe_filtered);
8104 _c4dbgp(
"runk: start new block map, set double-quoted scalar as key");
8105 if C4_UNLIKELY(m_evt_handler->m_curr->pos.line > startline)
8108 startindent = _handle_unk_check_left_tokens(startindent, col);
8109 beginmap(startindent);
8110 csubstr maybe_filtered = _maybe_filter_val_scalar_dquot(sc);
8111 m_evt_handler->set_key_scalar_dquoted(maybe_filtered);
8112 after_beginmap(startindent);
8117 bool firsttoken = m_evt_handler->m_curr->at_first_token();
8118 size_t col = m_evt_handler->m_curr->pos.col;
8120 if(_scan_scalar_plain_unk(&sc))
8122 _c4dbgp(
"runk: plain scalar");
8123 _handle_unk_begin_doc();
8124 if(!_maybe_scan_following_colon())
8126 _c4dbgp(
"runk: set as val");
8127 _handle_annotations_before_blck_val_scalar();
8128 csubstr maybe_filtered = _maybe_filter_val_scalar_plain(sc, startindent);
8129 m_evt_handler->set_val_scalar_plain(maybe_filtered);
8133 _c4dbgp(
"runk: start new block map, set plain scalar as key");
8138 _c4assert(m_evt_handler->m_curr->pos.line == startline);
8140 startindent = _handle_unk_check_left_tokens(startindent, col);
8141 beginmap(startindent);
8142 csubstr maybe_filtered = _maybe_filter_val_scalar_plain(sc, startindent);
8143 m_evt_handler->set_key_scalar_plain(maybe_filtered);
8144 after_beginmap(startindent);
8154 if(m_bom_len && has_none(
RUNK))
8156 _c4dbgpf(
"runk: BOMlen={} BOMline={} now={} at_end={}", m_bom_len, m_bom_line, m_evt_handler->m_curr->pos.line, !m_evt_handler->m_curr->line_contents.rem.len);
8157 if(m_evt_handler->m_curr->pos.line != m_bom_line || !m_evt_handler->m_curr->line_contents.rem.len)
8159 _c4dbgp(
"runk: clear BOMlen");
8165template<
class EventHandler>
8166void ParseEngine<EventHandler>::_handle_unk_begin_doc()
8168 _c4dbgp(
"runk: begin doc");
8169 _check_trailing_doc_token();
8172 m_doc_empty =
false;
8175template<
class EventHandler>
8176size_t ParseEngine<EventHandler>::_handle_unk_check_left_tokens(
size_t realindent,
size_t col,
bool skip_annotations)
8181 csubstr s = m_evt_handler->m_curr->line_contents.full.
range(m_bom_len, col);
8183 _c4dbgpf(
"runk: check left tokens: s={}", prs_(s,
true));
8184 if(skip_annotations)
8186 _handle_unk_get_first_non_pending_token_pos(s, &realindent, &pos);
8187 _c4dbgpf(
"runk: skip annotations: realindent={} pos={}", realindent, pos);
8189 size_t firstns = s.first_not_of(
' ', pos);
8192 _c4dbgpf(
"runk: check left tokens:\n"
8193 " tokens={} skipped={}\n"
8194 " bomlen={} first={} col={}\n"
8195 " (bomlen+first)={} vs {}=col\n"
8196 " startindent={} lineindent={}"
8197 , prs_(s,
true), prs_(s.sub(firstns),
true)
8198 , m_bom_len, firstns, col
8199 , m_bom_len+firstns, col,
8200 realindent, m_evt_handler->m_curr->line_contents.indentation);
8201 if(m_bom_len + firstns != col)
8203 if(!skip_annotations)
8204 realindent = firstns;
8205 _c4dbgpf(
"runk: pos={} firstns={} -> realindent={}", pos, firstns, realindent);
8211template<
class EventHandler>
8212void ParseEngine<EventHandler>::_handle_unk_get_first_non_pending_token_pos(
csubstr s,
size_t *indent,
size_t *first_non_token_pos)
8215 uint32_t total = _get_annotations_same_line(s, &first, &second);
8216 _c4dbgpf(
"runk: before skip: {}", prs_(s,
true));
8217 size_t pos = s.first_not_of(
" \t");
8222 *indent = *first_non_token_pos = pos;
8225 _c4assert(!s.sub(pos).begins_with_any(
" \t"));
8226 _c4dbgpf(
"runk: after skip leading {} whitespace: {}", pos, prs_(s.sub(pos),
true));
8227 _c4dbgpf(
"runk: first annotation: {}", first);
8231 _c4assert(s.sub(pos).begins_with(first));
8234 _c4dbgpf(
"runk: after skip first annotation: pos={} {}", pos, prs_(s.sub(pos),
true));
8237 _c4dbgpf(
"runk: second annotation: {}", second);
8245 _c4dbgpf(
"runk: next nonspace: {}", pos + more);
8247 _c4dbgpf(
"runk: after skip annotation whitespace: pos={} {}", pos, prs_(s.sub(pos),
true));
8248 _c4assert(s.sub(pos).begins_with(second));
8250 _c4dbgpf(
"runk: after skip annotation 2: pos={} {}", pos, prs_(s.sub(pos),
true));
8252 *first_non_token_pos = pos;
8256template<
class EventHandler>
8257uint32_t ParseEngine<EventHandler>::_get_annotations_same_line(
csubstr token_soup,
csubstr *first_,
csubstr *second_)
const
8259 _c4assert(!m_evt_handler->m_curr->at_first_token());
8261 using EntryPtr =
typename Annotation::Entry
const* C4_RESTRICT;
8262 EntryPtr first =
nullptr;
8263 EntryPtr second =
nullptr;
8264 uint32_t total = (uint32_t)(m_pending_anchors.num_entries + m_pending_tags.num_entries);
8267 _c4dbgpf(
"there are {} pending annotations: {} anchors + {} tags", total, m_pending_anchors.num_entries, m_pending_tags.num_entries);
8268 auto valid_if_same_line = [
this](EntryPtr entry){
8269 _c4dbgpf(
"pending: {} indent={} line={} vs currline={}", maybe_null_str_(entry->str), entry->indentation, entry->line, m_evt_handler->m_curr->pos.line);
8270 return (entry->line == m_evt_handler->m_curr->pos.line) ? entry :
nullptr;
8274 for(
size_t i = 0; i < m_pending_anchors.num_entries; ++i)
8275 total += !!valid_if_same_line(&m_pending_anchors.annotations[i]);
8276 for(
size_t i = 0; i < m_pending_tags.num_entries; ++i)
8277 total += !!valid_if_same_line(&m_pending_tags.annotations[i]);
8278 _c4dbgpf(
"{} annotations on same line", total);
8283 auto get_first_on_same_line = [
this](EntryPtr not_this_one){
8284 for(
size_t i = 0; i < m_pending_anchors.num_entries; ++i)
8285 if(&m_pending_anchors.annotations[i] != not_this_one
8286 && m_pending_anchors.annotations[i].line == m_evt_handler->m_curr->pos.line)
8287 return &m_pending_anchors.annotations[i];
8288 for(
size_t i = 0; i < m_pending_tags.num_entries; ++i)
8289 if(&m_pending_tags.annotations[i] != not_this_one
8290 && m_pending_tags.annotations[i].line == m_evt_handler->m_curr->pos.line)
8291 return &m_pending_tags.annotations[i];
8293 return (EntryPtr)
nullptr;
8297 first = get_first_on_same_line(
nullptr);
8299 _c4dbgpf(
"first annotation: {} indent={} line={}", maybe_null_str_(first->str), first->indentation, first->line);
8304 second = get_first_on_same_line(first);
8306 _c4dbgpf(
"second annotation: {} indent={} line={}", maybe_null_str_(second->str), second->indentation, second->line);
8308 auto extract_string = [&](EntryPtr e){
8310 if(!e->str.str || e->str.begins_with_any(
"!<"))
8316 _c4dbgpf(
"tag: {} -> {}", maybe_null_str_(e->str), tag);
8324 _c4assert(anchor.str - token_soup.str > 0);
8329 _c4dbgpf(
"anchor: {} -> {}", e->str, anchor);
8332 *first_ = first ? extract_string(first) : nullptr;
8333 *second_ = second ? extract_string(second) : nullptr;
8334 if(total > 1 && (first_->str > second_->str))
8339 _c4dbgpf(
"swap first and second: {} -> {}", *first_, *second_);
8348template<
class EventHandler>
8349C4_COLD
void ParseEngine<EventHandler>::_handle_usty()
8351 _c4dbgpf(
"handle_usty target={}", m_evt_handler->m_curr->indref, m_evt_handler->m_curr->node_id);
8353 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_none(
RBLCK|
RFLOW), m_evt_handler->m_curr->pos);
8355 #ifdef RYML_NO_COVERAGE__TO_BE_DELETED
8358 _c4dbgp(
"usty[RNXT]: finishing!");
8363 _maybe_skip_comment();
8364 csubstr rem = m_evt_handler->m_curr->line_contents.rem;
8371 pos = pos !=
npos ? pos : rem.len;
8372 _c4dbgpf(
"skipping indentation of {}", pos);
8373 _line_progressed(pos);
8374 rem = m_evt_handler->m_curr->line_contents.rem;
8377 _c4dbgpf(
"rem is now {}", prs_(rem));
8380 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, rem.len > 0, m_evt_handler->m_curr->pos);
8381 size_t startindent = m_evt_handler->m_curr->line_contents.indentation;
8382 char first = rem.str[0];
8385 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, ! has_any(
RMAP), m_evt_handler->m_curr->pos);
8386 _c4dbgpf(
"usty[RSEQ]: first='{}'", _c4prc(first));
8389 _c4dbgp(
"usty[RSEQ]: it's a flow seq. merging it");
8391 m_evt_handler->_push();
8393 _set_indentation(startindent);
8394 _line_progressed(1);
8395 _maybe_skip_whitespace_tokens();
8397 else if(first ==
'-' && _is_blck_token(rem))
8399 _c4dbgp(
"usty[RSEQ]: it's a block seq. merging it");
8401 m_evt_handler->_push();
8403 _set_indentation(startindent);
8404 _line_progressed(1);
8405 _maybe_skip_whitespace_tokens();
8409 _c4err(
"can only parse a seq into an existing seq");
8412 else if(has_any(
RMAP))
8414 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, ! has_any(
RSEQ), m_evt_handler->m_curr->pos);
8415 _c4dbgpf(
"usty[RMAP]: first='{}'", _c4prc(first));
8418 _c4dbgp(
"usty[RMAP]: it's a flow map. merging it");
8420 _handle_annotations_before_blck_val_scalar();
8421 m_evt_handler->_push();
8423 _set_indentation(startindent);
8424 _line_progressed(1);
8425 _maybe_skip_whitespace_tokens();
8427 else if(first ==
'?' && _is_blck_token(rem))
8429 _c4dbgp(
"usty[RMAP]: it's a block map + this key is complex");
8431 _handle_annotations_before_blck_val_scalar();
8432 m_evt_handler->_push();
8434 _save_indentation();
8435 _line_progressed(1);
8436 _maybe_skip_whitespace_tokens();
8438 else if(first ==
':' && _is_blck_token(rem))
8440 _c4dbgp(
"usty[RMAP]: it's a map with an empty key");
8442 _handle_annotations_before_blck_val_scalar();
8443 m_evt_handler->_push();
8444 m_evt_handler->set_key_scalar_plain_empty();
8446 _save_indentation();
8447 _line_progressed(1);
8448 _maybe_skip_whitespace_tokens();
8450 else if(rem.begins_with(
'&'))
8452 csubstr anchor = _scan_anchor();
8453 _c4dbgpf(
"usty[RMAP]: anchor! {}", prs_(anchor));
8454 const size_t indentation = m_evt_handler->m_curr->line_contents.current_col(rem);
8455 const size_t line = m_evt_handler->m_curr->pos.line;
8456 _add_annotation(&m_pending_anchors, anchor, indentation, line);
8457 _set_indentation(m_evt_handler->m_curr->line_contents.current_col(rem));
8459 else if(first ==
'*')
8461 csubstr ref = _scan_ref_map();
8462 _c4dbgpf(
"usty[RMAP]: ref! {}", prs_(ref));
8463 if(!_maybe_scan_following_colon())
8465 _c4err(
"cannot read a VAL to a map");
8469 _c4dbgp(
"usty[RMAP]: start new block map, set ref as key");
8470 const size_t startline = m_evt_handler->m_curr->pos.line;
8472 _handle_annotations_before_start_mapblck(startline);
8473 m_evt_handler->_push();
8474 _handle_keyref(ref);
8475 _maybe_skip_whitespace_tokens();
8476 _set_indentation(startindent);
8480 else if(first ==
'!')
8483 _c4dbgpf(
"usty[RMAP]: val tag! {}", prs_(tag));
8486 const size_t indentation = m_evt_handler->m_curr->line_contents.current_col(rem);
8487 const size_t line = m_evt_handler->m_curr->pos.line;
8488 _add_annotation(&m_pending_tags, tag, indentation, line);
8490 else if(first ==
'[' || (first ==
'-' && _is_blck_token(rem)))
8492 _c4err(
"cannot parse a seq into an existing map");
8496 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, ! has_any(
SSCL), m_evt_handler->m_curr->pos);
8497 startindent = m_evt_handler->m_curr->line_contents.indentation;
8498 const size_t startline = m_evt_handler->m_curr->pos.line;
8500 _c4dbgpf(
"usty[RMAP]: maybe scalar. first='{}'", _c4prc(first));
8503 _c4dbgp(
"usty[RMAP]: scanning single-quoted scalar");
8504 sc = _scan_scalar_squot();
8505 if(!_maybe_scan_following_colon())
8507 _c4err(
"cannot read a VAL to a map");
8511 _c4dbgp(
"usty[RMAP]: start new block map, set scalar as key");
8513 _handle_annotations_before_start_mapblck(startline);
8514 m_evt_handler->_push();
8515 _handle_annotations_and_indentation_after_start_mapblck(startindent, startline);
8516 csubstr maybe_filtered = _maybe_filter_key_scalar_squot(sc);
8517 m_evt_handler->set_key_scalar_squoted(maybe_filtered);
8518 _set_indentation(startindent);
8520 _maybe_skip_whitespace_tokens();
8523 else if(first ==
'"')
8525 _c4dbgp(
"usty[RMAP]: scanning double-quoted scalar");
8526 sc = _scan_scalar_dquot();
8527 if(!_maybe_scan_following_colon())
8529 _c4err(
"cannot read a VAL to a map");
8533 _c4dbgp(
"usty[RMAP]: start new block map, set double-quoted scalar as key");
8535 _handle_annotations_before_start_mapblck(startline);
8536 m_evt_handler->_push();
8537 _handle_annotations_and_indentation_after_start_mapblck(startindent, startline);
8538 csubstr maybe_filtered = _maybe_filter_key_scalar_dquot(sc);
8539 m_evt_handler->set_key_scalar_dquoted(maybe_filtered);
8540 _set_indentation(startindent);
8542 _maybe_skip_whitespace_tokens();
8545 else if(first ==
'|')
8547 _c4err(
"block literal keys must be enclosed in '?'");
8549 else if(first ==
'>')
8551 _c4err(
"block literal keys must be enclosed in '?'");
8553 else if(_scan_scalar_plain_unk(&sc))
8555 _c4dbgp(
"usty[RMAP]: got a plain scalar");
8556 if(!_maybe_scan_following_colon())
8558 _c4err(
"cannot read a VAL to a map");
8562 _c4dbgp(
"usty[RMAP]: start new block map, set scalar as key");
8564 _handle_annotations_before_start_mapblck(startline);
8565 m_evt_handler->_push();
8566 _handle_annotations_and_indentation_after_start_mapblck(startindent, startline);
8567 csubstr maybe_filtered = _maybe_filter_key_scalar_plain(sc, startindent);
8568 m_evt_handler->set_key_scalar_plain(maybe_filtered);
8569 _set_indentation(startindent);
8571 _maybe_skip_whitespace_tokens();
8582 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, ! has_any(
RSEQ), m_evt_handler->m_curr->pos);
8583 _c4dbgpf(
"usty[UNK]: first='{}'", _c4prc(first));
8586 _c4dbgp(
"usty[UNK]: it's a flow seq");
8588 _handle_annotations_before_blck_val_scalar();
8589 m_evt_handler->begin_seq_val_flow();
8591 _set_indentation(startindent);
8592 _line_progressed(1);
8593 _maybe_skip_whitespace_tokens();
8595 else if(first ==
'-' && _is_blck_token(rem))
8597 _c4dbgp(
"usty[UNK]: it's a block seq");
8599 _handle_annotations_before_blck_val_scalar();
8600 m_evt_handler->begin_seq_val_block();
8602 _set_indentation(startindent);
8603 _line_progressed(1);
8604 _maybe_skip_whitespace_tokens();
8606 else if(first ==
'{')
8608 _c4dbgp(
"usty[UNK]: it's a flow map");
8610 _handle_annotations_before_blck_val_scalar();
8611 m_evt_handler->begin_map_val_flow();
8613 _set_indentation(startindent);
8614 _line_progressed(1);
8615 _maybe_skip_whitespace_tokens();
8617 else if(first ==
'?' && _is_blck_token(rem))
8619 _c4dbgp(
"usty[UNK]: it's a map + this key is complex");
8621 _handle_annotations_before_blck_val_scalar();
8622 m_evt_handler->begin_map_val_block();
8624 _save_indentation();
8625 _line_progressed(1);
8626 _maybe_skip_whitespace_tokens();
8628 else if(first ==
':' && _is_blck_token(rem))
8630 _c4dbgp(
"usty[UNK]: it's a map with an empty key");
8632 _handle_annotations_before_blck_val_scalar();
8633 m_evt_handler->begin_map_val_block();
8634 m_evt_handler->set_key_scalar_plain_empty();
8636 _save_indentation();
8637 _line_progressed(1);
8638 _maybe_skip_whitespace_tokens();
8640 else if(first ==
'&')
8642 csubstr anchor = _scan_anchor();
8643 _c4dbgpf(
"usty[UNK]: anchor! {}", prs_(anchor));
8644 const size_t indentation = m_evt_handler->m_curr->line_contents.current_col(rem);
8645 const size_t line = m_evt_handler->m_curr->pos.line;
8646 _add_annotation(&m_pending_anchors, anchor, indentation, line);
8647 _set_indentation(m_evt_handler->m_curr->line_contents.current_col(rem));
8649 else if(first ==
'*')
8651 csubstr ref = _scan_ref_map();
8652 _c4dbgpf(
"usty[UNK]: ref! {}", prs_(ref));
8653 if(!_maybe_scan_following_colon())
8655 _c4dbgp(
"usty[UNK]: set val ref");
8656 _handle_valref(ref);
8660 _c4dbgp(
"usty[UNK]: start new block map, set ref as key");
8661 const size_t startline = m_evt_handler->m_curr->pos.line;
8663 _handle_annotations_before_start_mapblck(startline);
8664 m_evt_handler->begin_map_val_block();
8665 _handle_keyref(ref);
8666 _maybe_skip_whitespace_tokens();
8667 _set_indentation(startindent);
8671 else if(first ==
'!')
8674 _c4dbgpf(
"usty[UNK]: val tag! {}", prs_(tag));
8677 const size_t indentation = m_evt_handler->m_curr->line_contents.current_col(rem);
8678 const size_t line = m_evt_handler->m_curr->pos.line;
8679 _add_annotation(&m_pending_tags, tag, indentation, line);
8683 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, ! has_any(
SSCL), m_evt_handler->m_curr->pos);
8684 startindent = m_evt_handler->m_curr->line_contents.indentation;
8685 const size_t startline = m_evt_handler->m_curr->pos.line;
8688 _c4dbgpf(
"usty[UNK]: maybe scalar. first='{}'", _c4prc(first));
8691 _c4dbgp(
"usty[UNK]: scanning single-quoted scalar");
8692 sc = _scan_scalar_squot();
8693 if(!_maybe_scan_following_colon())
8695 _c4dbgp(
"usty[UNK]: set as val");
8696 _handle_annotations_before_blck_val_scalar();
8697 csubstr maybe_filtered = _maybe_filter_val_scalar_squot(sc);
8698 m_evt_handler->set_val_scalar_squoted(maybe_filtered);
8703 _c4dbgp(
"usty[UNK]: start new block map, set scalar as key");
8705 _handle_annotations_before_start_mapblck(startline);
8706 m_evt_handler->begin_map_val_block();
8707 _handle_annotations_and_indentation_after_start_mapblck(startindent, startline);
8708 csubstr maybe_filtered = _maybe_filter_key_scalar_squot(sc);
8709 m_evt_handler->set_key_scalar_squoted(maybe_filtered);
8710 _set_indentation(startindent);
8712 _maybe_skip_whitespace_tokens();
8715 else if(first ==
'"')
8717 _c4dbgp(
"usty[UNK]: scanning double-quoted scalar");
8718 sc = _scan_scalar_dquot();
8719 if(!_maybe_scan_following_colon())
8721 _c4dbgp(
"usty[UNK]: set as val");
8722 _handle_annotations_before_blck_val_scalar();
8723 csubstr maybe_filtered = _maybe_filter_val_scalar_dquot(sc);
8724 m_evt_handler->set_val_scalar_dquoted(maybe_filtered);
8729 _c4dbgp(
"usty[UNK]: start new block map, set double-quoted scalar as key");
8731 _handle_annotations_before_start_mapblck(startline);
8732 m_evt_handler->begin_map_val_block();
8733 _handle_annotations_and_indentation_after_start_mapblck(startindent, startline);
8734 csubstr maybe_filtered = _maybe_filter_key_scalar_dquot(sc);
8735 m_evt_handler->set_key_scalar_dquoted(maybe_filtered);
8736 _set_indentation(startindent);
8738 _maybe_skip_whitespace_tokens();
8741 else if(first ==
'|')
8743 _c4dbgp(
"usty[UNK]: scanning block-literal scalar");
8745 _scan_block(&sb, startindent);
8746 _c4dbgp(
"usty[UNK]: set as val");
8747 _handle_annotations_before_blck_val_scalar();
8748 csubstr maybe_filtered = _maybe_filter_val_scalar_literal(sb);
8749 m_evt_handler->set_val_scalar_literal(maybe_filtered);
8752 else if(first ==
'>')
8754 _c4dbgp(
"usty[UNK]: scanning block-folded scalar");
8756 _scan_block(&sb, startindent);
8757 _c4dbgp(
"usty[UNK]: set as val");
8758 _handle_annotations_before_blck_val_scalar();
8759 csubstr maybe_filtered = _maybe_filter_val_scalar_folded(sb);
8760 m_evt_handler->set_val_scalar_folded(maybe_filtered);
8763 else if(_scan_scalar_plain_unk(&sc))
8765 _c4dbgp(
"usty[UNK]: got a plain scalar");
8766 if(!_maybe_scan_following_colon())
8768 _c4dbgp(
"usty[UNK]: set as val");
8769 _handle_annotations_before_blck_val_scalar();
8770 csubstr maybe_filtered = _maybe_filter_val_scalar_plain(sc, startindent);
8771 m_evt_handler->set_val_scalar_plain(maybe_filtered);
8776 _c4dbgp(
"usty[UNK]: start new block map, set scalar as key");
8778 _handle_annotations_before_start_mapblck(startline);
8779 m_evt_handler->begin_map_val_block();
8780 _handle_annotations_and_indentation_after_start_mapblck(startindent, startline);
8781 csubstr maybe_filtered = _maybe_filter_key_scalar_plain(sc, startindent);
8782 m_evt_handler->set_key_scalar_plain(maybe_filtered);
8783 _set_indentation(startindent);
8785 _maybe_skip_whitespace_tokens();
8799template<
class EventHandler>
8802 RYML_ASSERT_BASIC_CB_(m_evt_handler->m_stack.m_callbacks, m_evt_handler->m_stack.size() >= 1);
8803 RYML_SAVE_TEST_JSON_(filename, src);
8804 m_evt_handler->start_parse(filename.str, src);
8805 m_evt_handler->begin_stream();
8807 while( ! _finished_file())
8810 while( ! _finished_line())
8813 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, ! m_evt_handler->m_curr->line_contents.rem.empty(), m_evt_handler->m_curr->pos);
8818 else if(has_any(
RMAP))
8822 else if(has_any(
RUNK))
8828 _c4err(
"internal error");
8831 if(_finished_file())
8836 m_evt_handler->finish_parse();
8842template<
class EventHandler>
8845 RYML_ASSERT_BASIC_CB_(m_evt_handler->m_stack.m_callbacks, m_evt_handler->m_stack.size() >= 1);
8846 RYML_SAVE_TEST_YAML_(filename, src);
8847 m_evt_handler->start_parse(filename.str, src);
8848 m_evt_handler->begin_stream();
8850 while( ! _finished_file())
8853 while( ! _finished_line())
8856 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, ! m_evt_handler->m_curr->line_contents.rem.empty(), m_evt_handler->m_curr->pos);
8867 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_all(
RMAP), m_evt_handler->m_curr->pos);
8876 else if(has_any(
RBLCK))
8880 _handle_seq_block();
8884 RYML_ASSERT_PARSE_CB_(m_evt_handler->m_stack.m_callbacks, has_all(
RMAP), m_evt_handler->m_curr->pos);
8885 _handle_map_block();
8888 else if(has_any(
RUNK))
8892 else if(has_any(
USTY))
8898 _c4err(
"internal error");
8901 if(_finished_file())
8906 m_evt_handler->finish_parse();
8915#undef _c4dbgnextline
8919C4_SUPPRESS_WARNING_MSVC_POP
8920C4_SUPPRESS_WARNING_GCC_CLANG_POP