mirror of
https://github.com/biojppm/rapidyaml.git
synced 2026-01-18 13:31:19 +01:00
refactor error API: update tools
This commit is contained in:
@@ -7,6 +7,7 @@
|
|||||||
#else
|
#else
|
||||||
#include <c4/yml/std/std.hpp>
|
#include <c4/yml/std/std.hpp>
|
||||||
#include <c4/yml/parse.hpp>
|
#include <c4/yml/parse.hpp>
|
||||||
|
#include <c4/yml/error.def.hpp>
|
||||||
#include <c4/yml/emit.hpp>
|
#include <c4/yml/emit.hpp>
|
||||||
#include <c4/yml/event_handler_tree.hpp>
|
#include <c4/yml/event_handler_tree.hpp>
|
||||||
#include <c4/yml/parse_engine.def.hpp>
|
#include <c4/yml/parse_engine.def.hpp>
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#include <c4/yml/parse.hpp>
|
#include <c4/yml/parse.hpp>
|
||||||
#include <c4/yml/emit.hpp>
|
#include <c4/yml/emit.hpp>
|
||||||
#include <c4/yml/common.hpp>
|
#include <c4/yml/common.hpp>
|
||||||
|
#include <c4/yml/error.def.hpp>
|
||||||
#endif
|
#endif
|
||||||
#include <c4/fs/fs.hpp>
|
#include <c4/fs/fs.hpp>
|
||||||
|
|
||||||
@@ -88,7 +89,13 @@ bool timing_enabled = false;
|
|||||||
bool parse_args(int argc, const char *argv[], Args &args)
|
bool parse_args(int argc, const char *argv[], Args &args)
|
||||||
{
|
{
|
||||||
args = {};
|
args = {};
|
||||||
for(int i = 1; i < argc; ++i)
|
if(argc < 2)
|
||||||
|
{
|
||||||
|
print_usage(argv[0]);
|
||||||
|
_RYML_ERR_BASIC("missing filename (use - to read from stdin)");
|
||||||
|
}
|
||||||
|
args.filename = c4::to_csubstr(argv[argc - 1]);
|
||||||
|
for(int i = 1; i+1 < argc; ++i)
|
||||||
{
|
{
|
||||||
c4::csubstr arg = c4::to_csubstr(argv[i]);
|
c4::csubstr arg = c4::to_csubstr(argv[i]);
|
||||||
auto arg0_is = [&](c4::csubstr argshort, c4::csubstr arglong){
|
auto arg0_is = [&](c4::csubstr argshort, c4::csubstr arglong){
|
||||||
@@ -98,7 +105,7 @@ bool parse_args(int argc, const char *argv[], Args &args)
|
|||||||
if(arg0_is(argshort, arglong))
|
if(arg0_is(argshort, arglong))
|
||||||
{
|
{
|
||||||
if(i + 1 >= argc)
|
if(i + 1 >= argc)
|
||||||
c4::yml::error("missing argument value");
|
_RYML_ERR_BASIC("missing argument value: {}", arg);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -120,14 +127,14 @@ bool parse_args(int argc, const char *argv[], Args &args)
|
|||||||
else if(i+1 < argc)
|
else if(i+1 < argc)
|
||||||
{
|
{
|
||||||
print_usage(argv[0]);
|
print_usage(argv[0]);
|
||||||
c4::yml::error("unknown argument");
|
_RYML_ERR_BASIC("unknown argument: {}", arg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
timing_enabled = args.timed_sections;
|
timing_enabled = args.timed_sections;
|
||||||
if(argc < 2)
|
if(argc < 2)
|
||||||
{
|
{
|
||||||
print_usage(argv[0]);
|
print_usage(argv[0]);
|
||||||
c4::yml::error("missing filename (use - to read from stdin)");
|
_RYML_ERR_BASIC("missing filename (use - to read from stdin)");
|
||||||
}
|
}
|
||||||
args.filename = c4::to_csubstr(argv[argc - 1]);
|
args.filename = c4::to_csubstr(argv[argc - 1]);
|
||||||
return true;
|
return true;
|
||||||
@@ -147,11 +154,7 @@ void read_file(csubstr filename, std::string *buf)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(!fs::path_exists(filename.str))
|
_RYML_CHECK_BASIC_MSG(fs::path_exists(filename.str), "file not found: {} (cwd={})", filename, fs::cwd<std::string>());
|
||||||
{
|
|
||||||
std::fprintf(stderr, "cannot find file: %s (cwd=%s)\n", filename.str, fs::cwd<std::string>().c_str()); // NOLINT
|
|
||||||
yml::error("file not found");
|
|
||||||
}
|
|
||||||
fs::file_get_contents<std::string>(filename.str, buf);
|
fs::file_get_contents<std::string>(filename.str, buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -192,37 +195,41 @@ void emit_json_docs(yml::Tree const& tree, FILE *output)
|
|||||||
emitnode(doc);
|
emitnode(doc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void report_error(const char* msg, size_t length, yml::Location loc, FILE *f)
|
void dump2stderr(csubstr s)
|
||||||
{
|
{
|
||||||
if(!loc.name.empty())
|
if(s.len)
|
||||||
{
|
{
|
||||||
fwrite(loc.name.str, 1, loc.name.len, f); // NOLINT
|
fwrite(s.str, 1, s.len, stderr); // NOLINT
|
||||||
fputc(':', f); // NOLINT
|
fflush(stderr); // NOLINT
|
||||||
}
|
}
|
||||||
fprintf(f, "%zu:", loc.line); // NOLINT
|
}
|
||||||
if(loc.col)
|
|
||||||
fprintf(f, "%zu:", loc.col); // NOLINT
|
[[noreturn]] void throwerr(csubstr msg)
|
||||||
if(loc.offset)
|
{
|
||||||
fprintf(f, " (%zuB):", loc.offset); // NOLINT
|
C4_IF_EXCEPTIONS(
|
||||||
fputc(' ', f); // NOLINT
|
throw std::runtime_error({msg.str, msg.len});
|
||||||
fprintf(f, "%.*s\n", static_cast<int>(length), msg); // NOLINT
|
,
|
||||||
fflush(f); // NOLINT
|
jmp_msg.assign(msg.str, msg.len);
|
||||||
|
std::longjmp(jmp_env, 1);
|
||||||
|
);
|
||||||
|
C4_UNREACHABLE_AFTER_ERR();
|
||||||
}
|
}
|
||||||
|
|
||||||
yml::Callbacks create_custom_callbacks()
|
yml::Callbacks create_custom_callbacks()
|
||||||
{
|
{
|
||||||
yml::Callbacks callbacks = {};
|
return yml::Callbacks{}
|
||||||
callbacks.m_error = [](const char *msg, size_t msg_len, yml::Location location, void *)
|
.set_error_basic([](csubstr msg, yml::ErrorDataBasic const& errdata, void *){
|
||||||
{
|
yml::err_basic_format(dump2stderr, msg, errdata);
|
||||||
report_error(msg, msg_len, location, stderr);
|
throwerr(msg);
|
||||||
C4_IF_EXCEPTIONS(
|
})
|
||||||
throw std::runtime_error({msg, msg_len});
|
.set_error_parse([](csubstr msg, yml::ErrorDataParse const& errdata, void *){
|
||||||
,
|
yml::err_parse_format(dump2stderr, msg, errdata);
|
||||||
jmp_msg.assign(msg, msg_len);
|
throwerr(msg);
|
||||||
std::longjmp(jmp_env, 1);
|
})
|
||||||
);
|
.set_error_visit([](csubstr msg, yml::ErrorDataVisit const& errdata, void *){
|
||||||
};
|
yml::err_visit_format(dump2stderr, msg, errdata);
|
||||||
return callbacks;
|
throwerr(msg);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#define TS(name) timed_section C4_XCAT(__, C4_XCAT(name, __LINE__))(#name)
|
#define TS(name) timed_section C4_XCAT(__, C4_XCAT(name, __LINE__))(#name)
|
||||||
@@ -254,14 +261,13 @@ struct timed_section
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
void process_file(Args const& args)
|
void process_file(Args const& args, std::string *contents)
|
||||||
{
|
{
|
||||||
TS(objects);
|
TS(objects);
|
||||||
std::string contents;
|
|
||||||
yml::Tree tree(yml::get_callbacks());
|
yml::Tree tree(yml::get_callbacks());
|
||||||
{
|
{
|
||||||
TS(read_file);
|
TS(read_file);
|
||||||
read_file(args.filename, &contents);
|
read_file(args.filename, contents);
|
||||||
}
|
}
|
||||||
if(args.reserve_size)
|
if(args.reserve_size)
|
||||||
{
|
{
|
||||||
@@ -270,15 +276,15 @@ void process_file(Args const& args)
|
|||||||
if(args.reserve_size)
|
if(args.reserve_size)
|
||||||
{
|
{
|
||||||
TS(estimate_capacity);
|
TS(estimate_capacity);
|
||||||
cap = yml::estimate_tree_capacity(to_csubstr(contents));
|
cap = yml::estimate_tree_capacity(to_csubstr(*contents));
|
||||||
}
|
}
|
||||||
if(timing_enabled)
|
if(args.timed_sections)
|
||||||
fprintf(stderr, "reserving capacity=%zu\n", (size_t)cap); // NOLINT
|
fprintf(stderr, "reserving capacity=%zu\n", (size_t)cap); // NOLINT
|
||||||
tree.reserve(cap);
|
tree.reserve(cap);
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
TS(parse_yml);
|
TS(parse_yml);
|
||||||
yml::parse_in_place(args.filename, to_substr(contents), &tree);
|
yml::parse_in_place(args.filename, to_substr(*contents), &tree);
|
||||||
}
|
}
|
||||||
if(args.print_tree)
|
if(args.print_tree)
|
||||||
{
|
{
|
||||||
@@ -298,7 +304,7 @@ void process_file(Args const& args)
|
|||||||
std::string output;
|
std::string output;
|
||||||
{
|
{
|
||||||
TS(emit_to_buffer);
|
TS(emit_to_buffer);
|
||||||
output.resize(contents.size()); // resize, not just reserve
|
output.resize(contents->size()); // resize, not just reserve
|
||||||
if(!args.emit_as_json)
|
if(!args.emit_as_json)
|
||||||
yml::emitrs_yaml(tree, &output);
|
yml::emitrs_yaml(tree, &output);
|
||||||
else
|
else
|
||||||
@@ -323,7 +329,8 @@ void process_file(Args const& args)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
FILE *output = fopen(args.output.str, "wb");
|
FILE *output = fopen(args.output.str, "wb");
|
||||||
if (!output) c4::yml::error("could not open file");
|
if (!output)
|
||||||
|
_RYML_ERR_BASIC("could not open file: {}", args.output.str);
|
||||||
{
|
{
|
||||||
TS(emit_to_file);
|
TS(emit_to_file);
|
||||||
if(!args.emit_as_json)
|
if(!args.emit_as_json)
|
||||||
@@ -344,12 +351,19 @@ int main(int argc, const char *argv[])
|
|||||||
return 0;
|
return 0;
|
||||||
TS(TOTAL);
|
TS(TOTAL);
|
||||||
set_callbacks(create_custom_callbacks());
|
set_callbacks(create_custom_callbacks());
|
||||||
|
TS(TOTAL);
|
||||||
|
std::string yaml;
|
||||||
C4_IF_EXCEPTIONS_(try, if(setjmp(jmp_env) == 0))
|
C4_IF_EXCEPTIONS_(try, if(setjmp(jmp_env) == 0))
|
||||||
{
|
{
|
||||||
process_file(args);
|
process_file(args, &yaml);
|
||||||
}
|
}
|
||||||
C4_IF_EXCEPTIONS_(catch(std::exception const&), else) // LCOV_EXCL_LINE
|
C4_IF_EXCEPTIONS_(catch(std::exception const& exc), else) // LCOV_EXCL_LINE
|
||||||
{
|
{
|
||||||
|
C4_IF_EXCEPTIONS(
|
||||||
|
dump2stderr(to_csubstr(exc.what())); // LCOV_EXCL_LINE
|
||||||
|
,
|
||||||
|
dump2stderr(to_csubstr(jmp_msg)); // LCOV_EXCL_LINE
|
||||||
|
);
|
||||||
return 1; // LCOV_EXCL_LINE
|
return 1; // LCOV_EXCL_LINE
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -2,7 +2,9 @@
|
|||||||
#include <ryml_all.hpp>
|
#include <ryml_all.hpp>
|
||||||
#else
|
#else
|
||||||
#include <c4/yml/std/std.hpp>
|
#include <c4/yml/std/std.hpp>
|
||||||
|
#include <c4/yml/error.def.hpp>
|
||||||
#include <c4/yml/parse.hpp>
|
#include <c4/yml/parse.hpp>
|
||||||
|
#include <c4/yml/error.def.hpp>
|
||||||
#include <c4/yml/event_handler_tree.hpp>
|
#include <c4/yml/event_handler_tree.hpp>
|
||||||
#include <c4/yml/parse_engine.def.hpp>
|
#include <c4/yml/parse_engine.def.hpp>
|
||||||
#endif
|
#endif
|
||||||
@@ -309,7 +311,10 @@ csubstr parse_events_ints(csubstr filename, substr filecontents, std::string &pa
|
|||||||
if(timing_enabled) fprintf(stderr, "current_size=%zu vs needed_size=%zu. arena_size=%zu\n", evts.size(), sz, arena.size());
|
if(timing_enabled) fprintf(stderr, "current_size=%zu vs needed_size=%zu. arena_size=%zu\n", evts.size(), sz, arena.size());
|
||||||
if (!handler.fits_buffers())
|
if (!handler.fits_buffers())
|
||||||
{
|
{
|
||||||
RYML_CHECK(!fail_size);
|
if(fail_size)
|
||||||
|
{
|
||||||
|
_RYML_ERR_BASIC("buffers too small");
|
||||||
|
}
|
||||||
{
|
{
|
||||||
STOPWATCH("resize");
|
STOPWATCH("resize");
|
||||||
evts.resize(sz);
|
evts.resize(sz);
|
||||||
@@ -325,7 +330,7 @@ csubstr parse_events_ints(csubstr filename, substr filecontents, std::string &pa
|
|||||||
STOPWATCH("redo_parse");
|
STOPWATCH("redo_parse");
|
||||||
parser.parse_in_place_ev(filename, src);
|
parser.parse_in_place_ev(filename, src);
|
||||||
}
|
}
|
||||||
RYML_CHECK((size_t)handler.m_evt_pos == sz);
|
_RYML_CHECK_BASIC((size_t)handler.m_evt_pos == sz);
|
||||||
}
|
}
|
||||||
evts.resize(sz);
|
evts.resize(sz);
|
||||||
return src;
|
return src;
|
||||||
@@ -472,41 +477,45 @@ std::string load_file(csubstr filename)
|
|||||||
}
|
}
|
||||||
else if(!fs::path_exists(filename.str))
|
else if(!fs::path_exists(filename.str))
|
||||||
{
|
{
|
||||||
std::fprintf(stderr, "%s: file not found (cwd=%s)\n", filename.str, fs::cwd<std::string>().c_str());
|
std::fprintf(stderr, "%s: file not found (cwd=%s)\n", filename.str, fs::cwd<std::string>().c_str()); // LCOV_EXCL_LINE
|
||||||
error("file not found");
|
err_basic(RYML_LOC_HERE(), "file not found"); // LCOV_EXCL_LINE
|
||||||
}
|
}
|
||||||
return fs::file_get_contents<std::string>(filename.str);
|
return fs::file_get_contents<std::string>(filename.str);
|
||||||
}
|
}
|
||||||
|
|
||||||
void report_error(const char* msg, size_t length, Location loc, FILE *f)
|
[[noreturn]] C4_NO_INLINE void throwerr(csubstr msg)
|
||||||
{
|
{
|
||||||
if(!loc.name.empty())
|
C4_IF_EXCEPTIONS(
|
||||||
|
throw std::runtime_error({msg.str, msg.len});
|
||||||
|
,
|
||||||
|
jmp_msg.assign(msg.str, msg.len);
|
||||||
|
std::longjmp(jmp_env, 1);
|
||||||
|
);
|
||||||
|
C4_UNREACHABLE_AFTER_ERR();
|
||||||
|
}
|
||||||
|
|
||||||
|
void dump2stderr(csubstr s)
|
||||||
|
{
|
||||||
|
if(s.len)
|
||||||
{
|
{
|
||||||
fwrite(loc.name.str, 1, loc.name.len, f);
|
fwrite(s.str, 1, s.len, stderr); // NOLINT
|
||||||
fputc(':', f);
|
fflush(stderr); // NOLINT
|
||||||
}
|
}
|
||||||
fprintf(f, "%zu:", loc.line);
|
|
||||||
if(loc.col)
|
|
||||||
fprintf(f, "%zu:", loc.col);
|
|
||||||
if(loc.offset)
|
|
||||||
fprintf(f, " (%zuB):", loc.offset);
|
|
||||||
fputc(' ', f);
|
|
||||||
fprintf(f, "%.*s\n", static_cast<int>(length), msg);
|
|
||||||
fflush(f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Callbacks create_custom_callbacks()
|
Callbacks create_custom_callbacks()
|
||||||
{
|
{
|
||||||
Callbacks callbacks = {};
|
return Callbacks{}
|
||||||
callbacks.m_error = [](const char *msg, size_t msg_len, Location location, void *)
|
.set_error_basic([](csubstr msg, yml::ErrorDataBasic const& errdata, void *){
|
||||||
{
|
yml::err_basic_format(dump2stderr, msg, errdata); // LCOV_EXCL_LINE
|
||||||
report_error(msg, msg_len, location, stderr);
|
throwerr(msg); // LCOV_EXCL_LINE
|
||||||
C4_IF_EXCEPTIONS(
|
})
|
||||||
throw std::runtime_error({msg, msg_len});
|
.set_error_parse([](csubstr msg, yml::ErrorDataParse const& errdata, void *){
|
||||||
,
|
yml::err_parse_format(dump2stderr, msg, errdata); // LCOV_EXCL_LINE
|
||||||
jmp_msg.assign(msg, msg_len);
|
throwerr(msg); // LCOV_EXCL_LINE
|
||||||
std::longjmp(jmp_env, 1);
|
})
|
||||||
);
|
.set_error_visit([](csubstr msg, yml::ErrorDataVisit const& errdata, void *){
|
||||||
};
|
yml::err_visit_format(dump2stderr, msg, errdata); // LCOV_EXCL_LINE
|
||||||
return callbacks;
|
throwerr(msg); // LCOV_EXCL_LINE
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user