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

View File

@ -115,16 +115,19 @@ ostd::ConstCharRange CsErrorException::save_msg(
GenState *gs = cs.p_pstate;
if (gs) {
/* we can attach line number */
ostd::CharRange r(cs.p_errbuf, cs.p_errbuf + sizeof(cs.p_errbuf));
std::ptrdiff_t sz = -1;
if (!gs->src_name.empty()) {
sz = ostd::format(r, "%s:%d: %s", gs->src_name, 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);
std::size_t sz = 0;
try {
ostd::CharRange r(cs.p_errbuf, cs.p_errbuf + sizeof(cs.p_errbuf));
if (!gs->src_name.empty()) {
sz = ostd::format(r, "%s:%d: %s", gs->src_name, gs->current_line, msg);
} else {
sz = ostd::format(r, "%d: %s", gs->current_line, msg);
}
} 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());
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 {
CsInt i = p_storage;
auto app = ostd::appender<CsString>();
if (!(get_flags() & CsIdfHex) || (i < 0)) {
format(app, IvarFormat, get_name(), i);
} else if (p_maxval == 0xFFFFFF) {
format(
app, IvarHexColorFormat, get_name(),
i, (i >> 16) & 0xFF, (i >> 8) & 0xFF, i & 0xFF
);
} else {
format(app, IvarHexFormat, get_name(), i);
try {
if (!(get_flags() & CsIdfHex) || (i < 0)) {
format(app, IvarFormat, get_name(), i);
} else if (p_maxval == 0xFFFFFF) {
format(
app, IvarHexColorFormat, get_name(),
i, (i >> 16) & 0xFF, (i >> 8) & 0xFF, i & 0xFF
);
} else {
format(app, IvarHexFormat, get_name(), i);
}
} catch (ostd::format_error const &e) {
throw cs_internal_error{e.what()};
}
return std::move(app.get());
}
@ -254,7 +258,13 @@ void CsFvar::set_value(CsFloat val) {
CsString CsFvar::to_printable() const {
CsFloat f = p_storage;
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());
}
@ -268,10 +278,14 @@ void CsSvar::set_value(CsString val) {
CsString CsSvar::to_printable() const {
ostd::ConstCharRange s = p_storage;
auto app = ostd::appender<CsString>();
if (ostd::find(s, '"').empty()) {
format(app, SvarFormat, get_name(), s);
} else {
format(app, SvarQuotedFormat, get_name(), s);
try {
if (ostd::find(s, '"').empty()) {
format(app, SvarFormat, 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());
}
@ -307,13 +321,19 @@ CsState::CsState(CsAllocCb func, void *data):
new_ident(static_cast<char const *>(buf), CsIdfArg);
}
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);
assert(id->get_index() == NumargsIdx);
if (id->get_index() != NumargsIdx) {
throw cs_internal_error{"invalid numargs index"};
}
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) {
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) {
auto r = ostd::appender<CsString>();
ostd::format(
r, "0x%.*X", ostd::max(args[1].get_int(), CsInt(1)),
args[0].get_int()
);
try {
ostd::format(
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()));
});