add cs_internal_error exception and use it for unrecoverable unlikely errors

master
Daniel Kolesa 2017-02-12 22:52:43 +01:00
parent 6e67ce8574
commit 140ccf08c6
4 changed files with 93 additions and 55 deletions

View File

@ -27,6 +27,10 @@ static_assert(std::is_integral_v<CsInt>, "CsInt must be integral");
static_assert(std::is_signed_v<CsInt>, "CsInt must be signed"); static_assert(std::is_signed_v<CsInt>, "CsInt must be signed");
static_assert(std::is_floating_point_v<CsFloat>, "CsFloat must be floating point"); static_assert(std::is_floating_point_v<CsFloat>, "CsFloat must be floating point");
struct cs_internal_error: public std::runtime_error {
using std::runtime_error::runtime_error;
};
enum { enum {
CsIdfPersist = 1 << 0, CsIdfPersist = 1 << 0,
CsIdfOverride = 1 << 1, CsIdfOverride = 1 << 1,
@ -529,15 +533,15 @@ struct CsErrorException {
CsErrorException(CsState &cs, ostd::ConstCharRange msg, A &&...args): CsErrorException(CsState &cs, ostd::ConstCharRange msg, A &&...args):
p_errmsg(), p_stack(cs) p_errmsg(), p_stack(cs)
{ {
char fbuf[512]; try {
auto ret = ostd::format( char fbuf[512];
ostd::CharRange(fbuf, fbuf + sizeof(fbuf)), msg, auto ret = ostd::format(
std::forward<A>(args)... ostd::CharRange(fbuf, fbuf + sizeof(fbuf)), msg,
); std::forward<A>(args)...
if ((ret < 0) || (size_t(ret) > sizeof(fbuf))) { );
p_errmsg = save_msg(cs, msg);
} else {
p_errmsg = save_msg(cs, ostd::CharRange(fbuf, fbuf + ret)); p_errmsg = save_msg(cs, ostd::CharRange(fbuf, fbuf + ret));
} catch (...) {
p_errmsg = save_msg(cs, msg);
} }
p_stack = save_stack(cs); p_stack = save_stack(cs);
} }
@ -716,16 +720,24 @@ private:
}; };
template<typename R> template<typename R>
inline std::ptrdiff_t format_int(R &&writer, CsInt val) { inline std::size_t format_int(R &&writer, CsInt val) {
return ostd::format(std::forward<R>(writer), IntFormat, val); try {
return ostd::format(std::forward<R>(writer), IntFormat, val);
} catch (ostd::format_error const &e) {
throw cs_internal_error{e.what()};
}
} }
template<typename R> template<typename R>
inline std::ptrdiff_t format_float(R &&writer, CsFloat val) { inline std::size_t format_float(R &&writer, CsFloat val) {
return ostd::format( try {
std::forward<R>(writer), return ostd::format(
(val == CsInt(val)) ? RoundFloatFormat : FloatFormat, val std::forward<R>(writer),
); (val == CsInt(val)) ? RoundFloatFormat : FloatFormat, val
);
} catch (ostd::format_error const &e) {
throw cs_internal_error{e.what()};
}
} }
template<typename R> template<typename R>
@ -778,16 +790,15 @@ private:
size_t ret = 0; size_t ret = 0;
auto nd = st.get(); auto nd = st.get();
while (nd) { while (nd) {
auto rt = ostd::format( try {
writer, ret += ostd::format(
((nd->index == 1) && st.gap()) writer,
? " ..%d) %s" : " %d) %s", ((nd->index == 1) && st.gap())
nd->index, nd->id->get_name() ? " ..%d) %s" : " %d) %s",
); nd->index, nd->id->get_name()
if (rt > 0) { );
ret += size_t(rt); } catch (ostd::format_error const &e) {
} else { throw cs_internal_error{e.what()};
return ret;
} }
nd = nd->next; nd = nd->next;
if (nd) { if (nd) {

View File

@ -115,16 +115,19 @@ ostd::ConstCharRange CsErrorException::save_msg(
GenState *gs = cs.p_pstate; GenState *gs = cs.p_pstate;
if (gs) { if (gs) {
/* we can attach line number */ /* we can attach line number */
ostd::CharRange r(cs.p_errbuf, cs.p_errbuf + sizeof(cs.p_errbuf)); std::size_t sz = 0;
std::ptrdiff_t sz = -1; try {
if (!gs->src_name.empty()) { ostd::CharRange r(cs.p_errbuf, cs.p_errbuf + sizeof(cs.p_errbuf));
sz = ostd::format(r, "%s:%d: %s", gs->src_name, gs->current_line, msg); if (!gs->src_name.empty()) {
} else { sz = ostd::format(r, "%s:%d: %s", gs->src_name, gs->current_line, msg);
sz = ostd::format(r, "%d: %s", gs->current_line, msg); } else {
} sz = ostd::format(r, "%d: %s", gs->current_line, msg);
if (sz > 0) { }
return ostd::ConstCharRange(cs.p_errbuf, cs.p_errbuf + sz); } catch (ostd::format_error const &e) {
memcpy(cs.p_errbuf, msg.data(), msg.size());
sz = msg.size();
} }
return ostd::ConstCharRange(cs.p_errbuf, cs.p_errbuf + sz);
} }
memcpy(cs.p_errbuf, msg.data(), msg.size()); memcpy(cs.p_errbuf, msg.data(), msg.size());
return ostd::ConstCharRange(cs.p_errbuf, cs.p_errbuf + msg.size()); return ostd::ConstCharRange(cs.p_errbuf, cs.p_errbuf + msg.size());

View File

@ -224,15 +224,19 @@ void CsIvar::set_value(CsInt val) {
CsString CsIvar::to_printable() const { CsString CsIvar::to_printable() const {
CsInt i = p_storage; CsInt i = p_storage;
auto app = ostd::appender<CsString>(); auto app = ostd::appender<CsString>();
if (!(get_flags() & CsIdfHex) || (i < 0)) { try {
format(app, IvarFormat, get_name(), i); if (!(get_flags() & CsIdfHex) || (i < 0)) {
} else if (p_maxval == 0xFFFFFF) { format(app, IvarFormat, get_name(), i);
format( } else if (p_maxval == 0xFFFFFF) {
app, IvarHexColorFormat, get_name(), format(
i, (i >> 16) & 0xFF, (i >> 8) & 0xFF, i & 0xFF app, IvarHexColorFormat, get_name(),
); i, (i >> 16) & 0xFF, (i >> 8) & 0xFF, i & 0xFF
} else { );
format(app, IvarHexFormat, get_name(), i); } else {
format(app, IvarHexFormat, get_name(), i);
}
} catch (ostd::format_error const &e) {
throw cs_internal_error{e.what()};
} }
return std::move(app.get()); return std::move(app.get());
} }
@ -254,7 +258,13 @@ void CsFvar::set_value(CsFloat val) {
CsString CsFvar::to_printable() const { CsString CsFvar::to_printable() const {
CsFloat f = p_storage; CsFloat f = p_storage;
auto app = ostd::appender<CsString>(); auto app = ostd::appender<CsString>();
format(app, (f == CsInt(f)) ? FvarRoundFormat : FvarFormat, get_name(), f); try {
format(
app, (f == CsInt(f)) ? FvarRoundFormat : FvarFormat, get_name(), f
);
} catch (ostd::format_error const &e) {
throw cs_internal_error{e.what()};
}
return std::move(app.get()); return std::move(app.get());
} }
@ -268,10 +278,14 @@ void CsSvar::set_value(CsString val) {
CsString CsSvar::to_printable() const { CsString CsSvar::to_printable() const {
ostd::ConstCharRange s = p_storage; ostd::ConstCharRange s = p_storage;
auto app = ostd::appender<CsString>(); auto app = ostd::appender<CsString>();
if (ostd::find(s, '"').empty()) { try {
format(app, SvarFormat, get_name(), s); if (ostd::find(s, '"').empty()) {
} else { format(app, SvarFormat, get_name(), s);
format(app, SvarQuotedFormat, get_name(), s); } else {
format(app, SvarQuotedFormat, get_name(), s);
}
} catch (ostd::format_error const &e) {
throw cs_internal_error{e.what()};
} }
return std::move(app.get()); return std::move(app.get());
} }
@ -307,13 +321,19 @@ CsState::CsState(CsAllocCb func, void *data):
new_ident(static_cast<char const *>(buf), CsIdfArg); new_ident(static_cast<char const *>(buf), CsIdfArg);
} }
CsIdent *id = new_ident("//dummy"); CsIdent *id = new_ident("//dummy");
assert(id->get_index() == DummyIdx); if (id->get_index() != DummyIdx) {
throw cs_internal_error{"invalid dummy index"};
}
id = new_ivar("numargs", MaxArguments, 0, 0); id = new_ivar("numargs", MaxArguments, 0, 0);
assert(id->get_index() == NumargsIdx); if (id->get_index() != NumargsIdx) {
throw cs_internal_error{"invalid numargs index"};
}
id = new_ivar("dbgalias", 0, 1000, 4); id = new_ivar("dbgalias", 0, 1000, 4);
assert(id->get_index() == DbgaliasIdx); if (id->get_index() != DbgaliasIdx) {
throw cs_internal_error{"invalid dbgalias index"};
}
new_command("do", "e", [](auto &cs, auto args, auto &res) { new_command("do", "e", [](auto &cs, auto args, auto &res) {
cs.run(args[0].get_code(), res); cs.run(args[0].get_code(), res);

View File

@ -123,10 +123,14 @@ void cs_init_lib_string(CsState &cs) {
cs.new_command("tohex", "ii", [](auto &, auto args, auto &res) { cs.new_command("tohex", "ii", [](auto &, auto args, auto &res) {
auto r = ostd::appender<CsString>(); auto r = ostd::appender<CsString>();
ostd::format( try {
r, "0x%.*X", ostd::max(args[1].get_int(), CsInt(1)), ostd::format(
args[0].get_int() r, "0x%.*X", ostd::max(args[1].get_int(), CsInt(1)),
); args[0].get_int()
);
} catch (ostd::format_error const &e) {
throw cs_internal_error{e.what()};
}
res.set_str(std::move(r.get())); res.set_str(std::move(r.get()));
}); });