| /* Module support implementation */ | |
| #include "Python.h" | |
| #define FLAG_SIZE_T 1 | |
| typedef double va_double; | |
| static PyObject *va_build_value(const char *, va_list, int); | |
| /* Package context -- the full module name for package imports */ | |
| char *_Py_PackageContext = NULL; | |
| /* Py_InitModule4() parameters: | |
| - name is the module name | |
| - methods is the list of top-level functions | |
| - doc is the documentation string | |
| - passthrough is passed as self to functions defined in the module | |
| - api_version is the value of PYTHON_API_VERSION at the time the | |
| module was compiled | |
| Return value is a borrowed reference to the module object; or NULL | |
| if an error occurred (in Python 1.4 and before, errors were fatal). | |
| Errors may still leak memory. | |
| */ | |
| static char api_version_warning[] = | |
| "Python C API version mismatch for module %.100s:\ | |
| This Python has API version %d, module %.100s has version %d."; | |
| PyObject * | |
| Py_InitModule4(const char *name, PyMethodDef *methods, const char *doc, | |
| PyObject *passthrough, int module_api_version) | |
| { | |
| PyObject *m, *d, *v, *n; | |
| PyMethodDef *ml; | |
| PyInterpreterState *interp = PyThreadState_Get()->interp; | |
| if (interp->modules == NULL) | |
| Py_FatalError("Python import machinery not initialized"); | |
| if (module_api_version != PYTHON_API_VERSION) { | |
| char message[512]; | |
| PyOS_snprintf(message, sizeof(message), | |
| api_version_warning, name, | |
| PYTHON_API_VERSION, name, | |
| module_api_version); | |
| if (PyErr_Warn(PyExc_RuntimeWarning, message)) | |
| return NULL; | |
| } | |
| /* Make sure name is fully qualified. | |
| This is a bit of a hack: when the shared library is loaded, | |
| the module name is "package.module", but the module calls | |
| Py_InitModule*() with just "module" for the name. The shared | |
| library loader squirrels away the true name of the module in | |
| _Py_PackageContext, and Py_InitModule*() will substitute this | |
| (if the name actually matches). | |
| */ | |
| if (_Py_PackageContext != NULL) { | |
| char *p = strrchr(_Py_PackageContext, '.'); | |
| if (p != NULL && strcmp(name, p+1) == 0) { | |
| name = _Py_PackageContext; | |
| _Py_PackageContext = NULL; | |
| } | |
| } | |
| if ((m = PyImport_AddModule(name)) == NULL) | |
| return NULL; | |
| d = PyModule_GetDict(m); | |
| if (methods != NULL) { | |
| n = PyString_FromString(name); | |
| if (n == NULL) | |
| return NULL; | |
| for (ml = methods; ml->ml_name != NULL; ml++) { | |
| if ((ml->ml_flags & METH_CLASS) || | |
| (ml->ml_flags & METH_STATIC)) { | |
| PyErr_SetString(PyExc_ValueError, | |
| "module functions cannot set" | |
| " METH_CLASS or METH_STATIC"); | |
| Py_DECREF(n); | |
| return NULL; | |
| } | |
| v = PyCFunction_NewEx(ml, passthrough, n); | |
| if (v == NULL) { | |
| Py_DECREF(n); | |
| return NULL; | |
| } | |
| if (PyDict_SetItemString(d, ml->ml_name, v) != 0) { | |
| Py_DECREF(v); | |
| Py_DECREF(n); | |
| return NULL; | |
| } | |
| Py_DECREF(v); | |
| } | |
| Py_DECREF(n); | |
| } | |
| if (doc != NULL) { | |
| v = PyString_FromString(doc); | |
| if (v == NULL || PyDict_SetItemString(d, "__doc__", v) != 0) { | |
| Py_XDECREF(v); | |
| return NULL; | |
| } | |
| Py_DECREF(v); | |
| } | |
| return m; | |
| } | |
| /* Helper for mkvalue() to scan the length of a format */ | |
| static int | |
| countformat(const char *format, int endchar) | |
| { | |
| int count = 0; | |
| int level = 0; | |
| while (level > 0 || *format != endchar) { | |
| switch (*format) { | |
| case '\0': | |
| /* Premature end */ | |
| PyErr_SetString(PyExc_SystemError, | |
| "unmatched paren in format"); | |
| return -1; | |
| case '(': | |
| case '[': | |
| case '{': | |
| if (level == 0) | |
| count++; | |
| level++; | |
| break; | |
| case ')': | |
| case ']': | |
| case '}': | |
| level--; | |
| break; | |
| case '#': | |
| case '&': | |
| case ',': | |
| case ':': | |
| case ' ': | |
| case '\t': | |
| break; | |
| default: | |
| if (level == 0) | |
| count++; | |
| } | |
| format++; | |
| } | |
| return count; | |
| } | |
| /* Generic function to create a value -- the inverse of getargs() */ | |
| /* After an original idea and first implementation by Steven Miale */ | |
| static PyObject *do_mktuple(const char**, va_list *, int, int, int); | |
| static PyObject *do_mklist(const char**, va_list *, int, int, int); | |
| static PyObject *do_mkdict(const char**, va_list *, int, int, int); | |
| static PyObject *do_mkvalue(const char**, va_list *, int); | |
| static PyObject * | |
| do_mkdict(const char **p_format, va_list *p_va, int endchar, int n, int flags) | |
| { | |
| PyObject *d; | |
| int i; | |
| int itemfailed = 0; | |
| if (n < 0) | |
| return NULL; | |
| if ((d = PyDict_New()) == NULL) | |
| return NULL; | |
| /* Note that we can't bail immediately on error as this will leak | |
| refcounts on any 'N' arguments. */ | |
| for (i = 0; i < n; i+= 2) { | |
| PyObject *k, *v; | |
| int err; | |
| k = do_mkvalue(p_format, p_va, flags); | |
| if (k == NULL) { | |
| itemfailed = 1; | |
| Py_INCREF(Py_None); | |
| k = Py_None; | |
| } | |
| v = do_mkvalue(p_format, p_va, flags); | |
| if (v == NULL) { | |
| itemfailed = 1; | |
| Py_INCREF(Py_None); | |
| v = Py_None; | |
| } | |
| err = PyDict_SetItem(d, k, v); | |
| Py_DECREF(k); | |
| Py_DECREF(v); | |
| if (err < 0 || itemfailed) { | |
| Py_DECREF(d); | |
| return NULL; | |
| } | |
| } | |
| if (d != NULL && **p_format != endchar) { | |
| Py_DECREF(d); | |
| d = NULL; | |
| PyErr_SetString(PyExc_SystemError, | |
| "Unmatched paren in format"); | |
| } | |
| else if (endchar) | |
| ++*p_format; | |
| return d; | |
| } | |
| static PyObject * | |
| do_mklist(const char **p_format, va_list *p_va, int endchar, int n, int flags) | |
| { | |
| PyObject *v; | |
| int i; | |
| int itemfailed = 0; | |
| if (n < 0) | |
| return NULL; | |
| v = PyList_New(n); | |
| if (v == NULL) | |
| return NULL; | |
| /* Note that we can't bail immediately on error as this will leak | |
| refcounts on any 'N' arguments. */ | |
| for (i = 0; i < n; i++) { | |
| PyObject *w = do_mkvalue(p_format, p_va, flags); | |
| if (w == NULL) { | |
| itemfailed = 1; | |
| Py_INCREF(Py_None); | |
| w = Py_None; | |
| } | |
| PyList_SET_ITEM(v, i, w); | |
| } | |
| if (itemfailed) { | |
| /* do_mkvalue() should have already set an error */ | |
| Py_DECREF(v); | |
| return NULL; | |
| } | |
| if (**p_format != endchar) { | |
| Py_DECREF(v); | |
| PyErr_SetString(PyExc_SystemError, | |
| "Unmatched paren in format"); | |
| return NULL; | |
| } | |
| if (endchar) | |
| ++*p_format; | |
| return v; | |
| } | |
| #ifdef Py_USING_UNICODE | |
| static int | |
| _ustrlen(Py_UNICODE *u) | |
| { | |
| int i = 0; | |
| Py_UNICODE *v = u; | |
| while (*v != 0) { i++; v++; } | |
| return i; | |
| } | |
| #endif | |
| static PyObject * | |
| do_mktuple(const char **p_format, va_list *p_va, int endchar, int n, int flags) | |
| { | |
| PyObject *v; | |
| int i; | |
| int itemfailed = 0; | |
| if (n < 0) | |
| return NULL; | |
| if ((v = PyTuple_New(n)) == NULL) | |
| return NULL; | |
| /* Note that we can't bail immediately on error as this will leak | |
| refcounts on any 'N' arguments. */ | |
| for (i = 0; i < n; i++) { | |
| PyObject *w = do_mkvalue(p_format, p_va, flags); | |
| if (w == NULL) { | |
| itemfailed = 1; | |
| Py_INCREF(Py_None); | |
| w = Py_None; | |
| } | |
| PyTuple_SET_ITEM(v, i, w); | |
| } | |
| if (itemfailed) { | |
| /* do_mkvalue() should have already set an error */ | |
| Py_DECREF(v); | |
| return NULL; | |
| } | |
| if (**p_format != endchar) { | |
| Py_DECREF(v); | |
| PyErr_SetString(PyExc_SystemError, | |
| "Unmatched paren in format"); | |
| return NULL; | |
| } | |
| if (endchar) | |
| ++*p_format; | |
| return v; | |
| } | |
| static PyObject * | |
| do_mkvalue(const char **p_format, va_list *p_va, int flags) | |
| { | |
| for (;;) { | |
| switch (*(*p_format)++) { | |
| case '(': | |
| return do_mktuple(p_format, p_va, ')', | |
| countformat(*p_format, ')'), flags); | |
| case '[': | |
| return do_mklist(p_format, p_va, ']', | |
| countformat(*p_format, ']'), flags); | |
| case '{': | |
| return do_mkdict(p_format, p_va, '}', | |
| countformat(*p_format, '}'), flags); | |
| case 'b': | |
| case 'B': | |
| case 'h': | |
| case 'i': | |
| return PyInt_FromLong((long)va_arg(*p_va, int)); | |
| case 'H': | |
| return PyInt_FromLong((long)va_arg(*p_va, unsigned int)); | |
| case 'I': | |
| { | |
| unsigned int n; | |
| n = va_arg(*p_va, unsigned int); | |
| if (n > (unsigned long)PyInt_GetMax()) | |
| return PyLong_FromUnsignedLong((unsigned long)n); | |
| else | |
| return PyInt_FromLong(n); | |
| } | |
| case 'n': | |
| #if SIZEOF_SIZE_T!=SIZEOF_LONG | |
| return PyInt_FromSsize_t(va_arg(*p_va, Py_ssize_t)); | |
| #endif | |
| /* Fall through from 'n' to 'l' if Py_ssize_t is long */ | |
| case 'l': | |
| return PyInt_FromLong(va_arg(*p_va, long)); | |
| case 'k': | |
| { | |
| unsigned long n; | |
| n = va_arg(*p_va, unsigned long); | |
| if (n > (unsigned long)PyInt_GetMax()) | |
| return PyLong_FromUnsignedLong(n); | |
| else | |
| return PyInt_FromLong(n); | |
| } | |
| #ifdef HAVE_LONG_LONG | |
| case 'L': | |
| return PyLong_FromLongLong((PY_LONG_LONG)va_arg(*p_va, PY_LONG_LONG)); | |
| case 'K': | |
| return PyLong_FromUnsignedLongLong((PY_LONG_LONG)va_arg(*p_va, unsigned PY_LONG_LONG)); | |
| #endif | |
| #ifdef Py_USING_UNICODE | |
| case 'u': | |
| { | |
| PyObject *v; | |
| Py_UNICODE *u = va_arg(*p_va, Py_UNICODE *); | |
| Py_ssize_t n; | |
| if (**p_format == '#') { | |
| ++*p_format; | |
| if (flags & FLAG_SIZE_T) | |
| n = va_arg(*p_va, Py_ssize_t); | |
| else | |
| n = va_arg(*p_va, int); | |
| } | |
| else | |
| n = -1; | |
| if (u == NULL) { | |
| v = Py_None; | |
| Py_INCREF(v); | |
| } | |
| else { | |
| if (n < 0) | |
| n = _ustrlen(u); | |
| v = PyUnicode_FromUnicode(u, n); | |
| } | |
| return v; | |
| } | |
| #endif | |
| case 'f': | |
| case 'd': | |
| return PyFloat_FromDouble( | |
| (double)va_arg(*p_va, va_double)); | |
| #ifndef WITHOUT_COMPLEX | |
| case 'D': | |
| return PyComplex_FromCComplex( | |
| *((Py_complex *)va_arg(*p_va, Py_complex *))); | |
| #endif /* WITHOUT_COMPLEX */ | |
| case 'c': | |
| { | |
| char p[1]; | |
| p[0] = (char)va_arg(*p_va, int); | |
| return PyString_FromStringAndSize(p, 1); | |
| } | |
| case 's': | |
| case 'z': | |
| { | |
| PyObject *v; | |
| char *str = va_arg(*p_va, char *); | |
| Py_ssize_t n; | |
| if (**p_format == '#') { | |
| ++*p_format; | |
| if (flags & FLAG_SIZE_T) | |
| n = va_arg(*p_va, Py_ssize_t); | |
| else | |
| n = va_arg(*p_va, int); | |
| } | |
| else | |
| n = -1; | |
| if (str == NULL) { | |
| v = Py_None; | |
| Py_INCREF(v); | |
| } | |
| else { | |
| if (n < 0) { | |
| size_t m = strlen(str); | |
| if (m > PY_SSIZE_T_MAX) { | |
| PyErr_SetString(PyExc_OverflowError, | |
| "string too long for Python string"); | |
| return NULL; | |
| } | |
| n = (Py_ssize_t)m; | |
| } | |
| v = PyString_FromStringAndSize(str, n); | |
| } | |
| return v; | |
| } | |
| case 'N': | |
| case 'S': | |
| case 'O': | |
| if (**p_format == '&') { | |
| typedef PyObject *(*converter)(void *); | |
| converter func = va_arg(*p_va, converter); | |
| void *arg = va_arg(*p_va, void *); | |
| ++*p_format; | |
| return (*func)(arg); | |
| } | |
| else { | |
| PyObject *v; | |
| v = va_arg(*p_va, PyObject *); | |
| if (v != NULL) { | |
| if (*(*p_format - 1) != 'N') | |
| Py_INCREF(v); | |
| } | |
| else if (!PyErr_Occurred()) | |
| /* If a NULL was passed | |
| * because a call that should | |
| * have constructed a value | |
| * failed, that's OK, and we | |
| * pass the error on; but if | |
| * no error occurred it's not | |
| * clear that the caller knew | |
| * what she was doing. */ | |
| PyErr_SetString(PyExc_SystemError, | |
| "NULL object passed to Py_BuildValue"); | |
| return v; | |
| } | |
| case ':': | |
| case ',': | |
| case ' ': | |
| case '\t': | |
| break; | |
| default: | |
| PyErr_SetString(PyExc_SystemError, | |
| "bad format char passed to Py_BuildValue"); | |
| return NULL; | |
| } | |
| } | |
| } | |
| PyObject * | |
| Py_BuildValue(const char *format, ...) | |
| { | |
| va_list va; | |
| PyObject* retval; | |
| va_start(va, format); | |
| retval = va_build_value(format, va, 0); | |
| va_end(va); | |
| return retval; | |
| } | |
| PyObject * | |
| _Py_BuildValue_SizeT(const char *format, ...) | |
| { | |
| va_list va; | |
| PyObject* retval; | |
| va_start(va, format); | |
| retval = va_build_value(format, va, FLAG_SIZE_T); | |
| va_end(va); | |
| return retval; | |
| } | |
| PyObject * | |
| Py_VaBuildValue(const char *format, va_list va) | |
| { | |
| return va_build_value(format, va, 0); | |
| } | |
| PyObject * | |
| _Py_VaBuildValue_SizeT(const char *format, va_list va) | |
| { | |
| return va_build_value(format, va, FLAG_SIZE_T); | |
| } | |
| static PyObject * | |
| va_build_value(const char *format, va_list va, int flags) | |
| { | |
| const char *f = format; | |
| int n = countformat(f, '\0'); | |
| va_list lva; | |
| #ifdef VA_LIST_IS_ARRAY | |
| memcpy(lva, va, sizeof(va_list)); | |
| #else | |
| #ifdef __va_copy | |
| __va_copy(lva, va); | |
| #else | |
| lva = va; | |
| #endif | |
| #endif | |
| if (n < 0) | |
| return NULL; | |
| if (n == 0) { | |
| Py_INCREF(Py_None); | |
| return Py_None; | |
| } | |
| if (n == 1) | |
| return do_mkvalue(&f, &lva, flags); | |
| return do_mktuple(&f, &lva, '\0', n, flags); | |
| } | |
| PyObject * | |
| PyEval_CallFunction(PyObject *obj, const char *format, ...) | |
| { | |
| va_list vargs; | |
| PyObject *args; | |
| PyObject *res; | |
| va_start(vargs, format); | |
| args = Py_VaBuildValue(format, vargs); | |
| va_end(vargs); | |
| if (args == NULL) | |
| return NULL; | |
| res = PyEval_CallObject(obj, args); | |
| Py_DECREF(args); | |
| return res; | |
| } | |
| PyObject * | |
| PyEval_CallMethod(PyObject *obj, const char *methodname, const char *format, ...) | |
| { | |
| va_list vargs; | |
| PyObject *meth; | |
| PyObject *args; | |
| PyObject *res; | |
| meth = PyObject_GetAttrString(obj, methodname); | |
| if (meth == NULL) | |
| return NULL; | |
| va_start(vargs, format); | |
| args = Py_VaBuildValue(format, vargs); | |
| va_end(vargs); | |
| if (args == NULL) { | |
| Py_DECREF(meth); | |
| return NULL; | |
| } | |
| res = PyEval_CallObject(meth, args); | |
| Py_DECREF(meth); | |
| Py_DECREF(args); | |
| return res; | |
| } | |
| int | |
| PyModule_AddObject(PyObject *m, const char *name, PyObject *o) | |
| { | |
| PyObject *dict; | |
| if (!PyModule_Check(m)) { | |
| PyErr_SetString(PyExc_TypeError, | |
| "PyModule_AddObject() needs module as first arg"); | |
| return -1; | |
| } | |
| if (!o) { | |
| if (!PyErr_Occurred()) | |
| PyErr_SetString(PyExc_TypeError, | |
| "PyModule_AddObject() needs non-NULL value"); | |
| return -1; | |
| } | |
| dict = PyModule_GetDict(m); | |
| if (dict == NULL) { | |
| /* Internal error -- modules must have a dict! */ | |
| PyErr_Format(PyExc_SystemError, "module '%s' has no __dict__", | |
| PyModule_GetName(m)); | |
| return -1; | |
| } | |
| if (PyDict_SetItemString(dict, name, o)) | |
| return -1; | |
| Py_DECREF(o); | |
| return 0; | |
| } | |
| int | |
| PyModule_AddIntConstant(PyObject *m, const char *name, long value) | |
| { | |
| PyObject *o = PyInt_FromLong(value); | |
| if (!o) | |
| return -1; | |
| if (PyModule_AddObject(m, name, o) == 0) | |
| return 0; | |
| Py_DECREF(o); | |
| return -1; | |
| } | |
| int | |
| PyModule_AddStringConstant(PyObject *m, const char *name, const char *value) | |
| { | |
| PyObject *o = PyString_FromString(value); | |
| if (!o) | |
| return -1; | |
| if (PyModule_AddObject(m, name, o) == 0) | |
| return 0; | |
| Py_DECREF(o); | |
| return -1; | |
| } |