@@ -1219,12 +1219,54 @@ struct EventHandlerInts : public c4::yml::EventHandlerStack<EventHandlerInts, Ev
12191219 }
12201220 csubstr _transform_directive (csubstr tag)
12211221 {
1222+ // lookup from the end. We want to find the first directive that
1223+ // matches the tag and has a target node id leq than the given
1224+ // node_id.
1225+ for (id_type i = RYML_MAX_TAG_DIRECTIVES-1 ; i != NONE; --i)
1226+ {
1227+ TagDirective const & td = m_tag_directives[i];
1228+ if (td.handle .empty ())
1229+ continue ;
1230+ if (tag.begins_with (td.handle ))
1231+ {
1232+ bool retry = false ;
1233+ again1:
1234+ size_t len = td.transform (tag, *output, m_stack.m_callbacks );
1235+ if (len == 0 )
1236+ {
1237+ if (tag.begins_with (" !<" ))
1238+ return tag.sub (1 );
1239+ return tag;
1240+ }
1241+ if (len > output->size ())
1242+ {
1243+ _RYML_CB_CHECK (m_stack.m_callbacks , !retry);
1244+ retry = true ;
1245+ output->resize (len);
1246+ output->resize (output->capacity ());
1247+ goto again1;
1248+ }
1249+ return csubstr (*output).first (len);
1250+ }
1251+ }
12221252 if (tag.begins_with (' !' ))
1223- return tag;
1224- csubstr result = c4::yml::normalize_tag_long (tag);
1225- _RYML_CB_ASSERT (m_stack.m_callbacks , result.is_sub (tag));
1226- _RYML_CB_CHECK (m_stack.m_callbacks , result.len > 0 );
1227- _RYML_CB_CHECK (m_stack.m_callbacks , result.str );
1253+ {
1254+ if (is_custom_tag (tag))
1255+ {
1256+ _RYML_CB_ERR_ (m_stack.m_callbacks , " tag not found" , m_curr->pos );
1257+ }
1258+ }
1259+ bool retry = false ;
1260+ again2:
1261+ csubstr result = normalize_tag_long (tag, *output);
1262+ if (!result.str )
1263+ {
1264+ _RYML_CB_CHECK (m_stack.m_callbacks , !retry);
1265+ retry = true ;
1266+ output->resize (result.len );
1267+ output->resize (output->capacity ());
1268+ goto again2;
1269+ }
12281270 return result;
12291271 }
12301272#undef _enable_
0 commit comments