Argument numbers/names for Ruby too

This commit is contained in:
Matthias Koefferlein 2022-07-30 01:32:27 +02:00
parent 7d078ed041
commit 590c4a6b31
7 changed files with 77 additions and 83 deletions

View File

@ -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);
}
}
// --------------------------------------------------------------------------
/**

View File

@ -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;
/**

View File

@ -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 (...) {

View File

@ -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<void *> (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 ()) {

View File

@ -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<tl::Variant> &a);

View File

@ -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
{

View File

@ -128,8 +128,6 @@ public:
virtual std::string msg () const;
std::string basic_msg () const;
private:
std::string m_sourcefile;
int m_line;