| Index: Python/getargs.c |
| =================================================================== |
| --- Python/getargs.c (révision 81974) |
| +++ Python/getargs.c (copie de travail) |
| @@ -162,11 +162,20 @@ |
| } |
| static int |
| -addcleanup(void *ptr, PyObject **freelist, PyCapsule_Destructor destr) |
| +addcleanup(void *ptr, PyObject **freelist, int is_buffer) |
| { |
| PyObject *cobj; |
| const char *name; |
| + PyCapsule_Destructor destr; |
| + if (is_buffer) { |
| + destr = cleanup_buffer; |
| + name = GETARGS_CAPSULE_NAME_CLEANUP_BUFFER; |
| + } else { |
| + destr = cleanup_ptr; |
| + name = GETARGS_CAPSULE_NAME_CLEANUP_PTR; |
| + } |
| + |
| if (!*freelist) { |
| *freelist = PyList_New(0); |
| if (!*freelist) { |
| @@ -175,13 +184,6 @@ |
| } |
| } |
| - if (destr == cleanup_ptr) { |
| - name = GETARGS_CAPSULE_NAME_CLEANUP_PTR; |
| - } else if (destr == cleanup_buffer) { |
| - name = GETARGS_CAPSULE_NAME_CLEANUP_BUFFER; |
| - } else { |
| - return -1; |
| - } |
| cobj = PyCapsule_New(ptr, name, destr); |
| if (!cobj) { |
| destr(ptr); |
| @@ -615,6 +617,7 @@ |
| else q=va_arg(*p_va, int*); |
| #define STORE_SIZE(s) if (flags & FLAG_SIZE_T) *q2=s; else *q=s; |
| #define BUFFER_LEN ((flags & FLAG_SIZE_T) ? *q2:*q) |
| +#define RETURN_ERR_OCCURRED return msgbuf |
| const char *format = *p_format; |
| char c = *format++; |
| @@ -626,19 +629,19 @@ |
| char *p = va_arg(*p_va, char *); |
| long ival; |
| if (float_argument_error(arg)) |
| - return converterr("integer<b>", arg, msgbuf, bufsize); |
| + RETURN_ERR_OCCURRED; |
| ival = PyLong_AsLong(arg); |
| if (ival == -1 && PyErr_Occurred()) |
| - return converterr("integer<b>", arg, msgbuf, bufsize); |
| + RETURN_ERR_OCCURRED; |
| else if (ival < 0) { |
| PyErr_SetString(PyExc_OverflowError, |
| "unsigned byte integer is less than minimum"); |
| - return converterr("integer<b>", arg, msgbuf, bufsize); |
| + RETURN_ERR_OCCURRED; |
| } |
| else if (ival > UCHAR_MAX) { |
| PyErr_SetString(PyExc_OverflowError, |
| "unsigned byte integer is greater than maximum"); |
| - return converterr("integer<b>", arg, msgbuf, bufsize); |
| + RETURN_ERR_OCCURRED; |
| } |
| else |
| *p = (unsigned char) ival; |
| @@ -650,10 +653,10 @@ |
| char *p = va_arg(*p_va, char *); |
| long ival; |
| if (float_argument_error(arg)) |
| - return converterr("integer<B>", arg, msgbuf, bufsize); |
| + RETURN_ERR_OCCURRED; |
| ival = PyLong_AsUnsignedLongMask(arg); |
| if (ival == -1 && PyErr_Occurred()) |
| - return converterr("integer<B>", arg, msgbuf, bufsize); |
| + RETURN_ERR_OCCURRED; |
| else |
| *p = (unsigned char) ival; |
| break; |
| @@ -663,19 +666,19 @@ |
| short *p = va_arg(*p_va, short *); |
| long ival; |
| if (float_argument_error(arg)) |
| - return converterr("integer<h>", arg, msgbuf, bufsize); |
| + RETURN_ERR_OCCURRED; |
| ival = PyLong_AsLong(arg); |
| if (ival == -1 && PyErr_Occurred()) |
| - return converterr("integer<h>", arg, msgbuf, bufsize); |
| + RETURN_ERR_OCCURRED; |
| else if (ival < SHRT_MIN) { |
| PyErr_SetString(PyExc_OverflowError, |
| "signed short integer is less than minimum"); |
| - return converterr("integer<h>", arg, msgbuf, bufsize); |
| + RETURN_ERR_OCCURRED; |
| } |
| else if (ival > SHRT_MAX) { |
| PyErr_SetString(PyExc_OverflowError, |
| "signed short integer is greater than maximum"); |
| - return converterr("integer<h>", arg, msgbuf, bufsize); |
| + RETURN_ERR_OCCURRED; |
| } |
| else |
| *p = (short) ival; |
| @@ -687,10 +690,10 @@ |
| unsigned short *p = va_arg(*p_va, unsigned short *); |
| long ival; |
| if (float_argument_error(arg)) |
| - return converterr("integer<H>", arg, msgbuf, bufsize); |
| + RETURN_ERR_OCCURRED; |
| ival = PyLong_AsUnsignedLongMask(arg); |
| if (ival == -1 && PyErr_Occurred()) |
| - return converterr("integer<H>", arg, msgbuf, bufsize); |
| + RETURN_ERR_OCCURRED; |
| else |
| *p = (unsigned short) ival; |
| break; |
| @@ -700,19 +703,19 @@ |
| int *p = va_arg(*p_va, int *); |
| long ival; |
| if (float_argument_error(arg)) |
| - return converterr("integer<i>", arg, msgbuf, bufsize); |
| + RETURN_ERR_OCCURRED; |
| ival = PyLong_AsLong(arg); |
| if (ival == -1 && PyErr_Occurred()) |
| - return converterr("integer<i>", arg, msgbuf, bufsize); |
| + RETURN_ERR_OCCURRED; |
| else if (ival > INT_MAX) { |
| PyErr_SetString(PyExc_OverflowError, |
| "signed integer is greater than maximum"); |
| - return converterr("integer<i>", arg, msgbuf, bufsize); |
| + RETURN_ERR_OCCURRED; |
| } |
| else if (ival < INT_MIN) { |
| PyErr_SetString(PyExc_OverflowError, |
| "signed integer is less than minimum"); |
| - return converterr("integer<i>", arg, msgbuf, bufsize); |
| + RETURN_ERR_OCCURRED; |
| } |
| else |
| *p = ival; |
| @@ -724,10 +727,10 @@ |
| unsigned int *p = va_arg(*p_va, unsigned int *); |
| unsigned int ival; |
| if (float_argument_error(arg)) |
| - return converterr("integer<I>", arg, msgbuf, bufsize); |
| + RETURN_ERR_OCCURRED; |
| ival = (unsigned int)PyLong_AsUnsignedLongMask(arg); |
| if (ival == (unsigned int)-1 && PyErr_Occurred()) |
| - return converterr("integer<I>", arg, msgbuf, bufsize); |
| + RETURN_ERR_OCCURRED; |
| else |
| *p = ival; |
| break; |
| @@ -739,14 +742,14 @@ |
| Py_ssize_t *p = va_arg(*p_va, Py_ssize_t *); |
| Py_ssize_t ival = -1; |
| if (float_argument_error(arg)) |
| - return converterr("integer<n>", arg, msgbuf, bufsize); |
| + RETURN_ERR_OCCURRED; |
| iobj = PyNumber_Index(arg); |
| if (iobj != NULL) { |
| ival = PyLong_AsSsize_t(iobj); |
| Py_DECREF(iobj); |
| } |
| if (ival == -1 && PyErr_Occurred()) |
| - return converterr("integer<n>", arg, msgbuf, bufsize); |
| + RETURN_ERR_OCCURRED; |
| *p = ival; |
| break; |
| } |
| @@ -754,10 +757,10 @@ |
| long *p = va_arg(*p_va, long *); |
| long ival; |
| if (float_argument_error(arg)) |
| - return converterr("integer<l>", arg, msgbuf, bufsize); |
| + RETURN_ERR_OCCURRED; |
| ival = PyLong_AsLong(arg); |
| if (ival == -1 && PyErr_Occurred()) |
| - return converterr("integer<l>", arg, msgbuf, bufsize); |
| + RETURN_ERR_OCCURRED; |
| else |
| *p = ival; |
| break; |
| @@ -779,10 +782,10 @@ |
| PY_LONG_LONG *p = va_arg( *p_va, PY_LONG_LONG * ); |
| PY_LONG_LONG ival; |
| if (float_argument_error(arg)) |
| - return converterr("long<L>", arg, msgbuf, bufsize); |
| + RETURN_ERR_OCCURRED; |
| ival = PyLong_AsLongLong(arg); |
| if (ival == (PY_LONG_LONG)-1 && PyErr_Occurred()) |
| - return converterr("long<L>", arg, msgbuf, bufsize); |
| + RETURN_ERR_OCCURRED; |
| else |
| *p = ival; |
| break; |
| @@ -804,7 +807,7 @@ |
| float *p = va_arg(*p_va, float *); |
| double dval = PyFloat_AsDouble(arg); |
| if (PyErr_Occurred()) |
| - return converterr("float<f>", arg, msgbuf, bufsize); |
| + RETURN_ERR_OCCURRED; |
| else |
| *p = (float) dval; |
| break; |
| @@ -814,7 +817,7 @@ |
| double *p = va_arg(*p_va, double *); |
| double dval = PyFloat_AsDouble(arg); |
| if (PyErr_Occurred()) |
| - return converterr("float<d>", arg, msgbuf, bufsize); |
| + RETURN_ERR_OCCURRED; |
| else |
| *p = dval; |
| break; |
| @@ -825,7 +828,7 @@ |
| Py_complex cval; |
| cval = PyComplex_AsCComplex(arg); |
| if (PyErr_Occurred()) |
| - return converterr("complex<D>", arg, msgbuf, bufsize); |
| + RETURN_ERR_OCCURRED; |
| else |
| *p = cval; |
| break; |
| @@ -860,8 +863,7 @@ |
| if (PyUnicode_Check(arg)) { |
| uarg = UNICODE_DEFAULT_ENCODING(arg); |
| if (uarg == NULL) |
| - return converterr(CONV_UNICODE, |
| - arg, msgbuf, bufsize); |
| + RETURN_ERR_OCCURRED; |
| PyBuffer_FillInfo(p, arg, |
| PyBytes_AS_STRING(uarg), PyBytes_GET_SIZE(uarg), |
| 1, 0); |
| @@ -871,11 +873,8 @@ |
| if (getbuffer(arg, p, &buf) < 0) |
| return converterr(buf, arg, msgbuf, bufsize); |
| } |
| - if (addcleanup(p, freelist, cleanup_buffer)) { |
| - return converterr( |
| - "(cleanup problem)", |
| - arg, msgbuf, bufsize); |
| - } |
| + if (addcleanup(p, freelist, 1)) |
| + RETURN_ERR_OCCURRED; |
| format++; |
| } else if (*format == '#') { |
| void **p = (void **)va_arg(*p_va, char **); |
| @@ -884,8 +883,7 @@ |
| if (PyUnicode_Check(arg)) { |
| uarg = UNICODE_DEFAULT_ENCODING(arg); |
| if (uarg == NULL) |
| - return converterr(CONV_UNICODE, |
| - arg, msgbuf, bufsize); |
| + RETURN_ERR_OCCURRED; |
| *p = PyBytes_AS_STRING(uarg); |
| STORE_SIZE(PyBytes_GET_SIZE(uarg)); |
| } |
| @@ -904,8 +902,7 @@ |
| if (PyUnicode_Check(arg)) { |
| uarg = UNICODE_DEFAULT_ENCODING(arg); |
| if (uarg == NULL) |
| - return converterr(CONV_UNICODE, |
| - arg, msgbuf, bufsize); |
| + RETURN_ERR_OCCURRED; |
| *p = PyBytes_AS_STRING(uarg); |
| } |
| else |
| @@ -925,11 +922,8 @@ |
| if (getbuffer(arg, (Py_buffer*)p, &buf) < 0) |
| return converterr(buf, arg, msgbuf, bufsize); |
| format++; |
| - if (addcleanup(p, freelist, cleanup_buffer)) { |
| - return converterr( |
| - "(cleanup problem)", |
| - arg, msgbuf, bufsize); |
| - } |
| + if (addcleanup(p, freelist, 1)) |
| + RETURN_ERR_OCCURRED; |
| break; |
| } |
| count = convertbuffer(arg, p, &buf); |
| @@ -957,8 +951,7 @@ |
| else if (PyUnicode_Check(arg)) { |
| uarg = UNICODE_DEFAULT_ENCODING(arg); |
| if (uarg == NULL) |
| - return converterr(CONV_UNICODE, |
| - arg, msgbuf, bufsize); |
| + RETURN_ERR_OCCURRED; |
| PyBuffer_FillInfo(p, arg, |
| PyBytes_AS_STRING(uarg), PyBytes_GET_SIZE(uarg), |
| 1, 0); |
| @@ -968,11 +961,8 @@ |
| if (getbuffer(arg, p, &buf) < 0) |
| return converterr(buf, arg, msgbuf, bufsize); |
| } |
| - if (addcleanup(p, freelist, cleanup_buffer)) { |
| - return converterr( |
| - "(cleanup problem)", |
| - arg, msgbuf, bufsize); |
| - } |
| + if (addcleanup(p, freelist, 1)) |
| + RETURN_ERR_OCCURRED; |
| format++; |
| } else if (*format == '#') { /* any buffer-like object */ |
| void **p = (void **)va_arg(*p_va, char **); |
| @@ -985,8 +975,7 @@ |
| else if (PyUnicode_Check(arg)) { |
| uarg = UNICODE_DEFAULT_ENCODING(arg); |
| if (uarg == NULL) |
| - return converterr(CONV_UNICODE, |
| - arg, msgbuf, bufsize); |
| + RETURN_ERR_OCCURRED; |
| *p = PyBytes_AS_STRING(uarg); |
| STORE_SIZE(PyBytes_GET_SIZE(uarg)); |
| } |
| @@ -1013,8 +1002,7 @@ |
| else if (PyUnicode_Check(arg)) { |
| uarg = UNICODE_DEFAULT_ENCODING(arg); |
| if (uarg == NULL) |
| - return converterr(CONV_UNICODE, |
| - arg, msgbuf, bufsize); |
| + RETURN_ERR_OCCURRED; |
| *p = PyBytes_AS_STRING(uarg); |
| } |
| else |
| @@ -1099,8 +1087,7 @@ |
| s = arg; |
| Py_INCREF(s); |
| if (PyObject_AsCharBuffer(s, &ptr, &size) < 0) |
| - return converterr("(AsCharBuffer failed)", |
| - arg, msgbuf, bufsize); |
| + RETURN_ERR_OCCURRED; |
| } |
| else { |
| PyObject *u; |
| @@ -1108,24 +1095,13 @@ |
| /* Convert object to Unicode */ |
| u = PyUnicode_FromObject(arg); |
| if (u == NULL) |
| - return converterr( |
| - "string or unicode or text buffer", |
| - arg, msgbuf, bufsize); |
| + RETURN_ERR_OCCURRED; |
| /* Encode object; use default error handling */ |
| - s = PyUnicode_AsEncodedString(u, |
| - encoding, |
| - NULL); |
| + s = PyUnicode_AsEncodedString(u, encoding, NULL); |
| Py_DECREF(u); |
| if (s == NULL) |
| - return converterr("(encoding failed)", |
| - arg, msgbuf, bufsize); |
| - if (!PyBytes_Check(s)) { |
| - Py_DECREF(s); |
| - return converterr( |
| - "(encoder failed to return bytes)", |
| - arg, msgbuf, bufsize); |
| - } |
| + RETURN_ERR_OCCURRED; |
| size = PyBytes_GET_SIZE(s); |
| ptr = PyBytes_AS_STRING(s); |
| if (ptr == NULL) |
| @@ -1169,15 +1145,11 @@ |
| if (*buffer == NULL) { |
| Py_DECREF(s); |
| PyErr_NoMemory(); |
| - return converterr( |
| - "(memory error)", |
| - arg, msgbuf, bufsize); |
| + RETURN_ERR_OCCURRED; |
| } |
| - if (addcleanup(*buffer, freelist, cleanup_ptr)) { |
| + if (addcleanup(*buffer, freelist, 0)) { |
| Py_DECREF(s); |
| - return converterr( |
| - "(cleanup problem)", |
| - arg, msgbuf, bufsize); |
| + RETURN_ERR_OCCURRED; |
| } |
| } else { |
| if (size + 1 > BUFFER_LEN) { |
| @@ -1213,13 +1185,11 @@ |
| if (*buffer == NULL) { |
| Py_DECREF(s); |
| PyErr_NoMemory(); |
| - return converterr("(memory error)", |
| - arg, msgbuf, bufsize); |
| + RETURN_ERR_OCCURRED; |
| } |
| - if (addcleanup(*buffer, freelist, cleanup_ptr)) { |
| + if (addcleanup(*buffer, freelist, 0)) { |
| Py_DECREF(s); |
| - return converterr("(cleanup problem)", |
| - arg, msgbuf, bufsize); |
| + RETURN_ERR_OCCURRED; |
| } |
| memcpy(*buffer, ptr, size+1); |
| } |
| @@ -1292,12 +1262,10 @@ |
| int res; |
| format++; |
| if (! (res = (*convert)(arg, addr))) |
| - return converterr("(unspecified)", |
| - arg, msgbuf, bufsize); |
| + return converterr("(converter error)", arg, msgbuf, bufsize); |
| if (res == Py_CLEANUP_SUPPORTED && |
| addcleanup_convert(addr, freelist, convert) == -1) |
| - return converterr("(cleanup problem)", |
| - arg, msgbuf, bufsize); |
| + RETURN_ERR_OCCURRED; |
| } |
| else { |
| p = va_arg(*p_va, PyObject **); |
| @@ -1328,11 +1296,8 @@ |
| PyErr_Clear(); |
| return converterr("read-write buffer", arg, msgbuf, bufsize); |
| } |
| - if (addcleanup(p, freelist, cleanup_buffer)) { |
| - return converterr( |
| - "(cleanup problem)", |
| - arg, msgbuf, bufsize); |
| - } |
| + if (addcleanup(p, freelist, 1)) |
| + RETURN_ERR_OCCURRED; |
| if (!PyBuffer_IsContiguous((Py_buffer*)p, 'C')) |
| return converterr("contiguous buffer", arg, msgbuf, bufsize); |
| break; |