src_extra: add event handler to create compact int events array

This commit is contained in:
Joao Paulo Magalhaes
2025-09-28 19:07:02 +01:00
parent c2a1f18051
commit 6c6c722cf8
7 changed files with 1828 additions and 1 deletions

View File

@@ -0,0 +1,66 @@
#ifdef RYML_SINGLE_HEADER_INTS
#ifndef _RYML_SINGLE_HEADER_AMALGAMATED_HPP_
#include <ryml_ints.hpp>
#endif
#elif defined(RYML_SINGLE_HEADER)
#ifndef _RYML_SINGLE_HEADER_AMALGAMATED_HPP_
#include <ryml_all.hpp>
#endif
#else
#include <c4/yml/parse_engine.def.hpp>
#endif
#ifndef _C4_YML_EXTRA_EVENT_HANDLER_INTS_HPP_
#include "c4/yml/extra/event_handler_ints.hpp"
#endif
namespace c4 {
namespace yml {
// instantiate the template
template class ParseEngine<extra::EventHandlerInts>;
namespace extra {
int32_t estimate_events_ints_size(csubstr src)
{
int32_t count = 7; // BSTR + BDOC + =VAL + EDOC + ESTR
for(size_t i = 0; i < src.len; ++i)
{
switch(src.str[i])
{
// this has strings preceding/following it
case ':':
case ',': // overestimate, assume map
count += 6;
break;
// these have (or are likely to have) a string following it
case '-':
case '&':
case '*':
case '<':
case '!':
case '\'':
case '"':
case '|':
case '>':
case '?':
case '\n':
count += 3;
break;
case '[':
case ']':
count += 4;
break;
case '{':
case '}':
count += 7;
break;
}
}
return count;
}
} // namespace extra
} // namespace yml
} // namespace c4

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,207 @@
#ifdef RYML_SINGLE_HEADER_INTS
#ifndef _RYML_SINGLE_HEADER_AMALGAMATED_HPP_
#include <ryml_ints.hpp>
#endif
#elif defined(RYML_SINGLE_HEADER)
#ifndef _RYML_SINGLE_HEADER_AMALGAMATED_HPP_
#include <ryml_all.hpp>
#endif
#endif
#ifndef _C4_YML_EXTRA_SCALAR_HPP_
#include "c4/yml/extra/scalar.hpp"
#endif
#ifndef _C4_YML_EXTRA_INTS_UTILS_HPP_
#include "c4/yml/extra/ints_utils.hpp"
#endif
#ifndef _C4_BITMASK_HPP_
#include "c4/bitmask.hpp"
#endif
C4_SUPPRESS_WARNING_GCC_WITH_PUSH("-Wold-style-cast")
C4_SUPPRESS_WARNING_CLANG_WITH_PUSH("-Wold-style-cast")
// NOLINTBEGIN(hicpp-signed-bitwise)
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
namespace c4 {
namespace yml {
namespace extra {
size_t events_ints_to_testsuite(csubstr parsed_yaml,
csubstr arena,
ievt::DataType const* evts_ints,
ievt::DataType evts_ints_sz,
substr evts_test_suite)
{
auto getstr = [&](ievt::DataType i){
bool in_arena = evts_ints[i] & ievt::AREN;
csubstr region = !in_arena ? parsed_yaml : arena;
return region.sub((size_t)evts_ints[i+1], (size_t)evts_ints[i+2]);
};
size_t sz = 0;
auto append = [&](csubstr s){
size_t next = sz + s.len;
if (s.len && (next <= evts_test_suite.len && evts_test_suite.len))
memcpy(evts_test_suite.str + sz, s.str, s.len);
sz = next;
};
bool has_tag = false;
csubstr tag;
auto maybe_append_tag = [&]{
if(has_tag)
{
#ifdef RYML_NO_COVERAGE__TO_BE_DELETED
if(tag.begins_with('<'))
{
append(" ");
append(tag);
}
else
#endif
if(tag.begins_with("!<"))
{
append(" ");
append(tag.sub(1));
}
else if(tag.begins_with('!'))
{
append(" <");
append(tag);
append(">");
}
else
{
append(" <!");
append(tag);
append(">");
}
}
has_tag = false;
};
bool has_anchor = false;
csubstr anchor;
auto maybe_append_anchor = [&]{
if(has_anchor)
{
append(" &");
append(anchor);
}
has_anchor = false;
};
auto append_cont = [&](csubstr evt, csubstr style){
append(evt);
if(style.len)
{
append(" ");
append(style);
}
maybe_append_anchor();
maybe_append_tag();
append("\n");
};
auto append_val = [&](csubstr evt, csubstr val){
append("=VAL");
maybe_append_anchor();
maybe_append_tag();
append(" ");
append(evt);
substr buf = sz <= evts_test_suite.len ? evts_test_suite.sub(sz) : evts_test_suite.last(0);
sz += escape_scalar(buf, val);
append("\n");
};
for(ievt::DataType i = 0; i < evts_ints_sz; )
{
ievt::DataType evt = evts_ints[i];
if(evt & ievt::SCLR)
{
csubstr s = getstr(i);
if(evt & ievt::SQUO)
append_val("'", s);
else if(evt & ievt::DQUO)
append_val("\"", s);
else if(evt & ievt::LITL)
append_val("|", s);
else if(evt & ievt::FOLD)
append_val(">", s);
else //if(evt & ievt::PLAI)
append_val(":", s);
}
else if(evt & ievt::BSEQ)
{
if(evt & ievt::FLOW)
append_cont("+SEQ", "[]");
else
append_cont("+SEQ", "");
}
else if(evt & ievt::ESEQ)
{
append("-SEQ\n");
}
else if(evt & ievt::BMAP)
{
if(evt & ievt::FLOW)
append_cont("+MAP", "{}");
else
append_cont("+MAP", "");
}
else if(evt & ievt::EMAP)
{
append("-MAP\n");
}
else if(evt & ievt::ALIA)
{
append("=ALI *");
append(getstr(i));
append("\n");
}
else if(evt & ievt::TAG_)
{
has_tag = true;
tag = getstr(i);
}
else if(evt & ievt::ANCH)
{
has_anchor = true;
anchor = getstr(i);
}
else if(evt & ievt::BDOC)
{
if(evt & ievt::EXPL)
append("+DOC ---\n");
else
append("+DOC\n");
}
else if(evt & ievt::EDOC)
{
if(evt & ievt::EXPL)
append("-DOC ...\n");
else
append("-DOC\n");
}
else if(evt & ievt::BSTR)
{
append("+STR\n");
}
else if(evt & ievt::ESTR)
{
append("-STR\n");
}
i += (evt & ievt::WSTR) ? 3 : 1;
}
return sz;
}
} // namespace extra
} // namespace yml
} // namespace c4
// NOLINTEND(hicpp-signed-bitwise)
C4_SUPPRESS_WARNING_CLANG_POP
C4_SUPPRESS_WARNING_GCC_POP

