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_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) {
|
||||||
|
|
21
src/cs_vm.cc
21
src/cs_vm.cc
|
@ -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());
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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()));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue