[pypy-commit] pypy default: Update cpyext C sources with recent 2.7 version.
amauryfa
noreply at buildbot.pypy.org
Wed May 2 01:01:58 CEST 2012
Author: Amaury Forgeot d'Arc <amauryfa at gmail.com>
Branch:
Changeset: r54843:d15f5852eabb
Date: 2012-04-28 12:19 +0200
http://bitbucket.org/pypy/pypy/changeset/d15f5852eabb/
Log: Update cpyext C sources with recent 2.7 version. mostly whitespace
change, but also
- exarkun's rewrite of the PyArg_Parse cleanup list.
- remove all "#if 0" from these functions
diff --git a/pypy/module/cpyext/api.py b/pypy/module/cpyext/api.py
--- a/pypy/module/cpyext/api.py
+++ b/pypy/module/cpyext/api.py
@@ -927,12 +927,12 @@
source_dir / "pyerrors.c",
source_dir / "modsupport.c",
source_dir / "getargs.c",
+ source_dir / "abstract.c",
source_dir / "stringobject.c",
source_dir / "mysnprintf.c",
source_dir / "pythonrun.c",
source_dir / "sysmodule.c",
source_dir / "bufferobject.c",
- source_dir / "object.c",
source_dir / "cobject.c",
source_dir / "structseq.c",
source_dir / "capsule.c",
diff --git a/pypy/module/cpyext/include/pyerrors.h b/pypy/module/cpyext/include/pyerrors.h
--- a/pypy/module/cpyext/include/pyerrors.h
+++ b/pypy/module/cpyext/include/pyerrors.h
@@ -29,6 +29,10 @@
# define vsnprintf _vsnprintf
#endif
+#include <stdarg.h>
+PyAPI_FUNC(int) PyOS_snprintf(char *str, size_t size, const char *format, ...);
+PyAPI_FUNC(int) PyOS_vsnprintf(char *str, size_t size, const char *format, va_list va);
+
#ifdef __cplusplus
}
#endif
diff --git a/pypy/module/cpyext/include/stringobject.h b/pypy/module/cpyext/include/stringobject.h
--- a/pypy/module/cpyext/include/stringobject.h
+++ b/pypy/module/cpyext/include/stringobject.h
@@ -7,8 +7,6 @@
extern "C" {
#endif
-int PyOS_snprintf(char *str, size_t size, const char *format, ...);
-
#define PyString_GET_SIZE(op) PyString_Size(op)
#define PyString_AS_STRING(op) PyString_AsString(op)
diff --git a/pypy/module/cpyext/src/bufferobject.c b/pypy/module/cpyext/src/bufferobject.c
--- a/pypy/module/cpyext/src/bufferobject.c
+++ b/pypy/module/cpyext/src/bufferobject.c
@@ -13,207 +13,207 @@
static int
get_buf(PyBufferObject *self, void **ptr, Py_ssize_t *size,
- enum buffer_t buffer_type)
+ enum buffer_t buffer_type)
{
- if (self->b_base == NULL) {
- assert (ptr != NULL);
- *ptr = self->b_ptr;
- *size = self->b_size;
- }
- else {
- Py_ssize_t count, offset;
- readbufferproc proc = 0;
- PyBufferProcs *bp = self->b_base->ob_type->tp_as_buffer;
- if ((*bp->bf_getsegcount)(self->b_base, NULL) != 1) {
- PyErr_SetString(PyExc_TypeError,
- "single-segment buffer object expected");
- return 0;
- }
- if ((buffer_type == READ_BUFFER) ||
- ((buffer_type == ANY_BUFFER) && self->b_readonly))
- proc = bp->bf_getreadbuffer;
- else if ((buffer_type == WRITE_BUFFER) ||
- (buffer_type == ANY_BUFFER))
- proc = (readbufferproc)bp->bf_getwritebuffer;
- else if (buffer_type == CHAR_BUFFER) {
+ if (self->b_base == NULL) {
+ assert (ptr != NULL);
+ *ptr = self->b_ptr;
+ *size = self->b_size;
+ }
+ else {
+ Py_ssize_t count, offset;
+ readbufferproc proc = 0;
+ PyBufferProcs *bp = self->b_base->ob_type->tp_as_buffer;
+ if ((*bp->bf_getsegcount)(self->b_base, NULL) != 1) {
+ PyErr_SetString(PyExc_TypeError,
+ "single-segment buffer object expected");
+ return 0;
+ }
+ if ((buffer_type == READ_BUFFER) ||
+ ((buffer_type == ANY_BUFFER) && self->b_readonly))
+ proc = bp->bf_getreadbuffer;
+ else if ((buffer_type == WRITE_BUFFER) ||
+ (buffer_type == ANY_BUFFER))
+ proc = (readbufferproc)bp->bf_getwritebuffer;
+ else if (buffer_type == CHAR_BUFFER) {
if (!PyType_HasFeature(self->ob_type,
- Py_TPFLAGS_HAVE_GETCHARBUFFER)) {
- PyErr_SetString(PyExc_TypeError,
- "Py_TPFLAGS_HAVE_GETCHARBUFFER needed");
- return 0;
- }
- proc = (readbufferproc)bp->bf_getcharbuffer;
- }
- if (!proc) {
- char *buffer_type_name;
- switch (buffer_type) {
- case READ_BUFFER:
- buffer_type_name = "read";
- break;
- case WRITE_BUFFER:
- buffer_type_name = "write";
- break;
- case CHAR_BUFFER:
- buffer_type_name = "char";
- break;
- default:
- buffer_type_name = "no";
- break;
- }
- PyErr_Format(PyExc_TypeError,
- "%s buffer type not available",
- buffer_type_name);
- return 0;
- }
- if ((count = (*proc)(self->b_base, 0, ptr)) < 0)
- return 0;
- /* apply constraints to the start/end */
- if (self->b_offset > count)
- offset = count;
- else
- offset = self->b_offset;
- *(char **)ptr = *(char **)ptr + offset;
- if (self->b_size == Py_END_OF_BUFFER)
- *size = count;
- else
- *size = self->b_size;
- if (offset + *size > count)
- *size = count - offset;
- }
- return 1;
+ Py_TPFLAGS_HAVE_GETCHARBUFFER)) {
+ PyErr_SetString(PyExc_TypeError,
+ "Py_TPFLAGS_HAVE_GETCHARBUFFER needed");
+ return 0;
+ }
+ proc = (readbufferproc)bp->bf_getcharbuffer;
+ }
+ if (!proc) {
+ char *buffer_type_name;
+ switch (buffer_type) {
+ case READ_BUFFER:
+ buffer_type_name = "read";
+ break;
+ case WRITE_BUFFER:
+ buffer_type_name = "write";
+ break;
+ case CHAR_BUFFER:
+ buffer_type_name = "char";
+ break;
+ default:
+ buffer_type_name = "no";
+ break;
+ }
+ PyErr_Format(PyExc_TypeError,
+ "%s buffer type not available",
+ buffer_type_name);
+ return 0;
+ }
+ if ((count = (*proc)(self->b_base, 0, ptr)) < 0)
+ return 0;
+ /* apply constraints to the start/end */
+ if (self->b_offset > count)
+ offset = count;
+ else
+ offset = self->b_offset;
+ *(char **)ptr = *(char **)ptr + offset;
+ if (self->b_size == Py_END_OF_BUFFER)
+ *size = count;
+ else
+ *size = self->b_size;
+ if (offset + *size > count)
+ *size = count - offset;
+ }
+ return 1;
}
static PyObject *
buffer_from_memory(PyObject *base, Py_ssize_t size, Py_ssize_t offset, void *ptr,
- int readonly)
+ int readonly)
{
- PyBufferObject * b;
+ PyBufferObject * b;
- if (size < 0 && size != Py_END_OF_BUFFER) {
- PyErr_SetString(PyExc_ValueError,
- "size must be zero or positive");
- return NULL;
- }
- if (offset < 0) {
- PyErr_SetString(PyExc_ValueError,
- "offset must be zero or positive");
- return NULL;
- }
+ if (size < 0 && size != Py_END_OF_BUFFER) {
+ PyErr_SetString(PyExc_ValueError,
+ "size must be zero or positive");
+ return NULL;
+ }
+ if (offset < 0) {
+ PyErr_SetString(PyExc_ValueError,
+ "offset must be zero or positive");
+ return NULL;
+ }
- b = PyObject_NEW(PyBufferObject, &PyBuffer_Type);
- if ( b == NULL )
- return NULL;
+ b = PyObject_NEW(PyBufferObject, &PyBuffer_Type);
+ if ( b == NULL )
+ return NULL;
- Py_XINCREF(base);
- b->b_base = base;
- b->b_ptr = ptr;
- b->b_size = size;
- b->b_offset = offset;
- b->b_readonly = readonly;
- b->b_hash = -1;
+ Py_XINCREF(base);
+ b->b_base = base;
+ b->b_ptr = ptr;
+ b->b_size = size;
+ b->b_offset = offset;
+ b->b_readonly = readonly;
+ b->b_hash = -1;
- return (PyObject *) b;
+ return (PyObject *) b;
}
static PyObject *
buffer_from_object(PyObject *base, Py_ssize_t size, Py_ssize_t offset, int readonly)
{
- if (offset < 0) {
- PyErr_SetString(PyExc_ValueError,
- "offset must be zero or positive");
- return NULL;
- }
- if ( PyBuffer_Check(base) && (((PyBufferObject *)base)->b_base) ) {
- /* another buffer, refer to the base object */
- PyBufferObject *b = (PyBufferObject *)base;
- if (b->b_size != Py_END_OF_BUFFER) {
- Py_ssize_t base_size = b->b_size - offset;
- if (base_size < 0)
- base_size = 0;
- if (size == Py_END_OF_BUFFER || size > base_size)
- size = base_size;
- }
- offset += b->b_offset;
- base = b->b_base;
- }
- return buffer_from_memory(base, size, offset, NULL, readonly);
+ if (offset < 0) {
+ PyErr_SetString(PyExc_ValueError,
+ "offset must be zero or positive");
+ return NULL;
+ }
+ if ( PyBuffer_Check(base) && (((PyBufferObject *)base)->b_base) ) {
+ /* another buffer, refer to the base object */
+ PyBufferObject *b = (PyBufferObject *)base;
+ if (b->b_size != Py_END_OF_BUFFER) {
+ Py_ssize_t base_size = b->b_size - offset;
+ if (base_size < 0)
+ base_size = 0;
+ if (size == Py_END_OF_BUFFER || size > base_size)
+ size = base_size;
+ }
+ offset += b->b_offset;
+ base = b->b_base;
+ }
+ return buffer_from_memory(base, size, offset, NULL, readonly);
}
PyObject *
PyBuffer_FromObject(PyObject *base, Py_ssize_t offset, Py_ssize_t size)
{
- PyBufferProcs *pb = base->ob_type->tp_as_buffer;
+ PyBufferProcs *pb = base->ob_type->tp_as_buffer;
- if ( pb == NULL ||
- pb->bf_getreadbuffer == NULL ||
- pb->bf_getsegcount == NULL )
- {
- PyErr_SetString(PyExc_TypeError, "buffer object expected");
- return NULL;
- }
+ if ( pb == NULL ||
+ pb->bf_getreadbuffer == NULL ||
+ pb->bf_getsegcount == NULL )
+ {
+ PyErr_SetString(PyExc_TypeError, "buffer object expected");
+ return NULL;
+ }
- return buffer_from_object(base, size, offset, 1);
+ return buffer_from_object(base, size, offset, 1);
}
PyObject *
PyBuffer_FromReadWriteObject(PyObject *base, Py_ssize_t offset, Py_ssize_t size)
{
- PyBufferProcs *pb = base->ob_type->tp_as_buffer;
+ PyBufferProcs *pb = base->ob_type->tp_as_buffer;
- if ( pb == NULL ||
- pb->bf_getwritebuffer == NULL ||
- pb->bf_getsegcount == NULL )
- {
- PyErr_SetString(PyExc_TypeError, "buffer object expected");
- return NULL;
- }
+ if ( pb == NULL ||
+ pb->bf_getwritebuffer == NULL ||
+ pb->bf_getsegcount == NULL )
+ {
+ PyErr_SetString(PyExc_TypeError, "buffer object expected");
+ return NULL;
+ }
- return buffer_from_object(base, size, offset, 0);
+ return buffer_from_object(base, size, offset, 0);
}
PyObject *
PyBuffer_FromMemory(void *ptr, Py_ssize_t size)
{
- return buffer_from_memory(NULL, size, 0, ptr, 1);
+ return buffer_from_memory(NULL, size, 0, ptr, 1);
}
PyObject *
PyBuffer_FromReadWriteMemory(void *ptr, Py_ssize_t size)
{
- return buffer_from_memory(NULL, size, 0, ptr, 0);
+ return buffer_from_memory(NULL, size, 0, ptr, 0);
}
PyObject *
PyBuffer_New(Py_ssize_t size)
{
- PyObject *o;
- PyBufferObject * b;
+ PyObject *o;
+ PyBufferObject * b;
- if (size < 0) {
- PyErr_SetString(PyExc_ValueError,
- "size must be zero or positive");
- return NULL;
- }
- if (sizeof(*b) > PY_SSIZE_T_MAX - size) {
- /* unlikely */
- return PyErr_NoMemory();
- }
- /* Inline PyObject_New */
- o = (PyObject *)PyObject_MALLOC(sizeof(*b) + size);
- if ( o == NULL )
- return PyErr_NoMemory();
- b = (PyBufferObject *) PyObject_INIT(o, &PyBuffer_Type);
+ if (size < 0) {
+ PyErr_SetString(PyExc_ValueError,
+ "size must be zero or positive");
+ return NULL;
+ }
+ if (sizeof(*b) > PY_SSIZE_T_MAX - size) {
+ /* unlikely */
+ return PyErr_NoMemory();
+ }
+ /* Inline PyObject_New */
+ o = (PyObject *)PyObject_MALLOC(sizeof(*b) + size);
+ if ( o == NULL )
+ return PyErr_NoMemory();
+ b = (PyBufferObject *) PyObject_INIT(o, &PyBuffer_Type);
- b->b_base = NULL;
- b->b_ptr = (void *)(b + 1);
- b->b_size = size;
- b->b_offset = 0;
- b->b_readonly = 0;
- b->b_hash = -1;
+ b->b_base = NULL;
+ b->b_ptr = (void *)(b + 1);
+ b->b_size = size;
+ b->b_offset = 0;
+ b->b_readonly = 0;
+ b->b_hash = -1;
- return o;
+ return o;
}
/* Methods */
@@ -221,19 +221,21 @@
static PyObject *
buffer_new(PyTypeObject *type, PyObject *args, PyObject *kw)
{
- PyObject *ob;
- Py_ssize_t offset = 0;
- Py_ssize_t size = Py_END_OF_BUFFER;
+ PyObject *ob;
+ Py_ssize_t offset = 0;
+ Py_ssize_t size = Py_END_OF_BUFFER;
- /*if (PyErr_WarnPy3k("buffer() not supported in 3.x", 1) < 0)
- return NULL;*/
-
- if (!_PyArg_NoKeywords("buffer()", kw))
- return NULL;
+ /*
+ * if (PyErr_WarnPy3k("buffer() not supported in 3.x", 1) < 0)
+ * return NULL;
+ */
- if (!PyArg_ParseTuple(args, "O|nn:buffer", &ob, &offset, &size))
- return NULL;
- return PyBuffer_FromObject(ob, offset, size);
+ if (!_PyArg_NoKeywords("buffer()", kw))
+ return NULL;
+
+ if (!PyArg_ParseTuple(args, "O|nn:buffer", &ob, &offset, &size))
+ return NULL;
+ return PyBuffer_FromObject(ob, offset, size);
}
PyDoc_STRVAR(buffer_doc,
@@ -248,99 +250,99 @@
static void
buffer_dealloc(PyBufferObject *self)
{
- Py_XDECREF(self->b_base);
- PyObject_DEL(self);
+ Py_XDECREF(self->b_base);
+ PyObject_DEL(self);
}
static int
buffer_compare(PyBufferObject *self, PyBufferObject *other)
{
- void *p1, *p2;
- Py_ssize_t len_self, len_other, min_len;
- int cmp;
+ void *p1, *p2;
+ Py_ssize_t len_self, len_other, min_len;
+ int cmp;
- if (!get_buf(self, &p1, &len_self, ANY_BUFFER))
- return -1;
- if (!get_buf(other, &p2, &len_other, ANY_BUFFER))
- return -1;
- min_len = (len_self < len_other) ? len_self : len_other;
- if (min_len > 0) {
- cmp = memcmp(p1, p2, min_len);
- if (cmp != 0)
- return cmp < 0 ? -1 : 1;
- }
- return (len_self < len_other) ? -1 : (len_self > len_other) ? 1 : 0;
+ if (!get_buf(self, &p1, &len_self, ANY_BUFFER))
+ return -1;
+ if (!get_buf(other, &p2, &len_other, ANY_BUFFER))
+ return -1;
+ min_len = (len_self < len_other) ? len_self : len_other;
+ if (min_len > 0) {
+ cmp = memcmp(p1, p2, min_len);
+ if (cmp != 0)
+ return cmp < 0 ? -1 : 1;
+ }
+ return (len_self < len_other) ? -1 : (len_self > len_other) ? 1 : 0;
}
static PyObject *
buffer_repr(PyBufferObject *self)
{
- const char *status = self->b_readonly ? "read-only" : "read-write";
+ const char *status = self->b_readonly ? "read-only" : "read-write";
if ( self->b_base == NULL )
- return PyString_FromFormat("<%s buffer ptr %p, size %zd at %p>",
- status,
- self->b_ptr,
- self->b_size,
- self);
- else
- return PyString_FromFormat(
- "<%s buffer for %p, size %zd, offset %zd at %p>",
- status,
- self->b_base,
- self->b_size,
- self->b_offset,
- self);
+ return PyString_FromFormat("<%s buffer ptr %p, size %zd at %p>",
+ status,
+ self->b_ptr,
+ self->b_size,
+ self);
+ else
+ return PyString_FromFormat(
+ "<%s buffer for %p, size %zd, offset %zd at %p>",
+ status,
+ self->b_base,
+ self->b_size,
+ self->b_offset,
+ self);
}
static long
buffer_hash(PyBufferObject *self)
{
- void *ptr;
- Py_ssize_t size;
- register Py_ssize_t len;
- register unsigned char *p;
- register long x;
+ void *ptr;
+ Py_ssize_t size;
+ register Py_ssize_t len;
+ register unsigned char *p;
+ register long x;
- if ( self->b_hash != -1 )
- return self->b_hash;
+ if ( self->b_hash != -1 )
+ return self->b_hash;
- /* XXX potential bugs here, a readonly buffer does not imply that the
- * underlying memory is immutable. b_readonly is a necessary but not
- * sufficient condition for a buffer to be hashable. Perhaps it would
- * be better to only allow hashing if the underlying object is known to
- * be immutable (e.g. PyString_Check() is true). Another idea would
- * be to call tp_hash on the underlying object and see if it raises
- * an error. */
- if ( !self->b_readonly )
- {
- PyErr_SetString(PyExc_TypeError,
- "writable buffers are not hashable");
- return -1;
- }
+ /* XXX potential bugs here, a readonly buffer does not imply that the
+ * underlying memory is immutable. b_readonly is a necessary but not
+ * sufficient condition for a buffer to be hashable. Perhaps it would
+ * be better to only allow hashing if the underlying object is known to
+ * be immutable (e.g. PyString_Check() is true). Another idea would
+ * be to call tp_hash on the underlying object and see if it raises
+ * an error. */
+ if ( !self->b_readonly )
+ {
+ PyErr_SetString(PyExc_TypeError,
+ "writable buffers are not hashable");
+ return -1;
+ }
- if (!get_buf(self, &ptr, &size, ANY_BUFFER))
- return -1;
- p = (unsigned char *) ptr;
- len = size;
- x = *p << 7;
- while (--len >= 0)
- x = (1000003*x) ^ *p++;
- x ^= size;
- if (x == -1)
- x = -2;
- self->b_hash = x;
- return x;
+ if (!get_buf(self, &ptr, &size, ANY_BUFFER))
+ return -1;
+ p = (unsigned char *) ptr;
+ len = size;
+ x = *p << 7;
+ while (--len >= 0)
+ x = (1000003*x) ^ *p++;
+ x ^= size;
+ if (x == -1)
+ x = -2;
+ self->b_hash = x;
+ return x;
}
static PyObject *
buffer_str(PyBufferObject *self)
{
- void *ptr;
- Py_ssize_t size;
- if (!get_buf(self, &ptr, &size, ANY_BUFFER))
- return NULL;
- return PyString_FromStringAndSize((const char *)ptr, size);
+ void *ptr;
+ Py_ssize_t size;
+ if (!get_buf(self, &ptr, &size, ANY_BUFFER))
+ return NULL;
+ return PyString_FromStringAndSize((const char *)ptr, size);
}
/* Sequence methods */
@@ -348,374 +350,372 @@
static Py_ssize_t
buffer_length(PyBufferObject *self)
{
- void *ptr;
- Py_ssize_t size;
- if (!get_buf(self, &ptr, &size, ANY_BUFFER))
- return -1;
- return size;
+ void *ptr;
+ Py_ssize_t size;
+ if (!get_buf(self, &ptr, &size, ANY_BUFFER))
+ return -1;
+ return size;
}
static PyObject *
buffer_concat(PyBufferObject *self, PyObject *other)
{
- PyBufferProcs *pb = other->ob_type->tp_as_buffer;
- void *ptr1, *ptr2;
- char *p;
- PyObject *ob;
- Py_ssize_t size, count;
+ PyBufferProcs *pb = other->ob_type->tp_as_buffer;
+ void *ptr1, *ptr2;
+ char *p;
+ PyObject *ob;
+ Py_ssize_t size, count;
- if ( pb == NULL ||
- pb->bf_getreadbuffer == NULL ||
- pb->bf_getsegcount == NULL )
- {
- PyErr_BadArgument();
- return NULL;
- }
- if ( (*pb->bf_getsegcount)(other, NULL) != 1 )
- {
- /* ### use a different exception type/message? */
- PyErr_SetString(PyExc_TypeError,
- "single-segment buffer object expected");
- return NULL;
- }
+ if ( pb == NULL ||
+ pb->bf_getreadbuffer == NULL ||
+ pb->bf_getsegcount == NULL )
+ {
+ PyErr_BadArgument();
+ return NULL;
+ }
+ if ( (*pb->bf_getsegcount)(other, NULL) != 1 )
+ {
+ /* ### use a different exception type/message? */
+ PyErr_SetString(PyExc_TypeError,
+ "single-segment buffer object expected");
+ return NULL;
+ }
- if (!get_buf(self, &ptr1, &size, ANY_BUFFER))
- return NULL;
-
- /* optimize special case */
- if ( size == 0 )
- {
- Py_INCREF(other);
- return other;
- }
+ if (!get_buf(self, &ptr1, &size, ANY_BUFFER))
+ return NULL;
- if ( (count = (*pb->bf_getreadbuffer)(other, 0, &ptr2)) < 0 )
- return NULL;
+ /* optimize special case */
+ if ( size == 0 )
+ {
+ Py_INCREF(other);
+ return other;
+ }
- assert(count <= PY_SIZE_MAX - size);
+ if ( (count = (*pb->bf_getreadbuffer)(other, 0, &ptr2)) < 0 )
+ return NULL;
- ob = PyString_FromStringAndSize(NULL, size + count);
- if ( ob == NULL )
- return NULL;
- p = PyString_AS_STRING(ob);
- memcpy(p, ptr1, size);
- memcpy(p + size, ptr2, count);
+ assert(count <= PY_SIZE_MAX - size);
- /* there is an extra byte in the string object, so this is safe */
- p[size + count] = '\0';
+ ob = PyString_FromStringAndSize(NULL, size + count);
+ if ( ob == NULL )
+ return NULL;
+ p = PyString_AS_STRING(ob);
+ memcpy(p, ptr1, size);
+ memcpy(p + size, ptr2, count);
- return ob;
+ /* there is an extra byte in the string object, so this is safe */
+ p[size + count] = '\0';
+
+ return ob;
}
static PyObject *
buffer_repeat(PyBufferObject *self, Py_ssize_t count)
{
- PyObject *ob;
- register char *p;
- void *ptr;
- Py_ssize_t size;
+ PyObject *ob;
+ register char *p;
+ void *ptr;
+ Py_ssize_t size;
- if ( count < 0 )
- count = 0;
- if (!get_buf(self, &ptr, &size, ANY_BUFFER))
- return NULL;
- if (count > PY_SSIZE_T_MAX / size) {
- PyErr_SetString(PyExc_MemoryError, "result too large");
- return NULL;
- }
- ob = PyString_FromStringAndSize(NULL, size * count);
- if ( ob == NULL )
- return NULL;
+ if ( count < 0 )
+ count = 0;
+ if (!get_buf(self, &ptr, &size, ANY_BUFFER))
+ return NULL;
+ if (count > PY_SSIZE_T_MAX / size) {
+ PyErr_SetString(PyExc_MemoryError, "result too large");
+ return NULL;
+ }
+ ob = PyString_FromStringAndSize(NULL, size * count);
+ if ( ob == NULL )
+ return NULL;
- p = PyString_AS_STRING(ob);
- while ( count-- )
- {
- memcpy(p, ptr, size);
- p += size;
- }
+ p = PyString_AS_STRING(ob);
+ while ( count-- )
+ {
+ memcpy(p, ptr, size);
+ p += size;
+ }
- /* there is an extra byte in the string object, so this is safe */
- *p = '\0';
+ /* there is an extra byte in the string object, so this is safe */
+ *p = '\0';
- return ob;
+ return ob;
}
static PyObject *
buffer_item(PyBufferObject *self, Py_ssize_t idx)
{
- void *ptr;
- Py_ssize_t size;
- if (!get_buf(self, &ptr, &size, ANY_BUFFER))
- return NULL;
- if ( idx < 0 || idx >= size ) {
- PyErr_SetString(PyExc_IndexError, "buffer index out of range");
- return NULL;
- }
- return PyString_FromStringAndSize((char *)ptr + idx, 1);
+ void *ptr;
+ Py_ssize_t size;
+ if (!get_buf(self, &ptr, &size, ANY_BUFFER))
+ return NULL;
+ if ( idx < 0 || idx >= size ) {
+ PyErr_SetString(PyExc_IndexError, "buffer index out of range");
+ return NULL;
+ }
+ return PyString_FromStringAndSize((char *)ptr + idx, 1);
}
static PyObject *
buffer_slice(PyBufferObject *self, Py_ssize_t left, Py_ssize_t right)
{
- void *ptr;
- Py_ssize_t size;
- if (!get_buf(self, &ptr, &size, ANY_BUFFER))
- return NULL;
- if ( left < 0 )
- left = 0;
- if ( right < 0 )
- right = 0;
- if ( right > size )
- right = size;
- if ( right < left )
- right = left;
- return PyString_FromStringAndSize((char *)ptr + left,
- right - left);
+ void *ptr;
+ Py_ssize_t size;
+ if (!get_buf(self, &ptr, &size, ANY_BUFFER))
+ return NULL;
+ if ( left < 0 )
+ left = 0;
+ if ( right < 0 )
+ right = 0;
+ if ( right > size )
+ right = size;
+ if ( right < left )
+ right = left;
+ return PyString_FromStringAndSize((char *)ptr + left,
+ right - left);
}
static PyObject *
buffer_subscript(PyBufferObject *self, PyObject *item)
{
- void *p;
- Py_ssize_t size;
-
- if (!get_buf(self, &p, &size, ANY_BUFFER))
- return NULL;
-
+ void *p;
+ Py_ssize_t size;
+
+ if (!get_buf(self, &p, &size, ANY_BUFFER))
+ return NULL;
if (PyIndex_Check(item)) {
- Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
- if (i == -1 && PyErr_Occurred())
- return NULL;
- if (i < 0)
- i += size;
- return buffer_item(self, i);
- }
- else if (PySlice_Check(item)) {
- Py_ssize_t start, stop, step, slicelength, cur, i;
+ Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
+ if (i == -1 && PyErr_Occurred())
+ return NULL;
+ if (i < 0)
+ i += size;
+ return buffer_item(self, i);
+ }
+ else if (PySlice_Check(item)) {
+ Py_ssize_t start, stop, step, slicelength, cur, i;
- if (PySlice_GetIndicesEx((PySliceObject*)item, size,
- &start, &stop, &step, &slicelength) < 0) {
- return NULL;
- }
+ if (PySlice_GetIndicesEx((PySliceObject*)item, size,
+ &start, &stop, &step, &slicelength) < 0) {
+ return NULL;
+ }
- if (slicelength <= 0)
- return PyString_FromStringAndSize("", 0);
- else if (step == 1)
- return PyString_FromStringAndSize((char *)p + start,
- stop - start);
- else {
- PyObject *result;
- char *source_buf = (char *)p;
- char *result_buf = (char *)PyMem_Malloc(slicelength);
+ if (slicelength <= 0)
+ return PyString_FromStringAndSize("", 0);
+ else if (step == 1)
+ return PyString_FromStringAndSize((char *)p + start,
+ stop - start);
+ else {
+ PyObject *result;
+ char *source_buf = (char *)p;
+ char *result_buf = (char *)PyMem_Malloc(slicelength);
- if (result_buf == NULL)
- return PyErr_NoMemory();
+ if (result_buf == NULL)
+ return PyErr_NoMemory();
- for (cur = start, i = 0; i < slicelength;
- cur += step, i++) {
- result_buf[i] = source_buf[cur];
- }
+ for (cur = start, i = 0; i < slicelength;
+ cur += step, i++) {
+ result_buf[i] = source_buf[cur];
+ }
- result = PyString_FromStringAndSize(result_buf,
- slicelength);
- PyMem_Free(result_buf);
- return result;
- }
- }
- else {
- PyErr_SetString(PyExc_TypeError,
- "sequence index must be integer");
- return NULL;
- }
+ result = PyString_FromStringAndSize(result_buf,
+ slicelength);
+ PyMem_Free(result_buf);
+ return result;
+ }
+ }
+ else {
+ PyErr_SetString(PyExc_TypeError,
+ "sequence index must be integer");
+ return NULL;
+ }
}
static int
buffer_ass_item(PyBufferObject *self, Py_ssize_t idx, PyObject *other)
{
- PyBufferProcs *pb;
- void *ptr1, *ptr2;
- Py_ssize_t size;
- Py_ssize_t count;
+ PyBufferProcs *pb;
+ void *ptr1, *ptr2;
+ Py_ssize_t size;
+ Py_ssize_t count;
- if ( self->b_readonly ) {
- PyErr_SetString(PyExc_TypeError,
- "buffer is read-only");
- return -1;
- }
+ if ( self->b_readonly ) {
+ PyErr_SetString(PyExc_TypeError,
+ "buffer is read-only");
+ return -1;
+ }
- if (!get_buf(self, &ptr1, &size, ANY_BUFFER))
- return -1;
+ if (!get_buf(self, &ptr1, &size, ANY_BUFFER))
+ return -1;
- if (idx < 0 || idx >= size) {
- PyErr_SetString(PyExc_IndexError,
- "buffer assignment index out of range");
- return -1;
- }
+ if (idx < 0 || idx >= size) {
+ PyErr_SetString(PyExc_IndexError,
+ "buffer assignment index out of range");
+ return -1;
+ }
- pb = other ? other->ob_type->tp_as_buffer : NULL;
- if ( pb == NULL ||
- pb->bf_getreadbuffer == NULL ||
- pb->bf_getsegcount == NULL )
- {
- PyErr_BadArgument();
- return -1;
- }
- if ( (*pb->bf_getsegcount)(other, NULL) != 1 )
- {
- /* ### use a different exception type/message? */
- PyErr_SetString(PyExc_TypeError,
- "single-segment buffer object expected");
- return -1;
- }
+ pb = other ? other->ob_type->tp_as_buffer : NULL;
+ if ( pb == NULL ||
+ pb->bf_getreadbuffer == NULL ||
+ pb->bf_getsegcount == NULL )
+ {
+ PyErr_BadArgument();
+ return -1;
+ }
+ if ( (*pb->bf_getsegcount)(other, NULL) != 1 )
+ {
+ /* ### use a different exception type/message? */
+ PyErr_SetString(PyExc_TypeError,
+ "single-segment buffer object expected");
+ return -1;
+ }
- if ( (count = (*pb->bf_getreadbuffer)(other, 0, &ptr2)) < 0 )
- return -1;
- if ( count != 1 ) {
- PyErr_SetString(PyExc_TypeError,
- "right operand must be a single byte");
- return -1;
- }
+ if ( (count = (*pb->bf_getreadbuffer)(other, 0, &ptr2)) < 0 )
+ return -1;
+ if ( count != 1 ) {
+ PyErr_SetString(PyExc_TypeError,
+ "right operand must be a single byte");
+ return -1;
+ }
- ((char *)ptr1)[idx] = *(char *)ptr2;
- return 0;
+ ((char *)ptr1)[idx] = *(char *)ptr2;
+ return 0;
}
static int
buffer_ass_slice(PyBufferObject *self, Py_ssize_t left, Py_ssize_t right, PyObject *other)
{
- PyBufferProcs *pb;
- void *ptr1, *ptr2;
- Py_ssize_t size;
- Py_ssize_t slice_len;
- Py_ssize_t count;
+ PyBufferProcs *pb;
+ void *ptr1, *ptr2;
+ Py_ssize_t size;
+ Py_ssize_t slice_len;
+ Py_ssize_t count;
- if ( self->b_readonly ) {
- PyErr_SetString(PyExc_TypeError,
- "buffer is read-only");
- return -1;
- }
+ if ( self->b_readonly ) {
+ PyErr_SetString(PyExc_TypeError,
+ "buffer is read-only");
+ return -1;
+ }
- pb = other ? other->ob_type->tp_as_buffer : NULL;
- if ( pb == NULL ||
- pb->bf_getreadbuffer == NULL ||
- pb->bf_getsegcount == NULL )
- {
- PyErr_BadArgument();
- return -1;
- }
- if ( (*pb->bf_getsegcount)(other, NULL) != 1 )
- {
- /* ### use a different exception type/message? */
- PyErr_SetString(PyExc_TypeError,
- "single-segment buffer object expected");
- return -1;
- }
- if (!get_buf(self, &ptr1, &size, ANY_BUFFER))
- return -1;
- if ( (count = (*pb->bf_getreadbuffer)(other, 0, &ptr2)) < 0 )
- return -1;
+ pb = other ? other->ob_type->tp_as_buffer : NULL;
+ if ( pb == NULL ||
+ pb->bf_getreadbuffer == NULL ||
+ pb->bf_getsegcount == NULL )
+ {
+ PyErr_BadArgument();
+ return -1;
+ }
+ if ( (*pb->bf_getsegcount)(other, NULL) != 1 )
+ {
+ /* ### use a different exception type/message? */
+ PyErr_SetString(PyExc_TypeError,
+ "single-segment buffer object expected");
+ return -1;
+ }
+ if (!get_buf(self, &ptr1, &size, ANY_BUFFER))
+ return -1;
+ if ( (count = (*pb->bf_getreadbuffer)(other, 0, &ptr2)) < 0 )
+ return -1;
- if ( left < 0 )
- left = 0;
- else if ( left > size )
- left = size;
- if ( right < left )
- right = left;
- else if ( right > size )
- right = size;
- slice_len = right - left;
+ if ( left < 0 )
+ left = 0;
+ else if ( left > size )
+ left = size;
+ if ( right < left )
+ right = left;
+ else if ( right > size )
+ right = size;
+ slice_len = right - left;
- if ( count != slice_len ) {
- PyErr_SetString(
- PyExc_TypeError,
- "right operand length must match slice length");
- return -1;
- }
+ if ( count != slice_len ) {
+ PyErr_SetString(
+ PyExc_TypeError,
+ "right operand length must match slice length");
+ return -1;
+ }
- if ( slice_len )
- memcpy((char *)ptr1 + left, ptr2, slice_len);
+ if ( slice_len )
+ memcpy((char *)ptr1 + left, ptr2, slice_len);
- return 0;
+ return 0;
}
static int
buffer_ass_subscript(PyBufferObject *self, PyObject *item, PyObject *value)
{
- PyBufferProcs *pb;
- void *ptr1, *ptr2;
- Py_ssize_t selfsize;
- Py_ssize_t othersize;
+ PyBufferProcs *pb;
+ void *ptr1, *ptr2;
+ Py_ssize_t selfsize;
+ Py_ssize_t othersize;
- if ( self->b_readonly ) {
- PyErr_SetString(PyExc_TypeError,
- "buffer is read-only");
- return -1;
- }
+ if ( self->b_readonly ) {
+ PyErr_SetString(PyExc_TypeError,
+ "buffer is read-only");
+ return -1;
+ }
- pb = value ? value->ob_type->tp_as_buffer : NULL;
- if ( pb == NULL ||
- pb->bf_getreadbuffer == NULL ||
- pb->bf_getsegcount == NULL )
- {
- PyErr_BadArgument();
- return -1;
- }
- if ( (*pb->bf_getsegcount)(value, NULL) != 1 )
- {
- /* ### use a different exception type/message? */
- PyErr_SetString(PyExc_TypeError,
- "single-segment buffer object expected");
- return -1;
- }
- if (!get_buf(self, &ptr1, &selfsize, ANY_BUFFER))
- return -1;
-
+ pb = value ? value->ob_type->tp_as_buffer : NULL;
+ if ( pb == NULL ||
+ pb->bf_getreadbuffer == NULL ||
+ pb->bf_getsegcount == NULL )
+ {
+ PyErr_BadArgument();
+ return -1;
+ }
+ if ( (*pb->bf_getsegcount)(value, NULL) != 1 )
+ {
+ /* ### use a different exception type/message? */
+ PyErr_SetString(PyExc_TypeError,
+ "single-segment buffer object expected");
+ return -1;
+ }
+ if (!get_buf(self, &ptr1, &selfsize, ANY_BUFFER))
+ return -1;
if (PyIndex_Check(item)) {
- Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
- if (i == -1 && PyErr_Occurred())
- return -1;
- if (i < 0)
- i += selfsize;
- return buffer_ass_item(self, i, value);
- }
- else if (PySlice_Check(item)) {
- Py_ssize_t start, stop, step, slicelength;
-
- if (PySlice_GetIndicesEx((PySliceObject *)item, selfsize,
- &start, &stop, &step, &slicelength) < 0)
- return -1;
+ Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
+ if (i == -1 && PyErr_Occurred())
+ return -1;
+ if (i < 0)
+ i += selfsize;
+ return buffer_ass_item(self, i, value);
+ }
+ else if (PySlice_Check(item)) {
+ Py_ssize_t start, stop, step, slicelength;
- if ((othersize = (*pb->bf_getreadbuffer)(value, 0, &ptr2)) < 0)
- return -1;
+ if (PySlice_GetIndicesEx((PySliceObject *)item, selfsize,
+ &start, &stop, &step, &slicelength) < 0)
+ return -1;
- if (othersize != slicelength) {
- PyErr_SetString(
- PyExc_TypeError,
- "right operand length must match slice length");
- return -1;
- }
+ if ((othersize = (*pb->bf_getreadbuffer)(value, 0, &ptr2)) < 0)
+ return -1;
- if (slicelength == 0)
- return 0;
- else if (step == 1) {
- memcpy((char *)ptr1 + start, ptr2, slicelength);
- return 0;
- }
- else {
- Py_ssize_t cur, i;
-
- for (cur = start, i = 0; i < slicelength;
- cur += step, i++) {
- ((char *)ptr1)[cur] = ((char *)ptr2)[i];
- }
+ if (othersize != slicelength) {
+ PyErr_SetString(
+ PyExc_TypeError,
+ "right operand length must match slice length");
+ return -1;
+ }
- return 0;
- }
- } else {
- PyErr_SetString(PyExc_TypeError,
- "buffer indices must be integers");
- return -1;
- }
+ if (slicelength == 0)
+ return 0;
+ else if (step == 1) {
+ memcpy((char *)ptr1 + start, ptr2, slicelength);
+ return 0;
+ }
+ else {
+ Py_ssize_t cur, i;
+
+ for (cur = start, i = 0; i < slicelength;
+ cur += step, i++) {
+ ((char *)ptr1)[cur] = ((char *)ptr2)[i];
+ }
+
+ return 0;
+ }
+ } else {
+ PyErr_SetString(PyExc_TypeError,
+ "buffer indices must be integers");
+ return -1;
+ }
}
/* Buffer methods */
@@ -723,64 +723,64 @@
static Py_ssize_t
buffer_getreadbuf(PyBufferObject *self, Py_ssize_t idx, void **pp)
{
- Py_ssize_t size;
- if ( idx != 0 ) {
- PyErr_SetString(PyExc_SystemError,
- "accessing non-existent buffer segment");
- return -1;
- }
- if (!get_buf(self, pp, &size, READ_BUFFER))
- return -1;
- return size;
+ Py_ssize_t size;
+ if ( idx != 0 ) {
+ PyErr_SetString(PyExc_SystemError,
+ "accessing non-existent buffer segment");
+ return -1;
+ }
+ if (!get_buf(self, pp, &size, READ_BUFFER))
+ return -1;
+ return size;
}
static Py_ssize_t
buffer_getwritebuf(PyBufferObject *self, Py_ssize_t idx, void **pp)
{
- Py_ssize_t size;
+ Py_ssize_t size;
- if ( self->b_readonly )
- {
- PyErr_SetString(PyExc_TypeError, "buffer is read-only");
- return -1;
- }
+ if ( self->b_readonly )
+ {
+ PyErr_SetString(PyExc_TypeError, "buffer is read-only");
+ return -1;
+ }
- if ( idx != 0 ) {
- PyErr_SetString(PyExc_SystemError,
- "accessing non-existent buffer segment");
- return -1;
- }
- if (!get_buf(self, pp, &size, WRITE_BUFFER))
- return -1;
- return size;
+ if ( idx != 0 ) {
+ PyErr_SetString(PyExc_SystemError,
+ "accessing non-existent buffer segment");
+ return -1;
+ }
+ if (!get_buf(self, pp, &size, WRITE_BUFFER))
+ return -1;
+ return size;
}
static Py_ssize_t
buffer_getsegcount(PyBufferObject *self, Py_ssize_t *lenp)
{
- void *ptr;
- Py_ssize_t size;
- if (!get_buf(self, &ptr, &size, ANY_BUFFER))
- return -1;
- if (lenp)
- *lenp = size;
- return 1;
+ void *ptr;
+ Py_ssize_t size;
+ if (!get_buf(self, &ptr, &size, ANY_BUFFER))
+ return -1;
+ if (lenp)
+ *lenp = size;
+ return 1;
}
static Py_ssize_t
buffer_getcharbuf(PyBufferObject *self, Py_ssize_t idx, const char **pp)
{
- void *ptr;
- Py_ssize_t size;
- if ( idx != 0 ) {
- PyErr_SetString(PyExc_SystemError,
- "accessing non-existent buffer segment");
- return -1;
- }
- if (!get_buf(self, &ptr, &size, CHAR_BUFFER))
- return -1;
- *pp = (const char *)ptr;
- return size;
+ void *ptr;
+ Py_ssize_t size;
+ if ( idx != 0 ) {
+ PyErr_SetString(PyExc_SystemError,
+ "accessing non-existent buffer segment");
+ return -1;
+ }
+ if (!get_buf(self, &ptr, &size, CHAR_BUFFER))
+ return -1;
+ *pp = (const char *)ptr;
+ return size;
}
void init_bufferobject(void)
@@ -789,67 +789,65 @@
}
static PySequenceMethods buffer_as_sequence = {
- (lenfunc)buffer_length, /*sq_length*/
- (binaryfunc)buffer_concat, /*sq_concat*/
- (ssizeargfunc)buffer_repeat, /*sq_repeat*/
- (ssizeargfunc)buffer_item, /*sq_item*/
- (ssizessizeargfunc)buffer_slice, /*sq_slice*/
- (ssizeobjargproc)buffer_ass_item, /*sq_ass_item*/
- (ssizessizeobjargproc)buffer_ass_slice, /*sq_ass_slice*/
+ (lenfunc)buffer_length, /*sq_length*/
+ (binaryfunc)buffer_concat, /*sq_concat*/
+ (ssizeargfunc)buffer_repeat, /*sq_repeat*/
+ (ssizeargfunc)buffer_item, /*sq_item*/
+ (ssizessizeargfunc)buffer_slice, /*sq_slice*/
+ (ssizeobjargproc)buffer_ass_item, /*sq_ass_item*/
+ (ssizessizeobjargproc)buffer_ass_slice, /*sq_ass_slice*/
};
static PyMappingMethods buffer_as_mapping = {
- (lenfunc)buffer_length,
- (binaryfunc)buffer_subscript,
- (objobjargproc)buffer_ass_subscript,
+ (lenfunc)buffer_length,
+ (binaryfunc)buffer_subscript,
+ (objobjargproc)buffer_ass_subscript,
};
static PyBufferProcs buffer_as_buffer = {
- (readbufferproc)buffer_getreadbuf,
- (writebufferproc)buffer_getwritebuf,
- (segcountproc)buffer_getsegcount,
- (charbufferproc)buffer_getcharbuf,
+ (readbufferproc)buffer_getreadbuf,
+ (writebufferproc)buffer_getwritebuf,
+ (segcountproc)buffer_getsegcount,
+ (charbufferproc)buffer_getcharbuf,
};
PyTypeObject PyBuffer_Type = {
- PyObject_HEAD_INIT(NULL)
+ PyVarObject_HEAD_INIT(NULL, 0)
+ "buffer",
+ sizeof(PyBufferObject),
0,
- "buffer",
- sizeof(PyBufferObject),
- 0,
- (destructor)buffer_dealloc, /* tp_dealloc */
- 0, /* tp_print */
- 0, /* tp_getattr */
- 0, /* tp_setattr */
- (cmpfunc)buffer_compare, /* tp_compare */
- (reprfunc)buffer_repr, /* tp_repr */
- 0, /* tp_as_number */
- &buffer_as_sequence, /* tp_as_sequence */
- &buffer_as_mapping, /* tp_as_mapping */
- (hashfunc)buffer_hash, /* tp_hash */
- 0, /* tp_call */
- (reprfunc)buffer_str, /* tp_str */
- PyObject_GenericGetAttr, /* tp_getattro */
- 0, /* tp_setattro */
- &buffer_as_buffer, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GETCHARBUFFER, /* tp_flags */
- buffer_doc, /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- 0, /* tp_methods */
- 0, /* tp_members */
- 0, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- 0, /* tp_init */
- 0, /* tp_alloc */
- buffer_new, /* tp_new */
+ (destructor)buffer_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ (cmpfunc)buffer_compare, /* tp_compare */
+ (reprfunc)buffer_repr, /* tp_repr */
+ 0, /* tp_as_number */
+ &buffer_as_sequence, /* tp_as_sequence */
+ &buffer_as_mapping, /* tp_as_mapping */
+ (hashfunc)buffer_hash, /* tp_hash */
+ 0, /* tp_call */
+ (reprfunc)buffer_str, /* tp_str */
+ PyObject_GenericGetAttr, /* tp_getattro */
+ 0, /* tp_setattro */
+ &buffer_as_buffer, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GETCHARBUFFER, /* tp_flags */
+ buffer_doc, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ 0, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ buffer_new, /* tp_new */
};
-
diff --git a/pypy/module/cpyext/src/cobject.c b/pypy/module/cpyext/src/cobject.c
--- a/pypy/module/cpyext/src/cobject.c
+++ b/pypy/module/cpyext/src/cobject.c
@@ -50,6 +50,10 @@
PyCObject_AsVoidPtr(PyObject *self)
{
if (self) {
+ if (PyCapsule_CheckExact(self)) {
+ const char *name = PyCapsule_GetName(self);
+ return (void *)PyCapsule_GetPointer(self, name);
+ }
if (self->ob_type == &PyCObject_Type)
return ((PyCObject *)self)->cobject;
PyErr_SetString(PyExc_TypeError,
diff --git a/pypy/module/cpyext/src/getargs.c b/pypy/module/cpyext/src/getargs.c
--- a/pypy/module/cpyext/src/getargs.c
+++ b/pypy/module/cpyext/src/getargs.c
@@ -7,349 +7,348 @@
#ifdef __cplusplus
-extern "C" {
+extern "C" {
#endif
-
int PyArg_Parse(PyObject *, const char *, ...);
int PyArg_ParseTuple(PyObject *, const char *, ...);
int PyArg_VaParse(PyObject *, const char *, va_list);
int PyArg_ParseTupleAndKeywords(PyObject *, PyObject *,
- const char *, char **, ...);
+ const char *, char **, ...);
int PyArg_VaParseTupleAndKeywords(PyObject *, PyObject *,
- const char *, char **, va_list);
+ const char *, char **, va_list);
#define FLAG_COMPAT 1
#define FLAG_SIZE_T 2
-typedef int (*destr_t)(PyObject *, void *);
-
-
-/* Keep track of "objects" that have been allocated or initialized and
- which will need to be deallocated or cleaned up somehow if overall
- parsing fails.
-*/
-typedef struct {
- void *item;
- destr_t destructor;
-} freelistentry_t;
-
-typedef struct {
- int first_available;
- freelistentry_t *entries;
-} freelist_t;
-
/* Forward */
static int vgetargs1(PyObject *, const char *, va_list *, int);
static void seterror(int, const char *, int *, const char *, const char *);
-static char *convertitem(PyObject *, const char **, va_list *, int, int *,
- char *, size_t, freelist_t *);
+static char *convertitem(PyObject *, const char **, va_list *, int, int *,
+ char *, size_t, PyObject **);
static char *converttuple(PyObject *, const char **, va_list *, int,
- int *, char *, size_t, int, freelist_t *);
+ int *, char *, size_t, int, PyObject **);
static char *convertsimple(PyObject *, const char **, va_list *, int, char *,
- size_t, freelist_t *);
+ size_t, PyObject **);
static Py_ssize_t convertbuffer(PyObject *, void **p, char **);
static int getbuffer(PyObject *, Py_buffer *, char**);
static int vgetargskeywords(PyObject *, PyObject *,
- const char *, char **, va_list *, int);
+ const char *, char **, va_list *, int);
static char *skipitem(const char **, va_list *, int);
int
PyArg_Parse(PyObject *args, const char *format, ...)
{
- int retval;
- va_list va;
-
- va_start(va, format);
- retval = vgetargs1(args, format, &va, FLAG_COMPAT);
- va_end(va);
- return retval;
+ int retval;
+ va_list va;
+
+ va_start(va, format);
+ retval = vgetargs1(args, format, &va, FLAG_COMPAT);
+ va_end(va);
+ return retval;
}
int
_PyArg_Parse_SizeT(PyObject *args, char *format, ...)
{
- int retval;
- va_list va;
-
- va_start(va, format);
- retval = vgetargs1(args, format, &va, FLAG_COMPAT|FLAG_SIZE_T);
- va_end(va);
- return retval;
+ int retval;
+ va_list va;
+
+ va_start(va, format);
+ retval = vgetargs1(args, format, &va, FLAG_COMPAT|FLAG_SIZE_T);
+ va_end(va);
+ return retval;
}
int
PyArg_ParseTuple(PyObject *args, const char *format, ...)
{
- int retval;
- va_list va;
-
- va_start(va, format);
- retval = vgetargs1(args, format, &va, 0);
- va_end(va);
- return retval;
+ int retval;
+ va_list va;
+
+ va_start(va, format);
+ retval = vgetargs1(args, format, &va, 0);
+ va_end(va);
+ return retval;
}
int
_PyArg_ParseTuple_SizeT(PyObject *args, char *format, ...)
{
- int retval;
- va_list va;
-
- va_start(va, format);
- retval = vgetargs1(args, format, &va, FLAG_SIZE_T);
- va_end(va);
- return retval;
+ int retval;
+ va_list va;
+
+ va_start(va, format);
+ retval = vgetargs1(args, format, &va, FLAG_SIZE_T);
+ va_end(va);
+ return retval;
}
int
PyArg_VaParse(PyObject *args, const char *format, va_list va)
{
- va_list lva;
+ va_list lva;
#ifdef VA_LIST_IS_ARRAY
- memcpy(lva, va, sizeof(va_list));
+ memcpy(lva, va, sizeof(va_list));
#else
#ifdef __va_copy
- __va_copy(lva, va);
+ __va_copy(lva, va);
#else
- lva = va;
+ lva = va;
#endif
#endif
- return vgetargs1(args, format, &lva, 0);
+ return vgetargs1(args, format, &lva, 0);
}
int
_PyArg_VaParse_SizeT(PyObject *args, char *format, va_list va)
{
- va_list lva;
+ va_list lva;
#ifdef VA_LIST_IS_ARRAY
- memcpy(lva, va, sizeof(va_list));
+ memcpy(lva, va, sizeof(va_list));
#else
#ifdef __va_copy
- __va_copy(lva, va);
+ __va_copy(lva, va);
#else
- lva = va;
+ lva = va;
#endif
#endif
- return vgetargs1(args, format, &lva, FLAG_SIZE_T);
+ return vgetargs1(args, format, &lva, FLAG_SIZE_T);
}
/* Handle cleanup of allocated memory in case of exception */
+#define GETARGS_CAPSULE_NAME_CLEANUP_PTR "getargs.cleanup_ptr"
+#define GETARGS_CAPSULE_NAME_CLEANUP_BUFFER "getargs.cleanup_buffer"
+
+static void
+cleanup_ptr(PyObject *self)
+{
+ void *ptr = PyCapsule_GetPointer(self, GETARGS_CAPSULE_NAME_CLEANUP_PTR);
+ if (ptr) {
+ PyMem_FREE(ptr);
+ }
+}
+
+static void
+cleanup_buffer(PyObject *self)
+{
+ Py_buffer *ptr = (Py_buffer *)PyCapsule_GetPointer(self, GETARGS_CAPSULE_NAME_CLEANUP_BUFFER);
+ if (ptr) {
+ PyBuffer_Release(ptr);
+ }
+}
+
static int
-cleanup_ptr(PyObject *self, void *ptr)
+addcleanup(void *ptr, PyObject **freelist, PyCapsule_Destructor destr)
{
- if (ptr) {
- PyMem_FREE(ptr);
+ PyObject *cobj;
+ const char *name;
+
+ if (!*freelist) {
+ *freelist = PyList_New(0);
+ if (!*freelist) {
+ destr(ptr);
+ return -1;
+ }
}
+
+ 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);
+ return -1;
+ }
+ if (PyList_Append(*freelist, cobj)) {
+ Py_DECREF(cobj);
+ return -1;
+ }
+ Py_DECREF(cobj);
return 0;
}
static int
-cleanup_buffer(PyObject *self, void *ptr)
+cleanreturn(int retval, PyObject *freelist)
{
- Py_buffer *buf = (Py_buffer *)ptr;
- if (buf) {
- PyBuffer_Release(buf);
+ if (freelist && retval != 0) {
+ /* We were successful, reset the destructors so that they
+ don't get called. */
+ Py_ssize_t len = PyList_GET_SIZE(freelist), i;
+ for (i = 0; i < len; i++)
+ PyCapsule_SetDestructor(PyList_GET_ITEM(freelist, i), NULL);
}
- return 0;
+ Py_XDECREF(freelist);
+ return retval;
}
-static int
-addcleanup(void *ptr, freelist_t *freelist, destr_t destructor)
-{
- int index;
-
- index = freelist->first_available;
- freelist->first_available += 1;
-
- freelist->entries[index].item = ptr;
- freelist->entries[index].destructor = destructor;
-
- return 0;
-}
-
-static int
-cleanreturn(int retval, freelist_t *freelist)
-{
- int index;
-
- if (retval == 0) {
- /* A failure occurred, therefore execute all of the cleanup
- functions.
- */
- for (index = 0; index < freelist->first_available; ++index) {
- freelist->entries[index].destructor(NULL,
- freelist->entries[index].item);
- }
- }
- PyMem_Free(freelist->entries);
- return retval;
-}
static int
vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags)
{
- char msgbuf[256];
- int levels[32];
- const char *fname = NULL;
- const char *message = NULL;
- int min = -1;
- int max = 0;
- int level = 0;
- int endfmt = 0;
- const char *formatsave = format;
- Py_ssize_t i, len;
- char *msg;
- freelist_t freelist = {0, NULL};
- int compat = flags & FLAG_COMPAT;
+ char msgbuf[256];
+ int levels[32];
+ const char *fname = NULL;
+ const char *message = NULL;
+ int min = -1;
+ int max = 0;
+ int level = 0;
+ int endfmt = 0;
+ const char *formatsave = format;
+ Py_ssize_t i, len;
+ char *msg;
+ PyObject *freelist = NULL;
+ int compat = flags & FLAG_COMPAT;
- assert(compat || (args != (PyObject*)NULL));
- flags = flags & ~FLAG_COMPAT;
+ assert(compat || (args != (PyObject*)NULL));
+ flags = flags & ~FLAG_COMPAT;
- while (endfmt == 0) {
- int c = *format++;
- switch (c) {
- case '(':
- if (level == 0)
- max++;
- level++;
- if (level >= 30)
- Py_FatalError("too many tuple nesting levels "
- "in argument format string");
- break;
- case ')':
- if (level == 0)
- Py_FatalError("excess ')' in getargs format");
- else
- level--;
- break;
- case '\0':
- endfmt = 1;
- break;
- case ':':
- fname = format;
- endfmt = 1;
- break;
- case ';':
- message = format;
- endfmt = 1;
- break;
- default:
- if (level == 0) {
- if (c == 'O')
- max++;
- else if (isalpha(Py_CHARMASK(c))) {
- if (c != 'e') /* skip encoded */
- max++;
- } else if (c == '|')
- min = max;
- }
- break;
- }
- }
-
- if (level != 0)
- Py_FatalError(/* '(' */ "missing ')' in getargs format");
-
- if (min < 0)
- min = max;
-
- format = formatsave;
-
- freelist.entries = PyMem_New(freelistentry_t, max);
+ while (endfmt == 0) {
+ int c = *format++;
+ switch (c) {
+ case '(':
+ if (level == 0)
+ max++;
+ level++;
+ if (level >= 30)
+ Py_FatalError("too many tuple nesting levels "
+ "in argument format string");
+ break;
+ case ')':
+ if (level == 0)
+ Py_FatalError("excess ')' in getargs format");
+ else
+ level--;
+ break;
+ case '\0':
+ endfmt = 1;
+ break;
+ case ':':
+ fname = format;
+ endfmt = 1;
+ break;
+ case ';':
+ message = format;
+ endfmt = 1;
+ break;
+ default:
+ if (level == 0) {
+ if (c == 'O')
+ max++;
+ else if (isalpha(Py_CHARMASK(c))) {
+ if (c != 'e') /* skip encoded */
+ max++;
+ } else if (c == '|')
+ min = max;
+ }
+ break;
+ }
+ }
- if (compat) {
- if (max == 0) {
- if (args == NULL)
- return cleanreturn(1, &freelist);
- PyOS_snprintf(msgbuf, sizeof(msgbuf),
- "%.200s%s takes no arguments",
- fname==NULL ? "function" : fname,
- fname==NULL ? "" : "()");
- PyErr_SetString(PyExc_TypeError, msgbuf);
- return cleanreturn(0, &freelist);
- }
- else if (min == 1 && max == 1) {
- if (args == NULL) {
- PyOS_snprintf(msgbuf, sizeof(msgbuf),
- "%.200s%s takes at least one argument",
- fname==NULL ? "function" : fname,
- fname==NULL ? "" : "()");
- PyErr_SetString(PyExc_TypeError, msgbuf);
- return cleanreturn(0, &freelist);
- }
- msg = convertitem(args, &format, p_va, flags, levels,
- msgbuf, sizeof(msgbuf), &freelist);
- if (msg == NULL)
- return cleanreturn(1, &freelist);
- seterror(levels[0], msg, levels+1, fname, message);
- return cleanreturn(0, &freelist);
- }
- else {
- PyErr_SetString(PyExc_SystemError,
- "old style getargs format uses new features");
- return cleanreturn(0, &freelist);
- }
- }
-
- if (!PyTuple_Check(args)) {
- PyErr_SetString(PyExc_SystemError,
- "new style getargs format but argument is not a tuple");
- return cleanreturn(0, &freelist);
- }
-
- len = PyTuple_GET_SIZE(args);
-
- if (len < min || max < len) {
- if (message == NULL) {
- PyOS_snprintf(msgbuf, sizeof(msgbuf),
- "%.150s%s takes %s %d argument%s "
- "(%ld given)",
- fname==NULL ? "function" : fname,
- fname==NULL ? "" : "()",
- min==max ? "exactly"
- : len < min ? "at least" : "at most",
- len < min ? min : max,
- (len < min ? min : max) == 1 ? "" : "s",
- Py_SAFE_DOWNCAST(len, Py_ssize_t, long));
- message = msgbuf;
- }
- PyErr_SetString(PyExc_TypeError, message);
- return cleanreturn(0, &freelist);
- }
-
- for (i = 0; i < len; i++) {
- if (*format == '|')
- format++;
- msg = convertitem(PyTuple_GET_ITEM(args, i), &format, p_va,
- flags, levels, msgbuf,
- sizeof(msgbuf), &freelist);
- if (msg) {
- seterror(i+1, msg, levels, fname, message);
- return cleanreturn(0, &freelist);
- }
- }
+ if (level != 0)
+ Py_FatalError(/* '(' */ "missing ')' in getargs format");
- if (*format != '\0' && !isalpha(Py_CHARMASK(*format)) &&
- *format != '(' &&
- *format != '|' && *format != ':' && *format != ';') {
- PyErr_Format(PyExc_SystemError,
- "bad format string: %.200s", formatsave);
- return cleanreturn(0, &freelist);
- }
-
- return cleanreturn(1, &freelist);
+ if (min < 0)
+ min = max;
+
+ format = formatsave;
+
+ if (compat) {
+ if (max == 0) {
+ if (args == NULL)
+ return 1;
+ PyOS_snprintf(msgbuf, sizeof(msgbuf),
+ "%.200s%s takes no arguments",
+ fname==NULL ? "function" : fname,
+ fname==NULL ? "" : "()");
+ PyErr_SetString(PyExc_TypeError, msgbuf);
+ return 0;
+ }
+ else if (min == 1 && max == 1) {
+ if (args == NULL) {
+ PyOS_snprintf(msgbuf, sizeof(msgbuf),
+ "%.200s%s takes at least one argument",
+ fname==NULL ? "function" : fname,
+ fname==NULL ? "" : "()");
+ PyErr_SetString(PyExc_TypeError, msgbuf);
+ return 0;
+ }
+ msg = convertitem(args, &format, p_va, flags, levels,
+ msgbuf, sizeof(msgbuf), &freelist);
+ if (msg == NULL)
+ return cleanreturn(1, freelist);
+ seterror(levels[0], msg, levels+1, fname, message);
+ return cleanreturn(0, freelist);
+ }
+ else {
+ PyErr_SetString(PyExc_SystemError,
+ "old style getargs format uses new features");
+ return 0;
+ }
+ }
+
+ if (!PyTuple_Check(args)) {
+ PyErr_SetString(PyExc_SystemError,
+ "new style getargs format but argument is not a tuple");
+ return 0;
+ }
+
+ len = PyTuple_GET_SIZE(args);
+
+ if (len < min || max < len) {
+ if (message == NULL) {
+ PyOS_snprintf(msgbuf, sizeof(msgbuf),
+ "%.150s%s takes %s %d argument%s "
+ "(%ld given)",
+ fname==NULL ? "function" : fname,
+ fname==NULL ? "" : "()",
+ min==max ? "exactly"
+ : len < min ? "at least" : "at most",
+ len < min ? min : max,
+ (len < min ? min : max) == 1 ? "" : "s",
+ Py_SAFE_DOWNCAST(len, Py_ssize_t, long));
+ message = msgbuf;
+ }
+ PyErr_SetString(PyExc_TypeError, message);
+ return 0;
+ }
+
+ for (i = 0; i < len; i++) {
+ if (*format == '|')
+ format++;
+ msg = convertitem(PyTuple_GET_ITEM(args, i), &format, p_va,
+ flags, levels, msgbuf,
+ sizeof(msgbuf), &freelist);
+ if (msg) {
+ seterror(i+1, msg, levels, fname, msg);
+ return cleanreturn(0, freelist);
+ }
+ }
+
+ if (*format != '\0' && !isalpha(Py_CHARMASK(*format)) &&
+ *format != '(' &&
+ *format != '|' && *format != ':' && *format != ';') {
+ PyErr_Format(PyExc_SystemError,
+ "bad format string: %.200s", formatsave);
+ return cleanreturn(0, freelist);
+ }
+
+ return cleanreturn(1, freelist);
}
@@ -358,37 +357,37 @@
seterror(int iarg, const char *msg, int *levels, const char *fname,
const char *message)
{
- char buf[512];
- int i;
- char *p = buf;
+ char buf[512];
+ int i;
+ char *p = buf;
- if (PyErr_Occurred())
- return;
- else if (message == NULL) {
- if (fname != NULL) {
- PyOS_snprintf(p, sizeof(buf), "%.200s() ", fname);
- p += strlen(p);
- }
- if (iarg != 0) {
- PyOS_snprintf(p, sizeof(buf) - (p - buf),
- "argument %d", iarg);
- i = 0;
- p += strlen(p);
- while (levels[i] > 0 && i < 32 && (int)(p-buf) < 220) {
- PyOS_snprintf(p, sizeof(buf) - (p - buf),
- ", item %d", levels[i]-1);
- p += strlen(p);
- i++;
- }
- }
- else {
- PyOS_snprintf(p, sizeof(buf) - (p - buf), "argument");
- p += strlen(p);
- }
- PyOS_snprintf(p, sizeof(buf) - (p - buf), " %.256s", msg);
- message = buf;
- }
- PyErr_SetString(PyExc_TypeError, message);
+ if (PyErr_Occurred())
+ return;
+ else if (message == NULL) {
+ if (fname != NULL) {
+ PyOS_snprintf(p, sizeof(buf), "%.200s() ", fname);
+ p += strlen(p);
+ }
+ if (iarg != 0) {
+ PyOS_snprintf(p, sizeof(buf) - (p - buf),
+ "argument %d", iarg);
+ i = 0;
+ p += strlen(p);
+ while (levels[i] > 0 && i < 32 && (int)(p-buf) < 220) {
+ PyOS_snprintf(p, sizeof(buf) - (p - buf),
+ ", item %d", levels[i]-1);
+ p += strlen(p);
+ i++;
+ }
+ }
+ else {
+ PyOS_snprintf(p, sizeof(buf) - (p - buf), "argument");
+ p += strlen(p);
+ }
+ PyOS_snprintf(p, sizeof(buf) - (p - buf), " %.256s", msg);
+ message = buf;
+ }
+ PyErr_SetString(PyExc_TypeError, message);
}
@@ -404,85 +403,84 @@
*p_va is undefined,
*levels is a 0-terminated list of item numbers,
*msgbuf contains an error message, whose format is:
- "must be <typename1>, not <typename2>", where:
- <typename1> is the name of the expected type, and
- <typename2> is the name of the actual type,
+ "must be <typename1>, not <typename2>", where:
+ <typename1> is the name of the expected type, and
+ <typename2> is the name of the actual type,
and msgbuf is returned.
*/
static char *
converttuple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
- int *levels, char *msgbuf, size_t bufsize, int toplevel,
- freelist_t *freelist)
+ int *levels, char *msgbuf, size_t bufsize, int toplevel,
+ PyObject **freelist)
{
- int level = 0;
- int n = 0;
- const char *format = *p_format;
- int i;
-
- for (;;) {
- int c = *format++;
- if (c == '(') {
- if (level == 0)
- n++;
- level++;
- }
- else if (c == ')') {
- if (level == 0)
- break;
- level--;
- }
- else if (c == ':' || c == ';' || c == '\0')
- break;
- else if (level == 0 && isalpha(Py_CHARMASK(c)))
- n++;
- }
-
- if (!PySequence_Check(arg) || PyString_Check(arg)) {
- levels[0] = 0;
- PyOS_snprintf(msgbuf, bufsize,
- toplevel ? "expected %d arguments, not %.50s" :
- "must be %d-item sequence, not %.50s",
- n,
- arg == Py_None ? "None" : arg->ob_type->tp_name);
- return msgbuf;
- }
-
- if ((i = PySequence_Size(arg)) != n) {
- levels[0] = 0;
- PyOS_snprintf(msgbuf, bufsize,
- toplevel ? "expected %d arguments, not %d" :
- "must be sequence of length %d, not %d",
- n, i);
- return msgbuf;
- }
+ int level = 0;
+ int n = 0;
+ const char *format = *p_format;
+ int i;
- format = *p_format;
- for (i = 0; i < n; i++) {
- char *msg;
- PyObject *item;
+ for (;;) {
+ int c = *format++;
+ if (c == '(') {
+ if (level == 0)
+ n++;
+ level++;
+ }
+ else if (c == ')') {
+ if (level == 0)
+ break;
+ level--;
+ }
+ else if (c == ':' || c == ';' || c == '\0')
+ break;
+ else if (level == 0 && isalpha(Py_CHARMASK(c)))
+ n++;
+ }
+
+ if (!PySequence_Check(arg) || PyString_Check(arg)) {
+ levels[0] = 0;
+ PyOS_snprintf(msgbuf, bufsize,
+ toplevel ? "expected %d arguments, not %.50s" :
+ "must be %d-item sequence, not %.50s",
+ n,
+ arg == Py_None ? "None" : arg->ob_type->tp_name);
+ return msgbuf;
+ }
+
+ if ((i = PySequence_Size(arg)) != n) {
+ levels[0] = 0;
+ PyOS_snprintf(msgbuf, bufsize,
+ toplevel ? "expected %d arguments, not %d" :
+ "must be sequence of length %d, not %d",
+ n, i);
+ return msgbuf;
+ }
+
+ format = *p_format;
+ for (i = 0; i < n; i++) {
+ char *msg;
+ PyObject *item;
item = PySequence_GetItem(arg, i);
- if (item == NULL) {
- PyErr_Clear();
- levels[0] = i+1;
- levels[1] = 0;
- strncpy(msgbuf, "is not retrievable",
- bufsize);
- return msgbuf;
- }
- PyPy_Borrow(arg, item);
- msg = convertitem(item, &format, p_va, flags, levels+1,
- msgbuf, bufsize, freelist);
+ if (item == NULL) {
+ PyErr_Clear();
+ levels[0] = i+1;
+ levels[1] = 0;
+ strncpy(msgbuf, "is not retrievable", bufsize);
+ return msgbuf;
+ }
+ PyPy_Borrow(arg, item);
+ msg = convertitem(item, &format, p_va, flags, levels+1,
+ msgbuf, bufsize, freelist);
/* PySequence_GetItem calls tp->sq_item, which INCREFs */
Py_XDECREF(item);
- if (msg != NULL) {
- levels[0] = i+1;
- return msg;
- }
- }
+ if (msg != NULL) {
+ levels[0] = i+1;
+ return msg;
+ }
+ }
- *p_format = format;
- return NULL;
+ *p_format = format;
+ return NULL;
}
@@ -490,45 +488,45 @@
static char *
convertitem(PyObject *arg, const char **p_format, va_list *p_va, int flags,
- int *levels, char *msgbuf, size_t bufsize, freelist_t *freelist)
+ int *levels, char *msgbuf, size_t bufsize, PyObject **freelist)
{
- char *msg;
- const char *format = *p_format;
-
- if (*format == '(' /* ')' */) {
- format++;
- msg = converttuple(arg, &format, p_va, flags, levels, msgbuf,
- bufsize, 0, freelist);
- if (msg == NULL)
- format++;
- }
- else {
- msg = convertsimple(arg, &format, p_va, flags,
- msgbuf, bufsize, freelist);
- if (msg != NULL)
- levels[0] = 0;
- }
- if (msg == NULL)
- *p_format = format;
- return msg;
+ char *msg;
+ const char *format = *p_format;
+
+ if (*format == '(' /* ')' */) {
+ format++;
+ msg = converttuple(arg, &format, p_va, flags, levels, msgbuf,
+ bufsize, 0, freelist);
+ if (msg == NULL)
+ format++;
+ }
+ else {
+ msg = convertsimple(arg, &format, p_va, flags,
+ msgbuf, bufsize, freelist);
+ if (msg != NULL)
+ levels[0] = 0;
+ }
+ if (msg == NULL)
+ *p_format = format;
+ return msg;
}
#define UNICODE_DEFAULT_ENCODING(arg) \
- _PyUnicode_AsDefaultEncodedString(arg, NULL)
+ _PyUnicode_AsDefaultEncodedString(arg, NULL)
/* Format an error message generated by convertsimple(). */
static char *
converterr(const char *expected, PyObject *arg, char *msgbuf, size_t bufsize)
{
- assert(expected != NULL);
- assert(arg != NULL);
- PyOS_snprintf(msgbuf, bufsize,
- "must be %.50s, not %.50s", expected,
- arg == Py_None ? "None" : arg->ob_type->tp_name);
- return msgbuf;
+ assert(expected != NULL);
+ assert(arg != NULL);
+ PyOS_snprintf(msgbuf, bufsize,
+ "must be %.50s, not %.50s", expected,
+ arg == Py_None ? "None" : arg->ob_type->tp_name);
+ return msgbuf;
}
#define CONV_UNICODE "(unicode conversion error)"
@@ -536,14 +534,28 @@
/* explicitly check for float arguments when integers are expected. For now
* signal a warning. Returns true if an exception was raised. */
static int
+float_argument_warning(PyObject *arg)
+{
+ if (PyFloat_Check(arg) &&
+ PyErr_Warn(PyExc_DeprecationWarning,
+ "integer argument expected, got float" ))
+ return 1;
+ else
+ return 0;
+}
+
+/* explicitly check for float arguments when integers are expected. Raises
+ TypeError and returns true for float arguments. */
+static int
float_argument_error(PyObject *arg)
{
- if (PyFloat_Check(arg) &&
- PyErr_Warn(PyExc_DeprecationWarning,
- "integer argument expected, got float" ))
- return 1;
- else
- return 0;
+ if (PyFloat_Check(arg)) {
+ PyErr_SetString(PyExc_TypeError,
+ "integer argument expected, got float");
+ return 1;
+ }
+ else
+ return 0;
}
/* Convert a non-tuple argument. Return NULL if conversion went OK,
@@ -557,836 +569,839 @@
static char *
convertsimple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
- char *msgbuf, size_t bufsize, freelist_t *freelist)
+ char *msgbuf, size_t bufsize, PyObject **freelist)
{
- /* For # codes */
-#define FETCH_SIZE int *q=NULL;Py_ssize_t *q2=NULL;\
- if (flags & FLAG_SIZE_T) q2=va_arg(*p_va, Py_ssize_t*); \
- else q=va_arg(*p_va, int*);
-#define STORE_SIZE(s) if (flags & FLAG_SIZE_T) *q2=s; else *q=s;
+ /* For # codes */
+#define FETCH_SIZE int *q=NULL;Py_ssize_t *q2=NULL;\
+ if (flags & FLAG_SIZE_T) q2=va_arg(*p_va, Py_ssize_t*); \
+ else q=va_arg(*p_va, int*);
+#define STORE_SIZE(s) \
+ if (flags & FLAG_SIZE_T) \
+ *q2=s; \
+ else { \
+ if (INT_MAX < s) { \
+ PyErr_SetString(PyExc_OverflowError, \
+ "size does not fit in an int"); \
+ return converterr("", arg, msgbuf, bufsize); \
+ } \
+ *q=s; \
+ }
#define BUFFER_LEN ((flags & FLAG_SIZE_T) ? *q2:*q)
- const char *format = *p_format;
- char c = *format++;
+ const char *format = *p_format;
+ char c = *format++;
#ifdef Py_USING_UNICODE
- PyObject *uarg;
-#endif
-
- switch (c) {
-
- case 'b': { /* unsigned byte -- very short int */
- char *p = va_arg(*p_va, char *);
- long ival;
- if (float_argument_error(arg))
- return converterr("integer<b>", arg, msgbuf, bufsize);
- ival = PyInt_AsLong(arg);
- if (ival == -1 && PyErr_Occurred())
- return converterr("integer<b>", arg, msgbuf, bufsize);
- else if (ival < 0) {
- PyErr_SetString(PyExc_OverflowError,
- "unsigned byte integer is less than minimum");
- return converterr("integer<b>", arg, msgbuf, bufsize);
- }
- else if (ival > UCHAR_MAX) {
- PyErr_SetString(PyExc_OverflowError,
- "unsigned byte integer is greater than maximum");
- return converterr("integer<b>", arg, msgbuf, bufsize);
- }
- 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;
- if (float_argument_error(arg))
- return converterr("integer<B>", arg, msgbuf, bufsize);
- ival = PyInt_AsUnsignedLongMask(arg);
- if (ival == -1 && PyErr_Occurred())
- return converterr("integer<B>", arg, msgbuf, bufsize);
- else
- *p = (unsigned char) ival;
- break;
- }
-
- case 'h': {/* signed short int */
- short *p = va_arg(*p_va, short *);
- long ival;
- if (float_argument_error(arg))
- return converterr("integer<h>", arg, msgbuf, bufsize);
- ival = PyInt_AsLong(arg);
- if (ival == -1 && PyErr_Occurred())
- return converterr("integer<h>", arg, msgbuf, bufsize);
- else if (ival < SHRT_MIN) {
- PyErr_SetString(PyExc_OverflowError,
- "signed short integer is less than minimum");
- return converterr("integer<h>", arg, msgbuf, bufsize);
- }
- else if (ival > SHRT_MAX) {
- PyErr_SetString(PyExc_OverflowError,
- "signed short integer is greater than maximum");
- return converterr("integer<h>", arg, msgbuf, bufsize);
- }
- 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;
- if (float_argument_error(arg))
- return converterr("integer<H>", arg, msgbuf, bufsize);
- ival = PyInt_AsUnsignedLongMask(arg);
- if (ival == -1 && PyErr_Occurred())
- return converterr("integer<H>", arg, msgbuf, bufsize);
- else
- *p = (unsigned short) ival;
- break;
- }
- case 'i': {/* signed int */
- int *p = va_arg(*p_va, int *);
- long ival;
- if (float_argument_error(arg))
- return converterr("integer<i>", arg, msgbuf, bufsize);
- ival = PyInt_AsLong(arg);
- if (ival == -1 && PyErr_Occurred())
- return converterr("integer<i>", arg, msgbuf, bufsize);
- else if (ival > INT_MAX) {
- PyErr_SetString(PyExc_OverflowError,
- "signed integer is greater than maximum");
- return converterr("integer<i>", arg, msgbuf, bufsize);
- }
- else if (ival < INT_MIN) {
- PyErr_SetString(PyExc_OverflowError,
- "signed integer is less than minimum");
- return converterr("integer<i>", arg, msgbuf, bufsize);
- }
- else
- *p = ival;
- break;
- }
- case 'I': { /* int sized bitfield, both signed and
- unsigned allowed */
- unsigned int *p = va_arg(*p_va, unsigned int *);
- unsigned int ival;
- if (float_argument_error(arg))
- return converterr("integer<I>", arg, msgbuf, bufsize);
- ival = (unsigned int)PyInt_AsUnsignedLongMask(arg);
- if (ival == (unsigned int)-1 && PyErr_Occurred())
- return converterr("integer<I>", arg, msgbuf, bufsize);
- else
- *p = ival;
- break;
- }
- case 'n': /* Py_ssize_t */
-#if SIZEOF_SIZE_T != SIZEOF_LONG
- {
- Py_ssize_t *p = va_arg(*p_va, Py_ssize_t *);
- Py_ssize_t ival;
- if (float_argument_error(arg))
- return converterr("integer<n>", arg, msgbuf, bufsize);
- ival = PyInt_AsSsize_t(arg);
- if (ival == -1 && PyErr_Occurred())
- return converterr("integer<n>", arg, msgbuf, bufsize);
- *p = ival;
- break;
- }
-#endif
- /* Fall through from 'n' to 'l' if Py_ssize_t is int */
- case 'l': {/* long int */
- long *p = va_arg(*p_va, long *);
- long ival;
- if (float_argument_error(arg))
- return converterr("integer<l>", arg, msgbuf, bufsize);
- ival = PyInt_AsLong(arg);
- if (ival == -1 && PyErr_Occurred())
- return converterr("integer<l>", arg, msgbuf, bufsize);
- else
- *p = ival;
- break;
- }
-
- case 'k': { /* long sized bitfield */
- unsigned long *p = va_arg(*p_va, unsigned long *);
- unsigned long ival;
- if (PyInt_Check(arg))
- ival = PyInt_AsUnsignedLongMask(arg);
- else if (PyLong_Check(arg))
- ival = PyLong_AsUnsignedLongMask(arg);
- else
- return converterr("integer<k>", arg, msgbuf, bufsize);
- *p = ival;
- break;
- }
-
-#ifdef HAVE_LONG_LONG
- case 'L': {/* PY_LONG_LONG */
- PY_LONG_LONG *p = va_arg( *p_va, PY_LONG_LONG * );
- PY_LONG_LONG ival = PyLong_AsLongLong( arg );
- if (ival == (PY_LONG_LONG)-1 && PyErr_Occurred() ) {
- return converterr("long<L>", arg, msgbuf, bufsize);
- } else {
- *p = ival;
- }
- break;
- }
-
- case 'K': { /* long long sized bitfield */
- unsigned PY_LONG_LONG *p = va_arg(*p_va, unsigned PY_LONG_LONG *);
- unsigned PY_LONG_LONG ival;
- if (PyInt_Check(arg))
- ival = PyInt_AsUnsignedLongMask(arg);
- else if (PyLong_Check(arg))
- ival = PyLong_AsUnsignedLongLongMask(arg);
- else
- return converterr("integer<K>", arg, msgbuf, bufsize);
- *p = ival;
- break;
- }
-#endif // HAVE_LONG_LONG
-
- case 'f': {/* float */
- float *p = va_arg(*p_va, float *);
- double dval = PyFloat_AsDouble(arg);
- if (PyErr_Occurred())
- return converterr("float<f>", arg, msgbuf, bufsize);
- else
- *p = (float) 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, bufsize);
- 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 converterr("complex<D>", arg, msgbuf, bufsize);
- 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_AS_STRING(arg)[0];
- else
- return converterr("char", arg, msgbuf, bufsize);
- break;
- }
- case 's': {/* string */
- if (*format == '*') {
- Py_buffer *p = (Py_buffer *)va_arg(*p_va, Py_buffer *);
-
- if (PyString_Check(arg)) {
- fflush(stdout);
- PyBuffer_FillInfo(p, arg,
- PyString_AS_STRING(arg), PyString_GET_SIZE(arg),
- 1, 0);
- }
-#ifdef Py_USING_UNICODE
- else if (PyUnicode_Check(arg)) {
-#if 0
- uarg = UNICODE_DEFAULT_ENCODING(arg);
- if (uarg == NULL)
- return converterr(CONV_UNICODE,
- arg, msgbuf, bufsize);
- PyBuffer_FillInfo(p, arg,
- PyString_AS_STRING(uarg), PyString_GET_SIZE(uarg),
- 1, 0);
-#else
- return converterr("string or buffer", arg, msgbuf, bufsize);
-#endif
- }
-#endif
- else { /* any buffer-like object */
- char *buf;
- 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);
- }
- format++;
- } else if (*format == '#') {
- void **p = (void **)va_arg(*p_va, char **);
- FETCH_SIZE;
-
- if (PyString_Check(arg)) {
- *p = PyString_AS_STRING(arg);
- STORE_SIZE(PyString_GET_SIZE(arg));
- }
-#ifdef Py_USING_UNICODE
- else if (PyUnicode_Check(arg)) {
- uarg = UNICODE_DEFAULT_ENCODING(arg);
- if (uarg == NULL)
- return converterr(CONV_UNICODE,
- arg, msgbuf, bufsize);
- *p = PyString_AS_STRING(uarg);
- STORE_SIZE(PyString_GET_SIZE(uarg));
- }
-#endif
- else { /* any buffer-like object */
- char *buf;
- Py_ssize_t count = convertbuffer(arg, p, &buf);
- if (count < 0)
- return converterr(buf, arg, msgbuf, bufsize);
- STORE_SIZE(count);
- }
- format++;
- } else {
- char **p = va_arg(*p_va, char **);
-
- if (PyString_Check(arg))
- *p = PyString_AS_STRING(arg);
-#ifdef Py_USING_UNICODE
- else if (PyUnicode_Check(arg)) {
- uarg = UNICODE_DEFAULT_ENCODING(arg);
- if (uarg == NULL)
- return converterr(CONV_UNICODE,
- arg, msgbuf, bufsize);
- *p = PyString_AS_STRING(uarg);
- }
-#endif
- else
- return converterr("string", arg, msgbuf, bufsize);
- if ((Py_ssize_t)strlen(*p) != PyString_Size(arg))
- return converterr("string without null bytes",
- arg, msgbuf, bufsize);
- }
- break;
- }
-
- case 'z': {/* string, may be NULL (None) */
- if (*format == '*') {
- Py_FatalError("'*' format not supported in PyArg_*\n");
-#if 0
- Py_buffer *p = (Py_buffer *)va_arg(*p_va, Py_buffer *);
-
- if (arg == Py_None)
- PyBuffer_FillInfo(p, NULL, NULL, 0, 1, 0);
- else if (PyString_Check(arg)) {
- PyBuffer_FillInfo(p, arg,
- PyString_AS_STRING(arg), PyString_GET_SIZE(arg),
- 1, 0);
- }
-#ifdef Py_USING_UNICODE
- else if (PyUnicode_Check(arg)) {
- uarg = UNICODE_DEFAULT_ENCODING(arg);
- if (uarg == NULL)
- return converterr(CONV_UNICODE,
- arg, msgbuf, bufsize);
- PyBuffer_FillInfo(p, arg,
- PyString_AS_STRING(uarg), PyString_GET_SIZE(uarg),
- 1, 0);
- }
-#endif
- else { /* any buffer-like object */
- char *buf;
- 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);
- }
- format++;
-#endif
- } else if (*format == '#') { /* any buffer-like object */
- void **p = (void **)va_arg(*p_va, char **);
- FETCH_SIZE;
-
- if (arg == Py_None) {
- *p = 0;
- STORE_SIZE(0);
- }
- else if (PyString_Check(arg)) {
- *p = PyString_AS_STRING(arg);
- STORE_SIZE(PyString_GET_SIZE(arg));
- }
-#ifdef Py_USING_UNICODE
- else if (PyUnicode_Check(arg)) {
- uarg = UNICODE_DEFAULT_ENCODING(arg);
- if (uarg == NULL)
- return converterr(CONV_UNICODE,
- arg, msgbuf, bufsize);
- *p = PyString_AS_STRING(uarg);
- STORE_SIZE(PyString_GET_SIZE(uarg));
- }
-#endif
- else { /* any buffer-like object */
- char *buf;
- Py_ssize_t count = convertbuffer(arg, p, &buf);
- if (count < 0)
- return converterr(buf, arg, msgbuf, bufsize);
- STORE_SIZE(count);
- }
- format++;
- } else {
- char **p = va_arg(*p_va, char **);
-
- if (arg == Py_None)
- *p = 0;
- else if (PyString_Check(arg))
- *p = PyString_AS_STRING(arg);
-#ifdef Py_USING_UNICODE
- else if (PyUnicode_Check(arg)) {
- uarg = UNICODE_DEFAULT_ENCODING(arg);
- if (uarg == NULL)
- return converterr(CONV_UNICODE,
- arg, msgbuf, bufsize);
- *p = PyString_AS_STRING(uarg);
- }
-#endif
- else
- return converterr("string or None",
- arg, msgbuf, bufsize);
- if (*format == '#') {
- FETCH_SIZE;
- assert(0); /* XXX redundant with if-case */
- if (arg == Py_None)
- *q = 0;
- else
- *q = PyString_Size(arg);
- format++;
- }
- else if (*p != NULL &&
- (Py_ssize_t)strlen(*p) != PyString_Size(arg))
- return converterr(
- "string without null bytes or None",
- arg, msgbuf, bufsize);
- }
- break;
- }
- case 'e': {/* encoded string */
- char **buffer;
- const char *encoding;
- PyObject *s;
- Py_ssize_t size;
- int recode_strings;
-
- /* Get 'e' parameter: the encoding name */
- encoding = (const char *)va_arg(*p_va, const char *);
-#ifdef Py_USING_UNICODE
- if (encoding == NULL)
- encoding = PyUnicode_GetDefaultEncoding();
+ PyObject *uarg;
#endif
- /* 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, bufsize);
- buffer = (char **)va_arg(*p_va, char **);
- format++;
- if (buffer == NULL)
- return converterr("(buffer is NULL)",
- arg, msgbuf, bufsize);
-
- /* Encode object */
- if (!recode_strings && PyString_Check(arg)) {
- s = arg;
- Py_INCREF(s);
- }
- else {
+ switch (c) {
+
+ case 'b': { /* unsigned byte -- very short int */
+ char *p = va_arg(*p_va, char *);
+ long ival;
+ if (float_argument_error(arg))
+ return converterr("integer<b>", arg, msgbuf, bufsize);
+ ival = PyInt_AsLong(arg);
+ if (ival == -1 && PyErr_Occurred())
+ return converterr("integer<b>", arg, msgbuf, bufsize);
+ else if (ival < 0) {
+ PyErr_SetString(PyExc_OverflowError,
+ "unsigned byte integer is less than minimum");
+ return converterr("integer<b>", arg, msgbuf, bufsize);
+ }
+ else if (ival > UCHAR_MAX) {
+ PyErr_SetString(PyExc_OverflowError,
+ "unsigned byte integer is greater than maximum");
+ return converterr("integer<b>", arg, msgbuf, bufsize);
+ }
+ 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;
+ if (float_argument_error(arg))
+ return converterr("integer<B>", arg, msgbuf, bufsize);
+ ival = PyInt_AsUnsignedLongMask(arg);
+ if (ival == -1 && PyErr_Occurred())
+ return converterr("integer<B>", arg, msgbuf, bufsize);
+ else
+ *p = (unsigned char) ival;
+ break;
+ }
+
+ case 'h': {/* signed short int */
+ short *p = va_arg(*p_va, short *);
+ long ival;
+ if (float_argument_error(arg))
+ return converterr("integer<h>", arg, msgbuf, bufsize);
+ ival = PyInt_AsLong(arg);
+ if (ival == -1 && PyErr_Occurred())
+ return converterr("integer<h>", arg, msgbuf, bufsize);
+ else if (ival < SHRT_MIN) {
+ PyErr_SetString(PyExc_OverflowError,
+ "signed short integer is less than minimum");
+ return converterr("integer<h>", arg, msgbuf, bufsize);
+ }
+ else if (ival > SHRT_MAX) {
+ PyErr_SetString(PyExc_OverflowError,
+ "signed short integer is greater than maximum");
+ return converterr("integer<h>", arg, msgbuf, bufsize);
+ }
+ 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;
+ if (float_argument_error(arg))
+ return converterr("integer<H>", arg, msgbuf, bufsize);
+ ival = PyInt_AsUnsignedLongMask(arg);
+ if (ival == -1 && PyErr_Occurred())
+ return converterr("integer<H>", arg, msgbuf, bufsize);
+ else
+ *p = (unsigned short) ival;
+ break;
+ }
+
+ case 'i': {/* signed int */
+ int *p = va_arg(*p_va, int *);
+ long ival;
+ if (float_argument_error(arg))
+ return converterr("integer<i>", arg, msgbuf, bufsize);
+ ival = PyInt_AsLong(arg);
+ if (ival == -1 && PyErr_Occurred())
+ return converterr("integer<i>", arg, msgbuf, bufsize);
+ else if (ival > INT_MAX) {
+ PyErr_SetString(PyExc_OverflowError,
+ "signed integer is greater than maximum");
+ return converterr("integer<i>", arg, msgbuf, bufsize);
+ }
+ else if (ival < INT_MIN) {
+ PyErr_SetString(PyExc_OverflowError,
+ "signed integer is less than minimum");
+ return converterr("integer<i>", arg, msgbuf, bufsize);
+ }
+ else
+ *p = ival;
+ break;
+ }
+
+ case 'I': { /* int sized bitfield, both signed and
+ unsigned allowed */
+ unsigned int *p = va_arg(*p_va, unsigned int *);
+ unsigned int ival;
+ if (float_argument_error(arg))
+ return converterr("integer<I>", arg, msgbuf, bufsize);
+ ival = (unsigned int)PyInt_AsUnsignedLongMask(arg);
+ if (ival == (unsigned int)-1 && PyErr_Occurred())
+ return converterr("integer<I>", arg, msgbuf, bufsize);
+ else
+ *p = ival;
+ break;
+ }
+
+ case 'n': /* Py_ssize_t */
+#if SIZEOF_SIZE_T != SIZEOF_LONG
+ {
+ Py_ssize_t *p = va_arg(*p_va, Py_ssize_t *);
+ Py_ssize_t ival;
+ if (float_argument_error(arg))
+ return converterr("integer<n>", arg, msgbuf, bufsize);
+ ival = PyInt_AsSsize_t(arg);
+ if (ival == -1 && PyErr_Occurred())
+ return converterr("integer<n>", arg, msgbuf, bufsize);
+ *p = ival;
+ break;
+ }
+#endif
+ /* Fall through from 'n' to 'l' if Py_ssize_t is int */
+ case 'l': {/* long int */
+ long *p = va_arg(*p_va, long *);
+ long ival;
+ if (float_argument_error(arg))
+ return converterr("integer<l>", arg, msgbuf, bufsize);
+ ival = PyInt_AsLong(arg);
+ if (ival == -1 && PyErr_Occurred())
+ return converterr("integer<l>", arg, msgbuf, bufsize);
+ else
+ *p = ival;
+ break;
+ }
+
+ case 'k': { /* long sized bitfield */
+ unsigned long *p = va_arg(*p_va, unsigned long *);
+ unsigned long ival;
+ if (PyInt_Check(arg))
+ ival = PyInt_AsUnsignedLongMask(arg);
+ else if (PyLong_Check(arg))
+ ival = PyLong_AsUnsignedLongMask(arg);
+ else
+ return converterr("integer<k>", arg, msgbuf, bufsize);
+ *p = ival;
+ break;
+ }
+
+#ifdef HAVE_LONG_LONG
+ case 'L': {/* PY_LONG_LONG */
+ PY_LONG_LONG *p = va_arg( *p_va, PY_LONG_LONG * );
+ PY_LONG_LONG ival;
+ if (float_argument_warning(arg))
+ return converterr("long<L>", arg, msgbuf, bufsize);
+ ival = PyLong_AsLongLong(arg);
+ if (ival == (PY_LONG_LONG)-1 && PyErr_Occurred() ) {
+ return converterr("long<L>", arg, msgbuf, bufsize);
+ } else {
+ *p = ival;
+ }
+ break;
+ }
+
+ case 'K': { /* long long sized bitfield */
+ unsigned PY_LONG_LONG *p = va_arg(*p_va, unsigned PY_LONG_LONG *);
+ unsigned PY_LONG_LONG ival;
+ if (PyInt_Check(arg))
+ ival = PyInt_AsUnsignedLongMask(arg);
+ else if (PyLong_Check(arg))
+ ival = PyLong_AsUnsignedLongLongMask(arg);
+ else
+ return converterr("integer<K>", arg, msgbuf, bufsize);
+ *p = ival;
+ break;
+ }
+#endif
+
+ case 'f': {/* float */
+ float *p = va_arg(*p_va, float *);
+ double dval = PyFloat_AsDouble(arg);
+ if (PyErr_Occurred())
+ return converterr("float<f>", arg, msgbuf, bufsize);
+ else
+ *p = (float) 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, bufsize);
+ 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 converterr("complex<D>", arg, msgbuf, bufsize);
+ 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_AS_STRING(arg)[0];
+ else
+ return converterr("char", arg, msgbuf, bufsize);
+ break;
+ }
+
+ case 's': {/* string */
+ if (*format == '*') {
+ Py_buffer *p = (Py_buffer *)va_arg(*p_va, Py_buffer *);
+
+ if (PyString_Check(arg)) {
+ PyBuffer_FillInfo(p, arg,
+ PyString_AS_STRING(arg), PyString_GET_SIZE(arg),
+ 1, 0);
+ }
#ifdef Py_USING_UNICODE
- PyObject *u;
+ else if (PyUnicode_Check(arg)) {
+ uarg = UNICODE_DEFAULT_ENCODING(arg);
+ if (uarg == NULL)
+ return converterr(CONV_UNICODE,
+ arg, msgbuf, bufsize);
+ PyBuffer_FillInfo(p, arg,
+ PyString_AS_STRING(uarg), PyString_GET_SIZE(uarg),
+ 1, 0);
+ }
+#endif
+ else { /* any buffer-like object */
+ char *buf;
+ 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);
+ }
+ format++;
+ } else if (*format == '#') {
+ void **p = (void **)va_arg(*p_va, char **);
+ FETCH_SIZE;
- /* Convert object to Unicode */
- u = PyUnicode_FromObject(arg);
- if (u == NULL)
- return converterr(
- "string or unicode or text buffer",
- arg, msgbuf, bufsize);
-
- /* Encode object; use default error handling */
- s = PyUnicode_AsEncodedString(u,
- encoding,
- NULL);
- Py_DECREF(u);
- if (s == NULL)
- return converterr("(encoding failed)",
- arg, msgbuf, bufsize);
- if (!PyString_Check(s)) {
- Py_DECREF(s);
- return converterr(
- "(encoder failed to return a string)",
- arg, msgbuf, bufsize);
- }
+ if (PyString_Check(arg)) {
+ *p = PyString_AS_STRING(arg);
+ STORE_SIZE(PyString_GET_SIZE(arg));
+ }
+#ifdef Py_USING_UNICODE
+ else if (PyUnicode_Check(arg)) {
+ uarg = UNICODE_DEFAULT_ENCODING(arg);
+ if (uarg == NULL)
+ return converterr(CONV_UNICODE,
+ arg, msgbuf, bufsize);
+ *p = PyString_AS_STRING(uarg);
+ STORE_SIZE(PyString_GET_SIZE(uarg));
+ }
+#endif
+ else { /* any buffer-like object */
+ char *buf;
+ Py_ssize_t count = convertbuffer(arg, p, &buf);
+ if (count < 0)
+ return converterr(buf, arg, msgbuf, bufsize);
+ STORE_SIZE(count);
+ }
+ format++;
+ } else {
+ char **p = va_arg(*p_va, char **);
+
+ if (PyString_Check(arg))
+ *p = PyString_AS_STRING(arg);
+#ifdef Py_USING_UNICODE
+ else if (PyUnicode_Check(arg)) {
+ uarg = UNICODE_DEFAULT_ENCODING(arg);
+ if (uarg == NULL)
+ return converterr(CONV_UNICODE,
+ arg, msgbuf, bufsize);
+ *p = PyString_AS_STRING(uarg);
+ }
+#endif
+ else
+ return converterr("string", arg, msgbuf, bufsize);
+ if ((Py_ssize_t)strlen(*p) != PyString_Size(arg))
+ return converterr("string without null bytes",
+ arg, msgbuf, bufsize);
+ }
+ break;
+ }
+
+ case 'z': {/* string, may be NULL (None) */
+ if (*format == '*') {
+ Py_buffer *p = (Py_buffer *)va_arg(*p_va, Py_buffer *);
+
+ if (arg == Py_None)
+ PyBuffer_FillInfo(p, NULL, NULL, 0, 1, 0);
+ else if (PyString_Check(arg)) {
+ PyBuffer_FillInfo(p, arg,
+ PyString_AS_STRING(arg), PyString_GET_SIZE(arg),
+ 1, 0);
+ }
+#ifdef Py_USING_UNICODE
+ else if (PyUnicode_Check(arg)) {
+ uarg = UNICODE_DEFAULT_ENCODING(arg);
+ if (uarg == NULL)
+ return converterr(CONV_UNICODE,
+ arg, msgbuf, bufsize);
+ PyBuffer_FillInfo(p, arg,
+ PyString_AS_STRING(uarg), PyString_GET_SIZE(uarg),
+ 1, 0);
+ }
+#endif
+ else { /* any buffer-like object */
+ char *buf;
+ 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);
+ }
+ format++;
+ } else if (*format == '#') { /* any buffer-like object */
+ void **p = (void **)va_arg(*p_va, char **);
+ FETCH_SIZE;
+
+ if (arg == Py_None) {
+ *p = 0;
+ STORE_SIZE(0);
+ }
+ else if (PyString_Check(arg)) {
+ *p = PyString_AS_STRING(arg);
+ STORE_SIZE(PyString_GET_SIZE(arg));
+ }
+#ifdef Py_USING_UNICODE
+ else if (PyUnicode_Check(arg)) {
+ uarg = UNICODE_DEFAULT_ENCODING(arg);
+ if (uarg == NULL)
+ return converterr(CONV_UNICODE,
+ arg, msgbuf, bufsize);
+ *p = PyString_AS_STRING(uarg);
+ STORE_SIZE(PyString_GET_SIZE(uarg));
+ }
+#endif
+ else { /* any buffer-like object */
+ char *buf;
+ Py_ssize_t count = convertbuffer(arg, p, &buf);
+ if (count < 0)
+ return converterr(buf, arg, msgbuf, bufsize);
+ STORE_SIZE(count);
+ }
+ format++;
+ } else {
+ char **p = va_arg(*p_va, char **);
+
+ if (arg == Py_None)
+ *p = 0;
+ else if (PyString_Check(arg))
+ *p = PyString_AS_STRING(arg);
+#ifdef Py_USING_UNICODE
+ else if (PyUnicode_Check(arg)) {
+ uarg = UNICODE_DEFAULT_ENCODING(arg);
+ if (uarg == NULL)
+ return converterr(CONV_UNICODE,
+ arg, msgbuf, bufsize);
+ *p = PyString_AS_STRING(uarg);
+ }
+#endif
+ else
+ return converterr("string or None",
+ arg, msgbuf, bufsize);
+ if (*format == '#') {
+ FETCH_SIZE;
+ assert(0); /* XXX redundant with if-case */
+ if (arg == Py_None) {
+ STORE_SIZE(0);
+ } else {
+ STORE_SIZE(PyString_Size(arg));
+ }
+ format++;
+ }
+ else if (*p != NULL &&
+ (Py_ssize_t)strlen(*p) != PyString_Size(arg))
+ return converterr(
+ "string without null bytes or None",
+ arg, msgbuf, bufsize);
+ }
+ break;
+ }
+
+ case 'e': {/* encoded string */
+ char **buffer;
+ const char *encoding;
+ PyObject *s;
+ Py_ssize_t size;
+ int recode_strings;
+
+ /* Get 'e' parameter: the encoding name */
+ encoding = (const char *)va_arg(*p_va, const char *);
+#ifdef Py_USING_UNICODE
+ if (encoding == NULL)
+ encoding = PyUnicode_GetDefaultEncoding();
+#endif
+
+ /* 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, bufsize);
+ buffer = (char **)va_arg(*p_va, char **);
+ format++;
+ if (buffer == NULL)
+ return converterr("(buffer is NULL)",
+ arg, msgbuf, bufsize);
+
+ /* Encode object */
+ if (!recode_strings && PyString_Check(arg)) {
+ s = arg;
+ Py_INCREF(s);
+ }
+ else {
+#ifdef Py_USING_UNICODE
+ PyObject *u;
+
+ /* Convert object to Unicode */
+ u = PyUnicode_FromObject(arg);
+ if (u == NULL)
+ return converterr(
+ "string or unicode or text buffer",
+ arg, msgbuf, bufsize);
+
+ /* Encode object; use default error handling */
+ s = PyUnicode_AsEncodedString(u,
+ encoding,
+ NULL);
+ Py_DECREF(u);
+ if (s == NULL)
+ return converterr("(encoding failed)",
+ arg, msgbuf, bufsize);
+ if (!PyString_Check(s)) {
+ Py_DECREF(s);
+ return converterr(
+ "(encoder failed to return a string)",
+ arg, msgbuf, bufsize);
+ }
#else
- return converterr("string<e>", arg, msgbuf, bufsize);
+ return converterr("string<e>", arg, msgbuf, bufsize);
#endif
- }
- size = PyString_GET_SIZE(s);
+ }
+ 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
+ /* Write output; output is guaranteed to be 0-terminated */
+ if (*format == '#') {
+ /* Using buffer length parameter '#':
- - 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
-
- */
- FETCH_SIZE;
+ - 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
- format++;
- if (q == NULL && q2 == NULL) {
- Py_DECREF(s);
- return converterr(
- "(buffer_len is NULL)",
- arg, msgbuf, bufsize);
- }
- if (*buffer == NULL) {
- *buffer = PyMem_NEW(char, size + 1);
- if (*buffer == NULL) {
- Py_DECREF(s);
- return converterr(
- "(memory error)",
- arg, msgbuf, bufsize);
- }
- if (addcleanup(*buffer, freelist, cleanup_ptr)) {
- Py_DECREF(s);
- return converterr(
- "(cleanup problem)",
- arg, msgbuf, bufsize);
- }
- } else {
- if (size + 1 > BUFFER_LEN) {
- Py_DECREF(s);
- return converterr(
- "(buffer overflow)",
- arg, msgbuf, bufsize);
- }
- }
- memcpy(*buffer,
- PyString_AS_STRING(s),
- size + 1);
- STORE_SIZE(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
+ - 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
- - 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
+ - in both cases, *buffer_len is updated to
+ the size of the buffer /excluding/ the
+ trailing 0-byte
- */
- if ((Py_ssize_t)strlen(PyString_AS_STRING(s))
- != size) {
- Py_DECREF(s);
- return converterr(
- "encoded string without NULL bytes",
- arg, msgbuf, bufsize);
- }
- *buffer = PyMem_NEW(char, size + 1);
- if (*buffer == NULL) {
- Py_DECREF(s);
- return converterr("(memory error)",
- arg, msgbuf, bufsize);
- }
- if (addcleanup(*buffer, freelist, cleanup_ptr)) {
- Py_DECREF(s);
- return converterr("(cleanup problem)",
- arg, msgbuf, bufsize);
- }
- memcpy(*buffer,
- PyString_AS_STRING(s),
- size + 1);
- }
- Py_DECREF(s);
- break;
- }
+ */
+ FETCH_SIZE;
+
+ format++;
+ if (q == NULL && q2 == NULL) {
+ Py_DECREF(s);
+ return converterr(
+ "(buffer_len is NULL)",
+ arg, msgbuf, bufsize);
+ }
+ if (*buffer == NULL) {
+ *buffer = PyMem_NEW(char, size + 1);
+ if (*buffer == NULL) {
+ Py_DECREF(s);
+ return converterr(
+ "(memory error)",
+ arg, msgbuf, bufsize);
+ }
+ if (addcleanup(*buffer, freelist, cleanup_ptr)) {
+ Py_DECREF(s);
+ return converterr(
+ "(cleanup problem)",
+ arg, msgbuf, bufsize);
+ }
+ } else {
+ if (size + 1 > BUFFER_LEN) {
+ Py_DECREF(s);
+ return converterr(
+ "(buffer overflow)",
+ arg, msgbuf, bufsize);
+ }
+ }
+ memcpy(*buffer,
+ PyString_AS_STRING(s),
+ size + 1);
+ STORE_SIZE(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 ((Py_ssize_t)strlen(PyString_AS_STRING(s))
+ != size) {
+ Py_DECREF(s);
+ return converterr(
+ "encoded string without NULL bytes",
+ arg, msgbuf, bufsize);
+ }
+ *buffer = PyMem_NEW(char, size + 1);
+ if (*buffer == NULL) {
+ Py_DECREF(s);
+ return converterr("(memory error)",
+ arg, msgbuf, bufsize);
+ }
+ if (addcleanup(*buffer, freelist, cleanup_ptr)) {
+ Py_DECREF(s);
+ return converterr("(cleanup problem)",
+ arg, msgbuf, bufsize);
+ }
+ memcpy(*buffer,
+ PyString_AS_STRING(s),
+ size + 1);
+ }
+ Py_DECREF(s);
+ break;
+ }
#ifdef Py_USING_UNICODE
- case 'u': {/* raw unicode buffer (Py_UNICODE *) */
- if (*format == '#') { /* any buffer-like object */
- void **p = (void **)va_arg(*p_va, char **);
- FETCH_SIZE;
- if (PyUnicode_Check(arg)) {
- *p = PyUnicode_AS_UNICODE(arg);
- STORE_SIZE(PyUnicode_GET_SIZE(arg));
- }
- else {
- return converterr("cannot convert raw buffers",
- arg, msgbuf, bufsize);
- }
- format++;
- } else {
- Py_UNICODE **p = va_arg(*p_va, Py_UNICODE **);
- if (PyUnicode_Check(arg))
- *p = PyUnicode_AS_UNICODE(arg);
- else
- return converterr("unicode", arg, msgbuf, bufsize);
- }
- break;
- }
+ case 'u': {/* raw unicode buffer (Py_UNICODE *) */
+ if (*format == '#') { /* any buffer-like object */
+ void **p = (void **)va_arg(*p_va, char **);
+ FETCH_SIZE;
+ if (PyUnicode_Check(arg)) {
+ *p = PyUnicode_AS_UNICODE(arg);
+ STORE_SIZE(PyUnicode_GET_SIZE(arg));
+ }
+ else {
+ return converterr("cannot convert raw buffers",
+ arg, msgbuf, bufsize);
+ }
+ format++;
+ } else {
+ Py_UNICODE **p = va_arg(*p_va, Py_UNICODE **);
+ if (PyUnicode_Check(arg))
+ *p = PyUnicode_AS_UNICODE(arg);
+ else
+ return converterr("unicode", arg, msgbuf, bufsize);
+ }
+ break;
+ }
#endif
- case 'S': { /* string object */
- PyObject **p = va_arg(*p_va, PyObject **);
- if (PyString_Check(arg))
- *p = arg;
- else
- return converterr("string", arg, msgbuf, bufsize);
- break;
- }
-
+ case 'S': { /* string object */
+ PyObject **p = va_arg(*p_va, PyObject **);
+ if (PyString_Check(arg))
+ *p = arg;
+ else
+ return converterr("string", arg, msgbuf, bufsize);
+ break;
+ }
+
#ifdef Py_USING_UNICODE
- case 'U': { /* Unicode object */
- PyObject **p = va_arg(*p_va, PyObject **);
- if (PyUnicode_Check(arg))
- *p = arg;
- else
- return converterr("unicode", arg, msgbuf, bufsize);
- break;
- }
+ case 'U': { /* Unicode object */
+ PyObject **p = va_arg(*p_va, PyObject **);
+ if (PyUnicode_Check(arg))
+ *p = arg;
+ else
+ return converterr("unicode", arg, msgbuf, bufsize);
+ break;
+ }
#endif
- case 'O': { /* object */
- PyTypeObject *type;
- PyObject **p;
- if (*format == '!') {
- type = va_arg(*p_va, PyTypeObject*);
- p = va_arg(*p_va, PyObject **);
- format++;
- if (PyType_IsSubtype(arg->ob_type, type))
- *p = arg;
- else
- return converterr(type->tp_name, arg, msgbuf, bufsize);
- }
- else if (*format == '?') {
- inquiry pred = va_arg(*p_va, inquiry);
- p = va_arg(*p_va, PyObject **);
- format++;
- if ((*pred)(arg))
- *p = arg;
- else
- return converterr("(unspecified)",
- arg, msgbuf, bufsize);
-
- }
- 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, bufsize);
- }
- else {
- p = va_arg(*p_va, PyObject **);
- *p = arg;
- }
- break;
- }
-
- case 'w': { /* memory buffer, read-write access */
- Py_FatalError("'w' unsupported\n");
-#if 0
- void **p = va_arg(*p_va, void **);
- void *res;
- PyBufferProcs *pb = arg->ob_type->tp_as_buffer;
- Py_ssize_t count;
+ case 'O': { /* object */
+ PyTypeObject *type;
+ PyObject **p;
+ if (*format == '!') {
+ type = va_arg(*p_va, PyTypeObject*);
+ p = va_arg(*p_va, PyObject **);
+ format++;
+ if (PyType_IsSubtype(arg->ob_type, type))
+ *p = arg;
+ else
+ return converterr(type->tp_name, arg, msgbuf, bufsize);
- if (pb && pb->bf_releasebuffer && *format != '*')
- /* Buffer must be released, yet caller does not use
- the Py_buffer protocol. */
- return converterr("pinned buffer", arg, msgbuf, bufsize);
+ }
+ else if (*format == '?') {
+ inquiry pred = va_arg(*p_va, inquiry);
+ p = va_arg(*p_va, PyObject **);
+ format++;
+ if ((*pred)(arg))
+ *p = arg;
+ else
+ return converterr("(unspecified)",
+ arg, msgbuf, bufsize);
- if (pb && pb->bf_getbuffer && *format == '*') {
- /* Caller is interested in Py_buffer, and the object
- supports it directly. */
- format++;
- if (pb->bf_getbuffer(arg, (Py_buffer*)p, PyBUF_WRITABLE) < 0) {
- PyErr_Clear();
- return converterr("read-write buffer", arg, msgbuf, bufsize);
- }
- if (addcleanup(p, freelist, cleanup_buffer)) {
- return converterr(
- "(cleanup problem)",
- arg, msgbuf, bufsize);
- }
- if (!PyBuffer_IsContiguous((Py_buffer*)p, 'C'))
- return converterr("contiguous buffer", arg, msgbuf, bufsize);
- break;
- }
+ }
+ 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, bufsize);
+ }
+ else {
+ p = va_arg(*p_va, PyObject **);
+ *p = arg;
+ }
+ break;
+ }
- if (pb == NULL ||
- pb->bf_getwritebuffer == NULL ||
- pb->bf_getsegcount == NULL)
- return converterr("read-write buffer", arg, msgbuf, bufsize);
- if ((*pb->bf_getsegcount)(arg, NULL) != 1)
- return converterr("single-segment read-write buffer",
- arg, msgbuf, bufsize);
- if ((count = pb->bf_getwritebuffer(arg, 0, &res)) < 0)
- return converterr("(unspecified)", arg, msgbuf, bufsize);
- if (*format == '*') {
- PyBuffer_FillInfo((Py_buffer*)p, arg, res, count, 1, 0);
- format++;
- }
- else {
- *p = res;
- if (*format == '#') {
- FETCH_SIZE;
- STORE_SIZE(count);
- format++;
- }
- }
- break;
-#endif
- }
-
- case 't': { /* 8-bit character buffer, read-only access */
- char **p = va_arg(*p_va, char **);
- PyBufferProcs *pb = arg->ob_type->tp_as_buffer;
- Py_ssize_t count;
-#if 0
- if (*format++ != '#')
- return converterr(
- "invalid use of 't' format character",
- arg, msgbuf, bufsize);
-#endif
- if (!PyType_HasFeature(arg->ob_type,
- Py_TPFLAGS_HAVE_GETCHARBUFFER)
-#if 0
- || pb == NULL || pb->bf_getcharbuffer == NULL ||
- pb->bf_getsegcount == NULL
-#endif
- )
- return converterr(
- "string or read-only character buffer",
- arg, msgbuf, bufsize);
-#if 0
- if (pb->bf_getsegcount(arg, NULL) != 1)
- return converterr(
- "string or single-segment read-only buffer",
- arg, msgbuf, bufsize);
+ case 'w': { /* memory buffer, read-write access */
+ void **p = va_arg(*p_va, void **);
+ void *res;
+ PyBufferProcs *pb = arg->ob_type->tp_as_buffer;
+ Py_ssize_t count;
- if (pb->bf_releasebuffer)
- return converterr(
- "string or pinned buffer",
- arg, msgbuf, bufsize);
-#endif
- count = pb->bf_getcharbuffer(arg, 0, p);
-#if 0
- if (count < 0)
- return converterr("(unspecified)", arg, msgbuf, bufsize);
-#endif
- {
- FETCH_SIZE;
- STORE_SIZE(count);
- ++format;
- }
- break;
- }
- default:
- return converterr("impossible<bad format char>", arg, msgbuf, bufsize);
-
- }
-
- *p_format = format;
- return NULL;
+ if (pb && pb->bf_releasebuffer && *format != '*')
+ /* Buffer must be released, yet caller does not use
+ the Py_buffer protocol. */
+ return converterr("pinned buffer", arg, msgbuf, bufsize);
+
+ if (pb && pb->bf_getbuffer && *format == '*') {
+ /* Caller is interested in Py_buffer, and the object
+ supports it directly. */
+ format++;
+ if (pb->bf_getbuffer(arg, (Py_buffer*)p, PyBUF_WRITABLE) < 0) {
+ PyErr_Clear();
+ return converterr("read-write buffer", arg, msgbuf, bufsize);
+ }
+ if (addcleanup(p, freelist, cleanup_buffer)) {
+ return converterr(
+ "(cleanup problem)",
+ arg, msgbuf, bufsize);
+ }
+ if (!PyBuffer_IsContiguous((Py_buffer*)p, 'C'))
+ return converterr("contiguous buffer", arg, msgbuf, bufsize);
+ break;
+ }
+
+ if (pb == NULL ||
+ pb->bf_getwritebuffer == NULL ||
+ pb->bf_getsegcount == NULL)
+ return converterr("read-write buffer", arg, msgbuf, bufsize);
+ if ((*pb->bf_getsegcount)(arg, NULL) != 1)
+ return converterr("single-segment read-write buffer",
+ arg, msgbuf, bufsize);
+ if ((count = pb->bf_getwritebuffer(arg, 0, &res)) < 0)
+ return converterr("(unspecified)", arg, msgbuf, bufsize);
+ if (*format == '*') {
+ PyBuffer_FillInfo((Py_buffer*)p, arg, res, count, 1, 0);
+ format++;
+ }
+ else {
+ *p = res;
+ if (*format == '#') {
+ FETCH_SIZE;
+ STORE_SIZE(count);
+ format++;
+ }
+ }
+ break;
+ }
+
+ case 't': { /* 8-bit character buffer, read-only access */
+ char **p = va_arg(*p_va, char **);
+ PyBufferProcs *pb = arg->ob_type->tp_as_buffer;
+ Py_ssize_t count;
+
+ if (*format++ != '#')
+ return converterr(
+ "invalid use of 't' format character",
+ arg, msgbuf, bufsize);
+ if (!PyType_HasFeature(arg->ob_type,
+ Py_TPFLAGS_HAVE_GETCHARBUFFER) ||
+ pb == NULL || pb->bf_getcharbuffer == NULL ||
+ pb->bf_getsegcount == NULL)
+ return converterr(
+ "string or read-only character buffer",
+ arg, msgbuf, bufsize);
+
+ if (pb->bf_getsegcount(arg, NULL) != 1)
+ return converterr(
+ "string or single-segment read-only buffer",
+ arg, msgbuf, bufsize);
+
+ if (pb->bf_releasebuffer)
+ return converterr(
+ "string or pinned buffer",
+ arg, msgbuf, bufsize);
+
+ count = pb->bf_getcharbuffer(arg, 0, p);
+ if (count < 0)
+ return converterr("(unspecified)", arg, msgbuf, bufsize);
+ {
+ FETCH_SIZE;
+ STORE_SIZE(count);
+ }
+ break;
+ }
+
+ default:
+ return converterr("impossible<bad format char>", arg, msgbuf, bufsize);
+
+ }
+
+ *p_format = format;
+ return NULL;
}
static Py_ssize_t
convertbuffer(PyObject *arg, void **p, char **errmsg)
{
- PyBufferProcs *pb = arg->ob_type->tp_as_buffer;
- Py_ssize_t count;
- if (pb == NULL ||
- pb->bf_getreadbuffer == NULL ||
- pb->bf_getsegcount == NULL ||
- pb->bf_releasebuffer != 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;
+ PyBufferProcs *pb = arg->ob_type->tp_as_buffer;
+ Py_ssize_t count;
+ if (pb == NULL ||
+ pb->bf_getreadbuffer == NULL ||
+ pb->bf_getsegcount == NULL ||
+ pb->bf_releasebuffer != 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;
}
static int
getbuffer(PyObject *arg, Py_buffer *view, char **errmsg)
{
- void *buf;
- Py_ssize_t count;
- PyBufferProcs *pb = arg->ob_type->tp_as_buffer;
- if (pb == NULL) {
- *errmsg = "string or buffer";
- return -1;
- }
- if (pb->bf_getbuffer) {
- if (pb->bf_getbuffer(arg, view, 0) < 0) {
- *errmsg = "convertible to a buffer";
- return -1;
- }
- if (!PyBuffer_IsContiguous(view, 'C')) {
- *errmsg = "contiguous buffer";
- return -1;
- }
- return 0;
- }
+ void *buf;
+ Py_ssize_t count;
+ PyBufferProcs *pb = arg->ob_type->tp_as_buffer;
+ if (pb == NULL) {
+ *errmsg = "string or buffer";
+ return -1;
+ }
+ if (pb->bf_getbuffer) {
+ if (pb->bf_getbuffer(arg, view, 0) < 0) {
+ *errmsg = "convertible to a buffer";
+ return -1;
+ }
+ if (!PyBuffer_IsContiguous(view, 'C')) {
+ *errmsg = "contiguous buffer";
+ return -1;
+ }
+ return 0;
+ }
- count = convertbuffer(arg, &buf, errmsg);
- if (count < 0) {
- *errmsg = "convertible to a buffer";
- return count;
- }
- PyBuffer_FillInfo(view, NULL, buf, count, 1, 0);
- return 0;
+ count = convertbuffer(arg, &buf, errmsg);
+ if (count < 0) {
+ *errmsg = "convertible to a buffer";
+ return count;
+ }
+ PyBuffer_FillInfo(view, arg, buf, count, 1, 0);
+ return 0;
}
/* Support for keyword arguments donated by
@@ -1395,501 +1410,487 @@
/* Return false (0) for error, else true. */
int
PyArg_ParseTupleAndKeywords(PyObject *args,
- PyObject *keywords,
- const char *format,
- char **kwlist, ...)
+ PyObject *keywords,
+ const char *format,
+ char **kwlist, ...)
{
- int retval;
- va_list va;
+ int retval;
+ va_list va;
- if ((args == NULL || !PyTuple_Check(args)) ||
- (keywords != NULL && !PyDict_Check(keywords)) ||
- format == NULL ||
- kwlist == NULL)
- {
- PyErr_BadInternalCall();
- return 0;
- }
+ if ((args == NULL || !PyTuple_Check(args)) ||
+ (keywords != NULL && !PyDict_Check(keywords)) ||
+ format == NULL ||
+ kwlist == NULL)
+ {
+ PyErr_BadInternalCall();
+ return 0;
+ }
- va_start(va, kwlist);
- retval = vgetargskeywords(args, keywords, format, kwlist, &va, 0);
- va_end(va);
- return retval;
+ va_start(va, kwlist);
+ retval = vgetargskeywords(args, keywords, format, kwlist, &va, 0);
+ va_end(va);
+ return retval;
}
int
_PyArg_ParseTupleAndKeywords_SizeT(PyObject *args,
- PyObject *keywords,
- const char *format,
- char **kwlist, ...)
+ PyObject *keywords,
+ const char *format,
+ char **kwlist, ...)
{
- int retval;
- va_list va;
+ int retval;
+ va_list va;
- if ((args == NULL || !PyTuple_Check(args)) ||
- (keywords != NULL && !PyDict_Check(keywords)) ||
- format == NULL ||
- kwlist == NULL)
- {
- PyErr_BadInternalCall();
- return 0;
- }
+ if ((args == NULL || !PyTuple_Check(args)) ||
+ (keywords != NULL && !PyDict_Check(keywords)) ||
+ format == NULL ||
+ kwlist == NULL)
+ {
+ PyErr_BadInternalCall();
+ return 0;
+ }
- va_start(va, kwlist);
- retval = vgetargskeywords(args, keywords, format,
- kwlist, &va, FLAG_SIZE_T);
- va_end(va);
- return retval;
+ va_start(va, kwlist);
+ retval = vgetargskeywords(args, keywords, format,
+ kwlist, &va, FLAG_SIZE_T);
+ va_end(va);
+ return retval;
}
int
PyArg_VaParseTupleAndKeywords(PyObject *args,
PyObject *keywords,
- const char *format,
+ const char *format,
char **kwlist, va_list va)
{
- int retval;
- va_list lva;
+ int retval;
+ va_list lva;
- if ((args == NULL || !PyTuple_Check(args)) ||
- (keywords != NULL && !PyDict_Check(keywords)) ||
- format == NULL ||
- kwlist == NULL)
- {
- PyErr_BadInternalCall();
- return 0;
- }
+ if ((args == NULL || !PyTuple_Check(args)) ||
+ (keywords != NULL && !PyDict_Check(keywords)) ||
+ format == NULL ||
+ kwlist == NULL)
+ {
+ PyErr_BadInternalCall();
+ return 0;
+ }
#ifdef VA_LIST_IS_ARRAY
- memcpy(lva, va, sizeof(va_list));
+ memcpy(lva, va, sizeof(va_list));
#else
#ifdef __va_copy
- __va_copy(lva, va);
+ __va_copy(lva, va);
#else
- lva = va;
+ lva = va;
#endif
#endif
- retval = vgetargskeywords(args, keywords, format, kwlist, &lva, 0);
- return retval;
+ retval = vgetargskeywords(args, keywords, format, kwlist, &lva, 0);
+ return retval;
}
int
_PyArg_VaParseTupleAndKeywords_SizeT(PyObject *args,
- PyObject *keywords,
- const char *format,
- char **kwlist, va_list va)
+ PyObject *keywords,
+ const char *format,
+ char **kwlist, va_list va)
{
- int retval;
- va_list lva;
+ int retval;
+ va_list lva;
- if ((args == NULL || !PyTuple_Check(args)) ||
- (keywords != NULL && !PyDict_Check(keywords)) ||
- format == NULL ||
- kwlist == NULL)
- {
- PyErr_BadInternalCall();
- return 0;
- }
+ if ((args == NULL || !PyTuple_Check(args)) ||
+ (keywords != NULL && !PyDict_Check(keywords)) ||
+ format == NULL ||
+ kwlist == NULL)
+ {
+ PyErr_BadInternalCall();
+ return 0;
+ }
#ifdef VA_LIST_IS_ARRAY
- memcpy(lva, va, sizeof(va_list));
+ memcpy(lva, va, sizeof(va_list));
#else
#ifdef __va_copy
- __va_copy(lva, va);
+ __va_copy(lva, va);
#else
- lva = va;
+ lva = va;
#endif
#endif
- retval = vgetargskeywords(args, keywords, format,
- kwlist, &lva, FLAG_SIZE_T);
- return retval;
+ retval = vgetargskeywords(args, keywords, format,
+ kwlist, &lva, FLAG_SIZE_T);
+ return retval;
}
#define IS_END_OF_FORMAT(c) (c == '\0' || c == ';' || c == ':')
static int
vgetargskeywords(PyObject *args, PyObject *keywords, const char *format,
- char **kwlist, va_list *p_va, int flags)
+ char **kwlist, va_list *p_va, int flags)
{
- char msgbuf[512];
- int levels[32];
- const char *fname, *msg, *custom_msg, *keyword;
- int min = INT_MAX;
- int i, len, nargs, nkeywords;
- PyObject *current_arg;
- freelist_t freelist = {0, NULL};
+ char msgbuf[512];
+ int levels[32];
+ const char *fname, *msg, *custom_msg, *keyword;
+ int min = INT_MAX;
+ int i, len, nargs, nkeywords;
+ PyObject *freelist = NULL, *current_arg;
+ assert(args != NULL && PyTuple_Check(args));
+ assert(keywords == NULL || PyDict_Check(keywords));
+ assert(format != NULL);
+ assert(kwlist != NULL);
+ assert(p_va != NULL);
- assert(args != NULL && PyTuple_Check(args));
- assert(keywords == NULL || PyDict_Check(keywords));
- assert(format != NULL);
- assert(kwlist != NULL);
- assert(p_va != NULL);
+ /* grab the function name or custom error msg first (mutually exclusive) */
+ fname = strchr(format, ':');
+ if (fname) {
+ fname++;
+ custom_msg = NULL;
+ }
+ else {
+ custom_msg = strchr(format,';');
+ if (custom_msg)
+ custom_msg++;
+ }
- /* grab the function name or custom error msg first (mutually exclusive) */
- fname = strchr(format, ':');
- if (fname) {
- fname++;
- custom_msg = NULL;
- }
- else {
- custom_msg = strchr(format,';');
- if (custom_msg)
- custom_msg++;
- }
+ /* scan kwlist and get greatest possible nbr of args */
+ for (len=0; kwlist[len]; len++)
+ continue;
- /* scan kwlist and get greatest possible nbr of args */
- for (len=0; kwlist[len]; len++)
- continue;
+ nargs = PyTuple_GET_SIZE(args);
+ nkeywords = (keywords == NULL) ? 0 : PyDict_Size(keywords);
+ if (nargs + nkeywords > len) {
+ PyErr_Format(PyExc_TypeError, "%s%s takes at most %d "
+ "argument%s (%d given)",
+ (fname == NULL) ? "function" : fname,
+ (fname == NULL) ? "" : "()",
+ len,
+ (len == 1) ? "" : "s",
+ nargs + nkeywords);
+ return 0;
+ }
- freelist.entries = PyMem_New(freelistentry_t, len);
+ /* convert tuple args and keyword args in same loop, using kwlist to drive process */
+ for (i = 0; i < len; i++) {
+ keyword = kwlist[i];
+ if (*format == '|') {
+ min = i;
+ format++;
+ }
+ if (IS_END_OF_FORMAT(*format)) {
+ PyErr_Format(PyExc_RuntimeError,
+ "More keyword list entries (%d) than "
+ "format specifiers (%d)", len, i);
+ return cleanreturn(0, freelist);
+ }
+ current_arg = NULL;
+ if (nkeywords) {
+ current_arg = PyDict_GetItemString(keywords, keyword);
+ }
+ if (current_arg) {
+ --nkeywords;
+ if (i < nargs) {
+ /* arg present in tuple and in dict */
+ PyErr_Format(PyExc_TypeError,
+ "Argument given by name ('%s') "
+ "and position (%d)",
+ keyword, i+1);
+ return cleanreturn(0, freelist);
+ }
+ }
+ else if (nkeywords && PyErr_Occurred())
+ return cleanreturn(0, freelist);
+ else if (i < nargs)
+ current_arg = PyTuple_GET_ITEM(args, i);
- nargs = PyTuple_GET_SIZE(args);
- nkeywords = (keywords == NULL) ? 0 : PyDict_Size(keywords);
- if (nargs + nkeywords > len) {
- PyErr_Format(PyExc_TypeError, "%s%s takes at most %d "
- "argument%s (%d given)",
- (fname == NULL) ? "function" : fname,
- (fname == NULL) ? "" : "()",
- len,
- (len == 1) ? "" : "s",
- nargs + nkeywords);
- return cleanreturn(0, &freelist);
- }
+ if (current_arg) {
+ msg = convertitem(current_arg, &format, p_va, flags,
+ levels, msgbuf, sizeof(msgbuf), &freelist);
+ if (msg) {
+ seterror(i+1, msg, levels, fname, custom_msg);
+ return cleanreturn(0, freelist);
+ }
+ continue;
+ }
- /* convert tuple args and keyword args in same loop, using kwlist to drive process */
- for (i = 0; i < len; i++) {
- keyword = kwlist[i];
- if (*format == '|') {
- min = i;
- format++;
- }
- if (IS_END_OF_FORMAT(*format)) {
- PyErr_Format(PyExc_RuntimeError,
- "More keyword list entries (%d) than "
- "format specifiers (%d)", len, i);
- return cleanreturn(0, &freelist);
- }
- current_arg = NULL;
- if (nkeywords) {
- current_arg = PyDict_GetItemString(keywords, keyword);
- }
- if (current_arg) {
- --nkeywords;
- if (i < nargs) {
- /* arg present in tuple and in dict */
- PyErr_Format(PyExc_TypeError,
- "Argument given by name ('%s') "
- "and position (%d)",
- keyword, i+1);
- return cleanreturn(0, &freelist);
- }
- }
- else if (nkeywords && PyErr_Occurred())
- return cleanreturn(0, &freelist);
- else if (i < nargs)
- current_arg = PyTuple_GET_ITEM(args, i);
-
- if (current_arg) {
- msg = convertitem(current_arg, &format, p_va, flags,
- levels, msgbuf, sizeof(msgbuf), &freelist);
- if (msg) {
- seterror(i+1, msg, levels, fname, custom_msg);
- return cleanreturn(0, &freelist);
- }
- continue;
- }
+ if (i < min) {
+ PyErr_Format(PyExc_TypeError, "Required argument "
+ "'%s' (pos %d) not found",
+ keyword, i+1);
+ return cleanreturn(0, freelist);
+ }
+ /* current code reports success when all required args
+ * fulfilled and no keyword args left, with no further
+ * validation. XXX Maybe skip this in debug build ?
+ */
+ if (!nkeywords)
+ return cleanreturn(1, freelist);
- if (i < min) {
- PyErr_Format(PyExc_TypeError, "Required argument "
- "'%s' (pos %d) not found",
- keyword, i+1);
- return cleanreturn(0, &freelist);
- }
- /* current code reports success when all required args
- * fulfilled and no keyword args left, with no further
- * validation. XXX Maybe skip this in debug build ?
- */
- if (!nkeywords)
- return cleanreturn(1, &freelist);
+ /* We are into optional args, skip thru to any remaining
+ * keyword args */
+ msg = skipitem(&format, p_va, flags);
+ if (msg) {
+ PyErr_Format(PyExc_RuntimeError, "%s: '%s'", msg,
+ format);
+ return cleanreturn(0, freelist);
+ }
+ }
- /* We are into optional args, skip thru to any remaining
- * keyword args */
- msg = skipitem(&format, p_va, flags);
- if (msg) {
- PyErr_Format(PyExc_RuntimeError, "%s: '%s'", msg,
- format);
- return cleanreturn(0, &freelist);
- }
- }
+ if (!IS_END_OF_FORMAT(*format) && *format != '|') {
+ PyErr_Format(PyExc_RuntimeError,
+ "more argument specifiers than keyword list entries "
+ "(remaining format:'%s')", format);
+ return cleanreturn(0, freelist);
+ }
- if (!IS_END_OF_FORMAT(*format) && *format != '|') {
- PyErr_Format(PyExc_RuntimeError,
- "more argument specifiers than keyword list entries "
- "(remaining format:'%s')", format);
- return cleanreturn(0, &freelist);
- }
+ /* make sure there are no extraneous keyword arguments */
+ if (nkeywords > 0) {
+ PyObject *key, *value;
+ Py_ssize_t pos = 0;
+ while (PyDict_Next(keywords, &pos, &key, &value)) {
+ int match = 0;
+ char *ks;
+ if (!PyString_Check(key)) {
+ PyErr_SetString(PyExc_TypeError,
+ "keywords must be strings");
+ return cleanreturn(0, freelist);
+ }
+ ks = PyString_AsString(key);
+ for (i = 0; i < len; i++) {
+ if (!strcmp(ks, kwlist[i])) {
+ match = 1;
+ break;
+ }
+ }
+ if (!match) {
+ PyErr_Format(PyExc_TypeError,
+ "'%s' is an invalid keyword "
+ "argument for this function",
+ ks);
+ return cleanreturn(0, freelist);
+ }
+ }
+ }
- /* make sure there are no extraneous keyword arguments */
- if (nkeywords > 0) {
- PyObject *key, *value;
- Py_ssize_t pos = 0;
- while (PyDict_Next(keywords, &pos, &key, &value)) {
- int match = 0;
- char *ks;
- if (!PyString_Check(key)) {
- PyErr_SetString(PyExc_TypeError,
- "keywords must be strings");
- return cleanreturn(0, &freelist);
- }
- ks = PyString_AsString(key);
- for (i = 0; i < len; i++) {
- if (!strcmp(ks, kwlist[i])) {
- match = 1;
- break;
- }
- }
- if (!match) {
- PyErr_Format(PyExc_TypeError,
- "'%s' is an invalid keyword "
- "argument for this function",
- ks);
- return cleanreturn(0, &freelist);
- }
- }
- }
-
- return cleanreturn(1, &freelist);
+ return cleanreturn(1, freelist);
}
static char *
skipitem(const char **p_format, va_list *p_va, int flags)
{
- const char *format = *p_format;
- char c = *format++;
-
- switch (c) {
+ const char *format = *p_format;
+ char c = *format++;
- /* simple codes
- * The individual types (second arg of va_arg) are irrelevant */
+ switch (c) {
- case 'b': /* byte -- very short int */
- case 'B': /* byte as bitfield */
- case 'h': /* short int */
- case 'H': /* short int as bitfield */
- case 'i': /* int */
- case 'I': /* int sized bitfield */
- case 'l': /* long int */
- case 'k': /* long int sized bitfield */
+ /* simple codes
+ * The individual types (second arg of va_arg) are irrelevant */
+
+ case 'b': /* byte -- very short int */
+ case 'B': /* byte as bitfield */
+ case 'h': /* short int */
+ case 'H': /* short int as bitfield */
+ case 'i': /* int */
+ case 'I': /* int sized bitfield */
+ case 'l': /* long int */
+ case 'k': /* long int sized bitfield */
#ifdef HAVE_LONG_LONG
- case 'L': /* PY_LONG_LONG */
- case 'K': /* PY_LONG_LONG sized bitfield */
+ case 'L': /* PY_LONG_LONG */
+ case 'K': /* PY_LONG_LONG sized bitfield */
#endif
- case 'f': /* float */
- case 'd': /* double */
+ case 'f': /* float */
+ case 'd': /* double */
#ifndef WITHOUT_COMPLEX
- case 'D': /* complex double */
+ case 'D': /* complex double */
#endif
- case 'c': /* char */
- {
- (void) va_arg(*p_va, void *);
- break;
- }
+ case 'c': /* char */
+ {
+ (void) va_arg(*p_va, void *);
+ break;
+ }
- case 'n': /* Py_ssize_t */
- {
- (void) va_arg(*p_va, Py_ssize_t *);
- break;
- }
-
- /* string codes */
-
- case 'e': /* string with encoding */
- {
- (void) va_arg(*p_va, const char *);
- if (!(*format == 's' || *format == 't'))
- /* after 'e', only 's' and 't' is allowed */
- goto err;
- format++;
- /* explicit fallthrough to string cases */
- }
-
- case 's': /* string */
- case 'z': /* string or None */
+ case 'n': /* Py_ssize_t */
+ {
+ (void) va_arg(*p_va, Py_ssize_t *);
+ break;
+ }
+
+ /* string codes */
+
+ case 'e': /* string with encoding */
+ {
+ (void) va_arg(*p_va, const char *);
+ if (!(*format == 's' || *format == 't'))
+ /* after 'e', only 's' and 't' is allowed */
+ goto err;
+ format++;
+ /* explicit fallthrough to string cases */
+ }
+
+ case 's': /* string */
+ case 'z': /* string or None */
#ifdef Py_USING_UNICODE
- case 'u': /* unicode string */
+ case 'u': /* unicode string */
#endif
- case 't': /* buffer, read-only */
- case 'w': /* buffer, read-write */
- {
- (void) va_arg(*p_va, char **);
- if (*format == '#') {
- if (flags & FLAG_SIZE_T)
- (void) va_arg(*p_va, Py_ssize_t *);
- else
- (void) va_arg(*p_va, int *);
- format++;
- } else if ((c == 's' || c == 'z') && *format == '*') {
- format++;
- }
- break;
- }
+ case 't': /* buffer, read-only */
+ case 'w': /* buffer, read-write */
+ {
+ (void) va_arg(*p_va, char **);
+ if (*format == '#') {
+ if (flags & FLAG_SIZE_T)
+ (void) va_arg(*p_va, Py_ssize_t *);
+ else
+ (void) va_arg(*p_va, int *);
+ format++;
+ } else if ((c == 's' || c == 'z') && *format == '*') {
+ format++;
+ }
+ break;
+ }
- /* object codes */
+ /* object codes */
- case 'S': /* string object */
+ case 'S': /* string object */
#ifdef Py_USING_UNICODE
- case 'U': /* unicode string object */
+ case 'U': /* unicode string object */
#endif
- {
- (void) va_arg(*p_va, PyObject **);
- break;
- }
-
- case 'O': /* object */
- {
- if (*format == '!') {
- format++;
- (void) va_arg(*p_va, PyTypeObject*);
- (void) va_arg(*p_va, PyObject **);
- }
-#if 0
-/* I don't know what this is for */
- else if (*format == '?') {
- inquiry pred = va_arg(*p_va, inquiry);
- format++;
- if ((*pred)(arg)) {
- (void) va_arg(*p_va, PyObject **);
- }
- }
-#endif
- else if (*format == '&') {
- typedef int (*converter)(PyObject *, void *);
- (void) va_arg(*p_va, converter);
- (void) va_arg(*p_va, void *);
- format++;
- }
- else {
- (void) va_arg(*p_va, PyObject **);
- }
- break;
- }
+ {
+ (void) va_arg(*p_va, PyObject **);
+ break;
+ }
- case '(': /* bypass tuple, not handled at all previously */
- {
- char *msg;
- for (;;) {
- if (*format==')')
- break;
- if (IS_END_OF_FORMAT(*format))
- return "Unmatched left paren in format "
- "string";
- msg = skipitem(&format, p_va, flags);
- if (msg)
- return msg;
- }
- format++;
- break;
- }
+ case 'O': /* object */
+ {
+ if (*format == '!') {
+ format++;
+ (void) va_arg(*p_va, PyTypeObject*);
+ (void) va_arg(*p_va, PyObject **);
+ }
+ else if (*format == '&') {
+ typedef int (*converter)(PyObject *, void *);
+ (void) va_arg(*p_va, converter);
+ (void) va_arg(*p_va, void *);
+ format++;
+ }
+ else {
+ (void) va_arg(*p_va, PyObject **);
+ }
+ break;
+ }
- case ')':
- return "Unmatched right paren in format string";
+ case '(': /* bypass tuple, not handled at all previously */
+ {
+ char *msg;
+ for (;;) {
+ if (*format==')')
+ break;
+ if (IS_END_OF_FORMAT(*format))
+ return "Unmatched left paren in format "
+ "string";
+ msg = skipitem(&format, p_va, flags);
+ if (msg)
+ return msg;
+ }
+ format++;
+ break;
+ }
- default:
+ case ')':
+ return "Unmatched right paren in format string";
+
+ default:
err:
- return "impossible<bad format char>";
-
- }
+ return "impossible<bad format char>";
- *p_format = format;
- return NULL;
+ }
+
+ *p_format = format;
+ return NULL;
}
int
PyArg_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t max, ...)
{
- Py_ssize_t i, l;
- PyObject **o;
- va_list vargs;
+ Py_ssize_t i, l;
+ PyObject **o;
+ va_list vargs;
#ifdef HAVE_STDARG_PROTOTYPES
- va_start(vargs, max);
+ va_start(vargs, max);
#else
- va_start(vargs);
+ va_start(vargs);
#endif
- assert(min >= 0);
- assert(min <= max);
- if (!PyTuple_Check(args)) {
- PyErr_SetString(PyExc_SystemError,
- "PyArg_UnpackTuple() argument list is not a tuple");
- return 0;
- }
- l = PyTuple_GET_SIZE(args);
- if (l < min) {
- if (name != NULL)
- PyErr_Format(
- PyExc_TypeError,
- "%s expected %s%zd arguments, got %zd",
- name, (min == max ? "" : "at least "), min, l);
- else
- PyErr_Format(
- PyExc_TypeError,
- "unpacked tuple should have %s%zd elements,"
- " but has %zd",
- (min == max ? "" : "at least "), min, l);
- va_end(vargs);
- return 0;
- }
- if (l > max) {
- if (name != NULL)
- PyErr_Format(
- PyExc_TypeError,
- "%s expected %s%zd arguments, got %zd",
- name, (min == max ? "" : "at most "), max, l);
- else
- PyErr_Format(
- PyExc_TypeError,
- "unpacked tuple should have %s%zd elements,"
- " but has %zd",
- (min == max ? "" : "at most "), max, l);
- va_end(vargs);
- return 0;
- }
- for (i = 0; i < l; i++) {
- o = va_arg(vargs, PyObject **);
- *o = PyTuple_GET_ITEM(args, i);
- }
- va_end(vargs);
- return 1;
+ assert(min >= 0);
+ assert(min <= max);
+ if (!PyTuple_Check(args)) {
+ PyErr_SetString(PyExc_SystemError,
+ "PyArg_UnpackTuple() argument list is not a tuple");
+ return 0;
+ }
+ l = PyTuple_GET_SIZE(args);
+ if (l < min) {
+ if (name != NULL)
+ PyErr_Format(
+ PyExc_TypeError,
+ "%s expected %s%zd arguments, got %zd",
+ name, (min == max ? "" : "at least "), min, l);
+ else
+ PyErr_Format(
+ PyExc_TypeError,
+ "unpacked tuple should have %s%zd elements,"
+ " but has %zd",
+ (min == max ? "" : "at least "), min, l);
+ va_end(vargs);
+ return 0;
+ }
+ if (l > max) {
+ if (name != NULL)
+ PyErr_Format(
+ PyExc_TypeError,
+ "%s expected %s%zd arguments, got %zd",
+ name, (min == max ? "" : "at most "), max, l);
+ else
+ PyErr_Format(
+ PyExc_TypeError,
+ "unpacked tuple should have %s%zd elements,"
+ " but has %zd",
+ (min == max ? "" : "at most "), max, l);
+ va_end(vargs);
+ return 0;
+ }
+ for (i = 0; i < l; i++) {
+ o = va_arg(vargs, PyObject **);
+ *o = PyTuple_GET_ITEM(args, i);
+ }
+ va_end(vargs);
+ return 1;
}
/* For type constructors that don't take keyword args
*
- * Sets a TypeError and returns 0 if the kwds dict is
+ * Sets a TypeError and returns 0 if the kwds dict is
* not empty, returns 1 otherwise
*/
int
_PyArg_NoKeywords(const char *funcname, PyObject *kw)
{
- if (kw == NULL)
- return 1;
- if (!PyDict_CheckExact(kw)) {
- PyErr_BadInternalCall();
- return 0;
- }
- if (PyDict_Size(kw) == 0)
- return 1;
-
- PyErr_Format(PyExc_TypeError, "%s does not take keyword arguments",
- funcname);
- return 0;
+ if (kw == NULL)
+ return 1;
+ if (!PyDict_CheckExact(kw)) {
+ PyErr_BadInternalCall();
+ return 0;
+ }
+ if (PyDict_Size(kw) == 0)
+ return 1;
+
+ PyErr_Format(PyExc_TypeError, "%s does not take keyword arguments",
+ funcname);
+ return 0;
}
#ifdef __cplusplus
};
diff --git a/pypy/module/cpyext/src/modsupport.c b/pypy/module/cpyext/src/modsupport.c
--- a/pypy/module/cpyext/src/modsupport.c
+++ b/pypy/module/cpyext/src/modsupport.c
@@ -33,41 +33,41 @@
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;
+ 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;
}
@@ -83,582 +83,435 @@
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;
+ 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);
- }
+ 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;
+ 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;
+ 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;
+ 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);
+ 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_mklist(p_format, p_va, ']',
+ countformat(*p_format, ']'), flags);
- case '{':
- return do_mkdict(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 'b':
+ case 'B':
+ case 'h':
+ case 'i':
+ return PyInt_FromLong((long)va_arg(*p_va, 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':
+ 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));
+ 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));
+ /* 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);
- }
+ 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 '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));
+ 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;
- }
+ 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));
+ 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 *)));
+ 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 '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 '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 '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;
+ case ':':
+ case ',':
+ case ' ':
+ case '\t':
+ break;
- default:
- PyErr_SetString(PyExc_SystemError,
- "bad format char passed to Py_BuildValue");
- return NULL;
+ 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;
+ 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;
+ 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);
+ 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);
+ 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;
+ const char *f = format;
+ int n = countformat(f, '\0');
+ va_list lva;
#ifdef VA_LIST_IS_ARRAY
- memcpy(lva, va, sizeof(va_list));
+ memcpy(lva, va, sizeof(va_list));
#else
#ifdef __va_copy
- __va_copy(lva, va);
+ __va_copy(lva, va);
#else
- lva = va;
+ 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);
+ 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_list vargs;
+ PyObject *args;
+ PyObject *res;
- va_start(vargs, format);
+ va_start(vargs, format);
- args = Py_VaBuildValue(format, vargs);
- va_end(vargs);
+ args = Py_VaBuildValue(format, vargs);
+ va_end(vargs);
- if (args == NULL)
- return NULL;
+ if (args == NULL)
+ return NULL;
- res = PyEval_CallObject(obj, args);
- Py_DECREF(args);
+ res = PyEval_CallObject(obj, args);
+ Py_DECREF(args);
- return res;
+ return res;
}
PyObject *
PyEval_CallMethod(PyObject *obj, const char *methodname, const char *format, ...)
{
- va_list vargs;
- PyObject *meth;
- PyObject *args;
- PyObject *res;
+ va_list vargs;
+ PyObject *meth;
+ PyObject *args;
+ PyObject *res;
- meth = PyObject_GetAttrString(obj, methodname);
- if (meth == NULL)
- return NULL;
+ meth = PyObject_GetAttrString(obj, methodname);
+ if (meth == NULL)
+ return NULL;
- va_start(vargs, format);
+ va_start(vargs, format);
- args = Py_VaBuildValue(format, vargs);
- va_end(vargs);
+ args = Py_VaBuildValue(format, vargs);
+ va_end(vargs);
- if (args == NULL) {
- Py_DECREF(meth);
- return NULL;
- }
+ if (args == NULL) {
+ Py_DECREF(meth);
+ return NULL;
+ }
- res = PyEval_CallObject(meth, args);
- Py_DECREF(meth);
- Py_DECREF(args);
+ res = PyEval_CallObject(meth, args);
+ Py_DECREF(meth);
+ Py_DECREF(args);
- return res;
-}
-
-static PyObject*
-call_function_tail(PyObject *callable, PyObject *args)
-{
- PyObject *retval;
-
- if (args == NULL)
- return NULL;
-
- if (!PyTuple_Check(args)) {
- PyObject *a;
-
- a = PyTuple_New(1);
- if (a == NULL) {
- Py_DECREF(args);
- return NULL;
- }
- PyTuple_SET_ITEM(a, 0, args);
- args = a;
- }
- retval = PyObject_Call(callable, args, NULL);
-
- Py_DECREF(args);
-
- return retval;
-}
-
-PyObject *
-PyObject_CallFunction(PyObject *callable, const char *format, ...)
-{
- va_list va;
- PyObject *args;
-
- if (format && *format) {
- va_start(va, format);
- args = Py_VaBuildValue(format, va);
- va_end(va);
- }
- else
- args = PyTuple_New(0);
-
- return call_function_tail(callable, args);
-}
-
-PyObject *
-PyObject_CallMethod(PyObject *o, const char *name, const char *format, ...)
-{
- va_list va;
- PyObject *args;
- PyObject *func = NULL;
- PyObject *retval = NULL;
-
- func = PyObject_GetAttrString(o, name);
- if (func == NULL) {
- PyErr_SetString(PyExc_AttributeError, name);
- return 0;
- }
-
- if (format && *format) {
- va_start(va, format);
- args = Py_VaBuildValue(format, va);
- va_end(va);
- }
- else
- args = PyTuple_New(0);
-
- retval = call_function_tail(func, args);
-
- exit:
- /* args gets consumed in call_function_tail */
- Py_XDECREF(func);
-
- return retval;
-}
-
-static PyObject *
-objargs_mktuple(va_list va)
-{
- int i, n = 0;
- va_list countva;
- PyObject *result, *tmp;
-
-#ifdef VA_LIST_IS_ARRAY
- memcpy(countva, va, sizeof(va_list));
-#else
-#ifdef __va_copy
- __va_copy(countva, va);
-#else
- countva = va;
-#endif
-#endif
-
- while (((PyObject *)va_arg(countva, PyObject *)) != NULL)
- ++n;
- result = PyTuple_New(n);
- if (result != NULL && n > 0) {
- for (i = 0; i < n; ++i) {
- tmp = (PyObject *)va_arg(va, PyObject *);
- Py_INCREF(tmp);
- PyTuple_SET_ITEM(result, i, tmp);
- }
- }
- return result;
-}
-
-PyObject *
-PyObject_CallFunctionObjArgs(PyObject *callable, ...)
-{
- PyObject *args, *tmp;
- va_list vargs;
-
- /* count the args */
- va_start(vargs, callable);
- args = objargs_mktuple(vargs);
- va_end(vargs);
- if (args == NULL)
- return NULL;
- tmp = PyObject_Call(callable, args, NULL);
- Py_DECREF(args);
-
- return tmp;
-}
-
-PyObject *
-PyObject_CallMethodObjArgs(PyObject *callable, PyObject *name, ...)
-{
- PyObject *args, *tmp;
- va_list vargs;
-
- callable = PyObject_GetAttr(callable, name);
- if (callable == NULL)
- return NULL;
-
- /* count the args */
- va_start(vargs, name);
- args = objargs_mktuple(vargs);
- va_end(vargs);
- if (args == NULL) {
- Py_DECREF(callable);
- return NULL;
- }
- tmp = PyObject_Call(callable, args, NULL);
- Py_DECREF(args);
- Py_DECREF(callable);
-
- return tmp;
+ return res;
}
/* returns -1 in case of error, 0 if a new key was added, 1 if the key
@@ -666,67 +519,67 @@
static int
_PyModule_AddObject_NoConsumeRef(PyObject *m, const char *name, PyObject *o)
{
- PyObject *dict, *prev;
- 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;
- }
+ PyObject *dict, *prev;
+ 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;
- }
- prev = PyDict_GetItemString(dict, name);
- if (PyDict_SetItemString(dict, name, o))
- return -1;
- return prev != NULL;
+ 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;
+ }
+ prev = PyDict_GetItemString(dict, name);
+ if (PyDict_SetItemString(dict, name, o))
+ return -1;
+ return prev != NULL;
}
int
PyModule_AddObject(PyObject *m, const char *name, PyObject *o)
{
- int result = _PyModule_AddObject_NoConsumeRef(m, name, o);
- /* XXX WORKAROUND for a common misusage of PyModule_AddObject:
- for the common case of adding a new key, we don't consume a
- reference, but instead just leak it away. The issue is that
- people generally don't realize that this function consumes a
- reference, because on CPython the reference is still stored
- on the dictionary. */
- if (result != 0)
- Py_DECREF(o);
- return result < 0 ? -1 : 0;
+ int result = _PyModule_AddObject_NoConsumeRef(m, name, o);
+ /* XXX WORKAROUND for a common misusage of PyModule_AddObject:
+ for the common case of adding a new key, we don't consume a
+ reference, but instead just leak it away. The issue is that
+ people generally don't realize that this function consumes a
+ reference, because on CPython the reference is still stored
+ on the dictionary. */
+ if (result != 0)
+ Py_DECREF(o);
+ return result < 0 ? -1 : 0;
}
-int
+int
PyModule_AddIntConstant(PyObject *m, const char *name, long value)
{
- int result;
- PyObject *o = PyInt_FromLong(value);
- if (!o)
- return -1;
- result = _PyModule_AddObject_NoConsumeRef(m, name, o);
- Py_DECREF(o);
- return result < 0 ? -1 : 0;
+ int result;
+ PyObject *o = PyInt_FromLong(value);
+ if (!o)
+ return -1;
+ result = _PyModule_AddObject_NoConsumeRef(m, name, o);
+ Py_DECREF(o);
+ return result < 0 ? -1 : 0;
}
-int
+int
PyModule_AddStringConstant(PyObject *m, const char *name, const char *value)
{
- int result;
- PyObject *o = PyString_FromString(value);
- if (!o)
- return -1;
- result = _PyModule_AddObject_NoConsumeRef(m, name, o);
- Py_DECREF(o);
- return result < 0 ? -1 : 0;
+ int result;
+ PyObject *o = PyString_FromString(value);
+ if (!o)
+ return -1;
+ result = _PyModule_AddObject_NoConsumeRef(m, name, o);
+ Py_DECREF(o);
+ return result < 0 ? -1 : 0;
}
diff --git a/pypy/module/cpyext/src/mysnprintf.c b/pypy/module/cpyext/src/mysnprintf.c
--- a/pypy/module/cpyext/src/mysnprintf.c
+++ b/pypy/module/cpyext/src/mysnprintf.c
@@ -20,86 +20,86 @@
Return value (rv):
- When 0 <= rv < size, the output conversion was unexceptional, and
- rv characters were written to str (excluding a trailing \0 byte at
- str[rv]).
+ When 0 <= rv < size, the output conversion was unexceptional, and
+ rv characters were written to str (excluding a trailing \0 byte at
+ str[rv]).
- When rv >= size, output conversion was truncated, and a buffer of
- size rv+1 would have been needed to avoid truncation. str[size-1]
- is \0 in this case.
+ When rv >= size, output conversion was truncated, and a buffer of
+ size rv+1 would have been needed to avoid truncation. str[size-1]
+ is \0 in this case.
- When rv < 0, "something bad happened". str[size-1] is \0 in this
- case too, but the rest of str is unreliable. It could be that
- an error in format codes was detected by libc, or on platforms
- with a non-C99 vsnprintf simply that the buffer wasn't big enough
- to avoid truncation, or on platforms without any vsnprintf that
- PyMem_Malloc couldn't obtain space for a temp buffer.
+ When rv < 0, "something bad happened". str[size-1] is \0 in this
+ case too, but the rest of str is unreliable. It could be that
+ an error in format codes was detected by libc, or on platforms
+ with a non-C99 vsnprintf simply that the buffer wasn't big enough
+ to avoid truncation, or on platforms without any vsnprintf that
+ PyMem_Malloc couldn't obtain space for a temp buffer.
CAUTION: Unlike C99, str != NULL and size > 0 are required.
*/
int
+PyOS_snprintf(char *str, size_t size, const char *format, ...)
+{
+ int rc;
+ va_list va;
+
+ va_start(va, format);
+ rc = PyOS_vsnprintf(str, size, format, va);
+ va_end(va);
+ return rc;
+}
+
+int
PyOS_vsnprintf(char *str, size_t size, const char *format, va_list va)
{
- int len; /* # bytes written, excluding \0 */
+ int len; /* # bytes written, excluding \0 */
#ifdef HAVE_SNPRINTF
#define _PyOS_vsnprintf_EXTRA_SPACE 1
#else
#define _PyOS_vsnprintf_EXTRA_SPACE 512
- char *buffer;
+ char *buffer;
#endif
- assert(str != NULL);
- assert(size > 0);
- assert(format != NULL);
- /* We take a size_t as input but return an int. Sanity check
- * our input so that it won't cause an overflow in the
- * vsnprintf return value or the buffer malloc size. */
- if (size > INT_MAX - _PyOS_vsnprintf_EXTRA_SPACE) {
- len = -666;
- goto Done;
- }
+ assert(str != NULL);
+ assert(size > 0);
+ assert(format != NULL);
+ /* We take a size_t as input but return an int. Sanity check
+ * our input so that it won't cause an overflow in the
+ * vsnprintf return value or the buffer malloc size. */
+ if (size > INT_MAX - _PyOS_vsnprintf_EXTRA_SPACE) {
+ len = -666;
+ goto Done;
+ }
#ifdef HAVE_SNPRINTF
- len = vsnprintf(str, size, format, va);
+ len = vsnprintf(str, size, format, va);
#else
- /* Emulate it. */
- buffer = PyMem_MALLOC(size + _PyOS_vsnprintf_EXTRA_SPACE);
- if (buffer == NULL) {
- len = -666;
- goto Done;
- }
+ /* Emulate it. */
+ buffer = PyMem_MALLOC(size + _PyOS_vsnprintf_EXTRA_SPACE);
+ if (buffer == NULL) {
+ len = -666;
+ goto Done;
+ }
- len = vsprintf(buffer, format, va);
- if (len < 0)
- /* ignore the error */;
+ len = vsprintf(buffer, format, va);
+ if (len < 0)
+ /* ignore the error */;
- else if ((size_t)len >= size + _PyOS_vsnprintf_EXTRA_SPACE)
- Py_FatalError("Buffer overflow in PyOS_snprintf/PyOS_vsnprintf");
+ else if ((size_t)len >= size + _PyOS_vsnprintf_EXTRA_SPACE)
+ Py_FatalError("Buffer overflow in PyOS_snprintf/PyOS_vsnprintf");
- else {
- const size_t to_copy = (size_t)len < size ?
- (size_t)len : size - 1;
- assert(to_copy < size);
- memcpy(str, buffer, to_copy);
- str[to_copy] = '\0';
- }
- PyMem_FREE(buffer);
+ else {
+ const size_t to_copy = (size_t)len < size ?
+ (size_t)len : size - 1;
+ assert(to_copy < size);
+ memcpy(str, buffer, to_copy);
+ str[to_copy] = '\0';
+ }
+ PyMem_FREE(buffer);
#endif
Done:
- if (size > 0)
- str[size-1] = '\0';
- return len;
+ if (size > 0)
+ str[size-1] = '\0';
+ return len;
#undef _PyOS_vsnprintf_EXTRA_SPACE
}
-
-int
-PyOS_snprintf(char *str, size_t size, const char *format, ...)
-{
- int rc;
- va_list va;
-
- va_start(va, format);
- rc = PyOS_vsnprintf(str, size, format, va);
- va_end(va);
- return rc;
-}
diff --git a/pypy/module/cpyext/src/object.c b/pypy/module/cpyext/src/object.c
deleted file mode 100644
--- a/pypy/module/cpyext/src/object.c
+++ /dev/null
@@ -1,91 +0,0 @@
-// contains code from abstract.c
-#include <Python.h>
-
-
-static PyObject *
-null_error(void)
-{
- if (!PyErr_Occurred())
- PyErr_SetString(PyExc_SystemError,
- "null argument to internal routine");
- return NULL;
-}
-
-int PyObject_AsReadBuffer(PyObject *obj,
- const void **buffer,
- Py_ssize_t *buffer_len)
-{
- PyBufferProcs *pb;
- void *pp;
- Py_ssize_t len;
-
- if (obj == NULL || buffer == NULL || buffer_len == NULL) {
- null_error();
- return -1;
- }
- pb = obj->ob_type->tp_as_buffer;
- if (pb == NULL ||
- pb->bf_getreadbuffer == NULL ||
- pb->bf_getsegcount == NULL) {
- PyErr_SetString(PyExc_TypeError,
- "expected a readable buffer object");
- return -1;
- }
- if ((*pb->bf_getsegcount)(obj, NULL) != 1) {
- PyErr_SetString(PyExc_TypeError,
- "expected a single-segment buffer object");
- return -1;
- }
- len = (*pb->bf_getreadbuffer)(obj, 0, &pp);
- if (len < 0)
- return -1;
- *buffer = pp;
- *buffer_len = len;
- return 0;
-}
-
-int PyObject_AsWriteBuffer(PyObject *obj,
- void **buffer,
- Py_ssize_t *buffer_len)
-{
- PyBufferProcs *pb;
- void*pp;
- Py_ssize_t len;
-
- if (obj == NULL || buffer == NULL || buffer_len == NULL) {
- null_error();
- return -1;
- }
- pb = obj->ob_type->tp_as_buffer;
- if (pb == NULL ||
- pb->bf_getwritebuffer == NULL ||
- pb->bf_getsegcount == NULL) {
- PyErr_SetString(PyExc_TypeError,
- "expected a writeable buffer object");
- return -1;
- }
- if ((*pb->bf_getsegcount)(obj, NULL) != 1) {
- PyErr_SetString(PyExc_TypeError,
- "expected a single-segment buffer object");
- return -1;
- }
- len = (*pb->bf_getwritebuffer)(obj,0,&pp);
- if (len < 0)
- return -1;
- *buffer = pp;
- *buffer_len = len;
- return 0;
-}
-
-int
-PyObject_CheckReadBuffer(PyObject *obj)
-{
- PyBufferProcs *pb = obj->ob_type->tp_as_buffer;
-
- if (pb == NULL ||
- pb->bf_getreadbuffer == NULL ||
- pb->bf_getsegcount == NULL ||
- (*pb->bf_getsegcount)(obj, NULL) != 1)
- return 0;
- return 1;
-}
diff --git a/pypy/module/cpyext/src/pyerrors.c b/pypy/module/cpyext/src/pyerrors.c
--- a/pypy/module/cpyext/src/pyerrors.c
+++ b/pypy/module/cpyext/src/pyerrors.c
@@ -4,72 +4,75 @@
PyObject *
PyErr_Format(PyObject *exception, const char *format, ...)
{
- va_list vargs;
- PyObject* string;
+ va_list vargs;
+ PyObject* string;
#ifdef HAVE_STDARG_PROTOTYPES
- va_start(vargs, format);
+ va_start(vargs, format);
#else
- va_start(vargs);
+ va_start(vargs);
#endif
- string = PyString_FromFormatV(format, vargs);
- PyErr_SetObject(exception, string);
- Py_XDECREF(string);
- va_end(vargs);
- return NULL;
+ string = PyString_FromFormatV(format, vargs);
+ PyErr_SetObject(exception, string);
+ Py_XDECREF(string);
+ va_end(vargs);
+ return NULL;
}
+
+
PyObject *
PyErr_NewException(const char *name, PyObject *base, PyObject *dict)
{
- char *dot;
- PyObject *modulename = NULL;
- PyObject *classname = NULL;
- PyObject *mydict = NULL;
- PyObject *bases = NULL;
- PyObject *result = NULL;
- dot = strrchr(name, '.');
- if (dot == NULL) {
- PyErr_SetString(PyExc_SystemError,
- "PyErr_NewException: name must be module.class");
- return NULL;
- }
- if (base == NULL)
- base = PyExc_Exception;
- if (dict == NULL) {
- dict = mydict = PyDict_New();
- if (dict == NULL)
- goto failure;
- }
- if (PyDict_GetItemString(dict, "__module__") == NULL) {
- modulename = PyString_FromStringAndSize(name,
- (Py_ssize_t)(dot-name));
- if (modulename == NULL)
- goto failure;
- if (PyDict_SetItemString(dict, "__module__", modulename) != 0)
- goto failure;
- }
- if (PyTuple_Check(base)) {
- bases = base;
- /* INCREF as we create a new ref in the else branch */
- Py_INCREF(bases);
- } else {
- bases = PyTuple_Pack(1, base);
- if (bases == NULL)
- goto failure;
- }
- /* Create a real new-style class. */
- result = PyObject_CallFunction((PyObject *)&PyType_Type, "sOO",
- dot+1, bases, dict);
+ char *dot;
+ PyObject *modulename = NULL;
+ PyObject *classname = NULL;
+ PyObject *mydict = NULL;
+ PyObject *bases = NULL;
+ PyObject *result = NULL;
+ dot = strrchr(name, '.');
+ if (dot == NULL) {
+ PyErr_SetString(PyExc_SystemError,
+ "PyErr_NewException: name must be module.class");
+ return NULL;
+ }
+ if (base == NULL)
+ base = PyExc_Exception;
+ if (dict == NULL) {
+ dict = mydict = PyDict_New();
+ if (dict == NULL)
+ goto failure;
+ }
+ if (PyDict_GetItemString(dict, "__module__") == NULL) {
+ modulename = PyString_FromStringAndSize(name,
+ (Py_ssize_t)(dot-name));
+ if (modulename == NULL)
+ goto failure;
+ if (PyDict_SetItemString(dict, "__module__", modulename) != 0)
+ goto failure;
+ }
+ if (PyTuple_Check(base)) {
+ bases = base;
+ /* INCREF as we create a new ref in the else branch */
+ Py_INCREF(bases);
+ } else {
+ bases = PyTuple_Pack(1, base);
+ if (bases == NULL)
+ goto failure;
+ }
+ /* Create a real new-style class. */
+ result = PyObject_CallFunction((PyObject *)&PyType_Type, "sOO",
+ dot+1, bases, dict);
failure:
- Py_XDECREF(bases);
- Py_XDECREF(mydict);
- Py_XDECREF(classname);
- Py_XDECREF(modulename);
- return result;
+ Py_XDECREF(bases);
+ Py_XDECREF(mydict);
+ Py_XDECREF(classname);
+ Py_XDECREF(modulename);
+ return result;
}
+
/* Create an exception with docstring */
PyObject *
PyErr_NewExceptionWithDoc(const char *name, const char *doc, PyObject *base, PyObject *dict)
diff --git a/pypy/module/cpyext/src/pysignals.c b/pypy/module/cpyext/src/pysignals.c
--- a/pypy/module/cpyext/src/pysignals.c
+++ b/pypy/module/cpyext/src/pysignals.c
@@ -17,17 +17,34 @@
PyOS_getsig(int sig)
{
#ifdef SA_RESTART
- /* assume sigaction exists */
- struct sigaction context;
- if (sigaction(sig, NULL, &context) == -1)
- return SIG_ERR;
- return context.sa_handler;
+ /* assume sigaction exists */
+ struct sigaction context;
+ if (sigaction(sig, NULL, &context) == -1)
+ return SIG_ERR;
+ return context.sa_handler;
#else
- PyOS_sighandler_t handler;
- handler = signal(sig, SIG_IGN);
- if (handler != SIG_ERR)
- signal(sig, handler);
- return handler;
+ PyOS_sighandler_t handler;
+/* Special signal handling for the secure CRT in Visual Studio 2005 */
+#if defined(_MSC_VER) && _MSC_VER >= 1400
+ switch (sig) {
+ /* Only these signals are valid */
+ case SIGINT:
+ case SIGILL:
+ case SIGFPE:
+ case SIGSEGV:
+ case SIGTERM:
+ case SIGBREAK:
+ case SIGABRT:
+ break;
+ /* Don't call signal() with other values or it will assert */
+ default:
+ return SIG_ERR;
+ }
+#endif /* _MSC_VER && _MSC_VER >= 1400 */
+ handler = signal(sig, SIG_IGN);
+ if (handler != SIG_ERR)
+ signal(sig, handler);
+ return handler;
#endif
}
@@ -35,21 +52,21 @@
PyOS_setsig(int sig, PyOS_sighandler_t handler)
{
#ifdef SA_RESTART
- /* assume sigaction exists */
- struct sigaction context, ocontext;
- context.sa_handler = handler;
- sigemptyset(&context.sa_mask);
- context.sa_flags = 0;
- if (sigaction(sig, &context, &ocontext) == -1)
- return SIG_ERR;
- return ocontext.sa_handler;
+ /* assume sigaction exists */
+ struct sigaction context, ocontext;
+ context.sa_handler = handler;
+ sigemptyset(&context.sa_mask);
+ context.sa_flags = 0;
+ if (sigaction(sig, &context, &ocontext) == -1)
+ return SIG_ERR;
+ return ocontext.sa_handler;
#else
- PyOS_sighandler_t oldhandler;
- oldhandler = signal(sig, handler);
+ PyOS_sighandler_t oldhandler;
+ oldhandler = signal(sig, handler);
#ifndef MS_WINDOWS
- /* should check if this exists */
- siginterrupt(sig, 1);
+ /* should check if this exists */
+ siginterrupt(sig, 1);
#endif
- return oldhandler;
+ return oldhandler;
#endif
}
diff --git a/pypy/module/cpyext/src/pythonrun.c b/pypy/module/cpyext/src/pythonrun.c
--- a/pypy/module/cpyext/src/pythonrun.c
+++ b/pypy/module/cpyext/src/pythonrun.c
@@ -9,28 +9,28 @@
void
Py_FatalError(const char *msg)
{
- fprintf(stderr, "Fatal Python error: %s\n", msg);
- fflush(stderr); /* it helps in Windows debug build */
+ fprintf(stderr, "Fatal Python error: %s\n", msg);
+ fflush(stderr); /* it helps in Windows debug build */
#ifdef MS_WINDOWS
- {
- size_t len = strlen(msg);
- WCHAR* buffer;
- size_t i;
+ {
+ size_t len = strlen(msg);
+ WCHAR* buffer;
+ size_t i;
- /* Convert the message to wchar_t. This uses a simple one-to-one
- conversion, assuming that the this error message actually uses ASCII
- only. If this ceases to be true, we will have to convert. */
- buffer = alloca( (len+1) * (sizeof *buffer));
- for( i=0; i<=len; ++i)
- buffer[i] = msg[i];
- OutputDebugStringW(L"Fatal Python error: ");
- OutputDebugStringW(buffer);
- OutputDebugStringW(L"\n");
- }
+ /* Convert the message to wchar_t. This uses a simple one-to-one
+ conversion, assuming that the this error message actually uses ASCII
+ only. If this ceases to be true, we will have to convert. */
+ buffer = alloca( (len+1) * (sizeof *buffer));
+ for( i=0; i<=len; ++i)
+ buffer[i] = msg[i];
+ OutputDebugStringW(L"Fatal Python error: ");
+ OutputDebugStringW(buffer);
+ OutputDebugStringW(L"\n");
+ }
#ifdef _DEBUG
- DebugBreak();
+ DebugBreak();
#endif
#endif /* MS_WINDOWS */
- abort();
+ abort();
}
diff --git a/pypy/module/cpyext/src/stringobject.c b/pypy/module/cpyext/src/stringobject.c
--- a/pypy/module/cpyext/src/stringobject.c
+++ b/pypy/module/cpyext/src/stringobject.c
@@ -4,246 +4,247 @@
PyObject *
PyString_FromFormatV(const char *format, va_list vargs)
{
- va_list count;
- Py_ssize_t n = 0;
- const char* f;
- char *s;
- PyObject* string;
+ va_list count;
+ Py_ssize_t n = 0;
+ const char* f;
+ char *s;
+ PyObject* string;
#ifdef VA_LIST_IS_ARRAY
- Py_MEMCPY(count, vargs, sizeof(va_list));
+ Py_MEMCPY(count, vargs, sizeof(va_list));
#else
#ifdef __va_copy
- __va_copy(count, vargs);
+ __va_copy(count, vargs);
#else
- count = vargs;
+ count = vargs;
#endif
#endif
- /* step 1: figure out how large a buffer we need */
- for (f = format; *f; f++) {
- if (*f == '%') {
+ /* step 1: figure out how large a buffer we need */
+ for (f = format; *f; f++) {
+ if (*f == '%') {
#ifdef HAVE_LONG_LONG
- int longlongflag = 0;
+ int longlongflag = 0;
#endif
- const char* p = f;
- while (*++f && *f != '%' && !isalpha(Py_CHARMASK(*f)))
- ;
+ const char* p = f;
+ while (*++f && *f != '%' && !isalpha(Py_CHARMASK(*f)))
+ ;
- /* skip the 'l' or 'z' in {%ld, %zd, %lu, %zu} since
- * they don't affect the amount of space we reserve.
- */
- if (*f == 'l') {
- if (f[1] == 'd' || f[1] == 'u') {
- ++f;
- }
+ /* skip the 'l' or 'z' in {%ld, %zd, %lu, %zu} since
+ * they don't affect the amount of space we reserve.
+ */
+ if (*f == 'l') {
+ if (f[1] == 'd' || f[1] == 'u') {
+ ++f;
+ }
#ifdef HAVE_LONG_LONG
- else if (f[1] == 'l' &&
- (f[2] == 'd' || f[2] == 'u')) {
- longlongflag = 1;
- f += 2;
- }
+ else if (f[1] == 'l' &&
+ (f[2] == 'd' || f[2] == 'u')) {
+ longlongflag = 1;
+ f += 2;
+ }
#endif
- }
- else if (*f == 'z' && (f[1] == 'd' || f[1] == 'u')) {
- ++f;
- }
+ }
+ else if (*f == 'z' && (f[1] == 'd' || f[1] == 'u')) {
+ ++f;
+ }
- switch (*f) {
- case 'c':
- (void)va_arg(count, int);
- /* fall through... */
- case '%':
- n++;
- break;
- case 'd': case 'u': case 'i': case 'x':
- (void) va_arg(count, int);
+ switch (*f) {
+ case 'c':
+ (void)va_arg(count, int);
+ /* fall through... */
+ case '%':
+ n++;
+ break;
+ case 'd': case 'u': case 'i': case 'x':
+ (void) va_arg(count, int);
#ifdef HAVE_LONG_LONG
- /* Need at most
- ceil(log10(256)*SIZEOF_LONG_LONG) digits,
- plus 1 for the sign. 53/22 is an upper
- bound for log10(256). */
- if (longlongflag)
- n += 2 + (SIZEOF_LONG_LONG*53-1) / 22;
- else
+ /* Need at most
+ ceil(log10(256)*SIZEOF_LONG_LONG) digits,
+ plus 1 for the sign. 53/22 is an upper
+ bound for log10(256). */
+ if (longlongflag)
+ n += 2 + (SIZEOF_LONG_LONG*53-1) / 22;
+ else
#endif
- /* 20 bytes is enough to hold a 64-bit
- integer. Decimal takes the most
- space. This isn't enough for
- octal. */
- n += 20;
+ /* 20 bytes is enough to hold a 64-bit
+ integer. Decimal takes the most
+ space. This isn't enough for
+ octal. */
+ n += 20;
- break;
- case 's':
- s = va_arg(count, char*);
- n += strlen(s);
- break;
- case 'p':
- (void) va_arg(count, int);
- /* maximum 64-bit pointer representation:
- * 0xffffffffffffffff
- * so 19 characters is enough.
- * XXX I count 18 -- what's the extra for?
- */
- n += 19;
- break;
- default:
- /* if we stumble upon an unknown
- formatting code, copy the rest of
- the format string to the output
- string. (we cannot just skip the
- code, since there's no way to know
- what's in the argument list) */
- n += strlen(p);
- goto expand;
- }
- } else
- n++;
- }
+ break;
+ case 's':
+ s = va_arg(count, char*);
+ n += strlen(s);
+ break;
+ case 'p':
+ (void) va_arg(count, int);
+ /* maximum 64-bit pointer representation:
+ * 0xffffffffffffffff
+ * so 19 characters is enough.
+ * XXX I count 18 -- what's the extra for?
+ */
+ n += 19;
+ break;
+ default:
+ /* if we stumble upon an unknown
+ formatting code, copy the rest of
+ the format string to the output
+ string. (we cannot just skip the
+ code, since there's no way to know
+ what's in the argument list) */
+ n += strlen(p);
+ goto expand;
+ }
+ } else
+ n++;
+ }
expand:
- /* step 2: fill the buffer */
- /* Since we've analyzed how much space we need for the worst case,
- use sprintf directly instead of the slower PyOS_snprintf. */
- string = PyString_FromStringAndSize(NULL, n);
- if (!string)
- return NULL;
+ /* step 2: fill the buffer */
+ /* Since we've analyzed how much space we need for the worst case,
+ use sprintf directly instead of the slower PyOS_snprintf. */
+ string = PyString_FromStringAndSize(NULL, n);
+ if (!string)
+ return NULL;
- s = PyString_AsString(string);
+ s = PyString_AsString(string);
- for (f = format; *f; f++) {
- if (*f == '%') {
- const char* p = f++;
- Py_ssize_t i;
- int longflag = 0;
+ for (f = format; *f; f++) {
+ if (*f == '%') {
+ const char* p = f++;
+ Py_ssize_t i;
+ int longflag = 0;
#ifdef HAVE_LONG_LONG
- int longlongflag = 0;
+ int longlongflag = 0;
#endif
- int size_tflag = 0;
- /* parse the width.precision part (we're only
- interested in the precision value, if any) */
- n = 0;
- while (isdigit(Py_CHARMASK(*f)))
- n = (n*10) + *f++ - '0';
- if (*f == '.') {
- f++;
- n = 0;
- while (isdigit(Py_CHARMASK(*f)))
- n = (n*10) + *f++ - '0';
- }
- while (*f && *f != '%' && !isalpha(Py_CHARMASK(*f)))
- f++;
- /* Handle %ld, %lu, %lld and %llu. */
- if (*f == 'l') {
- if (f[1] == 'd' || f[1] == 'u') {
- longflag = 1;
- ++f;
- }
+ int size_tflag = 0;
+ /* parse the width.precision part (we're only
+ interested in the precision value, if any) */
+ n = 0;
+ while (isdigit(Py_CHARMASK(*f)))
+ n = (n*10) + *f++ - '0';
+ if (*f == '.') {
+ f++;
+ n = 0;
+ while (isdigit(Py_CHARMASK(*f)))
+ n = (n*10) + *f++ - '0';
+ }
+ while (*f && *f != '%' && !isalpha(Py_CHARMASK(*f)))
+ f++;
+ /* Handle %ld, %lu, %lld and %llu. */
+ if (*f == 'l') {
+ if (f[1] == 'd' || f[1] == 'u') {
+ longflag = 1;
+ ++f;
+ }
#ifdef HAVE_LONG_LONG
- else if (f[1] == 'l' &&
- (f[2] == 'd' || f[2] == 'u')) {
- longlongflag = 1;
- f += 2;
- }
+ else if (f[1] == 'l' &&
+ (f[2] == 'd' || f[2] == 'u')) {
+ longlongflag = 1;
+ f += 2;
+ }
#endif
- }
- /* handle the size_t flag. */
- else if (*f == 'z' && (f[1] == 'd' || f[1] == 'u')) {
- size_tflag = 1;
- ++f;
- }
+ }
+ /* handle the size_t flag. */
+ else if (*f == 'z' && (f[1] == 'd' || f[1] == 'u')) {
+ size_tflag = 1;
+ ++f;
+ }
- switch (*f) {
- case 'c':
- *s++ = va_arg(vargs, int);
- break;
- case 'd':
- if (longflag)
- sprintf(s, "%ld", va_arg(vargs, long));
+ switch (*f) {
+ case 'c':
+ *s++ = va_arg(vargs, int);
+ break;
+ case 'd':
+ if (longflag)
+ sprintf(s, "%ld", va_arg(vargs, long));
#ifdef HAVE_LONG_LONG
- else if (longlongflag)
- sprintf(s, "%" PY_FORMAT_LONG_LONG "d",
- va_arg(vargs, PY_LONG_LONG));
+ else if (longlongflag)
+ sprintf(s, "%" PY_FORMAT_LONG_LONG "d",
+ va_arg(vargs, PY_LONG_LONG));
#endif
- else if (size_tflag)
- sprintf(s, "%" PY_FORMAT_SIZE_T "d",
- va_arg(vargs, Py_ssize_t));
- else
- sprintf(s, "%d", va_arg(vargs, int));
- s += strlen(s);
- break;
- case 'u':
- if (longflag)
- sprintf(s, "%lu",
- va_arg(vargs, unsigned long));
+ else if (size_tflag)
+ sprintf(s, "%" PY_FORMAT_SIZE_T "d",
+ va_arg(vargs, Py_ssize_t));
+ else
+ sprintf(s, "%d", va_arg(vargs, int));
+ s += strlen(s);
+ break;
+ case 'u':
+ if (longflag)
+ sprintf(s, "%lu",
+ va_arg(vargs, unsigned long));
#ifdef HAVE_LONG_LONG
- else if (longlongflag)
- sprintf(s, "%" PY_FORMAT_LONG_LONG "u",
- va_arg(vargs, PY_LONG_LONG));
+ else if (longlongflag)
+ sprintf(s, "%" PY_FORMAT_LONG_LONG "u",
+ va_arg(vargs, PY_LONG_LONG));
#endif
- else if (size_tflag)
- sprintf(s, "%" PY_FORMAT_SIZE_T "u",
- va_arg(vargs, size_t));
- else
- sprintf(s, "%u",
- va_arg(vargs, unsigned int));
- s += strlen(s);
- break;
- case 'i':
- sprintf(s, "%i", va_arg(vargs, int));
- s += strlen(s);
- break;
- case 'x':
- sprintf(s, "%x", va_arg(vargs, int));
- s += strlen(s);
- break;
- case 's':
- p = va_arg(vargs, char*);
- i = strlen(p);
- if (n > 0 && i > n)
- i = n;
- Py_MEMCPY(s, p, i);
- s += i;
- break;
- case 'p':
- sprintf(s, "%p", va_arg(vargs, void*));
- /* %p is ill-defined: ensure leading 0x. */
- if (s[1] == 'X')
- s[1] = 'x';
- else if (s[1] != 'x') {
- memmove(s+2, s, strlen(s)+1);
- s[0] = '0';
- s[1] = 'x';
- }
- s += strlen(s);
- break;
- case '%':
- *s++ = '%';
- break;
- default:
- strcpy(s, p);
- s += strlen(s);
- goto end;
- }
- } else
- *s++ = *f;
- }
+ else if (size_tflag)
+ sprintf(s, "%" PY_FORMAT_SIZE_T "u",
+ va_arg(vargs, size_t));
+ else
+ sprintf(s, "%u",
+ va_arg(vargs, unsigned int));
+ s += strlen(s);
+ break;
+ case 'i':
+ sprintf(s, "%i", va_arg(vargs, int));
+ s += strlen(s);
+ break;
+ case 'x':
+ sprintf(s, "%x", va_arg(vargs, int));
+ s += strlen(s);
+ break;
+ case 's':
+ p = va_arg(vargs, char*);
+ i = strlen(p);
+ if (n > 0 && i > n)
+ i = n;
+ Py_MEMCPY(s, p, i);
+ s += i;
+ break;
+ case 'p':
+ sprintf(s, "%p", va_arg(vargs, void*));
+ /* %p is ill-defined: ensure leading 0x. */
+ if (s[1] == 'X')
+ s[1] = 'x';
+ else if (s[1] != 'x') {
+ memmove(s+2, s, strlen(s)+1);
+ s[0] = '0';
+ s[1] = 'x';
+ }
+ s += strlen(s);
+ break;
+ case '%':
+ *s++ = '%';
+ break;
+ default:
+ strcpy(s, p);
+ s += strlen(s);
+ goto end;
+ }
+ } else
+ *s++ = *f;
+ }
end:
- _PyString_Resize(&string, s - PyString_AS_STRING(string));
- return string;
+ if (_PyString_Resize(&string, s - PyString_AS_STRING(string)))
+ return NULL;
+ return string;
}
PyObject *
PyString_FromFormat(const char *format, ...)
{
- PyObject* ret;
- va_list vargs;
+ PyObject* ret;
+ va_list vargs;
#ifdef HAVE_STDARG_PROTOTYPES
- va_start(vargs, format);
+ va_start(vargs, format);
#else
- va_start(vargs);
+ va_start(vargs);
#endif
- ret = PyString_FromFormatV(format, vargs);
- va_end(vargs);
- return ret;
+ ret = PyString_FromFormatV(format, vargs);
+ va_end(vargs);
+ return ret;
}
diff --git a/pypy/module/cpyext/src/structseq.c b/pypy/module/cpyext/src/structseq.c
--- a/pypy/module/cpyext/src/structseq.c
+++ b/pypy/module/cpyext/src/structseq.c
@@ -175,32 +175,33 @@
if (min_len != max_len) {
if (len < min_len) {
PyErr_Format(PyExc_TypeError,
- "%.500s() takes an at least %zd-sequence (%zd-sequence given)",
- type->tp_name, min_len, len);
- Py_DECREF(arg);
- return NULL;
+ "%.500s() takes an at least %zd-sequence (%zd-sequence given)",
+ type->tp_name, min_len, len);
+ Py_DECREF(arg);
+ return NULL;
}
if (len > max_len) {
PyErr_Format(PyExc_TypeError,
- "%.500s() takes an at most %zd-sequence (%zd-sequence given)",
- type->tp_name, max_len, len);
- Py_DECREF(arg);
- return NULL;
+ "%.500s() takes an at most %zd-sequence (%zd-sequence given)",
+ type->tp_name, max_len, len);
+ Py_DECREF(arg);
+ return NULL;
}
}
else {
if (len != min_len) {
PyErr_Format(PyExc_TypeError,
- "%.500s() takes a %zd-sequence (%zd-sequence given)",
- type->tp_name, min_len, len);
- Py_DECREF(arg);
- return NULL;
+ "%.500s() takes a %zd-sequence (%zd-sequence given)",
+ type->tp_name, min_len, len);
+ Py_DECREF(arg);
+ return NULL;
}
}
res = (PyStructSequence*) PyStructSequence_New(type);
if (res == NULL) {
+ Py_DECREF(arg);
return NULL;
}
for (i = 0; i < len; ++i) {
diff --git a/pypy/module/cpyext/src/sysmodule.c b/pypy/module/cpyext/src/sysmodule.c
--- a/pypy/module/cpyext/src/sysmodule.c
+++ b/pypy/module/cpyext/src/sysmodule.c
@@ -100,4 +100,3 @@
sys_write("stderr", stderr, format, va);
va_end(va);
}
-
diff --git a/pypy/module/cpyext/src/varargwrapper.c b/pypy/module/cpyext/src/varargwrapper.c
--- a/pypy/module/cpyext/src/varargwrapper.c
+++ b/pypy/module/cpyext/src/varargwrapper.c
@@ -1,21 +1,25 @@
#include <Python.h>
#include <stdarg.h>
-PyObject * PyTuple_Pack(Py_ssize_t size, ...)
+PyObject *
+PyTuple_Pack(Py_ssize_t n, ...)
{
- va_list ap;
- PyObject *cur, *tuple;
- int i;
+ Py_ssize_t i;
+ PyObject *o;
+ PyObject *result;
+ va_list vargs;
- tuple = PyTuple_New(size);
- va_start(ap, size);
- for (i = 0; i < size; i++) {
- cur = va_arg(ap, PyObject*);
- Py_INCREF(cur);
- if (PyTuple_SetItem(tuple, i, cur) < 0)
+ va_start(vargs, n);
+ result = PyTuple_New(n);
+ if (result == NULL)
+ return NULL;
+ for (i = 0; i < n; i++) {
+ o = va_arg(vargs, PyObject *);
+ Py_INCREF(o);
+ if (PyTuple_SetItem(result, i, o) < 0)
return NULL;
}
- va_end(ap);
- return tuple;
+ va_end(vargs);
+ return result;
}
More information about the pypy-commit
mailing list