diff --git a/src_extra/c4/yml/extra/event_handler_testsuite.cpp b/src_extra/c4/yml/extra/event_handler_testsuite.cpp new file mode 100644 index 00000000..175d04b3 --- /dev/null +++ b/src_extra/c4/yml/extra/event_handler_testsuite.cpp @@ -0,0 +1,48 @@ +#ifdef RYML_SINGLE_HEADER_INTS + #ifndef _RYML_SINGLE_HEADER_AMALGAMATED_HPP_ + #include + #endif +#elif defined(RYML_SINGLE_HEADER) + #ifndef _RYML_SINGLE_HEADER_AMALGAMATED_HPP_ + #include + #endif +#else +#include +#include +#endif + +#ifndef _C4_YML_EXTRA_EVENT_HANDLER_TESTSUITE_HPP_ +#include "c4/yml/extra/event_handler_testsuite.hpp" +#endif +#ifndef _C4_YML_EXTRA_SCALAR_HPP_ +#include "c4/yml/extra/scalar.hpp" +#endif +#ifndef _C4_YML_EXTRA_SCALAR_HPP_ +#include "c4/yml/extra/string.hpp" +#endif + + +namespace c4 { +namespace yml { +namespace extra { + +void append_scalar_escaped(extra::string *es, csubstr val) +{ + size_t orig = es->size(); + es->resize(es->capacity()); + size_t sz = escape_scalar(substr(*es).sub(orig), val); + if (orig + sz > es->size()) + { + es->resize(orig + sz); + sz = escape_scalar(substr(*es).sub(orig), val); + } + es->resize(orig + sz); +} + +} // namespace extra + +// instantiate the template +template class ParseEngine; + +} // namespace yml +} // namespace c4 diff --git a/test/test_suite/test_suite_event_handler.hpp b/src_extra/c4/yml/extra/event_handler_testsuite.hpp similarity index 92% rename from test/test_suite/test_suite_event_handler.hpp rename to src_extra/c4/yml/extra/event_handler_testsuite.hpp index 67a8b33f..9c9af2bb 100644 --- a/test/test_suite/test_suite_event_handler.hpp +++ b/src_extra/c4/yml/extra/event_handler_testsuite.hpp @@ -1,42 +1,38 @@ -#ifndef _C4_YML_EVENT_HANDLER_YAMLSTD_HPP_ -#define _C4_YML_EVENT_HANDLER_YAMLSTD_HPP_ +#ifndef _C4_YML_EXTRA_EVENT_HANDLER_TESTSUITE_HPP_ +#define _C4_YML_EXTRA_EVENT_HANDLER_TESTSUITE_HPP_ -#ifdef RYML_SINGLE_HEADER -#include -#else +#ifndef RYML_SINGLE_HEADER #ifndef _C4_YML_EVENT_HANDLER_STACK_HPP_ #include "c4/yml/event_handler_stack.hpp" #endif -#ifndef _C4_YML_DETAIL_PRINT_HPP_ -#include "c4/yml/detail/print.hpp" #endif -#endif - #ifndef _C4_YML_EXTRA_STRING_HPP_ -#include "./string.hpp" +#include "c4/yml/extra/string.hpp" #endif C4_SUPPRESS_WARNING_GCC_CLANG_PUSH C4_SUPPRESS_WARNING_GCC_CLANG("-Wold-style-cast") C4_SUPPRESS_WARNING_GCC("-Wuseless-cast") + namespace c4 { namespace yml { +namespace extra { /** @addtogroup doc_event_handlers * @{ */ -void append_escaped(extra::string *s, csubstr val); - -/** The stack state needed specifically by @ref EventHandlerYamlStd */ -struct EventHandlerYamlStdState : public ParserState +/** @cond dev */ +struct EventHandlerTestSuiteState : public ParserState { NodeData ev_data; }; +void append_scalar_escaped(extra::string *s, csubstr val); +/** @endcond */ -/** The event handler producing standard YAML events as used in the +/** This event produces standard YAML events as used in the * [YAML test suite](https://github.com/yaml/yaml-test-suite). * See the documentation for @ref doc_event_handlers, which has * important notes about the event model used by rapidyaml. @@ -46,14 +42,14 @@ struct EventHandlerYamlStdState : public ParserState * playground](https://play.yaml.io/main/parser). It is not part of * the library and is not installed. * */ -struct EventHandlerYamlStd : public EventHandlerStack +struct EventHandlerTestSuite : public EventHandlerStack { /** @name types * @{ */ // our internal state must inherit from parser state - using state = EventHandlerYamlStdState; + using state = EventHandlerTestSuiteState; using EventSink = extra::string; @@ -82,13 +78,13 @@ public: /** @name construction and resetting * @{ */ - EventHandlerYamlStd() : EventHandlerStack(), m_sink(), m_val_buffers(), m_key_tag_buf(), m_val_tag_buf(), m_tag_directives(), m_has_yaml_directive(), m_arena(), m_has_docs() {} - EventHandlerYamlStd(Callbacks const& cb) : EventHandlerStack(cb), m_sink(), m_val_buffers(), m_key_tag_buf(), m_val_tag_buf(), m_tag_directives(), m_has_yaml_directive(), m_arena(), m_has_docs() {} - EventHandlerYamlStd(EventSink *sink, Callbacks const& cb) : EventHandlerStack(cb), m_sink(sink), m_val_buffers(), m_key_tag_buf(), m_val_tag_buf(), m_tag_directives(), m_has_yaml_directive(), m_arena(), m_has_docs() + EventHandlerTestSuite() : EventHandlerStack(), m_sink(), m_val_buffers(), m_key_tag_buf(), m_val_tag_buf(), m_tag_directives(), m_has_yaml_directive(), m_arena(), m_has_docs() {} + EventHandlerTestSuite(Callbacks const& cb) : EventHandlerStack(cb), m_sink(), m_val_buffers(), m_key_tag_buf(), m_val_tag_buf(), m_tag_directives(), m_has_yaml_directive(), m_arena(), m_has_docs() {} + EventHandlerTestSuite(EventSink *sink, Callbacks const& cb) : EventHandlerStack(cb), m_sink(sink), m_val_buffers(), m_key_tag_buf(), m_val_tag_buf(), m_tag_directives(), m_has_yaml_directive(), m_arena(), m_has_docs() { reset(); } - EventHandlerYamlStd(EventSink *sink) : EventHandlerYamlStd(sink, get_callbacks()) {} + EventHandlerTestSuite(EventSink *sink) : EventHandlerTestSuite(sink, get_callbacks()) {} void reset() { @@ -478,11 +474,11 @@ public: C4_ALWAYS_INLINE void mark_key_scalar_unfiltered() { - C4_NOT_IMPLEMENTED(); + // nothing to do here } C4_ALWAYS_INLINE void mark_val_scalar_unfiltered() { - C4_NOT_IMPLEMENTED(); + // nothing to do here } /** @} */ @@ -495,8 +491,7 @@ public: void set_key_anchor(csubstr anchor) { _c4dbgpf("node[{}]: set key anchor: [{}]~~~{}~~~", m_curr->node_id, anchor.len, anchor); - if(C4_UNLIKELY(_has_any_(KEYANCH))) - _RYML_CB_ERR_(m_stack.m_callbacks, "key cannot have both anchor and ref", m_curr->pos); + _RYML_CB_ASSERT(m_stack.m_callbacks, !_has_any_(KEYREF)); _RYML_CB_ASSERT(m_stack.m_callbacks, !anchor.begins_with('&')); _enable_(KEYANCH); m_curr->ev_data.m_key.anchor = anchor; @@ -504,8 +499,7 @@ public: void set_val_anchor(csubstr anchor) { _c4dbgpf("node[{}]: set val anchor: [{}]~~~{}~~~", m_curr->node_id, anchor.len, anchor); - if(C4_UNLIKELY(_has_any_(VALREF))) - _RYML_CB_ERR_(m_stack.m_callbacks, "val cannot have both anchor and ref", m_curr->pos); + _RYML_CB_ASSERT(m_stack.m_callbacks, !_has_any_(VALREF)); _RYML_CB_ASSERT(m_stack.m_callbacks, !anchor.begins_with('&')); _enable_(VALANCH); m_curr->ev_data.m_val.anchor = anchor; @@ -710,7 +704,7 @@ public: _send_key_props_(); _send_(' '); _send_(scalar_type_code); - append_escaped(&_buf_(), scalar); + append_scalar_escaped(&_buf_(), scalar); _send_('\n'); } void _send_val_scalar_(csubstr scalar, char scalar_type_code) @@ -719,7 +713,7 @@ public: _send_val_props_(); _send_(' '); _send_(scalar_type_code); - append_escaped(&_buf_(), scalar); + append_scalar_escaped(&_buf_(), scalar); _send_('\n'); } @@ -842,9 +836,10 @@ public: /** @} */ +} // namespace extra } // namespace yml } // namespace c4 C4_SUPPRESS_WARNING_GCC_POP -#endif /* _C4_YML_EVENT_HANDLER_YAMLSTD_HPP_ */ +#endif /* _C4_YML_EVT_EXTRA_EVENT_HANDLER_TESTSUITE_HPP_ */ diff --git a/test/test_suite/test_suite_event_handler.cpp b/src_extra/c4/yml/extra/scalar.cpp similarity index 70% rename from test/test_suite/test_suite_event_handler.cpp rename to src_extra/c4/yml/extra/scalar.cpp index ec1fd180..67ed1116 100644 --- a/test/test_suite/test_suite_event_handler.cpp +++ b/src_extra/c4/yml/extra/scalar.cpp @@ -1,23 +1,35 @@ -#ifndef RYML_SINGLE_HEADER -#include -#include -#include +#ifdef RYML_SINGLE_HEADER_INTS + #ifndef _RYML_SINGLE_HEADER_AMALGAMATED_HPP_ + #include + #endif +#elif defined(RYML_SINGLE_HEADER) + #ifndef _RYML_SINGLE_HEADER_AMALGAMATED_HPP_ + #include + #endif +#endif + +#ifndef _C4_YML_EXTRA_SCALAR_HPP_ +#include #endif -#include "./test_suite_event_handler.hpp" namespace c4 { namespace yml { +namespace extra { -// instantiate the template -template class ParseEngine; - -void append_escaped(extra::string *es, csubstr val) +size_t escape_scalar(substr buffer, csubstr val) { + size_t pos = 0; + #define _append(repl) \ + do { \ + if(repl.len && (pos + repl.len <= buffer.len)) \ + memcpy(buffer.str + pos, repl.str, repl.len); \ + pos += repl.len; \ + } while(0) #define _c4flush_use_instead(i, repl, skip) \ do { \ - es->append(val.range(prev, i)); \ - es->append(repl); \ + _append(val.range(prev, i)); \ + _append(csubstr(repl)); \ prev = i + skip; \ } \ while(0) @@ -72,9 +84,12 @@ void append_escaped(extra::string *es, csubstr val) } } // flush the rest - es->append(val.sub(prev)); + _append(val.sub(prev)); #undef _c4flush_use_instead + #undef _append + return pos; } +} // namespace extra } // namespace yml } // namespace c4 diff --git a/src_extra/c4/yml/extra/scalar.hpp b/src_extra/c4/yml/extra/scalar.hpp new file mode 100644 index 00000000..22082f5e --- /dev/null +++ b/src_extra/c4/yml/extra/scalar.hpp @@ -0,0 +1,23 @@ +#ifndef _C4_YML_EXTRA_SCALAR_HPP_ +#define _C4_YML_EXTRA_SCALAR_HPP_ + +#ifndef _C4_SUBSTR_HPP_ +#include "c4/substr.hpp" +#endif + +namespace c4 { +namespace yml { +namespace extra { + +/** @addtogroup doc_event_handlers + * @{ */ + +size_t escape_scalar(substr s, csubstr val); + +/** @} */ + +} // namespace extra +} // namespace yml +} // namespace c4 + +#endif /* _C4_YML_EVT_EXTRA_SCALAR_HPP_ */ diff --git a/test/test_suite/string.hpp b/src_extra/c4/yml/extra/string.hpp similarity index 99% rename from test/test_suite/string.hpp rename to src_extra/c4/yml/extra/string.hpp index a61a8ea5..384cba18 100644 --- a/test/test_suite/string.hpp +++ b/src_extra/c4/yml/extra/string.hpp @@ -1,11 +1,7 @@ #ifndef _C4_YML_EXTRA_STRING_HPP_ #define _C4_YML_EXTRA_STRING_HPP_ -#ifdef RYML_SINGLE_HEADER -#ifndef _RYML_SINGLE_HEADER_AMALGAMATED_HPP_ -#include -#endif -#else +#ifndef RYML_SINGLE_HEADER #ifndef _C4_YML_COMMON_HPP_ #include "c4/yml/common.hpp" #endif @@ -85,6 +81,7 @@ public: public: + const char* data() const noexcept { return m_str; } id_type size() const noexcept { return m_size; } id_type capacity() const noexcept { return m_capacity; }