summaryrefslogtreecommitdiffstats
path: root/Python/getargs.c
diff options
context:
space:
mode:
Diffstat (limited to 'Python/getargs.c')
-rw-r--r--Python/getargs.c1029
1 files changed, 514 insertions, 515 deletions
diff --git a/Python/getargs.c b/Python/getargs.c
index b25b20a..c112386 100644
--- a/Python/getargs.c
+++ b/Python/getargs.c
@@ -25,7 +25,7 @@ static char *convertitem(PyObject *, char **, va_list *, int *, char *);
static char *converttuple(PyObject *, char **, va_list *,
int *, char *, int);
static char *convertsimple(PyObject *, char **, va_list *, char *);
-static char *convertsimple1(PyObject *, char **, va_list *);
+static int convertbuffer(PyObject *, void **p, char **);
static int vgetargskeywords(PyObject *, PyObject *,
char *, char **, va_list *);
@@ -352,374 +352,361 @@ convertitem(PyObject *arg, char **p_format, va_list *p_va, int *levels,
}
-/* Convert a non-tuple argument. Adds to convertsimple1 functionality
- by formatting messages as "must be <desired type>, not <actual type>". */
+
+/* Internal API needed by convertsimple() and a helper macro. */
+extern
+PyObject *_PyUnicode_AsDefaultEncodedString(PyObject *unicode,
+ const char *errors);
+
+#define UNICODE_DEFAULT_ENCODING(arg) \
+ _PyUnicode_AsDefaultEncodedString(arg, NULL)
+
+/* Format an error message generated by convertsimple(). */
static char *
-convertsimple(PyObject *arg, char **p_format, va_list *p_va, char *msgbuf)
+converterr(char *expected, PyObject *arg, char *msgbuf)
{
- char *msg = convertsimple1(arg, p_format, p_va);
- if (msg != NULL) {
- sprintf(msgbuf, "must be %.50s, not %.50s", msg,
- arg == Py_None ? "None" : arg->ob_type->tp_name);
- msg = msgbuf;
- }
- return msg;
+ assert (expected != NULL);
+ sprintf(msgbuf, "must be %.50s, not %.50s", expected,
+ arg == Py_None ? "None" : arg->ob_type->tp_name);
+ return msgbuf;
}
-
-/* Internal API needed by convertsimple1(): */
-extern
-PyObject *_PyUnicode_AsDefaultEncodedString(PyObject *unicode,
- const char *errors);
+#define CONV_UNICODE "(unicode conversion error)"
/* Convert a non-tuple argument. Return NULL if conversion went OK,
- or a string representing the expected type if the conversion failed.
+ or a string with a message describing the failure. The message is
+ formatted as "must be <desired type>, not <actual type>".
When failing, an exception may or may not have been raised.
- Don't call if a tuple is expected. */
+ Don't call if a tuple is expected.
+*/
static char *
-convertsimple1(PyObject *arg, char **p_format, va_list *p_va)
+convertsimple(PyObject *arg, char **p_format, va_list *p_va, char *msgbuf)
{
char *format = *p_format;
char c = *format++;
switch (c) {
- case 'b': /* unsigned byte -- very short int */
- {
- char *p = va_arg(*p_va, char *);
- long ival = PyInt_AsLong(arg);
- if (ival == -1 && PyErr_Occurred())
- return "integer<b>";
- else if (ival < 0) {
- PyErr_SetString(PyExc_OverflowError,
- "unsigned byte integer is less than minimum");
- return "integer<b>";
- }
- else if (ival > UCHAR_MAX) {
- PyErr_SetString(PyExc_OverflowError,
- "unsigned byte integer is greater than maximum");
- return "integer<b>";
- }
- else
- *p = (unsigned char) ival;
- break;
+ case 'b': { /* unsigned byte -- very short int */
+ char *p = va_arg(*p_va, char *);
+ long ival = PyInt_AsLong(arg);
+ if (ival == -1 && PyErr_Occurred())
+ return converterr("integer<b>", arg, msgbuf);
+ else if (ival < 0) {
+ PyErr_SetString(PyExc_OverflowError,
+ "unsigned byte integer is less than minimum");
+ return converterr("integer<b>", arg, msgbuf);
+ }
+ else if (ival > UCHAR_MAX) {
+ PyErr_SetString(PyExc_OverflowError,
+ "unsigned byte integer is greater than maximum");
+ return converterr("integer<b>", arg, msgbuf);
}
+ else
+ *p = (unsigned char) ival;
+ break;
+ }
- case 'B': /* byte sized bitfield - both signed and unsigned values allowed */
- {
- char *p = va_arg(*p_va, char *);
- long ival = PyInt_AsLong(arg);
- if (ival == -1 && PyErr_Occurred())
- return "integer<b>";
- else if (ival < SCHAR_MIN) {
- PyErr_SetString(PyExc_OverflowError,
- "byte-sized integer bitfield is less than minimum");
- return "integer<B>";
- }
- else if (ival > (int)UCHAR_MAX) {
- PyErr_SetString(PyExc_OverflowError,
- "byte-sized integer bitfield is greater than maximum");
- return "integer<B>";
- }
- else
- *p = (unsigned char) ival;
- break;
+ case 'B': {/* byte sized bitfield - both signed and unsigned
+ values allowed */
+ char *p = va_arg(*p_va, char *);
+ long ival = PyInt_AsLong(arg);
+ if (ival == -1 && PyErr_Occurred())
+ return converterr("integer<b>", arg, msgbuf);
+ else if (ival < SCHAR_MIN) {
+ PyErr_SetString(PyExc_OverflowError,
+ "byte-sized integer bitfield is less than minimum");
+ return converterr("integer<B>", arg, msgbuf);
}
+ else if (ival > (int)UCHAR_MAX) {
+ PyErr_SetString(PyExc_OverflowError,
+ "byte-sized integer bitfield is greater than maximum");
+ return converterr("integer<B>", arg, msgbuf);
+ }
+ else
+ *p = (unsigned char) ival;
+ break;
+ }
- case 'h': /* signed short int */
- {
- short *p = va_arg(*p_va, short *);
- long ival = PyInt_AsLong(arg);
- if (ival == -1 && PyErr_Occurred())
- return "integer<h>";
- else if (ival < SHRT_MIN) {
- PyErr_SetString(PyExc_OverflowError,
- "signed short integer is less than minimum");
- return "integer<h>";
- }
- else if (ival > SHRT_MAX) {
- PyErr_SetString(PyExc_OverflowError,
- "signed short integer is greater than maximum");
- return "integer<h>";
- }
- else
- *p = (short) ival;
- break;
+ case 'h': {/* signed short int */
+ short *p = va_arg(*p_va, short *);
+ long ival = PyInt_AsLong(arg);
+ if (ival == -1 && PyErr_Occurred())
+ return converterr("integer<h>", arg, msgbuf);
+ else if (ival < SHRT_MIN) {
+ PyErr_SetString(PyExc_OverflowError,
+ "signed short integer is less than minimum");
+ return converterr("integer<h>", arg, msgbuf);
}
+ else if (ival > SHRT_MAX) {
+ PyErr_SetString(PyExc_OverflowError,
+ "signed short integer is greater than maximum");
+ return converterr("integer<h>", arg, msgbuf);
+ }
+ else
+ *p = (short) ival;
+ break;
+ }
- case 'H': /* short int sized bitfield, both signed and unsigned allowed */
- {
- unsigned short *p = va_arg(*p_va, unsigned short *);
- long ival = PyInt_AsLong(arg);
- if (ival == -1 && PyErr_Occurred())
- return "integer<H>";
- else if (ival < SHRT_MIN) {
- PyErr_SetString(PyExc_OverflowError,
- "short integer bitfield is less than minimum");
- return "integer<H>";
- }
- else if (ival > USHRT_MAX) {
- PyErr_SetString(PyExc_OverflowError,
- "short integer bitfield is greater than maximum");
- return "integer<H>";
- }
- else
- *p = (unsigned short) ival;
- break;
+ case 'H': { /* short int sized bitfield, both signed and
+ unsigned allowed */
+ unsigned short *p = va_arg(*p_va, unsigned short *);
+ long ival = PyInt_AsLong(arg);
+ if (ival == -1 && PyErr_Occurred())
+ return converterr("integer<H>", arg, msgbuf);
+ else if (ival < SHRT_MIN) {
+ PyErr_SetString(PyExc_OverflowError,
+ "short integer bitfield is less than minimum");
+ return converterr("integer<H>", arg, msgbuf);
+ }
+ else if (ival > USHRT_MAX) {
+ PyErr_SetString(PyExc_OverflowError,
+ "short integer bitfield is greater than maximum");
+ return converterr("integer<H>", arg, msgbuf);
}
+ else
+ *p = (unsigned short) ival;
+ break;
+ }
- case 'i': /* signed int */
- {
- int *p = va_arg(*p_va, int *);
- long ival = PyInt_AsLong(arg);
- if (ival == -1 && PyErr_Occurred())
- return "integer<i>";
- else if (ival > INT_MAX) {
- PyErr_SetString(PyExc_OverflowError,
- "signed integer is greater than maximum");
- return "integer<i>";
- }
- else if (ival < INT_MIN) {
- PyErr_SetString(PyExc_OverflowError,
- "signed integer is less than minimum");
- return "integer<i>";
- }
- else
- *p = ival;
- break;
+ case 'i': {/* signed int */
+ int *p = va_arg(*p_va, int *);
+ long ival = PyInt_AsLong(arg);
+ if (ival == -1 && PyErr_Occurred())
+ return converterr("integer<i>", arg, msgbuf);
+ else if (ival > INT_MAX) {
+ PyErr_SetString(PyExc_OverflowError,
+ "signed integer is greater than maximum");
+ return converterr("integer<i>", arg, msgbuf);
}
- case 'l': /* long int */
- {
- long *p = va_arg(*p_va, long *);
- long ival = PyInt_AsLong(arg);
- if (ival == -1 && PyErr_Occurred())
- return "integer<l>";
- else
- *p = ival;
- break;
+ else if (ival < INT_MIN) {
+ PyErr_SetString(PyExc_OverflowError,
+ "signed integer is less than minimum");
+ return converterr("integer<i>", arg, msgbuf);
}
+ else
+ *p = ival;
+ break;
+ }
+
+ case 'l': {/* long int */
+ long *p = va_arg(*p_va, long *);
+ long ival = PyInt_AsLong(arg);
+ if (ival == -1 && PyErr_Occurred())
+ return converterr("integer<l>", arg, msgbuf);
+ else
+ *p = ival;
+ break;
+ }
#ifdef HAVE_LONG_LONG
- case 'L': /* LONG_LONG */
- {
- LONG_LONG *p = va_arg( *p_va, LONG_LONG * );
- LONG_LONG ival = PyLong_AsLongLong( arg );
- if( ival == (LONG_LONG)-1 && PyErr_Occurred() ) {
- return "long<L>";
- } else {
- *p = ival;
- }
- break;
+ case 'L': {/* LONG_LONG */
+ LONG_LONG *p = va_arg( *p_va, LONG_LONG * );
+ LONG_LONG ival = PyLong_AsLongLong( arg );
+ if( ival == (LONG_LONG)-1 && PyErr_Occurred() ) {
+ return converterr("long<L>", arg, msgbuf);
+ } else {
+ *p = ival;
}
+ break;
+ }
#endif
- case 'f': /* float */
- {
- float *p = va_arg(*p_va, float *);
- double dval = PyFloat_AsDouble(arg);
- if (PyErr_Occurred())
- return "float<f>";
- else
- *p = (float) dval;
- break;
- }
+ case 'f': {/* float */
+ float *p = va_arg(*p_va, float *);
+ double dval = PyFloat_AsDouble(arg);
+ if (PyErr_Occurred())
+ return converterr("float<f>", arg, msgbuf);
+ else
+ *p = (float) dval;
+ break;
+ }
- case 'd': /* double */
- {
- double *p = va_arg(*p_va, double *);
- double dval = PyFloat_AsDouble(arg);
- if (PyErr_Occurred())
- return "float<d>";
- else
- *p = dval;
- break;
- }
+ case 'd': {/* double */
+ double *p = va_arg(*p_va, double *);
+ double dval = PyFloat_AsDouble(arg);
+ if (PyErr_Occurred())
+ return converterr("float<d>", arg, msgbuf);
+ else
+ *p = dval;
+ break;
+ }
#ifndef WITHOUT_COMPLEX
- case 'D': /* complex double */
- {
- Py_complex *p = va_arg(*p_va, Py_complex *);
- Py_complex cval;
- cval = PyComplex_AsCComplex(arg);
- if (PyErr_Occurred())
- return "complex<D>";
- else
- *p = cval;
- break;
- }
+ case 'D': {/* complex double */
+ Py_complex *p = va_arg(*p_va, Py_complex *);
+ Py_complex cval;
+ cval = PyComplex_AsCComplex(arg);
+ if (PyErr_Occurred())
+ return converterr("complex<D>", arg, msgbuf);
+ else
+ *p = cval;
+ break;
+ }
#endif /* WITHOUT_COMPLEX */
- case 'c': /* char */
- {
- char *p = va_arg(*p_va, char *);
- if (PyString_Check(arg) && PyString_Size(arg) == 1)
- *p = PyString_AsString(arg)[0];
- else
- return "char";
- break;
- }
+ case 'c': {/* char */
+ char *p = va_arg(*p_va, char *);
+ if (PyString_Check(arg) && PyString_Size(arg) == 1)
+ *p = PyString_AsString(arg)[0];
+ else
+ return converterr("char", arg, msgbuf);
+ break;
+ }
- case 's': /* string */
- {
- if (*format == '#') {
- void **p = (void **)va_arg(*p_va, char **);
- int *q = va_arg(*p_va, int *);
-
- if (PyString_Check(arg)) {
- *p = PyString_AS_STRING(arg);
- *q = PyString_GET_SIZE(arg);
- }
- else if (PyUnicode_Check(arg)) {
- arg = _PyUnicode_AsDefaultEncodedString(
- arg, NULL);
- if (arg == NULL)
- return "(unicode conversion error)";
- *p = PyString_AS_STRING(arg);
- *q = PyString_GET_SIZE(arg);
- }
- else { /* any buffer-like object */
- PyBufferProcs *pb = arg->ob_type->tp_as_buffer;
- int count;
- if ( pb == NULL ||
- pb->bf_getreadbuffer == NULL ||
- pb->bf_getsegcount == NULL )
- return "string or read-only buffer";
- if ( (*pb->bf_getsegcount)(arg, NULL) != 1 )
- return "string or single-segment read-only buffer";
- if ( (count =
- (*pb->bf_getreadbuffer)(arg, 0, p)) < 0 )
- return "(unspecified)";
- *q = count;
- }
- format++;
- } else {
- char **p = va_arg(*p_va, char **);
+ case 's': {/* string */
+ if (*format == '#') {
+ void **p = (void **)va_arg(*p_va, char **);
+ int *q = va_arg(*p_va, int *);
- if (PyString_Check(arg))
- *p = PyString_AS_STRING(arg);
- else if (PyUnicode_Check(arg)) {
- arg = _PyUnicode_AsDefaultEncodedString(
- arg, NULL);
- if (arg == NULL)
- return "(unicode conversion error)";
- *p = PyString_AS_STRING(arg);
- }
- else
- return "string";
- if ((int)strlen(*p) != PyString_Size(arg))
- return "string without null bytes";
+ if (PyString_Check(arg)) {
+ *p = PyString_AS_STRING(arg);
+ *q = PyString_GET_SIZE(arg);
}
- break;
+ else if (PyUnicode_Check(arg)) {
+ arg = UNICODE_DEFAULT_ENCODING(arg);
+ if (arg == NULL)
+ return converterr(CONV_UNICODE,
+ arg, msgbuf);
+ *p = PyString_AS_STRING(arg);
+ *q = PyString_GET_SIZE(arg);
+ }
+ else { /* any buffer-like object */
+ char *buf;
+ int count = convertbuffer(arg, p, &buf);
+ if (count < 0)
+ return converterr(buf, arg, msgbuf);
+ *q = count;
+ }
+ format++;
+ } else {
+ char **p = va_arg(*p_va, char **);
+
+ if (PyString_Check(arg))
+ *p = PyString_AS_STRING(arg);
+ else if (PyUnicode_Check(arg)) {
+ arg = UNICODE_DEFAULT_ENCODING(arg);
+ if (arg == NULL)
+ return converterr(CONV_UNICODE,
+ arg, msgbuf);
+ *p = PyString_AS_STRING(arg);
+ }
+ else
+ return converterr("string", arg, msgbuf);
+ if ((int)strlen(*p) != PyString_Size(arg))
+ return converterr("string without null bytes",
+ arg, msgbuf);
}
+ break;
+ }
- case 'z': /* string, may be NULL (None) */
- {
- if (*format == '#') { /* any buffer-like object */
- void **p = (void **)va_arg(*p_va, char **);
- int *q = va_arg(*p_va, int *);
+ case 'z': {/* string, may be NULL (None) */
+ if (*format == '#') { /* any buffer-like object */
+ void **p = (void **)va_arg(*p_va, char **);
+ int *q = va_arg(*p_va, int *);
+
+ if (arg == Py_None) {
+ *p = 0;
+ *q = 0;
+ }
+ else if (PyString_Check(arg)) {
+ *p = PyString_AS_STRING(arg);
+ *q = PyString_GET_SIZE(arg);
+ }
+ else if (PyUnicode_Check(arg)) {
+ arg = UNICODE_DEFAULT_ENCODING(arg);
+ if (arg == NULL)
+ return converterr(CONV_UNICODE,
+ arg, msgbuf);
+ *p = PyString_AS_STRING(arg);
+ *q = PyString_GET_SIZE(arg);
+ }
+ else { /* any buffer-like object */
+ char *buf;
+ int count = convertbuffer(arg, p, &buf);
- if (arg == Py_None) {
- *p = 0;
- *q = 0;
- }
- else if (PyString_Check(arg)) {
- *p = PyString_AS_STRING(arg);
- *q = PyString_GET_SIZE(arg);
- }
- else if (PyUnicode_Check(arg)) {
- arg = _PyUnicode_AsDefaultEncodedString(
- arg, NULL);
- if (arg == NULL)
- return "(unicode conversion error)";
- *p = PyString_AS_STRING(arg);
- *q = PyString_GET_SIZE(arg);
- }
- else { /* any buffer-like object */
- PyBufferProcs *pb = arg->ob_type->tp_as_buffer;
- int count;
- if ( pb == NULL ||
- pb->bf_getreadbuffer == NULL ||
- pb->bf_getsegcount == NULL )
- return "string or read-only buffer";
- if ( (*pb->bf_getsegcount)(arg, NULL) != 1 )
- return "string or single-segment read-only buffer";
- if ( (count =
- (*pb->bf_getreadbuffer)(arg, 0, p)) < 0 )
- return "(unspecified)";
- *q = count;
- }
- format++;
- } else {
- char **p = va_arg(*p_va, char **);
+ if (count < 0)
+ return converterr(buf, arg, msgbuf);
+ *q = count;
+ }
+ format++;
+ } else {
+ char **p = va_arg(*p_va, char **);
+ if (arg == Py_None)
+ *p = 0;
+ else if (PyString_Check(arg))
+ *p = PyString_AsString(arg);
+ else if (PyUnicode_Check(arg)) {
+ arg = UNICODE_DEFAULT_ENCODING(arg);
+ if (arg == NULL)
+ return converterr(CONV_UNICODE,
+ arg, msgbuf);
+ *p = PyString_AS_STRING(arg);
+ }
+ else
+ return converterr("string or None",
+ arg, msgbuf);
+ if (*format == '#') {
+ int *q = va_arg(*p_va, int *);
if (arg == Py_None)
- *p = 0;
- else if (PyString_Check(arg))
- *p = PyString_AsString(arg);
- else if (PyUnicode_Check(arg)) {
- arg = _PyUnicode_AsDefaultEncodedString(
- arg, NULL);
- if (arg == NULL)
- return "(unicode conversion error)";
- *p = PyString_AS_STRING(arg);
- }
+ *q = 0;
else
- return "string or None";
- if (*format == '#') {
- int *q = va_arg(*p_va, int *);
- if (arg == Py_None)
- *q = 0;
- else
- *q = PyString_Size(arg);
- format++;
- }
- else if (*p != NULL &&
- (int)strlen(*p) != PyString_Size(arg))
- return "string without null bytes or None";
+ *q = PyString_Size(arg);
+ format++;
}
- break;
+ else if (*p != NULL &&
+ (int)strlen(*p) != PyString_Size(arg))
+ return converterr(
+ "string without null bytes or None",
+ arg, msgbuf);
}
+ break;
+ }
- case 'e': /* encoded string */
- {
- char **buffer;
- const char *encoding;
- PyObject *u, *s;
- int size, recode_strings;
-
- /* Get 'e' parameter: the encoding name */
- encoding = (const char *)va_arg(*p_va, const char *);
- if (encoding == NULL)
- encoding = PyUnicode_GetDefaultEncoding();
+ case 'e': {/* encoded string */
+ char **buffer;
+ const char *encoding;
+ PyObject *u, *s;
+ int size, recode_strings;
+
+ /* Get 'e' parameter: the encoding name */
+ encoding = (const char *)va_arg(*p_va, const char *);
+ if (encoding == NULL)
+ encoding = PyUnicode_GetDefaultEncoding();
- /* Get output buffer parameter:
- 's' (recode all objects via Unicode) or
- 't' (only recode non-string objects)
- */
- if (*format == 's')
- recode_strings = 1;
- else if (*format == 't')
- recode_strings = 0;
- else
- return "(unknown parser marker combination)";
- buffer = (char **)va_arg(*p_va, char **);
- format++;
- if (buffer == NULL)
- return "(buffer is NULL)";
+ /* Get output buffer parameter:
+ 's' (recode all objects via Unicode) or
+ 't' (only recode non-string objects)
+ */
+ if (*format == 's')
+ recode_strings = 1;
+ else if (*format == 't')
+ recode_strings = 0;
+ else
+ return converterr(
+ "(unknown parser marker combination)",
+ arg, msgbuf);
+ buffer = (char **)va_arg(*p_va, char **);
+ format++;
+ if (buffer == NULL)
+ return converterr("(buffer is NULL)",
+ arg, msgbuf);
- /* Encode object */
- if (!recode_strings && PyString_Check(arg)) {
- s = arg;
- Py_INCREF(s);
- }
- else {
+ /* Encode object */
+ if (!recode_strings && PyString_Check(arg)) {
+ s = arg;
+ Py_INCREF(s);
+ }
+ else {
/* Convert object to Unicode */
u = PyUnicode_FromObject(arg);
if (u == NULL)
- return \
- "string or unicode or text buffer";
+ return converterr(
+ "string or unicode or text buffer",
+ arg, msgbuf);
/* Encode object; use default error handling */
s = PyUnicode_AsEncodedString(u,
@@ -727,234 +714,227 @@ convertsimple1(PyObject *arg, char **p_format, va_list *p_va)
NULL);
Py_DECREF(u);
if (s == NULL)
- return "(encoding failed)";
+ return converterr("(encoding failed)",
+ arg, msgbuf);
if (!PyString_Check(s)) {
Py_DECREF(s);
- return \
- "(encoder failed to return a string)";
- }
+ return converterr(
+ "(encoder failed to return a string)",
+ arg, msgbuf);
}
- size = PyString_GET_SIZE(s);
-
- /* Write output; output is guaranteed to be
- 0-terminated */
- if (*format == '#') {
- /* Using buffer length parameter '#':
-
- - if *buffer is NULL, a new buffer
- of the needed size is allocated and
- the data copied into it; *buffer is
- updated to point to the new buffer;
- the caller is responsible for
- PyMem_Free()ing it after usage
-
- - if *buffer is not NULL, the data
- is copied to *buffer; *buffer_len
- has to be set to the size of the
- buffer on input; buffer overflow is
- signalled with an error; buffer has
- to provide enough room for the
- encoded string plus the trailing
- 0-byte
-
- - in both cases, *buffer_len is
- updated to the size of the buffer
- /excluding/ the trailing 0-byte
-
- */
- int *buffer_len = va_arg(*p_va, int *);
+ }
+ size = PyString_GET_SIZE(s);
+
+ /* Write output; output is guaranteed to be 0-terminated */
+ if (*format == '#') {
+ /* Using buffer length parameter '#':
+
+ - if *buffer is NULL, a new buffer of the
+ needed size is allocated and the data
+ copied into it; *buffer is updated to point
+ to the new buffer; the caller is
+ responsible for PyMem_Free()ing it after
+ usage
+
+ - if *buffer is not NULL, the data is
+ copied to *buffer; *buffer_len has to be
+ set to the size of the buffer on input;
+ buffer overflow is signalled with an error;
+ buffer has to provide enough room for the
+ encoded string plus the trailing 0-byte
+
+ - in both cases, *buffer_len is updated to
+ the size of the buffer /excluding/ the
+ trailing 0-byte
+
+ */
+ int *buffer_len = va_arg(*p_va, int *);
- format++;
- if (buffer_len == NULL)
- return "(buffer_len is NULL)";
+ format++;
+ if (buffer_len == NULL)
+ return converterr(
+ "(buffer_len is NULL)",
+ arg, msgbuf);
+ if (*buffer == NULL) {
+ *buffer = PyMem_NEW(char, size + 1);
if (*buffer == NULL) {
- *buffer = PyMem_NEW(char, size + 1);
- if (*buffer == NULL) {
- Py_DECREF(s);
- return "(memory error)";
- }
- } else {
- if (size + 1 > *buffer_len) {
- Py_DECREF(s);
- return "(buffer overflow)";
- }
+ Py_DECREF(s);
+ return converterr(
+ "(memory error)",
+ arg, msgbuf);
}
- memcpy(*buffer,
- PyString_AS_STRING(s),
- size + 1);
- *buffer_len = size;
} else {
- /* Using a 0-terminated buffer:
-
- - the encoded string has to be
- 0-terminated for this variant to
- work; if it is not, an error raised
-
- - a new buffer of the needed size
- is allocated and the data copied
- into it; *buffer is updated to
- point to the new buffer; the caller
- is responsible for PyMem_Free()ing it
- after usage
-
- */
- if ((int)strlen(PyString_AS_STRING(s)) != size)
- return "(encoded string without NULL bytes)";
- *buffer = PyMem_NEW(char, size + 1);
- if (*buffer == NULL) {
+ if (size + 1 > *buffer_len) {
Py_DECREF(s);
- return "(memory error)";
+ return converterr(
+ "(buffer overflow)",
+ arg, msgbuf);
}
- memcpy(*buffer,
- PyString_AS_STRING(s),
- size + 1);
}
- Py_DECREF(s);
- break;
- }
+ memcpy(*buffer,
+ PyString_AS_STRING(s),
+ size + 1);
+ *buffer_len = size;
+ } else {
+ /* Using a 0-terminated buffer:
+
+ - the encoded string has to be 0-terminated
+ for this variant to work; if it is not, an
+ error raised
+
+ - a new buffer of the needed size is
+ allocated and the data copied into it;
+ *buffer is updated to point to the new
+ buffer; the caller is responsible for
+ PyMem_Free()ing it after usage
- case 'u': /* raw unicode buffer (Py_UNICODE *) */
- {
- if (*format == '#') { /* any buffer-like object */
- void **p = (void **)va_arg(*p_va, char **);
- PyBufferProcs *pb = arg->ob_type->tp_as_buffer;
- int *q = va_arg(*p_va, int *);
- int count;
-
- if ( pb == NULL ||
- pb->bf_getreadbuffer == NULL ||
- pb->bf_getsegcount == NULL )
- return "unicode or read-only buffer";
- if ( (*pb->bf_getsegcount)(arg, NULL) != 1 )
- return "unicode or single-segment read-only buffer";
- if ( (count =
- (*pb->bf_getreadbuffer)(arg, 0, p)) < 0 )
- return "(unspecified)";
- /* buffer interface returns bytes, we want
- length in characters */
- *q = count/(sizeof(Py_UNICODE));
- format++;
- } else {
- Py_UNICODE **p = va_arg(*p_va, Py_UNICODE **);
-
- if (PyUnicode_Check(arg))
- *p = PyUnicode_AS_UNICODE(arg);
- else
- return "unicode";
+ */
+ if ((int)strlen(PyString_AS_STRING(s)) != size)
+ return converterr(
+ "(encoded string without NULL bytes)",
+ arg, msgbuf);
+ *buffer = PyMem_NEW(char, size + 1);
+ if (*buffer == NULL) {
+ Py_DECREF(s);
+ return converterr("(memory error)",
+ arg, msgbuf);
}
- break;
+ memcpy(*buffer,
+ PyString_AS_STRING(s),
+ size + 1);
}
+ Py_DECREF(s);
+ break;
+ }
- case 'S': /* string object */
- {
- PyObject **p = va_arg(*p_va, PyObject **);
- if (PyString_Check(arg))
- *p = arg;
+ case 'u': {/* raw unicode buffer (Py_UNICODE *) */
+ if (*format == '#') { /* any buffer-like object */
+ void **p = (void **)va_arg(*p_va, char **);
+ int *q = va_arg(*p_va, int *);
+ char *buf;
+ int count = convertbuffer(arg, p, &buf);
+
+ if (count < 0)
+ return converterr(buf, arg, msgbuf);
+ *q = count/(sizeof(Py_UNICODE));
+ format++;
+ } else {
+ Py_UNICODE **p = va_arg(*p_va, Py_UNICODE **);
+
+ if (PyUnicode_Check(arg))
+ *p = PyUnicode_AS_UNICODE(arg);
else
- return "string";
- break;
+ return converterr("unicode", arg, msgbuf);
}
+ break;
+ }
+
+ case 'S': { /* string object */
+ PyObject **p = va_arg(*p_va, PyObject **);
+ if (PyString_Check(arg))
+ *p = arg;
+ else
+ return converterr("string", arg, msgbuf);
+ break;
+ }
- case 'U': /* Unicode object */
- {
- PyObject **p = va_arg(*p_va, PyObject **);
- if (PyUnicode_Check(arg))
+ case 'U': { /* Unicode object */
+ PyObject **p = va_arg(*p_va, PyObject **);
+ if (PyUnicode_Check(arg))
+ *p = arg;
+ else
+ return converterr("unicode", arg, msgbuf);
+ break;
+ }
+
+ case 'O': { /* object */
+ PyTypeObject *type;
+ PyObject **p;
+ if (*format == '!') {
+ type = va_arg(*p_va, PyTypeObject*);
+ p = va_arg(*p_va, PyObject **);
+ format++;
+ if (arg->ob_type == type)
*p = arg;
else
- return "unicode";
- break;
- }
-
- case 'O': /* object */
- {
- PyTypeObject *type;
- PyObject **p;
- if (*format == '!') {
- type = va_arg(*p_va, PyTypeObject*);
- p = va_arg(*p_va, PyObject **);
- format++;
- if (arg->ob_type == type)
- *p = arg;
- else
- return type->tp_name;
+ return converterr(type->tp_name, arg, msgbuf);
- }
- else if (*format == '?') {
- inquiry pred = va_arg(*p_va, inquiry);
- p = va_arg(*p_va, PyObject **);
- format++;
- if ((*pred)(arg))
- *p = arg;
- else
- return "(unspecified)";
-
- }
- else if (*format == '&') {
- typedef int (*converter)(PyObject *, void *);
- converter convert = va_arg(*p_va, converter);
- void *addr = va_arg(*p_va, void *);
- format++;
- if (! (*convert)(arg, addr))
- return "(unspecified)";
- }
- else {
- p = va_arg(*p_va, PyObject **);
+ }
+ else if (*format == '?') {
+ inquiry pred = va_arg(*p_va, inquiry);
+ p = va_arg(*p_va, PyObject **);
+ format++;
+ if ((*pred)(arg))
*p = arg;
- }
- break;
+ else
+ return converterr("(unspecified)",
+ arg, msgbuf);
+
}
+ else if (*format == '&') {
+ typedef int (*converter)(PyObject *, void *);
+ converter convert = va_arg(*p_va, converter);
+ void *addr = va_arg(*p_va, void *);
+ format++;
+ if (! (*convert)(arg, addr))
+ return converterr("(unspecified)",
+ arg, msgbuf);
+ }
+ else {
+ p = va_arg(*p_va, PyObject **);
+ *p = arg;
+ }
+ break;
+ }
- case 'w': /* memory buffer, read-write access */
- {
- void **p = va_arg(*p_va, void **);
- PyBufferProcs *pb = arg->ob_type->tp_as_buffer;
- int count;
+ case 'w': { /* memory buffer, read-write access */
+ void **p = va_arg(*p_va, void **);
+ PyBufferProcs *pb = arg->ob_type->tp_as_buffer;
+ int count;
- if ( pb == NULL || pb->bf_getwritebuffer == NULL ||
- pb->bf_getsegcount == NULL )
- return "read-write buffer";
- if ( (*pb->bf_getsegcount)(arg, NULL) != 1 )
- return "single-segment read-write buffer";
- if ( (count = pb->bf_getwritebuffer(arg, 0, p)) < 0 )
- return "(unspecified)";
- if (*format == '#') {
- int *q = va_arg(*p_va, int *);
-
- *q = count;
- format++;
- }
- break;
+ if (pb == NULL ||
+ pb->bf_getwritebuffer == NULL ||
+ pb->bf_getsegcount == NULL)
+ return converterr("read-write buffer", arg, msgbuf);
+ if ((*pb->bf_getsegcount)(arg, NULL) != 1)
+ return converterr("single-segment read-write buffer",
+ arg, msgbuf);
+ if ((count = pb->bf_getwritebuffer(arg, 0, p)) < 0)
+ return converterr("(unspecified)", arg, msgbuf);
+ if (*format == '#') {
+ int *q = va_arg(*p_va, int *);
+
+ *q = count;
+ format++;
}
+ break;
+ }
- case 't': /* 8-bit character buffer, read-only access */
- {
- const char **p = va_arg(*p_va, const char **);
- PyBufferProcs *pb = arg->ob_type->tp_as_buffer;
- int count;
-
- if ( *format++ != '#' )
- return "invalid use of 't' format character";
- if ( !PyType_HasFeature(
- arg->ob_type,
- Py_TPFLAGS_HAVE_GETCHARBUFFER) ||
- pb == NULL ||
- pb->bf_getcharbuffer == NULL ||
- pb->bf_getsegcount == NULL )
- return "string or read-only character buffer";
- if ( (*pb->bf_getsegcount)(arg, NULL) != 1 )
- return "string or single-segment read-only buffer";
- if ( (count = pb->bf_getcharbuffer(arg, 0, p)) < 0 )
- return "(unspecified)";
-
- *va_arg(*p_va, int *) = count;
-
- break;
- }
+ case 't': { /* 8-bit character buffer, read-only access */
+ const char **p = va_arg(*p_va, const char **);
+ char *buf;
+ int count;
-
+ if (*format++ != '#')
+ return converterr(
+ "invalid use of 't' format character",
+ arg, msgbuf);
+ if (!PyType_HasFeature(arg->ob_type,
+ Py_TPFLAGS_HAVE_GETCHARBUFFER))
+ return converterr(
+ "string or read-only character buffer",
+ arg, msgbuf);
+
+ count = convertbuffer(arg, (void **)p, &buf);
+ if (count < 0)
+ return converterr(buf, arg, msgbuf);
+ *va_arg(*p_va, int *) = count;
+ break;
+ }
+
default:
- return "impossible<bad format char>";
+ return converterr("impossible<bad format char>", arg, msgbuf);
}
@@ -962,6 +942,25 @@ convertsimple1(PyObject *arg, char **p_format, va_list *p_va)
return NULL;
}
+int convertbuffer(PyObject *arg, void **p, char **errmsg)
+{
+ PyBufferProcs *pb = arg->ob_type->tp_as_buffer;
+ int count;
+ if (pb == NULL ||
+ pb->bf_getreadbuffer == NULL ||
+ pb->bf_getsegcount == NULL) {
+ *errmsg = "string or read-only buffer";
+ return -1;
+ }
+ if ((*pb->bf_getsegcount)(arg, NULL) != 1) {
+ *errmsg = "string or single-segment read-only buffer";
+ return -1;
+ }
+ if ((count = (*pb->bf_getreadbuffer)(arg, 0, p)) < 0) {
+ *errmsg = "(unspecified)";
+ }
+ return count;
+}
/* Support for keyword arguments donated by
Geoff Philbrick <philbric@delphi.hks.com> */