Skip to content

Commit

Permalink
re #61: improve patch coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
biojppm committed May 10, 2020
1 parent 8af25bf commit 7a17cfc
Show file tree
Hide file tree
Showing 7 changed files with 89 additions and 49 deletions.
24 changes: 17 additions & 7 deletions src/c4/yml/common.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,34 @@ namespace c4 {
namespace yml {

#ifndef RYML_NO_DEFAULT_CALLBACKS
namespace {

void error_impl(const char* msg, size_t length, Location loc, void * /*user_data*/)
void report_error_impl(const char* msg, size_t length, Location loc, FILE *f)
{
if(!f)
{
f = stderr;
}
if(loc)
{
if(!loc.name.empty())
{
fprintf(stderr, "%.*s:", (int)loc.name.len, loc.name.str);
fprintf(f, "%.*s:", (int)loc.name.len, loc.name.str);
}
fprintf(stderr, "%zu:%zu:", loc.line, loc.col);
fprintf(f, "%zu:%zu:", loc.line, loc.col);
if(loc.offset)
{
fprintf(stderr, " (%zuB):", loc.offset);
fprintf(f, " (%zuB):", loc.offset);
}
}
fprintf(stderr, "%.*s\n", (int)length, msg);
fflush(stderr);
fprintf(f, "ERROR: %.*s\n", (int)length, msg);
fflush(f);
}

namespace {

void error_impl(const char* msg, size_t length, Location loc, void * /*user_data*/)
{
report_error_impl(msg, length, loc, nullptr);
::abort();
}

Expand Down
5 changes: 4 additions & 1 deletion src/c4/yml/common.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,17 +124,20 @@ struct Location : public LineCol
* std::terminate()/std::abort(). */
using pfn_error = void (*)(const char* msg, size_t msg_len, Location location, void *user_data);

/** trigger an error: call the current error callback. */
void error(const char *msg, size_t msg_len, Location loc);
/** @overload error */
inline void error(const char *msg, size_t msg_len)
{
error(msg, msg_len, Location{});
}

/** @overload error */
template<size_t N>
inline void error(const char (&msg)[N], Location loc)
{
error(msg, N-1, loc);
}
/** @overload error */
template<size_t N>
inline void error(const char (&msg)[N])
{
Expand Down
37 changes: 5 additions & 32 deletions src/c4/yml/parse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1645,22 +1645,18 @@ substr Parser::_scan_plain_scalar_expl(csubstr currscalar, csubstr peeked_line)
{
_c4dbgpf("rscalar[EXPL]: found special character '%c' at %zu, stopping: '%.*s'", peeked_line[pos], pos, _c4prsp(peeked_line.left_of(pos).trimr("\r\n")));
peeked_line = peeked_line.left_of(pos);
_advance_to_peeked(peeked_line);
_line_progressed(peeked_line.end() - m_state->line_contents.rem.begin());
break;
}
_c4dbgpf("rscalar[EXPL]: append another line, full: '%.*s'", _c4prsp(peeked_line.trimr("\r\n")));
if(!first)
{
if(!_advance_to_peeked())
{
break;
}
RYML_CHECK(_advance_to_peeked());
}
peeked_line = _scan_to_next_nonempty_line(/*indentation*/0);
if(peeked_line.empty())
{
_c4dbgp("rscalar[EXPL]: ... finished.");
break;
_c4err("expected token or continuation");
}
pos = peeked_line.first_of(chars);
first = false;
Expand All @@ -1683,7 +1679,7 @@ substr Parser::_scan_plain_scalar_impl(csubstr currscalar, csubstr peeked_line,
while(true)
{
_c4dbgpf("rscalar[IMPL]: continuing... ref_indentation=%zu", indentation);
if(peeked_line.begins_with("..."))
if(peeked_line.begins_with("...") || peeked_line.begins_with("---"))
{
_c4dbgpf("rscalar[IMPL]: document termination next -- bail now '%.*s'", _c4prsp(peeked_line.trimr("\r\n")));
break;
Expand Down Expand Up @@ -1712,19 +1708,16 @@ substr Parser::_scan_plain_scalar_impl(csubstr currscalar, csubstr peeked_line,
{
_line_progressed(peeked_line.find(": "));
_c4err("': ' is not a valid token in plain flow (unquoted) scalars");
break;
}
else if(peeked_line.ends_with(':'))
{
_line_progressed(peeked_line.find(':'));
_c4err("lines cannot end with ':' in plain flow (unquoted) scalars");
break;
}
else if(peeked_line.find(" #") != npos)
{
_line_progressed(peeked_line.find(" #"));
_c4err("' #' is not a valid token in plain flow (unquoted) scalars");
break;
}

_c4dbgpf("rscalar[IMPL]: append another line: (len=%zu)'%.*s'", peeked_line.len, _c4prsp(peeked_line.trimr("\r\n")));
Expand Down Expand Up @@ -1779,26 +1772,6 @@ csubstr Parser::_scan_to_next_nonempty_line(size_t indentation)
return {};
}

// returns false when the file finished
bool Parser::_advance_to_peeked(csubstr peeked_part)
{
RYML_ASSERT(m_state->line_contents.rem.contains(peeked_part));
_line_progressed(peeked_part.end() - m_state->line_contents.rem.begin());
if(m_state->line_contents.rem.empty())
{
_line_ended(); // advances to the peeked-at line, consuming all remaining (probably newline) characters on the current line
RYML_ASSERT(m_state->line_contents.rem.first_of("\r\n") == csubstr::npos);
_c4dbgpf("advance to peeked: scan more... pos=%zu len=%zu", m_state->pos.offset, m_buf.len);
_scan_line(); // puts the peeked-at line in the buffer
if(_finished_file())
{
_c4dbgp("rscalar[IMPL]: finished file!");
return false;
}
}
return true;
}

// returns false when the file finished
bool Parser::_advance_to_peeked()
{
Expand All @@ -1809,7 +1782,7 @@ bool Parser::_advance_to_peeked()
_scan_line(); // puts the peeked-at line in the buffer
if(_finished_file())
{
_c4dbgp("rscalar[IMPL]: finished file!");
_c4dbgp("rscalar: finished file!");
return false;
}
return true;
Expand Down
1 change: 0 additions & 1 deletion src/c4/yml/parse.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,6 @@ class Parser

csubstr _peek_next_line(size_t pos=npos) const;
bool _advance_to_peeked();
bool _advance_to_peeked(csubstr peeked_portion);
void _scan_line();

bool _scan_scalar(csubstr *scalar);
Expand Down
56 changes: 53 additions & 3 deletions test/plain_scalar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,11 @@ namespace yml {
"plain scalar, do not accept ' #', at line start, but accept on first line", \
"plain scalar, do not accept ' #', at line end", \
"plain scalar, accept '#'", \
"plain scalar, explicit"
"plain scalar, explicit", \
"plain scalar, explicit, early end, seq", \
"plain scalar, explicit, early end, map", \
"plain scalar, multiple docs", \
"plain scalar, multiple docs, termination"


CASE_GROUP(PLAIN_SCALAR)
Expand Down Expand Up @@ -372,9 +376,10 @@ C("plain scalar, do not accept ':' at line end", HAS_PARSE_ERROR,
R"(- Several lines of text,
with special:characters, like:this-or-this -
- and some "quotes" of various 'types'.
But this: must cause a parse error.
But this must cause a parse error:
- well, did it?
)",
LineCol(4, 11)
LineCol(4, 36)
),

C("plain scalar, do not accept ' #', at line start", HAS_PARSE_ERROR,
Expand Down Expand Up @@ -443,6 +448,51 @@ and yet more, deindented
}
),

C("plain scalar, explicit, early end, seq", HAS_PARSE_ERROR,
R"([
a plain scalar
with several lines
)",
LineCol(4, 1)
),

C("plain scalar, explicit, early end, map", HAS_PARSE_ERROR,
R"({foo:
a plain scalar
with several lines
)",
LineCol(4, 1)
),

C("plain scalar, multiple docs",
R"(---
- a plain scalar
with several lines
---
- a second plain scalar
with several lines
)",
N(STREAM, L{
N(DOCSEQ, L{N("a plain scalar with several lines")}),
N(DOCSEQ, L{N("a second plain scalar with several lines")}),
})
),

C("plain scalar, multiple docs, termination",
R"(---
- a plain scalar
with several lines
...
---
- a second plain scalar
with several lines
)",
N(STREAM, L{
N(DOCSEQ, L{N("a plain scalar with several lines")}),
N(DOCSEQ, L{N("a second plain scalar with several lines")}),
})
),

)

}
Expand Down
13 changes: 9 additions & 4 deletions test/test_case.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,17 @@ void test_arena_not_shared(Tree const& a, Tree const& b)
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------

// ensure coverage of the default callback report
#ifndef RYML_NO_DEFAULT_CALLBACKS
extern void report_error_impl(const char* msg, size_t len, Location loc, FILE *file);
#endif

std::string format_error(const char* msg, size_t len, Location loc)
{
// ensure coverage of the default callback report
#ifndef RYML_NO_DEFAULT_CALLBACKS
report_error_impl(msg, len, loc, nullptr);
#endif
if(!loc) return msg;
std::string out;
if(!loc.name.empty()) c4::formatrs(append, &out, "{}:", loc.name);
Expand Down Expand Up @@ -186,10 +195,6 @@ void ExpectError::do_check(std::function<void()> fn, Location expected_location)
{
EXPECT_EQ(e.error_location.offset, context.expected_location.offset);
}
if(!context.expected_location.name.empty())
{
EXPECT_EQ(e.error_location.name, context.expected_location.name);
}
}
};
EXPECT_TRUE(context.m_got_an_error);
Expand Down
2 changes: 1 addition & 1 deletion test/test_case.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -413,7 +413,7 @@ struct Case
template<size_t N, class... Args> Case(csubstr name_, int f_, const char (&src_)[N], Args&& ...args) : name(name_), src(src_), root(std::forward<Args>(args)...), flags((TestCaseFlags_e)f_), expected_location() {}

//! create a test case with an error on an expected location
template<size_t N> Case(csubstr name_, int f_, const char (&src_)[N], LineCol loc) : name(name_), src(src_), root(), flags((TestCaseFlags_e)f_), expected_location(loc.line, loc.col) {}
template<size_t N> Case(csubstr name_, int f_, const char (&src_)[N], LineCol loc) : name(name_), src(src_), root(), flags((TestCaseFlags_e)f_), expected_location(name, loc.line, loc.col) {}

};

Expand Down

0 comments on commit 7a17cfc

Please sign in to comment.