diff --git a/python/pyextension_utils.c b/python/pyextension_utils.c new file mode 100644 index 0000000..e9cf369 --- /dev/null +++ b/python/pyextension_utils.c @@ -0,0 +1,138 @@ +/* +pyextension_utils.c : C extension utilities for Python + +Copyright (C) 2014 Simon D. Levy + +This code is free software: you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +This code is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License +along with this code. If not, see . +*/ + +#include + +static void raise_argument_exception(const char * classname, const char * methodname, const char * details) +{ + char errmsg[1000]; + sprintf(errmsg, "Wrong/insufficient arguments passed to %s.%s()%s %s", + classname, methodname, + details ? ":" : "", details ? details : ""); + PyErr_SetString(PyExc_TypeError, errmsg); + +} + +PyObject * null_on_raise_argument_exception_with_details(const char * classname, const char * methodname, const char * details) +{ + raise_argument_exception(classname, methodname, details); + return NULL; +} + +PyObject *null_on_raise_argument_exception(const char * classname, const char * methodname) +{ + return null_on_raise_argument_exception_with_details(classname, methodname, NULL); +} + +int error_on_raise_argument_exception_with_details(const char * classname, const char * methodname, const char * details) +{ + raise_argument_exception(classname, methodname, details); + return -1; +} + +int error_on_raise_argument_exception(const char * classname) +{ + return error_on_raise_argument_exception_with_details(classname, "__init__", NULL); +} + +int type_is_ready(PyTypeObject * type) +{ + return (PyType_Ready(type) >= 0); +} + + +void add_class(PyObject * module, PyTypeObject * type, const char * classname) +{ + Py_INCREF(type); + PyModule_AddObject(module, classname, (PyObject *)type); + +} + +int double_from_tuple(PyObject * tup, int pos, double * val) +{ + PyObject * py_val = PyTuple_GetItem(tup, pos); + + if (py_val) + { + *val = PyFloat_AsDouble(py_val); + return PyErr_Occurred() ? 0 : 1; + } + + return 0; +} + + +int +double_from_obj( + PyObject * obj, + const char * name, + double * val) +{ + PyObject * attr = PyObject_GetAttrString(obj, name); + + if (!attr) + { + return 0; + } + + *val = PyFloat_AsDouble(attr); + + return 1; +} + + +int +int_from_obj( + PyObject * obj, + const char * name, + int * val) +{ + PyObject * attr = PyObject_GetAttrString(obj, name); + + if (!attr) + { + return 0; + } + + *val = PyLong_AsLong(attr); + + return 1; +} + + +int +error_on_check_argument_type( + PyObject * obj, + PyTypeObject * typ, + int pos, + const char * typname, + const char * classname, + const char *methodname) +{ + + if (!PyObject_TypeCheck(obj, typ)) + { + char details[200]; + sprintf(details, "argument %d is not of type %s", pos+1, typname); + raise_argument_exception(classname, methodname, details); + return -1; + } + + return 0; +}