View File

@@ -0,0 +1,69 @@
#ifndef _C4_YML_EXTRA_INTS_TO_TESTSUITE_HPP_
#define _C4_YML_EXTRA_INTS_TO_TESTSUITE_HPP_
#ifndef _C4_YML_EXTRA_EVENT_HANDLER_INTS_HPP_
#include "c4/yml/extra/event_handler_ints.hpp"
#endif
//-----------------------------------------------------------------------------
namespace c4 {
namespace yml {
namespace extra {
/** @addtogroup doc_event_handlers
* @{ */
/** Create a testsuite event string from integer events.
*
* This overload receives a buffer where the string should be written,
* and returns the size needed for the buffer. If that size is larger
* than the buffer's size, the user must resize the buffer and call
* again. */
RYML_EXPORT C4_NODISCARD
size_t events_ints_to_testsuite(csubstr parsed_yaml,
csubstr arena,
ievt::DataType const* evts_ints,
ievt::DataType evts_ints_sz,
substr evts_testsuite);
/** Create a testsuite event string from integer events, writing into
* an output container. */
template<class Container>
void events_ints_to_testsuite(csubstr parsed_yaml,
csubstr arena,
ievt::DataType const* evts_ints,
ievt::DataType evts_ints_sz,
Container *evts_testsuite)
{
size_t len = events_ints_to_testsuite(parsed_yaml, arena, evts_ints, evts_ints_sz, to_substr(*evts_testsuite));
if(len > evts_testsuite->size())
{
evts_testsuite->resize(len);
len = events_ints_to_testsuite(parsed_yaml, arena, evts_ints, evts_ints_sz, to_substr(*evts_testsuite));
}
evts_testsuite->resize(len);
}
/** Create a testsuite event string from integer events, returning a
* new container with the result. */
template<class Container>
Container events_ints_to_testsuite(csubstr parsed_yaml,
csubstr arena,
ievt::DataType const* evts_ints,
ievt::DataType evts_ints_sz)
{
Container ret;
events_ints_to_testsuite(parsed_yaml, arena, evts_ints, evts_ints_sz, &ret);
return ret;
}
/** @} */
} // namespace extra
} // namespace yml
} // namespace c4
#endif /* _C4_YML_EXTRA_INTS_TO_TESTSUITE_UTILS_HPP_ */

