From 590c4a6b31353fda4f87fb5e6c6b42cd1bb613fa Mon Sep 17 00:00:00 2001 From: Matthias Koefferlein Date: Sat, 30 Jul 2022 01:32:27 +0200 Subject: [PATCH] Argument numbers/names for Ruby too --- src/pya/pya/pya.cc | 17 -------- src/pya/pya/pya.h | 15 ------- src/pya/pya/pyaModule.cc | 11 ++++- src/rba/rba/rba.cc | 89 ++++++++++++++++++++------------------ src/tl/tl/tlException.h | 20 +++++++++ src/tl/tl/tlScriptError.cc | 6 --- src/tl/tl/tlScriptError.h | 2 - 7 files changed, 77 insertions(+), 83 deletions(-) diff --git a/src/pya/pya/pya.cc b/src/pya/pya/pya.cc index 3092eb8e4..15456c0dc 100644 --- a/src/pya/pya/pya.cc +++ b/src/pya/pya/pya.cc @@ -67,23 +67,6 @@ PythonError::PythonError (const PythonError &d) : tl::ScriptError (d) { } -// -------------------------------------------------------------------------- -// PythonArgumentError implementation - -PythonArgumentError::PythonArgumentError (const tl::Exception &ex, int index, const std::string &name) - : tl::Exception (ex.msg ()), m_index (index), m_name (name) -{ } - -std::string -PythonArgumentError::msg () const -{ - if (! m_name.empty ()) { - return tl::sprintf (tl::to_string (tr ("%s for argument #%d ('%s')")), tl::Exception::msg (), m_index + 1, m_name); - } else { - return tl::sprintf (tl::to_string (tr ("%s for argument #%d")), tl::Exception::msg (), m_index + 1); - } -} - // -------------------------------------------------------------------------- /** diff --git a/src/pya/pya/pya.h b/src/pya/pya/pya.h index 11cdcd9f0..fe1337b40 100644 --- a/src/pya/pya/pya.h +++ b/src/pya/pya/pya.h @@ -82,21 +82,6 @@ public: PythonError (const PythonError &d); }; -/** - * @brief A class encapsulating an argument error - */ -class PYA_PUBLIC PythonArgumentError - : public tl::Exception -{ -public: - PythonArgumentError (const tl::Exception &ex, int index, const std::string &name); - virtual std::string msg () const; - -private: - int m_index; - std::string m_name; -}; - class PythonModule; /** diff --git a/src/pya/pya/pyaModule.cc b/src/pya/pya/pyaModule.cc index 37d7dfab0..fc4a7ee29 100644 --- a/src/pya/pya/pyaModule.cc +++ b/src/pya/pya/pyaModule.cc @@ -1195,8 +1195,17 @@ push_args (gsi::SerialArgs &arglist, const gsi::MethodBase *meth, PyObject *args pop_arg (*a, arglist, 0, heap); } + std::string msg; const gsi::ArgSpecBase *arg_spec = meth->begin_arguments () [i].spec (); - throw PythonArgumentError (ex, i, arg_spec ? arg_spec->name () : std::string ()); + + if (arg_spec && ! arg_spec->name ().empty ()) { + msg = tl::sprintf (tl::to_string (tr ("%s for argument #%d ('%s')")), ex.basic_msg (), i + 1, arg_spec->name ()); + } else { + msg = tl::sprintf (tl::to_string (tr ("%s for argument #%d")), ex.basic_msg (), i + 1); + } + + ex.set_basic_msg (msg); + throw ex; } catch (...) { diff --git a/src/rba/rba/rba.cc b/src/rba/rba/rba.cc index 2a0c1b8f5..ab323b222 100644 --- a/src/rba/rba/rba.cc +++ b/src/rba/rba/rba.cc @@ -914,6 +914,51 @@ static gsi::ArgType create_void_type () static gsi::ArgType s_void_type = create_void_type (); +static void +push_args (gsi::SerialArgs &arglist, const gsi::MethodBase *meth, VALUE *argv, int argc, tl::Heap &heap) +{ + int i = 0; + + try { + + VALUE *av = argv; + for (gsi::MethodBase::argument_iterator a = meth->begin_arguments (); a != meth->end_arguments () && av < argv + argc; ++a, ++av, ++i) { + push_arg (*a, arglist, *av, heap); + } + + } catch (tl::Exception &ex) { + + // In case of an error upon write, pop the arguments to clean them up. + // Without this, there is a risk to keep dead objects on the stack. + for (gsi::MethodBase::argument_iterator a = meth->begin_arguments (); a != meth->end_arguments () && arglist; ++a) { + pop_arg (*a, 0, arglist, heap); + } + + const gsi::ArgSpecBase *arg_spec = meth->begin_arguments () [i].spec (); + + std::string msg; + if (arg_spec && ! arg_spec->name ().empty ()) { + msg = tl::sprintf (tl::to_string (tr ("%s for argument #%d ('%s')")), ex.basic_msg (), i + 1, arg_spec->name ()); + } else { + msg = tl::sprintf (tl::to_string (tr ("%s for argument #%d")), ex.basic_msg (), i + 1); + } + + ex.set_basic_msg (msg); + throw ex; + + } catch (...) { + + // In case of an error upon write, pop the arguments to clean them up. + // Without this, there is a risk to keep dead objects on the stack. + for (gsi::MethodBase::argument_iterator a = meth->begin_arguments (); a != meth->end_arguments () && arglist; ++a) { + pop_arg (*a, 0, arglist, heap); + } + + throw; + + } +} + VALUE method_adaptor (int mid, int argc, VALUE *argv, VALUE self, bool ctor) { @@ -991,28 +1036,8 @@ method_adaptor (int mid, int argc, VALUE *argv, VALUE self, bool ctor) { gsi::SerialArgs arglist (meth->argsize ()); - - try { - - VALUE *av = argv; - for (gsi::MethodBase::argument_iterator a = meth->begin_arguments (); a != meth->end_arguments () && av < argv + argc; ++a, ++av) { - push_arg (*a, arglist, *av, heap); - } - - } catch (...) { - - // In case of an error upon write, pop the arguments to clean them up. - // Without this, there is a risk to keep dead objects on the stack. - for (gsi::MethodBase::argument_iterator a = meth->begin_arguments (); a != meth->end_arguments () && arglist; ++a) { - pop_arg (*a, 0, arglist, heap); - } - - throw; - - } - + push_args (arglist, meth, argv, argc, heap); meth->call (0, arglist, retlist); - } void *obj = retlist.read (heap); @@ -1065,28 +1090,8 @@ method_adaptor (int mid, int argc, VALUE *argv, VALUE self, bool ctor) { gsi::SerialArgs arglist (meth->argsize ()); - - try { - - VALUE *av = argv; - for (gsi::MethodBase::argument_iterator a = meth->begin_arguments (); a != meth->end_arguments () && av < argv + argc; ++a, ++av) { - push_arg (*a, arglist, *av, heap); - } - - } catch (...) { - - // In case of an error upon write, pop the arguments to clean them up. - // Without this, there is a risk to keep dead objects on the stack. - for (gsi::MethodBase::argument_iterator a = meth->begin_arguments (); a != meth->end_arguments () && arglist; ++a) { - pop_arg (*a, 0, arglist, heap); - } - - throw; - - } - + push_args (arglist, meth, argv, argc, heap); meth->call (obj, arglist, retlist); - } if (meth->ret_type ().is_iter ()) { diff --git a/src/tl/tl/tlException.h b/src/tl/tl/tlException.h index 4c5181aef..0eb93543f 100644 --- a/src/tl/tl/tlException.h +++ b/src/tl/tl/tlException.h @@ -126,8 +126,28 @@ public: virtual ~Exception () { } + /** + * @brief Gets the full message text + * Derived classes may dynamically build error messages. + * "basic_msg" is the core message. Derived classes may + * ignore the core message or modify the latter to build + * the full message. + */ virtual std::string msg () const { return m_msg; } + /** + * @brief Gets the basic message + * The basic message is the actual error text. Derived classes + * may decide to deliver a more elaborate version of the message + * through "msg". + */ + std::string basic_msg () const { return m_msg; } + + /** + * @brief Exchanges the basic message + */ + void set_basic_msg (const std::string &msg) { m_msg = msg; } + private: std::string m_msg; void init (const std::string &fmt, const std::vector &a); diff --git a/src/tl/tl/tlScriptError.cc b/src/tl/tl/tlScriptError.cc index 39a985833..9444db1d3 100644 --- a/src/tl/tl/tlScriptError.cc +++ b/src/tl/tl/tlScriptError.cc @@ -97,12 +97,6 @@ ScriptError::ScriptError (const ScriptError &d) // .. nothing yet .. } -std::string -ScriptError::basic_msg () const -{ - return tl::Exception::msg (); -} - std::string ScriptError::msg () const { diff --git a/src/tl/tl/tlScriptError.h b/src/tl/tl/tlScriptError.h index 937ce9d23..312dd4a6b 100644 --- a/src/tl/tl/tlScriptError.h +++ b/src/tl/tl/tlScriptError.h @@ -128,8 +128,6 @@ public: virtual std::string msg () const; - std::string basic_msg () const; - private: std::string m_sourcefile; int m_line;