forked from OctaForge/libcubescript
add cs_internal_error exception and use it for unrecoverable unlikely errors
parent
6e67ce8574
commit
140ccf08c6
|
@ -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) {
|
||||
|
|
21
src/cs_vm.cc
21
src/cs_vm.cc
|
@ -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());
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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()));
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in New Issue