View File

@@ -0,0 +1,132 @@
#ifdef RYML_SINGLE_HEADER_INTS
#ifndef _RYML_SINGLE_HEADER_AMALGAMATED_HPP_
#include <ryml_ints.hpp>
#endif
#elif defined(RYML_SINGLE_HEADER)
#ifndef _RYML_SINGLE_HEADER_AMALGAMATED_HPP_
#include <ryml_all.hpp>
#endif
#endif
#ifndef _C4_YML_EXTRA_SCALAR_HPP_
#include "c4/yml/extra/scalar.hpp"
#endif
#ifndef _C4_YML_EXTRA_INTS_UTILS_HPP_
#include "c4/yml/extra/ints_utils.hpp"
#endif
#ifndef _C4_BITMASK_HPP_
#include "c4/bitmask.hpp"
#endif
C4_SUPPRESS_WARNING_GCC_WITH_PUSH("-Wold-style-cast")
C4_SUPPRESS_WARNING_CLANG_WITH_PUSH("-Wold-style-cast")
// NOLINTBEGIN(hicpp-signed-bitwise)
namespace c4 {
template<>
c4::EnumSymbols<yml::extra::ievt::EventFlags> esyms<yml::extra::ievt::EventFlags>()
{
static constexpr const EnumSymbols<yml::extra::ievt::EventFlags>::Sym syms[] = {
{yml::extra::ievt::KEY_, "KEY_"},
{yml::extra::ievt::VAL_, "VAL_"},
{yml::extra::ievt::SCLR, "SCLR"},
{yml::extra::ievt::BSEQ, "BSEQ"},
{yml::extra::ievt::ESEQ, "ESEQ"},
{yml::extra::ievt::BMAP, "BMAP"},
{yml::extra::ievt::EMAP, "EMAP"},
{yml::extra::ievt::ALIA, "ALIA"},
{yml::extra::ievt::ANCH, "ANCH"},
{yml::extra::ievt::TAG_, "TAG_"},
{yml::extra::ievt::PLAI, "PLAI"},
{yml::extra::ievt::SQUO, "SQUO"},
{yml::extra::ievt::DQUO, "DQUO"},
{yml::extra::ievt::LITL, "LITL"},
{yml::extra::ievt::FOLD, "FOLD"},
{yml::extra::ievt::FLOW, "FLOW"},
{yml::extra::ievt::BLCK, "BLCK"},
{yml::extra::ievt::BDOC, "BDOC"},
{yml::extra::ievt::EDOC, "EDOC"},
{yml::extra::ievt::BSTR, "BSTR"},
{yml::extra::ievt::ESTR, "ESTR"},
{yml::extra::ievt::EXPL, "EXPL"},
{yml::extra::ievt::AREN, "AREN"},
{yml::extra::ievt::PSTR, "PSTR"},
{yml::extra::ievt::UNFILT, "UNFILT"},
{yml::extra::ievt::YAML, "YAML"},
{yml::extra::ievt::TAGD, "TAGD"},
{yml::extra::ievt::TAGV, "TAGV"},
};
return EnumSymbols<yml::extra::ievt::EventFlags>(syms);
}
namespace yml {
namespace extra {
namespace ievt {
size_t to_chars(substr buf, ievt::DataType flags)
{
return c4::bm2str<ievt::EventFlags>((flags & ievt::MASK), buf.str, buf.len);
}
csubstr to_chars_sub(substr buf, ievt::DataType flags)
{
size_t reqsize = ievt::to_chars(buf, flags);
RYML_CHECK(reqsize > 0u);
RYML_CHECK(reqsize < buf.len);
return buf.first(reqsize - 1u);
}
} // namespace ievt
} // namespace extra
} // namespace yml
} // namespace c4
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
namespace c4 {
namespace yml {
namespace extra {
void events_ints_print(csubstr parsed_yaml, csubstr arena, ievt::DataType const* evts, ievt::DataType evts_sz)
{
char buf[200];
for(ievt::DataType evtpos = 0, evtnumber = 0;
evtpos < evts_sz;
++evtnumber,
evtpos += ((evts[evtpos] & ievt::WSTR) ? 3 : 1))
{
ievt::DataType evt = evts[evtpos];
{
csubstr str = ievt::to_chars_sub(buf, evt);
printf("[%d][%d] %.*s(0x%x)", evtnumber, evtpos, (int)str.len, str.str, evt);
}
if (evt & ievt::WSTR)
{
bool in_arena = evt & ievt::AREN;
csubstr region = !in_arena ? parsed_yaml : arena;
bool safe = (evts[evtpos + 1] >= 0)
&& (evts[evtpos + 2] >= 0)
&& (evts[evtpos + 1] <= (int)region.len)
&& ((evts[evtpos + 1] + evts[evtpos + 2]) <= (int)region.len);
const char *str = safe ? (region.str + evts[evtpos + 1]) : "ERR!!!";
int len = safe ? evts[evtpos + 2] : 6;
printf(": %d [%d]~~~%.*s~~~", evts[evtpos+1], evts[evtpos+2], len, str);
if(in_arena)
printf(" (arenasz=%zu)", arena.len);
else
printf(" (srcsz=%zu)", parsed_yaml.len);
}
printf("\n");
}
}
} // namespace extra
} // namespace yml
} // namespace c4
// NOLINTEND(hicpp-signed-bitwise)
C4_SUPPRESS_WARNING_CLANG_POP
C4_SUPPRESS_WARNING_GCC_POP

View File

@@ -0,0 +1,38 @@
#ifndef _C4_YML_EXTRA_INTS_UTILS_HPP_
#define _C4_YML_EXTRA_INTS_UTILS_HPP_
#ifndef _C4_YML_EXTRA_EVENT_HANDLER_INTS_HPP_
#include "c4/yml/extra/event_handler_ints.hpp"
#endif
//-----------------------------------------------------------------------------
namespace c4 {
namespace yml {
namespace extra {
/** @addtogroup doc_event_handlers
* @{ */
namespace ievt {
/** Convert bit mask of @ref ievt::EventFlags to text. */
RYML_EXPORT size_t to_chars(substr buf, yml::extra::ievt::DataType flags);
/** Convert bit mask of @ref ievt::EventFlags to text. */
RYML_EXPORT csubstr to_chars_sub(substr buf, yml::extra::ievt::DataType flags);
} // namespace ievt
/** Print integer events to stdout */
RYML_EXPORT void events_ints_print(csubstr parsed_yaml, csubstr arena, ievt::DataType const* evts_ints, ievt::DataType evts_ints_sz);
/** @} */
} // namespace extra
} // namespace yml
} // namespace c4
#endif /* _C4_YML_EXTRA_INTS_UTILS_HPP_ */