diff options
author | orivej <orivej@yandex-team.ru> | 2022-02-10 16:44:49 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:44:49 +0300 |
commit | 718c552901d703c502ccbefdfc3c9028d608b947 (patch) | |
tree | 46534a98bbefcd7b1f3faa5b52c138ab27db75b7 /contrib/tools/python3/src/Python/modsupport.c | |
parent | e9656aae26e0358d5378e5b63dcac5c8dbe0e4d0 (diff) | |
download | ydb-718c552901d703c502ccbefdfc3c9028d608b947.tar.gz |
Restoring authorship annotation for <orivej@yandex-team.ru>. Commit 1 of 2.
Diffstat (limited to 'contrib/tools/python3/src/Python/modsupport.c')
-rw-r--r-- | contrib/tools/python3/src/Python/modsupport.c | 1322 |
1 files changed, 661 insertions, 661 deletions
diff --git a/contrib/tools/python3/src/Python/modsupport.c b/contrib/tools/python3/src/Python/modsupport.c index 13482c6508..118cd8ac72 100644 --- a/contrib/tools/python3/src/Python/modsupport.c +++ b/contrib/tools/python3/src/Python/modsupport.c @@ -1,687 +1,687 @@ - -/* Module support implementation */ - -#include "Python.h" + +/* Module support implementation */ + +#include "Python.h" #include "pycore_abstract.h" // _PyIndex_Check() - -#define FLAG_SIZE_T 1 -typedef double va_double; - -static PyObject *va_build_value(const char *, va_list, int); -static PyObject **va_build_stack(PyObject **small_stack, Py_ssize_t small_stack_len, const char *, va_list, int, Py_ssize_t*); - -/* Package context -- the full module name for package imports */ -const char *_Py_PackageContext = NULL; - - -int -_Py_convert_optional_to_ssize_t(PyObject *obj, void *result) -{ - Py_ssize_t limit; - if (obj == Py_None) { - return 1; - } + +#define FLAG_SIZE_T 1 +typedef double va_double; + +static PyObject *va_build_value(const char *, va_list, int); +static PyObject **va_build_stack(PyObject **small_stack, Py_ssize_t small_stack_len, const char *, va_list, int, Py_ssize_t*); + +/* Package context -- the full module name for package imports */ +const char *_Py_PackageContext = NULL; + + +int +_Py_convert_optional_to_ssize_t(PyObject *obj, void *result) +{ + Py_ssize_t limit; + if (obj == Py_None) { + return 1; + } else if (_PyIndex_Check(obj)) { - limit = PyNumber_AsSsize_t(obj, PyExc_OverflowError); - if (limit == -1 && PyErr_Occurred()) { - return 0; - } - } - else { - PyErr_Format(PyExc_TypeError, - "argument should be integer or None, not '%.200s'", - Py_TYPE(obj)->tp_name); - return 0; - } - *((Py_ssize_t *)result) = limit; - return 1; -} - - -/* Helper for mkvalue() to scan the length of a format */ - -static Py_ssize_t -countformat(const char *format, char endchar) -{ - Py_ssize_t 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 *, char, Py_ssize_t, int); -static int do_mkstack(PyObject **, const char**, va_list *, char, Py_ssize_t, int); -static PyObject *do_mklist(const char**, va_list *, char, Py_ssize_t, int); -static PyObject *do_mkdict(const char**, va_list *, char, Py_ssize_t, int); -static PyObject *do_mkvalue(const char**, va_list *, int); - - -static void -do_ignore(const char **p_format, va_list *p_va, char endchar, Py_ssize_t n, int flags) -{ - PyObject *v; - Py_ssize_t i; - assert(PyErr_Occurred()); - v = PyTuple_New(n); - for (i = 0; i < n; i++) { - PyObject *exception, *value, *tb, *w; - - PyErr_Fetch(&exception, &value, &tb); - w = do_mkvalue(p_format, p_va, flags); - PyErr_Restore(exception, value, tb); - if (w != NULL) { - if (v != NULL) { - PyTuple_SET_ITEM(v, i, w); - } - else { - Py_DECREF(w); - } - } - } - Py_XDECREF(v); - if (**p_format != endchar) { - PyErr_SetString(PyExc_SystemError, - "Unmatched paren in format"); - return; - } - if (endchar) { - ++*p_format; - } -} - -static PyObject * -do_mkdict(const char **p_format, va_list *p_va, char endchar, Py_ssize_t n, int flags) -{ - PyObject *d; - Py_ssize_t i; - if (n < 0) - return NULL; - if (n % 2) { - PyErr_SetString(PyExc_SystemError, - "Bad dict format"); - do_ignore(p_format, p_va, endchar, n, flags); - return NULL; - } - /* Note that we can't bail immediately on error as this will leak - refcounts on any 'N' arguments. */ - if ((d = PyDict_New()) == NULL) { - do_ignore(p_format, p_va, endchar, n, flags); - return NULL; - } - for (i = 0; i < n; i+= 2) { - PyObject *k, *v; - - k = do_mkvalue(p_format, p_va, flags); - if (k == NULL) { - do_ignore(p_format, p_va, endchar, n - i - 1, flags); - Py_DECREF(d); - return NULL; - } - v = do_mkvalue(p_format, p_va, flags); - if (v == NULL || PyDict_SetItem(d, k, v) < 0) { - do_ignore(p_format, p_va, endchar, n - i - 2, flags); - Py_DECREF(k); - Py_XDECREF(v); - Py_DECREF(d); - return NULL; - } - Py_DECREF(k); - Py_DECREF(v); - } - if (**p_format != endchar) { - Py_DECREF(d); - PyErr_SetString(PyExc_SystemError, - "Unmatched paren in format"); - return NULL; - } - if (endchar) - ++*p_format; - return d; -} - -static PyObject * -do_mklist(const char **p_format, va_list *p_va, char endchar, Py_ssize_t n, int flags) -{ - PyObject *v; - Py_ssize_t i; - if (n < 0) - return NULL; - /* Note that we can't bail immediately on error as this will leak - refcounts on any 'N' arguments. */ - v = PyList_New(n); - if (v == NULL) { - do_ignore(p_format, p_va, endchar, n, flags); - return NULL; - } - for (i = 0; i < n; i++) { - PyObject *w = do_mkvalue(p_format, p_va, flags); - if (w == NULL) { - do_ignore(p_format, p_va, endchar, n - i - 1, flags); - Py_DECREF(v); - return NULL; - } - PyList_SET_ITEM(v, i, w); - } - if (**p_format != endchar) { - Py_DECREF(v); - PyErr_SetString(PyExc_SystemError, - "Unmatched paren in format"); - return NULL; - } - if (endchar) - ++*p_format; - return v; -} - -static int -do_mkstack(PyObject **stack, const char **p_format, va_list *p_va, - char endchar, Py_ssize_t n, int flags) -{ - Py_ssize_t i; - - if (n < 0) { - return -1; - } - /* 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) { - do_ignore(p_format, p_va, endchar, n - i - 1, flags); - goto error; - } - stack[i] = w; - } - if (**p_format != endchar) { - PyErr_SetString(PyExc_SystemError, - "Unmatched paren in format"); - goto error; - } - if (endchar) { - ++*p_format; - } - return 0; - -error: - n = i; - for (i=0; i < n; i++) { - Py_DECREF(stack[i]); - } - return -1; -} - -static PyObject * -do_mktuple(const char **p_format, va_list *p_va, char endchar, Py_ssize_t n, int flags) -{ - PyObject *v; - Py_ssize_t i; - if (n < 0) - return NULL; - /* Note that we can't bail immediately on error as this will leak - refcounts on any 'N' arguments. */ - if ((v = PyTuple_New(n)) == NULL) { - do_ignore(p_format, p_va, endchar, n, flags); - return NULL; - } - for (i = 0; i < n; i++) { - PyObject *w = do_mkvalue(p_format, p_va, flags); - if (w == NULL) { - do_ignore(p_format, p_va, endchar, n - i - 1, flags); - Py_DECREF(v); - return NULL; - } - PyTuple_SET_ITEM(v, i, w); - } - 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 PyLong_FromLong((long)va_arg(*p_va, int)); - - case 'H': - return PyLong_FromLong((long)va_arg(*p_va, unsigned int)); - - case 'I': - { - unsigned int n; - n = va_arg(*p_va, unsigned int); - return PyLong_FromUnsignedLong(n); - } - - case 'n': -#if SIZEOF_SIZE_T!=SIZEOF_LONG - return PyLong_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 PyLong_FromLong(va_arg(*p_va, long)); - - case 'k': - { - unsigned long n; - n = va_arg(*p_va, unsigned long); - return PyLong_FromUnsignedLong(n); - } - - case 'L': - return PyLong_FromLongLong((long long)va_arg(*p_va, long long)); - - case 'K': - return PyLong_FromUnsignedLongLong((long long)va_arg(*p_va, unsigned long long)); - - 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); + limit = PyNumber_AsSsize_t(obj, PyExc_OverflowError); + if (limit == -1 && PyErr_Occurred()) { + return 0; + } + } + else { + PyErr_Format(PyExc_TypeError, + "argument should be integer or None, not '%.200s'", + Py_TYPE(obj)->tp_name); + return 0; + } + *((Py_ssize_t *)result) = limit; + return 1; +} + + +/* Helper for mkvalue() to scan the length of a format */ + +static Py_ssize_t +countformat(const char *format, char endchar) +{ + Py_ssize_t 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 *, char, Py_ssize_t, int); +static int do_mkstack(PyObject **, const char**, va_list *, char, Py_ssize_t, int); +static PyObject *do_mklist(const char**, va_list *, char, Py_ssize_t, int); +static PyObject *do_mkdict(const char**, va_list *, char, Py_ssize_t, int); +static PyObject *do_mkvalue(const char**, va_list *, int); + + +static void +do_ignore(const char **p_format, va_list *p_va, char endchar, Py_ssize_t n, int flags) +{ + PyObject *v; + Py_ssize_t i; + assert(PyErr_Occurred()); + v = PyTuple_New(n); + for (i = 0; i < n; i++) { + PyObject *exception, *value, *tb, *w; + + PyErr_Fetch(&exception, &value, &tb); + w = do_mkvalue(p_format, p_va, flags); + PyErr_Restore(exception, value, tb); + if (w != NULL) { + if (v != NULL) { + PyTuple_SET_ITEM(v, i, w); + } + else { + Py_DECREF(w); + } + } + } + Py_XDECREF(v); + if (**p_format != endchar) { + PyErr_SetString(PyExc_SystemError, + "Unmatched paren in format"); + return; + } + if (endchar) { + ++*p_format; + } +} + +static PyObject * +do_mkdict(const char **p_format, va_list *p_va, char endchar, Py_ssize_t n, int flags) +{ + PyObject *d; + Py_ssize_t i; + if (n < 0) + return NULL; + if (n % 2) { + PyErr_SetString(PyExc_SystemError, + "Bad dict format"); + do_ignore(p_format, p_va, endchar, n, flags); + return NULL; + } + /* Note that we can't bail immediately on error as this will leak + refcounts on any 'N' arguments. */ + if ((d = PyDict_New()) == NULL) { + do_ignore(p_format, p_va, endchar, n, flags); + return NULL; + } + for (i = 0; i < n; i+= 2) { + PyObject *k, *v; + + k = do_mkvalue(p_format, p_va, flags); + if (k == NULL) { + do_ignore(p_format, p_va, endchar, n - i - 1, flags); + Py_DECREF(d); + return NULL; + } + v = do_mkvalue(p_format, p_va, flags); + if (v == NULL || PyDict_SetItem(d, k, v) < 0) { + do_ignore(p_format, p_va, endchar, n - i - 2, flags); + Py_DECREF(k); + Py_XDECREF(v); + Py_DECREF(d); + return NULL; + } + Py_DECREF(k); + Py_DECREF(v); + } + if (**p_format != endchar) { + Py_DECREF(d); + PyErr_SetString(PyExc_SystemError, + "Unmatched paren in format"); + return NULL; + } + if (endchar) + ++*p_format; + return d; +} + +static PyObject * +do_mklist(const char **p_format, va_list *p_va, char endchar, Py_ssize_t n, int flags) +{ + PyObject *v; + Py_ssize_t i; + if (n < 0) + return NULL; + /* Note that we can't bail immediately on error as this will leak + refcounts on any 'N' arguments. */ + v = PyList_New(n); + if (v == NULL) { + do_ignore(p_format, p_va, endchar, n, flags); + return NULL; + } + for (i = 0; i < n; i++) { + PyObject *w = do_mkvalue(p_format, p_va, flags); + if (w == NULL) { + do_ignore(p_format, p_va, endchar, n - i - 1, flags); + Py_DECREF(v); + return NULL; + } + PyList_SET_ITEM(v, i, w); + } + if (**p_format != endchar) { + Py_DECREF(v); + PyErr_SetString(PyExc_SystemError, + "Unmatched paren in format"); + return NULL; + } + if (endchar) + ++*p_format; + return v; +} + +static int +do_mkstack(PyObject **stack, const char **p_format, va_list *p_va, + char endchar, Py_ssize_t n, int flags) +{ + Py_ssize_t i; + + if (n < 0) { + return -1; + } + /* 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) { + do_ignore(p_format, p_va, endchar, n - i - 1, flags); + goto error; + } + stack[i] = w; + } + if (**p_format != endchar) { + PyErr_SetString(PyExc_SystemError, + "Unmatched paren in format"); + goto error; + } + if (endchar) { + ++*p_format; + } + return 0; + +error: + n = i; + for (i=0; i < n; i++) { + Py_DECREF(stack[i]); + } + return -1; +} + +static PyObject * +do_mktuple(const char **p_format, va_list *p_va, char endchar, Py_ssize_t n, int flags) +{ + PyObject *v; + Py_ssize_t i; + if (n < 0) + return NULL; + /* Note that we can't bail immediately on error as this will leak + refcounts on any 'N' arguments. */ + if ((v = PyTuple_New(n)) == NULL) { + do_ignore(p_format, p_va, endchar, n, flags); + return NULL; + } + for (i = 0; i < n; i++) { + PyObject *w = do_mkvalue(p_format, p_va, flags); + if (w == NULL) { + do_ignore(p_format, p_va, endchar, n - i - 1, flags); + Py_DECREF(v); + return NULL; + } + PyTuple_SET_ITEM(v, i, w); + } + 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 PyLong_FromLong((long)va_arg(*p_va, int)); + + case 'H': + return PyLong_FromLong((long)va_arg(*p_va, unsigned int)); + + case 'I': + { + unsigned int n; + n = va_arg(*p_va, unsigned int); + return PyLong_FromUnsignedLong(n); + } + + case 'n': +#if SIZEOF_SIZE_T!=SIZEOF_LONG + return PyLong_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 PyLong_FromLong(va_arg(*p_va, long)); + + case 'k': + { + unsigned long n; + n = va_arg(*p_va, unsigned long); + return PyLong_FromUnsignedLong(n); + } + + case 'L': + return PyLong_FromLongLong((long long)va_arg(*p_va, long long)); + + case 'K': + return PyLong_FromUnsignedLongLong((long long)va_arg(*p_va, unsigned long long)); + + 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); + n = va_arg(*p_va, int); if (PyErr_WarnEx(PyExc_DeprecationWarning, "PY_SSIZE_T_CLEAN will be required for '#' formats", 1)) { return NULL; } } - } - else - n = -1; - if (u == NULL) { - v = Py_None; - Py_INCREF(v); - } - else { - if (n < 0) - n = wcslen(u); - v = PyUnicode_FromWideChar(u, n); - } - return v; - } - case 'f': - case 'd': - return PyFloat_FromDouble( - (double)va_arg(*p_va, va_double)); - - case 'D': - return PyComplex_FromCComplex( - *((Py_complex *)va_arg(*p_va, Py_complex *))); - - case 'c': - { - char p[1]; - p[0] = (char)va_arg(*p_va, int); - return PyBytes_FromStringAndSize(p, 1); - } - case 'C': - { - int i = va_arg(*p_va, int); - return PyUnicode_FromOrdinal(i); - } - - case 's': - case 'z': - case 'U': /* XXX deprecated alias */ - { - PyObject *v; - const char *str = va_arg(*p_va, const 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 = -1; + if (u == NULL) { + v = Py_None; + Py_INCREF(v); + } + else { + if (n < 0) + n = wcslen(u); + v = PyUnicode_FromWideChar(u, n); + } + return v; + } + case 'f': + case 'd': + return PyFloat_FromDouble( + (double)va_arg(*p_va, va_double)); + + case 'D': + return PyComplex_FromCComplex( + *((Py_complex *)va_arg(*p_va, Py_complex *))); + + case 'c': + { + char p[1]; + p[0] = (char)va_arg(*p_va, int); + return PyBytes_FromStringAndSize(p, 1); + } + case 'C': + { + int i = va_arg(*p_va, int); + return PyUnicode_FromOrdinal(i); + } + + case 's': + case 'z': + case 'U': /* XXX deprecated alias */ + { + PyObject *v; + const char *str = va_arg(*p_va, const 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); + n = va_arg(*p_va, int); if (PyErr_WarnEx(PyExc_DeprecationWarning, "PY_SSIZE_T_CLEAN will be required for '#' formats", 1)) { return NULL; } } - } - 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 = PyUnicode_FromStringAndSize(str, n); - } - return v; - } - - case 'y': - { - PyObject *v; - const char *str = va_arg(*p_va, const 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 = -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 = PyUnicode_FromStringAndSize(str, n); + } + return v; + } + + case 'y': + { + PyObject *v; + const char *str = va_arg(*p_va, const 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); + n = va_arg(*p_va, int); if (PyErr_WarnEx(PyExc_DeprecationWarning, "PY_SSIZE_T_CLEAN will be required for '#' formats", 1)) { return NULL; } } - } - 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 bytes"); - return NULL; - } - n = (Py_ssize_t)m; - } - v = PyBytes_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; - Py_ssize_t n = countformat(f, '\0'); - va_list lva; - PyObject *retval; - - if (n < 0) - return NULL; - if (n == 0) { - Py_RETURN_NONE; - } - va_copy(lva, va); - if (n == 1) { - retval = do_mkvalue(&f, &lva, flags); - } else { - retval = do_mktuple(&f, &lva, '\0', n, flags); - } - va_end(lva); - return retval; -} - -PyObject ** -_Py_VaBuildStack(PyObject **small_stack, Py_ssize_t small_stack_len, - const char *format, va_list va, Py_ssize_t *p_nargs) -{ - return va_build_stack(small_stack, small_stack_len, format, va, 0, p_nargs); -} - -PyObject ** -_Py_VaBuildStack_SizeT(PyObject **small_stack, Py_ssize_t small_stack_len, - const char *format, va_list va, Py_ssize_t *p_nargs) -{ - return va_build_stack(small_stack, small_stack_len, format, va, FLAG_SIZE_T, p_nargs); -} - -static PyObject ** -va_build_stack(PyObject **small_stack, Py_ssize_t small_stack_len, - const char *format, va_list va, int flags, Py_ssize_t *p_nargs) -{ - const char *f; - Py_ssize_t n; - va_list lva; - PyObject **stack; - int res; - - n = countformat(format, '\0'); - if (n < 0) { - *p_nargs = 0; - return NULL; - } - - if (n == 0) { - *p_nargs = 0; - return small_stack; - } - - if (n <= small_stack_len) { - stack = small_stack; - } - else { - stack = PyMem_Malloc(n * sizeof(stack[0])); - if (stack == NULL) { - PyErr_NoMemory(); - return NULL; - } - } - - va_copy(lva, va); - f = format; - res = do_mkstack(stack, &f, &lva, '\0', n, flags); - va_end(lva); - - if (res < 0) { + } + 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 bytes"); + return NULL; + } + n = (Py_ssize_t)m; + } + v = PyBytes_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; + Py_ssize_t n = countformat(f, '\0'); + va_list lva; + PyObject *retval; + + if (n < 0) + return NULL; + if (n == 0) { + Py_RETURN_NONE; + } + va_copy(lva, va); + if (n == 1) { + retval = do_mkvalue(&f, &lva, flags); + } else { + retval = do_mktuple(&f, &lva, '\0', n, flags); + } + va_end(lva); + return retval; +} + +PyObject ** +_Py_VaBuildStack(PyObject **small_stack, Py_ssize_t small_stack_len, + const char *format, va_list va, Py_ssize_t *p_nargs) +{ + return va_build_stack(small_stack, small_stack_len, format, va, 0, p_nargs); +} + +PyObject ** +_Py_VaBuildStack_SizeT(PyObject **small_stack, Py_ssize_t small_stack_len, + const char *format, va_list va, Py_ssize_t *p_nargs) +{ + return va_build_stack(small_stack, small_stack_len, format, va, FLAG_SIZE_T, p_nargs); +} + +static PyObject ** +va_build_stack(PyObject **small_stack, Py_ssize_t small_stack_len, + const char *format, va_list va, int flags, Py_ssize_t *p_nargs) +{ + const char *f; + Py_ssize_t n; + va_list lva; + PyObject **stack; + int res; + + n = countformat(format, '\0'); + if (n < 0) { + *p_nargs = 0; + return NULL; + } + + if (n == 0) { + *p_nargs = 0; + return small_stack; + } + + if (n <= small_stack_len) { + stack = small_stack; + } + else { + stack = PyMem_Malloc(n * sizeof(stack[0])); + if (stack == NULL) { + PyErr_NoMemory(); + return NULL; + } + } + + va_copy(lva, va); + f = format; + res = do_mkstack(stack, &f, &lva, '\0', n, flags); + va_end(lva); + + if (res < 0) { if (stack != small_stack) { PyMem_Free(stack); } - return NULL; - } - - *p_nargs = n; - return stack; -} - - -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 = PyLong_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 = PyUnicode_FromString(value); - if (!o) - return -1; - if (PyModule_AddObject(m, name, o) == 0) - return 0; - Py_DECREF(o); - return -1; -} + return NULL; + } + + *p_nargs = n; + return stack; +} + + +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 = PyLong_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 = PyUnicode_FromString(value); + if (!o) + return -1; + if (PyModule_AddObject(m, name, o) == 0) + return 0; + Py_DECREF(o); + return -1; +} int PyModule_AddType(PyObject *module, PyTypeObject *type) |