Skip to content

Commit 739e931

Browse files
authored
Merge pull request #547 from biojppm/fix/firstdocseq
fix Tree::set_root_as_stream() when the original root is an empty seq
2 parents dd87caa + 177bf53 commit 739e931

5 files changed

Lines changed: 216 additions & 15 deletions

File tree

changelog/current.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
### Changes
2+
3+
- [PR#547](https://github.com/biojppm/rapidyaml/pull/547) - Fix parsing of implicit first documents with empty sequences, caused by a problem in `Tree::set_root_as_stream()`:
4+
```yaml
5+
[] # this container was lost during parsing
6+
---
7+
more data here
8+
```

src/c4/yml/event_handler_tree.hpp

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ struct EventHandlerTree : public EventHandlerStack<EventHandlerTree, EventHandle
190190
id_type first = m_tree->first_child(m_tree->root_id());
191191
_RYML_CB_ASSERT(m_stack.m_callbacks, m_tree->is_stream(m_tree->root_id()));
192192
_RYML_CB_ASSERT(m_stack.m_callbacks, m_tree->num_children(m_tree->root_id()) == 1u);
193-
if(m_tree->has_children(first) || m_tree->is_val(first))
193+
if(m_tree->is_container(first) || m_tree->is_val(first))
194194
{
195195
_c4dbgp("push!");
196196
_push();
@@ -693,15 +693,10 @@ struct EventHandlerTree : public EventHandlerStack<EventHandlerTree, EventHandle
693693
_c4dbgp("set root as stream");
694694
_RYML_CB_ASSERT(m_tree->callbacks(), m_tree->root_id() == 0u);
695695
_RYML_CB_ASSERT(m_tree->callbacks(), m_curr->node_id == 0u);
696-
const bool hack = !m_tree->has_children(m_curr->node_id) && !m_tree->is_val(m_curr->node_id);
697-
if(hack)
698-
m_tree->_p(m_tree->root_id())->m_type.add(VAL);
699696
m_tree->set_root_as_stream();
700697
_RYML_CB_ASSERT(m_tree->callbacks(), m_tree->is_stream(m_tree->root_id()));
701698
_RYML_CB_ASSERT(m_tree->callbacks(), m_tree->has_children(m_tree->root_id()));
702699
_RYML_CB_ASSERT(m_tree->callbacks(), m_tree->is_doc(m_tree->first_child(m_tree->root_id())));
703-
if(hack)
704-
m_tree->_p(m_tree->first_child(m_tree->root_id()))->m_type.rem(VAL);
705700
_set_state_(m_curr, m_tree->root_id());
706701
}
707702

src/c4/yml/tree.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -825,7 +825,13 @@ void Tree::set_root_as_stream()
825825
// don't use _add_flags() because it's checked and will fail
826826
if(!has_children(root))
827827
{
828-
if(is_val(root))
828+
if(is_container(root))
829+
{
830+
id_type next_doc = append_child(root);
831+
_copy_props_wo_key(next_doc, root);
832+
_p(next_doc)->m_type.add(DOC);
833+
}
834+
else
829835
{
830836
_p(root)->m_type.add(SEQ);
831837
id_type next_doc = append_child(root);

test/test_engine_1_doc.cpp

Lines changed: 197 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -909,10 +909,10 @@ ENGINE_TEST(DocStream,
909909

910910
//-----------------------------------------------------------------------------
911911

912-
ENGINE_TEST(DocStreamImplicitDocFirst,
913-
"doc0\n--- doc1\n--- doc2\n"
912+
ENGINE_TEST(DocStreamImplicitDocFirstVal,
913+
"doc0\n--- doc1\n"
914914
,
915-
"--- doc0\n--- doc1\n--- doc2\n"
915+
"--- doc0\n--- doc1\n"
916916
,
917917
"+STR\n"
918918
"+DOC\n"
@@ -921,9 +921,6 @@ ENGINE_TEST(DocStreamImplicitDocFirst,
921921
"+DOC ---\n"
922922
"=VAL :doc1\n"
923923
"-DOC\n"
924-
"+DOC ---\n"
925-
"=VAL :doc2\n"
926-
"-DOC\n"
927924
"-STR\n")
928925
{
929926
___(ps.begin_stream());
@@ -933,8 +930,201 @@ ENGINE_TEST(DocStreamImplicitDocFirst,
933930
___(ps.begin_doc_expl());
934931
___(ps.set_val_scalar_plain("doc1"));
935932
___(ps.end_doc());
933+
___(ps.end_stream());
934+
}
935+
936+
ENGINE_TEST(DocStreamImplicitDocFirstAnchor,
937+
"&anch1\n"
938+
"--- &anch2\n"
939+
,
940+
"--- &anch1 \n"
941+
"--- &anch2 \n"
942+
,
943+
"+STR\n"
944+
"+DOC\n"
945+
"=VAL &anch1 :\n"
946+
"-DOC\n"
947+
"+DOC ---\n"
948+
"=VAL &anch2 :\n"
949+
"-DOC\n"
950+
"-STR\n")
951+
{
952+
___(ps.begin_stream());
953+
___(ps.begin_doc());
954+
___(ps.set_val_anchor("anch1"));
955+
___(ps.set_val_scalar_plain_empty());
956+
___(ps.end_doc());
957+
___(ps.begin_doc_expl());
958+
___(ps.set_val_anchor("anch2"));
959+
___(ps.set_val_scalar_plain_empty());
960+
___(ps.end_doc());
961+
___(ps.end_stream());
962+
}
963+
964+
ENGINE_TEST(DocStreamImplicitDocFirstTag,
965+
"!!str\n"
966+
"--- !!str\n"
967+
,
968+
"--- !!str \n"
969+
"--- !!str \n"
970+
,
971+
"+STR\n"
972+
"+DOC\n"
973+
"=VAL <tag:yaml.org,2002:str> :\n"
974+
"-DOC\n"
975+
"+DOC ---\n"
976+
"=VAL <tag:yaml.org,2002:str> :\n"
977+
"-DOC\n"
978+
"-STR\n")
979+
{
980+
___(ps.begin_stream());
981+
___(ps.begin_doc());
982+
___(ps.set_val_tag("!!str"));
983+
___(ps.set_val_scalar_plain_empty());
984+
___(ps.end_doc());
936985
___(ps.begin_doc_expl());
937-
___(ps.set_val_scalar_plain("doc2"));
986+
___(ps.set_val_tag("!!str"));
987+
___(ps.set_val_scalar_plain_empty());
988+
___(ps.end_doc());
989+
___(ps.end_stream());
990+
}
991+
992+
ENGINE_TEST(DocStreamImplicitDocFirstSeqFlowEmpty,
993+
"[]\n"
994+
"--- []\n"
995+
,
996+
"---\n"
997+
"[]\n"
998+
"---\n"
999+
"[]\n"
1000+
,
1001+
"+STR\n"
1002+
"+DOC\n"
1003+
"+SEQ []\n"
1004+
"-SEQ\n"
1005+
"-DOC\n"
1006+
"+DOC ---\n"
1007+
"+SEQ []\n"
1008+
"-SEQ\n"
1009+
"-DOC\n"
1010+
"-STR\n")
1011+
{
1012+
___(ps.begin_stream());
1013+
___(ps.begin_doc());
1014+
___(ps.begin_seq_val_flow());
1015+
___(ps.end_seq());
1016+
___(ps.end_doc());
1017+
___(ps.begin_doc_expl());
1018+
___(ps.begin_seq_val_flow());
1019+
___(ps.end_seq());
1020+
___(ps.end_doc());
1021+
___(ps.end_stream());
1022+
}
1023+
1024+
ENGINE_TEST(DocStreamImplicitDocFirstSeqFlow,
1025+
"[a]\n"
1026+
"--- [b]\n"
1027+
,
1028+
"---\n"
1029+
"[a]\n"
1030+
"---\n"
1031+
"[b]\n"
1032+
,
1033+
"+STR\n"
1034+
"+DOC\n"
1035+
"+SEQ []\n"
1036+
"=VAL :a\n"
1037+
"-SEQ\n"
1038+
"-DOC\n"
1039+
"+DOC ---\n"
1040+
"+SEQ []\n"
1041+
"=VAL :b\n"
1042+
"-SEQ\n"
1043+
"-DOC\n"
1044+
"-STR\n")
1045+
{
1046+
___(ps.begin_stream());
1047+
___(ps.begin_doc());
1048+
___(ps.begin_seq_val_flow());
1049+
___(ps.set_val_scalar_plain("a"));
1050+
___(ps.end_seq());
1051+
___(ps.end_doc());
1052+
___(ps.begin_doc_expl());
1053+
___(ps.begin_seq_val_flow());
1054+
___(ps.set_val_scalar_plain("b"));
1055+
___(ps.end_seq());
1056+
___(ps.end_doc());
1057+
___(ps.end_stream());
1058+
}
1059+
1060+
ENGINE_TEST(DocStreamImplicitDocFirstMapEmpty,
1061+
"{}\n"
1062+
"--- {}\n"
1063+
,
1064+
"---\n"
1065+
"{}\n"
1066+
"---\n"
1067+
"{}\n"
1068+
,
1069+
"+STR\n"
1070+
"+DOC\n"
1071+
"+MAP {}\n"
1072+
"-MAP\n"
1073+
"-DOC\n"
1074+
"+DOC ---\n"
1075+
"+MAP {}\n"
1076+
"-MAP\n"
1077+
"-DOC\n"
1078+
"-STR\n")
1079+
{
1080+
___(ps.begin_stream());
1081+
___(ps.begin_doc());
1082+
___(ps.begin_map_val_flow());
1083+
___(ps.end_map());
1084+
___(ps.end_doc());
1085+
___(ps.begin_doc_expl());
1086+
___(ps.begin_map_val_flow());
1087+
___(ps.end_map());
1088+
___(ps.end_doc());
1089+
___(ps.end_stream());
1090+
}
1091+
1092+
ENGINE_TEST(DocStreamImplicitDocFirstMap,
1093+
"{a: b}\n"
1094+
"--- {c: d}\n"
1095+
,
1096+
"---\n"
1097+
"{a: b}\n"
1098+
"---\n"
1099+
"{c: d}\n"
1100+
,
1101+
"+STR\n"
1102+
"+DOC\n"
1103+
"+MAP {}\n"
1104+
"=VAL :a\n"
1105+
"=VAL :b\n"
1106+
"-MAP\n"
1107+
"-DOC\n"
1108+
"+DOC ---\n"
1109+
"+MAP {}\n"
1110+
"=VAL :c\n"
1111+
"=VAL :d\n"
1112+
"-MAP\n"
1113+
"-DOC\n"
1114+
"-STR\n")
1115+
{
1116+
___(ps.begin_stream());
1117+
___(ps.begin_doc());
1118+
___(ps.begin_map_val_flow());
1119+
___(ps.set_key_scalar_plain("a"));
1120+
___(ps.set_val_scalar_plain("b"));
1121+
___(ps.end_map());
1122+
___(ps.end_doc());
1123+
___(ps.begin_doc_expl());
1124+
___(ps.begin_map_val_flow());
1125+
___(ps.set_key_scalar_plain("c"));
1126+
___(ps.set_val_scalar_plain("d"));
1127+
___(ps.end_map());
9381128
___(ps.end_doc());
9391129
___(ps.end_stream());
9401130
}

test/test_tree.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4132,8 +4132,10 @@ TEST(set_root_as_stream, empty_tree)
41324132
EXPECT_EQ(r.is_stream(), false);
41334133
EXPECT_EQ(r.num_children(), 0u);
41344134
t.set_root_as_stream();
4135+
r = t.rootref();
41354136
EXPECT_EQ(r.is_stream(), true);
4136-
EXPECT_EQ(r.num_children(), 0u);
4137+
ASSERT_EQ(r.num_children(), 1u);
4138+
EXPECT_EQ(r[0].is_doc(), 1u);
41374139
}
41384140

41394141
TEST(set_root_as_stream, already_with_stream)

0 commit comments

Comments
 (0)