Skip to content

Commit

Permalink
improve coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
biojppm committed May 4, 2024
1 parent 613c9e6 commit 98da41f
Show file tree
Hide file tree
Showing 7 changed files with 149 additions and 26 deletions.
8 changes: 7 additions & 1 deletion src/c4/yml/common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ void report_error_impl(const char* msg, size_t length, Location loc, FILE *f)
{
if(!loc.name.empty())
{
// this is more portable than using fprintf("%.*s:") which
// is not available in some embedded platforms
fwrite(loc.name.str, 1, loc.name.len, f);
fputc(':', f);
}
Expand All @@ -36,13 +38,17 @@ void report_error_impl(const char* msg, size_t length, Location loc, FILE *f)
fprintf(f, "%zu:", loc.col);
if(loc.offset)
fprintf(f, " (%zuB):", loc.offset);
fputc(' ', f);
}
fprintf(f, "%.*s\n", (int)length, msg);
RYML_ASSERT(!csubstr(msg, length).ends_with('\0'));
fwrite(msg, 1, length, f);
fputc('\n', f);
fflush(f);
}

[[noreturn]] void error_impl(const char* msg, size_t length, Location loc, void * /*user_data*/)
{
RYML_ASSERT(!csubstr(msg, length).ends_with('\0'));

Check warning on line 51 in src/c4/yml/common.cpp

View check run for this annotation

Codecov / codecov/patch

src/c4/yml/common.cpp#L51

Added line #L51 was not covered by tests
report_error_impl(msg, length, loc, nullptr);
#ifdef RYML_DEFAULT_CALLBACK_USES_EXCEPTIONS
throw std::runtime_error(std::string(msg, length));
Expand Down
24 changes: 13 additions & 11 deletions src/c4/yml/common.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,10 @@
#include <c4/substr.hpp>
#include <c4/yml/export.hpp>

#ifndef C4_MSVC
#include <alloca.h>
#else
#ifdef C4_MSVC
#include <malloc.h>
#else
#include <alloca.h>
#endif


Expand All @@ -26,7 +26,7 @@

#ifndef RYML_ERRMSG_SIZE
/// size for the error message buffer
#define RYML_ERRMSG_SIZE 1024
#define RYML_ERRMSG_SIZE (1024)
#endif


Expand Down Expand Up @@ -423,7 +423,7 @@ do \
{ \
const char msg[] = msg_literal; \
RYML_DEBUG_BREAK(); \
c4::yml::error((cb), msg, sizeof(msg), loc); \
c4::yml::error((cb), msg, sizeof(msg)-1, loc); \
C4_UNREACHABLE_AFTER_ERR(); \
} while(0)
#define _RYML_CB_CHECK_(cb, cond, loc) \
Expand All @@ -433,7 +433,7 @@ do \
{ \
const char msg[] = "check failed: " #cond; \
RYML_DEBUG_BREAK(); \
c4::yml::error((cb), msg, sizeof(msg), loc); \
c4::yml::error((cb), msg, sizeof(msg)-1, loc); \
C4_UNREACHABLE_AFTER_ERR(); \
} \
} while(0)
Expand Down Expand Up @@ -545,21 +545,23 @@ struct _SubstrWriter


namespace detail {
// dumpfn is a function abstracting prints to terminal (or to string).
template<class DumpFn, class ...Args>
C4_NO_INLINE void _parse_dump(DumpFn dumpfn, csubstr fmt, Args&& ...args)
C4_NO_INLINE void _parse_dump(DumpFn &&dumpfn, csubstr fmt, Args&& ...args)
{
// buffer for converting individual arguments.
char writebuf[RYML_LOGBUF_SIZE];
auto results = format_dump_resume(dumpfn, writebuf, fmt, std::forward<Args>(args)...);
auto results = format_dump_resume(std::forward<DumpFn>(dumpfn), writebuf, fmt, std::forward<Args>(args)...);
// resume writing if the results failed to fit the buffer
if(C4_UNLIKELY(results.bufsize > RYML_LOGBUF_SIZE)) // bufsize will be that of the largest element serialized. Eg int(1) will require 1 byte.
{
const size_t bufsize = results.bufsize <= RYML_LOGBUF_SIZE_MAX ? results.bufsize : RYML_LOGBUF_SIZE_MAX;
#ifdef C4_MSVC
substr largerbuf = {static_cast<char*>(_alloca(bufsize)), results.bufsize};
substr largerbuf = {static_cast<char*>(_alloca(bufsize)), bufsize};
#else
substr largerbuf = {static_cast<char*>(alloca(bufsize)), results.bufsize};
substr largerbuf = {static_cast<char*>(alloca(bufsize)), bufsize};
#endif
results = format_dump_resume(dumpfn, results, largerbuf, fmt, std::forward<Args>(args)...);
results = format_dump_resume(std::forward<DumpFn>(dumpfn), results, largerbuf, fmt, std::forward<Args>(args)...);
}
}
template<class ...Args>
Expand Down
2 changes: 1 addition & 1 deletion src/c4/yml/node_type.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ typedef enum : type_bits {
// style flags:
//
FLOW_SL = __(14), ///< mark container with single-line flow style (seqs as '[val1,val2], maps as '{key: val,key2: val2}')
FLOW_ML = __(15), ///< mark container with multi-line flow style (seqs as '[\n val1,\n val2\n], maps as '{\n key: val,\n key2: val2\n}')
FLOW_ML = __(15), ///< (NOT IMPLEMENTED, work in progress) mark container with multi-line flow style (seqs as '[\n val1,\n val2\n], maps as '{\n key: val,\n key2: val2\n}')
BLOCK = __(16), ///< mark container with block style (seqs as '- val\n', maps as 'key: val')
KEY_LITERAL = __(17), ///< mark key scalar as multiline, block literal |
VAL_LITERAL = __(18), ///< mark val scalar as multiline, block literal |
Expand Down
6 changes: 4 additions & 2 deletions src/c4/yml/tag.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@ YamlTag_e to_tag(csubstr tag)
return TAG_TIMESTAMP;
else if(tag == "value")
return TAG_VALUE;
else if(tag == "yaml")
return TAG_YAML;

return TAG_NONE;
}
Expand Down Expand Up @@ -153,9 +155,9 @@ csubstr from_tag_long(YamlTag_e tag)
case TAG_YAML:
return {"<tag:yaml.org,2002:yaml>"};
case TAG_NONE:
default:
return {""};
}
return {""};
}

