From f12197bbe511b044e52dd02d8ff0d7110ab54df5 Mon Sep 17 00:00:00 2001 From: q66 Date: Thu, 15 Sep 2016 21:15:54 +0200 Subject: [PATCH] throw CsErrorException where appropriate (robust error handling everywhere) --- include/cubescript/cubescript.hh | 2 +- src/cs_vm.cc | 6 +-- src/cs_vm.hh | 9 ---- src/cubescript.cc | 80 +++++++++++--------------------- 4 files changed, 30 insertions(+), 67 deletions(-) diff --git a/include/cubescript/cubescript.hh b/include/cubescript/cubescript.hh index ac6f4a0..58b1cdd 100644 --- a/include/cubescript/cubescript.hh +++ b/include/cubescript/cubescript.hh @@ -482,7 +482,7 @@ struct OSTD_EXPORT CsState { CsIdentRange get_idents(); CsConstIdentRange get_idents() const; - bool reset_var(ostd::ConstCharRange name); + void reset_var(ostd::ConstCharRange name); void touch_var(ostd::ConstCharRange name); CsString run_str(CsBytecode *code); diff --git a/src/cs_vm.cc b/src/cs_vm.cc index 8f037a6..9e13d5a 100644 --- a/src/cs_vm.cc +++ b/src/cs_vm.cc @@ -69,7 +69,7 @@ bool CsStackState::gap() const { return p_gap; } -CsStackState cs_save_stack(CsState &cs) { +CsStackState CsErrorException::save_stack(CsState &cs) { CsIvar *dalias = static_cast(cs.p_state->identmap[DbgaliasIdx]); if (!dalias->get_value()) { return CsStackState(cs, nullptr, !!cs.p_callstack); @@ -106,10 +106,6 @@ CsStackState cs_save_stack(CsState &cs) { return CsStackState(cs, ret, total > dalias->get_value()); } -CsStackState CsErrorException::save_stack(CsState &cs) { - return cs_save_stack(cs); -} - ostd::ConstCharRange CsErrorException::save_msg( CsState &cs, ostd::ConstCharRange msg ) { diff --git a/src/cs_vm.hh b/src/cs_vm.hh index 9cdedc4..686c80e 100644 --- a/src/cs_vm.hh +++ b/src/cs_vm.hh @@ -109,15 +109,6 @@ template constexpr ostd::Size CsTypeStorageSize = (sizeof(T) - 1) / sizeof(ostd::Uint32) + 1; -CsStackState cs_save_stack(CsState &cs); - -template -void cs_debug_code(CsState &cs, ostd::ConstCharRange fmt, A &&...args) { - cs.get_err().writefln(fmt, ostd::forward(args)...); - auto st = cs_save_stack(cs); - cscript::util::print_stack(cs.get_err().iter(), st); -} - struct GenState { CsState &cs; CsVector code; diff --git a/src/cubescript.cc b/src/cubescript.cc index 11390e0..58d5240 100644 --- a/src/cubescript.cc +++ b/src/cubescript.cc @@ -470,10 +470,9 @@ CsIdent *CsState::new_ident(ostd::ConstCharRange name, int flags) { CsIdent *id = get_ident(name); if (!id) { if (cs_check_num(name)) { - cs_debug_code( + throw CsErrorException( *this, "number %s is not a valid identifier name", name ); - return p_state->identmap[DummyIdx]; } id = add_ident(create(name, flags)); } @@ -553,17 +552,15 @@ CsSvar *CsState::new_svar( )->get_svar(); } -bool CsState::reset_var(ostd::ConstCharRange name) { +void CsState::reset_var(ostd::ConstCharRange name) { CsIdent *id = get_ident(name); if (!id) { - return false; + throw CsErrorException(*this, "variable %s does not exist", name); } if (id->get_flags() & CsIdfReadOnly) { - cs_debug_code(*this, "variable %s is read only", id->get_name()); - return false; + throw CsErrorException(*this, "variable %s is read only", name); } clear_override(*id); - return true; } void CsState::touch_var(ostd::ConstCharRange name) { @@ -596,14 +593,13 @@ void CsState::set_alias(ostd::ConstCharRange name, CsValue v) { set_var_str_checked(static_cast(id), v.get_str()); break; default: - cs_debug_code( + throw CsErrorException( *this, "cannot redefine builtin %s with an alias", id->get_name() ); - break; } } else if (cs_check_num(name)) { - cs_debug_code(*this, "cannot alias number %s", name); + throw CsErrorException(*this, "cannot alias number %s", name); } else { add_ident(create(name, ostd::move(v), identflags)); } @@ -726,13 +722,12 @@ int CsIdent::get_index() const { } template -static inline bool cs_override_var(CsState &cs, CsVar *v, int &vflags, SF sf) { +static inline void cs_override_var(CsState &cs, CsVar *v, int &vflags, SF sf) { if ((cs.identflags & CsIdfOverridden) || (vflags & CsIdfOverride)) { if (vflags & CsIdfPersist) { - cs_debug_code( + throw CsErrorException( cs, "cannot override persistent variable '%s'", v->get_name() ); - return false; } if (!(vflags & CsIdfOverridden)) { sf(); @@ -743,7 +738,6 @@ static inline bool cs_override_var(CsState &cs, CsVar *v, int &vflags, SF sf) { vflags &= ~CsIdfOverridden; } } - return true; } void CsState::set_var_int( @@ -754,13 +748,10 @@ void CsState::set_var_int( return; } CsIvar *iv = static_cast(id); - bool success = cs_override_var( + cs_override_var( *this, iv, iv->p_flags, [&iv]() { iv->p_overrideval = iv->get_value(); } ); - if (!success) { - return; - } if (doclamp) { iv->set_value(ostd::clamp(v, iv->get_val_min(), iv->get_val_max())); } else { @@ -779,13 +770,10 @@ void CsState::set_var_float( return; } CsFvar *fv = static_cast(id); - bool success = cs_override_var( + cs_override_var( *this, fv, fv->p_flags, [&fv]() { fv->p_overrideval = fv->get_value(); } ); - if (!success) { - return; - } if (doclamp) { fv->set_value(ostd::clamp(v, fv->get_val_min(), fv->get_val_max())); } else { @@ -804,13 +792,10 @@ void CsState::set_var_str( return; } CsSvar *sv = static_cast(id); - bool success = cs_override_var( + cs_override_var( *this, sv, sv->p_flags, [&sv]() { sv->p_overrideval = sv->get_value(); } ); - if (!success) { - return; - } sv->set_value(v); if (dofunc) { sv->changed(*this); @@ -893,7 +878,7 @@ CsInt cs_clamp_var(CsState &cs, CsIvar *iv, CsInt v) { } else { return v; } - cs_debug_code( + throw CsErrorException( cs, (iv->get_flags() & CsIdfHex) ? ( @@ -904,21 +889,18 @@ CsInt cs_clamp_var(CsState &cs, CsIvar *iv, CsInt v) { : "valid range for '%s' is %d..%d", iv->get_name(), iv->get_val_min(), iv->get_val_max() ); - return v; } void CsState::set_var_int_checked(CsIvar *iv, CsInt v) { if (iv->get_flags() & CsIdfReadOnly) { - cs_debug_code(*this, "variable '%s' is read only", iv->get_name()); - return; + throw CsErrorException( + *this, "variable '%s' is read only", iv->get_name() + ); } - bool success = cs_override_var( + cs_override_var( *this, iv, iv->p_flags, [&iv]() { iv->p_overrideval = iv->get_value(); } ); - if (!success) { - return; - } if ((v < iv->get_val_min()) || (v > iv->get_val_max())) { v = cs_clamp_var(*this, iv, v); } @@ -945,7 +927,7 @@ CsFloat cs_clamp_fvar(CsState &cs, CsFvar *fv, CsFloat v) { } else { return v; } - cs_debug_code( + throw CsErrorException( cs, "valid range for '%s' is %s..%s", floatstr(fv->get_val_min()), floatstr(fv->get_val_max()) ); @@ -954,16 +936,14 @@ CsFloat cs_clamp_fvar(CsState &cs, CsFvar *fv, CsFloat v) { void CsState::set_var_float_checked(CsFvar *fv, CsFloat v) { if (fv->get_flags() & CsIdfReadOnly) { - cs_debug_code(*this, "variable '%s' is read only", fv->get_name()); - return; + throw CsErrorException( + *this, "variable '%s' is read only", fv->get_name() + ); } - bool success = cs_override_var( + cs_override_var( *this, fv, fv->p_flags, [&fv]() { fv->p_overrideval = fv->get_value(); } ); - if (!success) { - return; - } if ((v < fv->get_val_min()) || (v > fv->get_val_max())) { v = cs_clamp_fvar(*this, fv, v); } @@ -973,16 +953,14 @@ void CsState::set_var_float_checked(CsFvar *fv, CsFloat v) { void CsState::set_var_str_checked(CsSvar *sv, ostd::ConstCharRange v) { if (sv->get_flags() & CsIdfReadOnly) { - cs_debug_code(*this, "variable '%s' is read only", sv->get_name()); - return; + throw CsErrorException( + *this, "variable '%s' is read only", sv->get_name() + ); } - bool success = cs_override_var( + cs_override_var( *this, sv, sv->p_flags, [&sv]() { sv->p_overrideval = sv->get_value(); } ); - if (!success) { - return; - } sv->set_value(v); sv->changed(*this); } @@ -1124,9 +1102,7 @@ void cs_init_lib_base(CsState &gcs) { } ret.set_int(rc); CsAliasInternal::set_alias(cret, cs, result); - if (css->get_index() != DummyIdx) { - CsAliasInternal::set_alias(css, cs, tback); - } + CsAliasInternal::set_alias(css, cs, tback); }); gcs.new_command("?", "tTT", [](auto &, auto args, auto &res) { @@ -1344,8 +1320,8 @@ end: cs.run(args[2].get_code(), res); }); - gcs.new_command("resetvar", "s", [](auto &cs, auto args, auto &res) { - res.set_int(cs.reset_var(args[0].get_strr())); + gcs.new_command("resetvar", "s", [](auto &cs, auto args, auto &) { + cs.reset_var(args[0].get_strr()); }); gcs.new_command("alias", "sT", [](auto &cs, auto args, auto &) {