Skip to content

Commit

Permalink
improve emit coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
biojppm committed May 19, 2024
1 parent 60baa16 commit e99c8e8
Show file tree
Hide file tree
Showing 5 changed files with 183 additions and 61 deletions.
8 changes: 5 additions & 3 deletions src/c4/yml/emit.def.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ substr Emitter<Writer>::emit_as(EmitType_e type, Tree const& t, id_type id, bool
if(type == EMIT_YAML)
_emit_yaml(id);
else if(type == EMIT_JSON)
_do_visit_json(id);
_do_visit_json(id, 0);
else
_RYML_CB_ERR(m_tree->callbacks(), "unknown emit type");
m_tree = nullptr;
Expand Down Expand Up @@ -535,9 +535,11 @@ C4_SUPPRESS_WARNING_MSVC_POP


template<class Writer>
void Emitter<Writer>::_do_visit_json(id_type id)
void Emitter<Writer>::_do_visit_json(id_type id, id_type depth)
{
_RYML_CB_CHECK(m_tree->callbacks(), !m_tree->is_stream(id)); // JSON does not have streams
if(C4_UNLIKELY(depth > m_opts.max_depth()))
_RYML_CB_ERR(m_tree->callbacks(), "max depth exceeded");
if(m_tree->is_keyval(id))
{
_writek_json(id);
Expand Down Expand Up @@ -565,7 +567,7 @@ void Emitter<Writer>::_do_visit_json(id_type id)
{
if(ich != m_tree->first_child(id))
this->Writer::_do_write(',');
_do_visit_json(ich);
_do_visit_json(ich, depth+1);
}

if(m_tree->is_seq(id))
Expand Down
55 changes: 29 additions & 26 deletions src/c4/yml/emit.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,8 @@ class Emitter : public Writer
/** emit starting at the given node */
substr emit_as(EmitType_e type, ConstNodeRef const& n, bool error_on_excess=true)
{
if(!n.tree() || n.id() == NONE)
return {};

Check warning on line 138 in src/c4/yml/emit.hpp

View check run for this annotation

Codecov / codecov/patch

src/c4/yml/emit.hpp#L138

Added line #L138 was not covered by tests
_RYML_CB_CHECK(n.tree()->callbacks(), n.readable());
return this->emit_as(type, *n.tree(), n.id(), error_on_excess);
}
Expand Down Expand Up @@ -161,7 +163,7 @@ class Emitter : public Writer
void _do_visit_flow_ml(id_type id, id_type ilevel=0, id_type do_indent=1);
void _do_visit_block(id_type id, id_type ilevel=0, id_type do_indent=1);
void _do_visit_block_container(id_type id, id_type next_level, bool do_indent);
void _do_visit_json(id_type id);
void _do_visit_json(id_type id, id_type depth);

private:

Expand Down Expand Up @@ -414,13 +416,13 @@ inline OStream& operator<< (OStream& s, as_yaml const& y)
/** (1) emit YAML to the given buffer. Return a substr trimmed to the emitted YAML.
* @param t the tree to emit.
* @param id the node where to start emitting.
* @param buf the output buffer.
* @param opts emit options.
* @param buf the output buffer.
* @param error_on_excess Raise an error if the space in the buffer is insufficient.
* @return a substr trimmed to the result in the output buffer. If the buffer is
* insufficient (when error_on_excess is false), the string pointer of the
* result will be set to null, and the length will report the required buffer size. */
inline substr emit_yaml(Tree const& t, id_type id, substr buf, EmitOptions const& opts, bool error_on_excess=true)
inline substr emit_yaml(Tree const& t, id_type id, EmitOptions const& opts, substr buf, bool error_on_excess=true)
{
EmitterBuf em(opts, buf);
return em.emit_as(EMIT_YAML, t, id, error_on_excess);
Expand All @@ -434,13 +436,13 @@ inline substr emit_yaml(Tree const& t, id_type id, substr buf, bool error_on_exc
/** (1) emit JSON to the given buffer. Return a substr trimmed to the emitted JSON.
* @param t the tree to emit.
* @param id the node where to start emitting.
* @param buf the output buffer.
* @param opts emit options.
* @param buf the output buffer.
* @param error_on_excess Raise an error if the space in the buffer is insufficient.
* @return a substr trimmed to the result in the output buffer. If the buffer is
* insufficient (when error_on_excess is false), the string pointer of the
* result will be set to null, and the length will report the required buffer size. */
inline substr emit_json(Tree const& t, id_type id, substr buf, EmitOptions const& opts, bool error_on_excess=true)
inline substr emit_json(Tree const& t, id_type id, EmitOptions const& opts, substr buf, bool error_on_excess=true)
{
EmitterBuf em(opts, buf);
return em.emit_as(EMIT_JSON, t, id, error_on_excess);
Expand All @@ -462,7 +464,7 @@ inline substr emit_json(Tree const& t, id_type id, substr buf, bool error_on_exc
* @return a substr trimmed to the result in the output buffer. If the buffer is
* insufficient (when error_on_excess is false), the string pointer of the
* result will be set to null, and the length will report the required buffer size. */
inline substr emit_yaml(Tree const& t, substr buf, EmitOptions const& opts, bool error_on_excess=true)
inline substr emit_yaml(Tree const& t, EmitOptions const& opts, substr buf, bool error_on_excess=true)
{
EmitterBuf em(opts, buf);
return em.emit_as(EMIT_YAML, t, error_on_excess);
Expand All @@ -480,7 +482,7 @@ inline substr emit_yaml(Tree const& t, substr buf, bool error_on_excess=true)
* @return a substr trimmed to the result in the output buffer. If the buffer is
* insufficient (when error_on_excess is false), the string pointer of the
* result will be set to null, and the length will report the required buffer size. */
inline substr emit_json(Tree const& t, substr buf, EmitOptions const& opts, bool error_on_excess=true)
inline substr emit_json(Tree const& t, EmitOptions const& opts, substr buf, bool error_on_excess=true)
{
EmitterBuf em(opts, buf);
return em.emit_as(EMIT_JSON, t, error_on_excess);
Expand All @@ -503,7 +505,7 @@ inline substr emit_json(Tree const& t, substr buf, bool error_on_excess=true)
* @return a substr trimmed to the result in the output buffer. If the buffer is
* insufficient (when error_on_excess is false), the string pointer of the
* result will be set to null, and the length will report the required buffer size. */
inline substr emit_yaml(ConstNodeRef const& r, substr buf, EmitOptions const& opts, bool error_on_excess=true)
inline substr emit_yaml(ConstNodeRef const& r, EmitOptions const& opts, substr buf, bool error_on_excess=true)
{
EmitterBuf em(opts, buf);
return em.emit_as(EMIT_YAML, r, error_on_excess);
Expand All @@ -522,7 +524,7 @@ inline substr emit_yaml(ConstNodeRef const& r, substr buf, bool error_on_excess=
* @return a substr trimmed to the result in the output buffer. If the buffer is
* insufficient (when error_on_excess is false), the string pointer of the
* result will be set to null, and the length will report the required buffer size. */
inline substr emit_json(ConstNodeRef const& r, substr buf, EmitOptions const& opts, bool error_on_excess=true)
inline substr emit_json(ConstNodeRef const& r, EmitOptions const& opts, substr buf, bool error_on_excess=true)
{
EmitterBuf em(opts, buf);
return em.emit_as(EMIT_JSON, r, error_on_excess);
Expand Down Expand Up @@ -552,15 +554,15 @@ inline substr emit_json(ConstNodeRef const& r, substr buf, bool error_on_excess=
template<class CharOwningContainer>
substr emitrs_yaml(Tree const& t, id_type id, EmitOptions const& opts, CharOwningContainer * cont, bool append=false)
{
const size_t startpos = append ? cont->size() : 0u;
size_t startpos = append ? cont->size() : 0u;
cont->resize(cont->capacity()); // otherwise the first emit would be certain to fail
substr buf = to_substr(*cont).sub(startpos);
substr ret = emit_yaml(t, id, buf, opts, /*error_on_excess*/false);
substr ret = emit_yaml(t, id, opts, buf, /*error_on_excess*/false);
if(ret.str == nullptr && ret.len > 0)
{
cont->resize(startpos + ret.len);
buf = to_substr(*cont).sub(startpos);
ret = emit_yaml(t, id, buf, opts, /*error_on_excess*/true);
ret = emit_yaml(t, id, opts, buf, /*error_on_excess*/true);
}
else
{
Expand All @@ -585,12 +587,13 @@ substr emitrs_json(Tree const& t, id_type id, EmitOptions const& opts, CharOwnin
const size_t startpos = append ? cont->size() : 0u;
cont->resize(cont->capacity()); // otherwise the first emit would be certain to fail
substr buf = to_substr(*cont).sub(startpos);
substr ret = emit_json(t, id, buf, opts, /*error_on_excess*/false);
EmitterBuf em(opts, buf);
substr ret = emit_json(t, id, opts, buf, /*error_on_excess*/false);
if(ret.str == nullptr && ret.len > 0)
{
cont->resize(startpos + ret.len);
buf = to_substr(*cont).sub(startpos);
ret = emit_json(t, id, buf, opts, /*error_on_excess*/true);
ret = emit_json(t, id, opts, buf, /*error_on_excess*/true);
}
else
{
Expand All @@ -608,18 +611,18 @@ substr emitrs_json(Tree const& t, id_type id, CharOwningContainer * cont, bool a

/** (3) emit+resize: YAML to a newly-created `std::string`/`std::vector`-like container. */
template<class CharOwningContainer>
CharOwningContainer emitrs_yaml(Tree const& t, id_type id, EmitOptions const& opts={}, bool append=false)
CharOwningContainer emitrs_yaml(Tree const& t, id_type id, EmitOptions const& opts={})
{
CharOwningContainer c;
emitrs_yaml(t, id, opts, &c, append);
emitrs_yaml(t, id, opts, &c);
return c;
}
/** (3) emit+resize: JSON to a newly-created `std::string`/`std::vector`-like container. */
template<class CharOwningContainer>
CharOwningContainer emitrs_json(Tree const& t, id_type id, EmitOptions const& opts={}, bool append=false)
CharOwningContainer emitrs_json(Tree const& t, id_type id, EmitOptions const& opts={})
{
CharOwningContainer c;
emitrs_json(t, id, opts, &c, append);
emitrs_json(t, id, opts, &c);
return c;
}

Expand Down Expand Up @@ -666,22 +669,22 @@ substr emitrs_json(Tree const& t, CharOwningContainer * cont, bool append=false)

/** (3) emit+resize: YAML to a newly-created `std::string`/`std::vector`-like container. */
template<class CharOwningContainer>
CharOwningContainer emitrs_yaml(Tree const& t, EmitOptions const& opts={}, bool append=false)
CharOwningContainer emitrs_yaml(Tree const& t, EmitOptions const& opts={})
{
CharOwningContainer c;
if(t.empty())
return c;
emitrs_yaml(t, t.root_id(), opts, &c, append);
emitrs_yaml(t, t.root_id(), opts, &c);
return c;
}
/** (3) emit+resize: JSON to a newly-created `std::string`/`std::vector`-like container. */
template<class CharOwningContainer>
CharOwningContainer emitrs_json(Tree const& t, EmitOptions const& opts={}, bool append=false)
CharOwningContainer emitrs_json(Tree const& t, EmitOptions const& opts={})
{
CharOwningContainer c;
if(t.empty())
return c;
emitrs_json(t, t.root_id(), opts, &c, append);
emitrs_json(t, t.root_id(), opts, &c);
return c;
}

Expand Down Expand Up @@ -725,20 +728,20 @@ substr emitrs_json(ConstNodeRef const& n, CharOwningContainer * cont, bool appen

/** (3) emit+resize: YAML to a newly-created `std::string`/`std::vector`-like container. */
template<class CharOwningContainer>
CharOwningContainer emitrs_yaml(ConstNodeRef const& n, EmitOptions const& opts={}, bool append=false)
CharOwningContainer emitrs_yaml(ConstNodeRef const& n, EmitOptions const& opts={})
{
_RYML_CB_CHECK(n.tree()->callbacks(), n.readable());
CharOwningContainer c;
emitrs_yaml(*n.tree(), n.id(), opts, &c, append);
emitrs_yaml(*n.tree(), n.id(), opts, &c);
return c;
}
/** (3) emit+resize: JSON to a newly-created `std::string`/`std::vector`-like container. */
template<class CharOwningContainer>
CharOwningContainer emitrs_json(ConstNodeRef const& n, EmitOptions const& opts={}, bool append=false)
CharOwningContainer emitrs_json(ConstNodeRef const& n, EmitOptions const& opts={})
{
_RYML_CB_CHECK(n.tree()->callbacks(), n.readable());
CharOwningContainer c;
emitrs_json(*n.tree(), n.id(), opts, &c, append);
emitrs_json(*n.tree(), n.id(), opts, &c);
return c;
}

Expand Down
Loading

0 comments on commit e99c8e8

Please sign in to comment.