csubstr from_tag(YamlTag_e tag)
Expand Down Expand Up @@ -193,9 +195,9 @@ csubstr from_tag(YamlTag_e tag)
case TAG_YAML:
return {"!!yaml"};
case TAG_NONE:
default:
return {""};
}
return {""};
}


Expand Down
74 changes: 74 additions & 0 deletions test/test_callbacks.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "./test_lib/test_case.hpp"
#ifndef RYML_SINGLE_HEADER
#include "c4/yml/common.hpp"
#include "c4/dump.hpp"
#endif
#include <stdexcept>
#include <csetjmp>
Expand Down Expand Up @@ -392,6 +393,79 @@ TEST(RYML_ASSERT, basic)
}


//-----------------------------------------------------------------------------

struct Dumper
{
char errmsg[RYML_ERRMSG_SIZE] = {0};
detail::_SubstrWriter writer{errmsg};
void operator()(csubstr s)
{
writer.append(s);
}
};
TEST(_parse_dump, small_args)
{
const std::string str(/*count*/RYML_LOGBUF_SIZE-1, 's');
const csubstr fmt = "smaller={}";
const std::string expected = formatrs<std::string>(fmt, str);
{
Dumper dumper;
char writebuf[RYML_LOGBUF_SIZE];
c4::DumpResults results = c4::format_dump_resume(dumper, writebuf, fmt, str);
EXPECT_EQ(results.bufsize, str.size());
EXPECT_EQ(dumper.writer.curr(), to_csubstr(expected));
}
{
Dumper dumper;
detail::_parse_dump(dumper, fmt, str);
EXPECT_EQ(dumper.writer.curr(), to_csubstr(expected));
}
}

TEST(_parse_dump, large_args)
{
const std::string str(/*count*/RYML_LOGBUF_SIZE+1, 'l');
const csubstr fmt = "larger={}";
{
Dumper dumper;
char writebuf[RYML_LOGBUF_SIZE];
c4::DumpResults results = c4::format_dump_resume(dumper, writebuf, fmt, str);
const csubstr expected = "larger=";
EXPECT_EQ(results.bufsize, str.size());
EXPECT_EQ(dumper.writer.curr(), expected);
}
{
Dumper dumper;
detail::_parse_dump(dumper, fmt, str);
const std::string expected = formatrs<std::string>(fmt, str);
EXPECT_EQ(dumper.writer.curr(), to_csubstr(expected));
}
}

TEST(_parse_dump, unprintable_args)
{
const std::string str(/*count*/RYML_LOGBUF_SIZE_MAX+1, 'u');
const csubstr fmt = "unprintable={}";
const csubstr expected = "unprintable=";
{
Dumper dumper;
char writebuf[RYML_LOGBUF_SIZE];
c4::DumpResults results = c4::format_dump_resume(dumper, writebuf, fmt, str);
EXPECT_EQ(results.bufsize, str.size());
EXPECT_EQ(dumper.writer.curr(), expected);
}
{
Dumper dumper;
detail::_parse_dump(dumper, fmt, str);
size_t unprintable_size = (size_t)(RYML_LOGBUF_SIZE_MAX+1);
const std::string zeros(/*count*/unprintable_size, '\0');
EXPECT_EQ(to_csubstr(zeros).len, unprintable_size);
EXPECT_EQ(dumper.writer.pos, expected.size());
EXPECT_EQ(dumper.writer.curr(), expected);
}
}

// FIXME this is here merely to avoid a linker error
Case const* get_case(csubstr)
{
Expand Down
8 changes: 8 additions & 0 deletions test/test_emit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,14 @@ TEST(emit, existing_tree)
test_emits(t, expected, expected_json);
}

TEST(emit, no_node)
{
const Tree t = parse_in_arena("[foo, bar]");
std::string expected = "[foo,bar]";
std::string expected_json = R"(["foo","bar"])";
test_emits(t, NONE, expected, expected_json);
}

TEST(emit, existing_seq_node)
{
Tree nct = parse_in_arena("[foo, bar, [nested, seq], {nested: map}]");
Expand Down
Loading

0 comments on commit 98da41f

Please sign in to comment.