Commit 0d50c2dd authored by Dominik Charousset's avatar Dominik Charousset

Improve to_string output of errors

parent 99d1af2b
......@@ -94,6 +94,12 @@ int main(int argc, char** argv) {
cerr << "enum found outside of a namespace\n";
return EXIT_FAILURE;
}
auto full_namespace = namespaces[0];
for (size_t index = 1; index < namespaces.size(); ++index) {
full_namespace += "::";
full_namespace += namespaces[index];
}
auto full_namespace_prefix = full_namespace + "::";
if (enum_name.empty()) {
cerr << "empty enum name found\n";
return EXIT_FAILURE;
......@@ -115,7 +121,7 @@ int main(int argc, char** argv) {
break;
if (line[0] != '/') {
keep_alnum(line);
enum_values.emplace_back(line);
enum_values.emplace_back(enum_name + "::" + line);
}
}
// Generate output file.
......@@ -137,9 +143,7 @@ int main(int argc, char** argv) {
out << '/' << namespaces[i];
out << '/' << enum_name << ".hpp\"\n\n"
<< "#include <string>\n\n"
<< "namespace " << namespaces[0] << " {\n";
for (size_t i = 1; i < namespaces.size(); ++i)
out << "namespace " << namespaces[i] << " {\n";
<< "namespace " << full_namespace << " {\n";
out << '\n';
// Generate to_string implementation.
out << "std::string to_string(" << enum_name << " x) {\n"
......@@ -147,15 +151,15 @@ int main(int argc, char** argv) {
<< " default:\n"
<< " return \"???\";\n";
for (auto& val : enum_values)
out << " case " << case_label_prefix << val << ":\n"
<< " return \"" << val << "\";\n";
out << " case " << val << ":\n"
<< " return \"" << full_namespace_prefix << val << "\";\n";
out << " };\n"
<< "}\n\n";
// Generate from_string implementation.
out << "bool from_string(string_view in, " << enum_name << "& out) {\n ";
for (auto& val : enum_values)
out << "if (in == \"" << val << "\") {\n"
<< " out = " << case_label_prefix << val << ";\n"
out << "if (in == \"" << full_namespace_prefix << val << "\") {\n"
<< " out = " << val << ";\n"
<< " return true;\n"
<< " } else ";
out << "{\n"
......@@ -170,14 +174,13 @@ int main(int argc, char** argv) {
<< " default:\n"
<< " return false;\n";
for (auto& val : enum_values)
out << " case " << case_label_prefix << val << ":\n";
out << " case " << val << ":\n";
out << " out = result;\n"
<< " return true;\n"
<< " };\n"
<< "}\n\n";
// Done. Print file footer and exit.
for (auto i = namespaces.rbegin(); i != namespaces.rend(); ++i)
out << "} // namespace " << *i << '\n';
out << "} // namespace " << full_namespace << '\n';
out << "\nCAF_POP_WARNINGS\n";
return EXIT_SUCCESS;
}
......@@ -64,15 +64,29 @@ int error::compare(uint8_t code, type_id_t category) const noexcept {
// -- inspection support -----------------------------------------------------
std::string to_string(const error& x) {
using const_void_ptr = const void*;
using const_meta_ptr = const detail::meta_object*;
if (!x)
return "none";
std::string result;
auto append = [&result](const_void_ptr ptr,
const_meta_ptr meta) -> const_void_ptr {
meta->stringify(result, ptr);
return static_cast<const byte*>(ptr) + meta->padded_size;
};
auto code = x.code();
auto mobj = detail::global_meta_object(x.category());
mobj->stringify(result, &code);
auto ctx = x.context();
if (ctx)
result += to_string(ctx);
append(&code, detail::global_meta_object(x.category()));
if (auto& ctx = x.context()) {
result += '(';
auto ptr = static_cast<const_void_ptr>(ctx.cdata().storage());
auto types = ctx.types();
ptr = append(ptr, detail::global_meta_object(types[0]));
for (size_t index = 1; index < types.size(); ++index) {
result += ", ";
ptr = append(ptr, detail::global_meta_object(types[index]));
}
result += ')';
}
return result;
}
......
......@@ -17,47 +17,47 @@ std::string to_string(exit_reason x) {
default:
return "???";
case exit_reason::normal:
return "normal";
return "caf::exit_reason::normal";
case exit_reason::unhandled_exception:
return "unhandled_exception";
return "caf::exit_reason::unhandled_exception";
case exit_reason::unknown:
return "unknown";
return "caf::exit_reason::unknown";
case exit_reason::out_of_workers:
return "out_of_workers";
return "caf::exit_reason::out_of_workers";
case exit_reason::user_shutdown:
return "user_shutdown";
return "caf::exit_reason::user_shutdown";
case exit_reason::kill:
return "kill";
return "caf::exit_reason::kill";
case exit_reason::remote_link_unreachable:
return "remote_link_unreachable";
return "caf::exit_reason::remote_link_unreachable";
case exit_reason::unreachable:
return "unreachable";
return "caf::exit_reason::unreachable";
};
}
bool from_string(string_view in, exit_reason& out) {
if (in == "normal") {
if (in == "caf::exit_reason::normal") {
out = exit_reason::normal;
return true;
} else if (in == "unhandled_exception") {
} else if (in == "caf::exit_reason::unhandled_exception") {
out = exit_reason::unhandled_exception;
return true;
} else if (in == "unknown") {
} else if (in == "caf::exit_reason::unknown") {
out = exit_reason::unknown;
return true;
} else if (in == "out_of_workers") {
} else if (in == "caf::exit_reason::out_of_workers") {
out = exit_reason::out_of_workers;
return true;
} else if (in == "user_shutdown") {
} else if (in == "caf::exit_reason::user_shutdown") {
out = exit_reason::user_shutdown;
return true;
} else if (in == "kill") {
} else if (in == "caf::exit_reason::kill") {
out = exit_reason::kill;
return true;
} else if (in == "remote_link_unreachable") {
} else if (in == "caf::exit_reason::remote_link_unreachable") {
out = exit_reason::remote_link_unreachable;
return true;
} else if (in == "unreachable") {
} else if (in == "caf::exit_reason::unreachable") {
out = exit_reason::unreachable;
return true;
} else {
......
......@@ -10,30 +10,29 @@ CAF_PUSH_DEPRECATED_WARNING
#include <string>
namespace caf {
namespace intrusive {
namespace caf::intrusive {
std::string to_string(inbox_result x) {
switch(x) {
default:
return "???";
case inbox_result::success:
return "success";
return "caf::intrusive::inbox_result::success";
case inbox_result::unblocked_reader:
return "unblocked_reader";
return "caf::intrusive::inbox_result::unblocked_reader";
case inbox_result::queue_closed:
return "queue_closed";
return "caf::intrusive::inbox_result::queue_closed";
};
}
bool from_string(string_view in, inbox_result& out) {
if (in == "success") {
if (in == "caf::intrusive::inbox_result::success") {
out = inbox_result::success;
return true;
} else if (in == "unblocked_reader") {
} else if (in == "caf::intrusive::inbox_result::unblocked_reader") {
out = inbox_result::unblocked_reader;
return true;
} else if (in == "queue_closed") {
} else if (in == "caf::intrusive::inbox_result::queue_closed") {
out = inbox_result::queue_closed;
return true;
} else {
......@@ -55,7 +54,6 @@ bool from_integer(std::underlying_type_t<inbox_result> in,
};
}
} // namespace intrusive
} // namespace caf
} // namespace caf::intrusive
CAF_POP_WARNINGS
......@@ -10,35 +10,34 @@ CAF_PUSH_DEPRECATED_WARNING
#include <string>
namespace caf {
namespace intrusive {
namespace caf::intrusive {
std::string to_string(task_result x) {
switch(x) {
default:
return "???";
case task_result::resume:
return "resume";
return "caf::intrusive::task_result::resume";
case task_result::skip:
return "skip";
return "caf::intrusive::task_result::skip";
case task_result::stop:
return "stop";
return "caf::intrusive::task_result::stop";
case task_result::stop_all:
return "stop_all";
return "caf::intrusive::task_result::stop_all";
};
}
bool from_string(string_view in, task_result& out) {
if (in == "resume") {
if (in == "caf::intrusive::task_result::resume") {
out = task_result::resume;
return true;
} else if (in == "skip") {
} else if (in == "caf::intrusive::task_result::skip") {
out = task_result::skip;
return true;
} else if (in == "stop") {
} else if (in == "caf::intrusive::task_result::stop") {
out = task_result::stop;
return true;
} else if (in == "stop_all") {
} else if (in == "caf::intrusive::task_result::stop_all") {
out = task_result::stop_all;
return true;
} else {
......@@ -61,7 +60,6 @@ bool from_integer(std::underlying_type_t<task_result> in,
};
}
} // namespace intrusive
} // namespace caf
} // namespace caf::intrusive
CAF_POP_WARNINGS
......@@ -17,22 +17,22 @@ std::string to_string(invoke_message_result x) {
default:
return "???";
case invoke_message_result::consumed:
return "consumed";
return "caf::invoke_message_result::consumed";
case invoke_message_result::skipped:
return "skipped";
return "caf::invoke_message_result::skipped";
case invoke_message_result::dropped:
return "dropped";
return "caf::invoke_message_result::dropped";
};
}
bool from_string(string_view in, invoke_message_result& out) {
if (in == "consumed") {
if (in == "caf::invoke_message_result::consumed") {
out = invoke_message_result::consumed;
return true;
} else if (in == "skipped") {
} else if (in == "caf::invoke_message_result::skipped") {
out = invoke_message_result::skipped;
return true;
} else if (in == "dropped") {
} else if (in == "caf::invoke_message_result::dropped") {
out = invoke_message_result::dropped;
return true;
} else {
......
......@@ -17,17 +17,17 @@ std::string to_string(message_priority x) {
default:
return "???";
case message_priority::high:
return "high";
return "caf::message_priority::high";
case message_priority::normal:
return "normal";
return "caf::message_priority::normal";
};
}
bool from_string(string_view in, message_priority& out) {
if (in == "high") {
if (in == "caf::message_priority::high") {
out = message_priority::high;
return true;
} else if (in == "normal") {
} else if (in == "caf::message_priority::normal") {
out = message_priority::normal;
return true;
} else {
......
......@@ -17,122 +17,122 @@ std::string to_string(pec x) {
default:
return "???";
case pec::success:
return "success";
return "caf::pec::success";
case pec::trailing_character:
return "trailing_character";
return "caf::pec::trailing_character";
case pec::unexpected_eof:
return "unexpected_eof";
return "caf::pec::unexpected_eof";
case pec::unexpected_character:
return "unexpected_character";
return "caf::pec::unexpected_character";
case pec::timespan_overflow:
return "timespan_overflow";
return "caf::pec::timespan_overflow";
case pec::fractional_timespan:
return "fractional_timespan";
return "caf::pec::fractional_timespan";
case pec::too_many_characters:
return "too_many_characters";
return "caf::pec::too_many_characters";
case pec::invalid_escape_sequence:
return "invalid_escape_sequence";
return "caf::pec::invalid_escape_sequence";
case pec::unexpected_newline:
return "unexpected_newline";
return "caf::pec::unexpected_newline";
case pec::integer_overflow:
return "integer_overflow";
return "caf::pec::integer_overflow";
case pec::integer_underflow:
return "integer_underflow";
return "caf::pec::integer_underflow";
case pec::exponent_underflow:
return "exponent_underflow";
return "caf::pec::exponent_underflow";
case pec::exponent_overflow:
return "exponent_overflow";
return "caf::pec::exponent_overflow";
case pec::type_mismatch:
return "type_mismatch";
return "caf::pec::type_mismatch";
case pec::not_an_option:
return "not_an_option";
return "caf::pec::not_an_option";
case pec::invalid_argument:
return "invalid_argument";
return "caf::pec::invalid_argument";
case pec::missing_argument:
return "missing_argument";
return "caf::pec::missing_argument";
case pec::invalid_category:
return "invalid_category";
return "caf::pec::invalid_category";
case pec::invalid_field_name:
return "invalid_field_name";
return "caf::pec::invalid_field_name";
case pec::repeated_field_name:
return "repeated_field_name";
return "caf::pec::repeated_field_name";
case pec::missing_field:
return "missing_field";
return "caf::pec::missing_field";
case pec::invalid_range_expression:
return "invalid_range_expression";
return "caf::pec::invalid_range_expression";
case pec::invalid_state:
return "invalid_state";
return "caf::pec::invalid_state";
};
}
bool from_string(string_view in, pec& out) {
if (in == "success") {
if (in == "caf::pec::success") {
out = pec::success;
return true;
} else if (in == "trailing_character") {
} else if (in == "caf::pec::trailing_character") {
out = pec::trailing_character;
return true;
} else if (in == "unexpected_eof") {
} else if (in == "caf::pec::unexpected_eof") {
out = pec::unexpected_eof;
return true;
} else if (in == "unexpected_character") {
} else if (in == "caf::pec::unexpected_character") {
out = pec::unexpected_character;
return true;
} else if (in == "timespan_overflow") {
} else if (in == "caf::pec::timespan_overflow") {
out = pec::timespan_overflow;
return true;
} else if (in == "fractional_timespan") {
} else if (in == "caf::pec::fractional_timespan") {
out = pec::fractional_timespan;
return true;
} else if (in == "too_many_characters") {
} else if (in == "caf::pec::too_many_characters") {
out = pec::too_many_characters;
return true;
} else if (in == "invalid_escape_sequence") {
} else if (in == "caf::pec::invalid_escape_sequence") {
out = pec::invalid_escape_sequence;
return true;
} else if (in == "unexpected_newline") {
} else if (in == "caf::pec::unexpected_newline") {
out = pec::unexpected_newline;
return true;
} else if (in == "integer_overflow") {
} else if (in == "caf::pec::integer_overflow") {
out = pec::integer_overflow;
return true;
} else if (in == "integer_underflow") {
} else if (in == "caf::pec::integer_underflow") {
out = pec::integer_underflow;
return true;
} else if (in == "exponent_underflow") {
} else if (in == "caf::pec::exponent_underflow") {
out = pec::exponent_underflow;
return true;
} else if (in == "exponent_overflow") {
} else if (in == "caf::pec::exponent_overflow") {
out = pec::exponent_overflow;
return true;
} else if (in == "type_mismatch") {
} else if (in == "caf::pec::type_mismatch") {
out = pec::type_mismatch;
return true;
} else if (in == "not_an_option") {
} else if (in == "caf::pec::not_an_option") {
out = pec::not_an_option;
return true;
} else if (in == "invalid_argument") {
} else if (in == "caf::pec::invalid_argument") {
out = pec::invalid_argument;
return true;
} else if (in == "missing_argument") {
} else if (in == "caf::pec::missing_argument") {
out = pec::missing_argument;
return true;
} else if (in == "invalid_category") {
} else if (in == "caf::pec::invalid_category") {
out = pec::invalid_category;
return true;
} else if (in == "invalid_field_name") {
} else if (in == "caf::pec::invalid_field_name") {
out = pec::invalid_field_name;
return true;
} else if (in == "repeated_field_name") {
} else if (in == "caf::pec::repeated_field_name") {
out = pec::repeated_field_name;
return true;
} else if (in == "missing_field") {
} else if (in == "caf::pec::missing_field") {
out = pec::missing_field;
return true;
} else if (in == "invalid_range_expression") {
} else if (in == "caf::pec::invalid_range_expression") {
out = pec::invalid_range_expression;
return true;
} else if (in == "invalid_state") {
} else if (in == "caf::pec::invalid_state") {
out = pec::invalid_state;
return true;
} else {
......
This diff is collapsed.
......@@ -17,32 +17,32 @@ std::string to_string(stream_priority x) {
default:
return "???";
case stream_priority::very_high:
return "very_high";
return "caf::stream_priority::very_high";
case stream_priority::high:
return "high";
return "caf::stream_priority::high";
case stream_priority::normal:
return "normal";
return "caf::stream_priority::normal";
case stream_priority::low:
return "low";
return "caf::stream_priority::low";
case stream_priority::very_low:
return "very_low";
return "caf::stream_priority::very_low";
};
}
bool from_string(string_view in, stream_priority& out) {
if (in == "very_high") {
if (in == "caf::stream_priority::very_high") {
out = stream_priority::very_high;
return true;
} else if (in == "high") {
} else if (in == "caf::stream_priority::high") {
out = stream_priority::high;
return true;
} else if (in == "normal") {
} else if (in == "caf::stream_priority::normal") {
out = stream_priority::normal;
return true;
} else if (in == "low") {
} else if (in == "caf::stream_priority::low") {
out = stream_priority::low;
return true;
} else if (in == "very_low") {
} else if (in == "caf::stream_priority::very_low") {
out = stream_priority::very_low;
return true;
} else {
......
......@@ -18,6 +18,16 @@ namespace {
using string_list = std::vector<std::string>;
std::string short_string(invoke_message_result result) {
auto str = to_string(result);
string_list components;
split(components, str, "::", false);
if (components.empty())
return str;
else
return std::move(components.back());
}
struct recorder : actor_profiler {
void add_actor(const local_actor& self, const local_actor* parent) override {
log.emplace_back("new: ");
......@@ -47,7 +57,7 @@ struct recorder : actor_profiler {
log.emplace_back(self.name());
auto& str = log.back();
str += " ";
str += to_string(result);
str += short_string(result);
str += " the message";
}
......
......@@ -12,22 +12,47 @@ using namespace caf;
CAF_TEST(default constructed errors evaluate to false) {
error err;
CAF_CHECK(!err);
CHECK(!err);
}
CAF_TEST(error code zero is not an error) {
CAF_CHECK(!error(sec::none));
CAF_CHECK(!make_error(sec::none));
CAF_CHECK(!error{error_code<sec>(sec::none)});
CHECK(!error(sec::none));
CHECK(!make_error(sec::none));
CHECK(!error{error_code<sec>(sec::none)});
}
CAF_TEST(error codes that are not zero are errors) {
CAF_CHECK(error(sec::unexpected_message));
CAF_CHECK(make_error(sec::unexpected_message));
CAF_CHECK(error{error_code<sec>(sec::unexpected_message)});
CHECK(error(sec::unexpected_message));
CHECK(make_error(sec::unexpected_message));
CHECK(error{error_code<sec>(sec::unexpected_message)});
}
CAF_TEST(errors convert enums to their integer value) {
CAF_CHECK_EQUAL(make_error(sec::unexpected_message).code(), 1u);
CAF_CHECK_EQUAL(error{error_code<sec>(sec::unexpected_message)}.code(), 1u);
CHECK_EQ(make_error(sec::unexpected_message).code(), 1u);
CHECK_EQ(error{error_code<sec>(sec::unexpected_message)}.code(), 1u);
}
SCENARIO("errors provide human-readable to_string output") {
auto err_str = [](auto... xs) {
return to_string(make_error(std::move(xs)...));
};
GIVEN("an error object") {
WHEN("converting an error without context to a string") {
THEN("the output is only the error code") {
CHECK_EQ(err_str(sec::invalid_argument), "caf::sec::invalid_argument");
}
}
WHEN("converting an error with a context containing one element") {
THEN("the output is the error code plus the context") {
CHECK_EQ(err_str(sec::invalid_argument, "foo is not bar"),
R"_(caf::sec::invalid_argument("foo is not bar"))_");
}
}
WHEN("converting an error with a context containing two or more elements") {
THEN("the output is the error code plus all elements in the context") {
CHECK_EQ(err_str(sec::invalid_argument, "want foo", "got bar"),
R"_(caf::sec::invalid_argument("want foo", "got bar"))_");
}
}
}
}
......@@ -10,51 +10,49 @@ CAF_PUSH_DEPRECATED_WARNING
#include <string>
namespace caf {
namespace io {
namespace basp {
namespace caf::io::basp {
std::string to_string(message_type x) {
switch(x) {
default:
return "???";
case message_type::server_handshake:
return "server_handshake";
return "caf::io::basp::message_type::server_handshake";
case message_type::client_handshake:
return "client_handshake";
return "caf::io::basp::message_type::client_handshake";
case message_type::direct_message:
return "direct_message";
return "caf::io::basp::message_type::direct_message";
case message_type::routed_message:
return "routed_message";
return "caf::io::basp::message_type::routed_message";
case message_type::monitor_message:
return "monitor_message";
return "caf::io::basp::message_type::monitor_message";
case message_type::down_message:
return "down_message";
return "caf::io::basp::message_type::down_message";
case message_type::heartbeat:
return "heartbeat";
return "caf::io::basp::message_type::heartbeat";
};
}
bool from_string(string_view in, message_type& out) {
if (in == "server_handshake") {
if (in == "caf::io::basp::message_type::server_handshake") {
out = message_type::server_handshake;
return true;
} else if (in == "client_handshake") {
} else if (in == "caf::io::basp::message_type::client_handshake") {
out = message_type::client_handshake;
return true;
} else if (in == "direct_message") {
} else if (in == "caf::io::basp::message_type::direct_message") {
out = message_type::direct_message;
return true;
} else if (in == "routed_message") {
} else if (in == "caf::io::basp::message_type::routed_message") {
out = message_type::routed_message;
return true;
} else if (in == "monitor_message") {
} else if (in == "caf::io::basp::message_type::monitor_message") {
out = message_type::monitor_message;
return true;
} else if (in == "down_message") {
} else if (in == "caf::io::basp::message_type::down_message") {
out = message_type::down_message;
return true;
} else if (in == "heartbeat") {
} else if (in == "caf::io::basp::message_type::heartbeat") {
out = message_type::heartbeat;
return true;
} else {
......@@ -80,8 +78,6 @@ bool from_integer(std::underlying_type_t<message_type> in,
};
}
} // namespace basp
} // namespace io
} // namespace caf
} // namespace caf::io::basp
CAF_POP_WARNINGS
......@@ -10,31 +10,29 @@ CAF_PUSH_DEPRECATED_WARNING
#include <string>
namespace caf {
namespace io {
namespace network {
namespace caf::io::network {
std::string to_string(operation x) {
switch(x) {
default:
return "???";
case operation::read:
return "read";
return "caf::io::network::operation::read";
case operation::write:
return "write";
return "caf::io::network::operation::write";
case operation::propagate_error:
return "propagate_error";
return "caf::io::network::operation::propagate_error";
};
}
bool from_string(string_view in, operation& out) {
if (in == "read") {
if (in == "caf::io::network::operation::read") {
out = operation::read;
return true;
} else if (in == "write") {
} else if (in == "caf::io::network::operation::write") {
out = operation::write;
return true;
} else if (in == "propagate_error") {
} else if (in == "caf::io::network::operation::propagate_error") {
out = operation::propagate_error;
return true;
} else {
......@@ -56,8 +54,6 @@ bool from_integer(std::underlying_type_t<operation> in,
};
}
} // namespace network
} // namespace io
} // namespace caf
} // namespace caf::io::network
CAF_POP_WARNINGS
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment