Ejemplo n.º 1
0
static PyObject *
do_mkvalue(char **p_format, va_list *p_va)
{
	for (;;) {
		switch (*(*p_format)++) {
		case '(':
			return do_mktuple(p_format, p_va, ')',
					  countformat(*p_format, ')'));

		case '[':
			return do_mklist(p_format, p_va, ']',
					 countformat(*p_format, ']'));

		case '{':
			return do_mkdict(p_format, p_va, '}',
					 countformat(*p_format, '}'));

		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 'l':
			return PyInt_FromLong((long)va_arg(*p_va, long));

#ifdef HAVE_LONG_LONG
		case 'L':
			return PyLong_FromLongLong((LONG_LONG)va_arg(*p_va, LONG_LONG));
#endif
		case 'u':
		{
			PyObject *v;
			Py_UNICODE *u = va_arg(*p_va, Py_UNICODE *);
			int n;
			if (**p_format == '#') {
				++*p_format;
				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;
		}
		case 'f':
		case 'd':
			return PyFloat_FromDouble(
				(double)va_arg(*p_va, va_double));

		case 'c':
		{
			char p[1];
			p[0] = va_arg(*p_va, int);
			return PyString_FromStringAndSize(p, 1);
		}

		case 's':
		case 'z':
		{
			PyObject *v;
			char *str = va_arg(*p_va, char *);
			int n;
			if (**p_format == '#') {
				++*p_format;
				n = va_arg(*p_va, int);
			}
			else
Ejemplo n.º 2
0
static PyObject* do_mkvalue(const char** p_format, va_list* p_va, int flags) noexcept {
    for (;;) {
        switch (*(*p_format)++) {
            case '(':
                return do_mktuple(p_format, p_va, ')', countformat(*p_format, ')'), flags);

#if 0
            case '[':
                return do_mklist(p_format, p_va, ']', countformat(*p_format, ']'), flags);

            case '{':
                return do_mkdict(p_format, p_va, '}', countformat(*p_format, '}'), flags);
#endif

            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 '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 '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;
            }