[fix] re #200: yaml events tool: do not abort on parse error

This commit is contained in:
Joao Paulo Magalhaes
2022-01-23 14:21:52 +00:00
parent f623b91656
commit c5842c2687
2 changed files with 68 additions and 18 deletions

View File

@@ -20,7 +20,10 @@ void report_error_impl(const char* msg, size_t length, Location loc, FILE *f)
if(loc)
{
if(!loc.name.empty())
fprintf(f, "%.*s:", (int)loc.name.len, loc.name.str);
{
fwrite(loc.name.str, 1, loc.name.len, f);
fputc(':', f);
}
fprintf(f, "%zu:", loc.line);
if(loc.col)
fprintf(f, "%zu:", loc.col);

View File

@@ -7,6 +7,56 @@
using namespace c4;
using namespace c4::yml;
void usage(const char *exename);
std::string load_file(csubstr filename);
void report_error_impl(const char* msg, size_t length, Location loc, FILE *f);
int main(int argc, const char *argv[])
{
if(argc < 2)
{
usage(argv[0]);
return 1;
}
// do not abort on error
Callbacks callbacks = {};
int exit_status = 0;
callbacks.m_user_data = &exit_status;
callbacks.m_error = [](const char *msg, size_t msg_len, Location location, void *user_data)
{
report_error_impl(msg, msg_len, location, stderr);
*(int*)user_data = 1;
};
Tree tree(callbacks);
csubstr filename = to_csubstr(argv[1]);
std::string buf = load_file(filename);
std::string events;
tree.reserve(to_substr(buf).count('\n'));
parse_in_place(filename, to_substr(buf), &tree);
if(exit_status)
return exit_status;
emit_events(&events, tree);
if(exit_status)
return exit_status;
std::fwrite(events.data(), 1, events.size(), stdout);
return 0;
}
//-----------------------------------------------------------------------------
void usage(const char *exename)
{
std::printf(R"(usage:
%s - # read from stdin
%s <file> # read from file
)", exename, exename);
}
std::string load_file(csubstr filename)
{
std::string buf;
@@ -30,24 +80,21 @@ std::string load_file(csubstr filename)
return buf;
}
int main(int argc, const char *argv[])
void report_error_impl(const char* msg, size_t length, Location loc, FILE *f)
{
if(argc != 2)
if(loc)
{
std::printf(R"(usage:
%s - # read from stdin
%s <file> # read from file
)", argv[0], argv[0]);
return 1;
if(!loc.name.empty())
{
std::fwrite(loc.name.str, 1, loc.name.len, f);
std::fputc(':', f);
}
std::fprintf(f, "%zu:", loc.line);
if(loc.col)
std::fprintf(f, "%zu:", loc.col);
if(loc.offset)
std::fprintf(f, " (%zuB):", loc.offset);
}
Tree tree;
csubstr filename = to_csubstr(argv[1]);
std::string buf = load_file(filename);
tree.reserve(to_substr(buf).count('\n'));
parse_in_place(filename, to_substr(buf), &tree);
std::string events;
emit_events(&events, tree);
std::fwrite(events.data(), 1, events.size(), stdout);
return 0;
std::fprintf(f, "ERROR: %.*s\n", (int)length, msg);
std::fflush(f);
}