mirror of
https://github.com/wxWidgets/Phoenix.git
synced 2025-12-16 01:30:07 +01:00
Start of porting to newest sip. Not quite ready yet…
This commit is contained in:
4
build.py
4
build.py
@@ -58,9 +58,9 @@ wxICON = 'docs/sphinx/_static/images/sphinxdocs/mondrian.png'
|
||||
|
||||
# Some tools will be downloaded for the builds. These are the versions and
|
||||
# MD5s of the tool binaries currently in use.
|
||||
sipCurrentVersion = '4.14.7'
|
||||
sipCurrentVersion = '4.16.7-snapshot-f652446e2462'
|
||||
sipMD5 = {
|
||||
'darwin' : '836e78f3c2bf9f8233b32c1a3599efec',
|
||||
'darwin' : '72f61157902148d067eed3145d22990d',
|
||||
'win32' : '208e8472342c07c2679868602d96a42b',
|
||||
'linux' : '382c01bae24ace03ec8ae1ba6d76351a',
|
||||
}
|
||||
|
||||
@@ -120,7 +120,7 @@ class Configuration(object):
|
||||
self.SIPOPTS = ' '.join(['-w', # enable warnings
|
||||
'-o', # turn on auto-docstrings
|
||||
#'-e', # turn on exceptions support
|
||||
'-T', # turn off writing the timestamp to the generated files '-g', # always release and reaquire the GIL
|
||||
#'-T', # turn off writing the timestamp to the generated files '-g', # always release and reaquire the GIL
|
||||
#'-r', # turn on function call tracing
|
||||
'-I', os.path.join(phoenixDir(), 'src'),
|
||||
'-I', os.path.join(phoenixDir(), 'sip', 'gen'),
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* The implementation of the supprt for setting API versions.
|
||||
*
|
||||
* Copyright (c) 2013 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
* Copyright (c) 2015 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
*
|
||||
* This file is part of SIP.
|
||||
*
|
||||
@@ -185,6 +185,8 @@ PyObject *sipGetAPI(PyObject *self, PyObject *args)
|
||||
const char *api;
|
||||
const apiVersionDef *avd;
|
||||
|
||||
(void)self;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "s:getapi", &api))
|
||||
return NULL;
|
||||
|
||||
@@ -211,6 +213,8 @@ PyObject *sipSetAPI(PyObject *self, PyObject *args)
|
||||
int version_nr;
|
||||
const apiVersionDef *avd;
|
||||
|
||||
(void)self;
|
||||
|
||||
if (!PyArg_ParseTuple(args, "si:setapi", &api, &version_nr))
|
||||
return NULL;
|
||||
|
||||
|
||||
887
sip/siplib/array.c
Normal file
887
sip/siplib/array.c
Normal file
@@ -0,0 +1,887 @@
|
||||
/*
|
||||
* This file implements the API for the array type.
|
||||
*
|
||||
* Copyright (c) 2015 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
*
|
||||
* This file is part of SIP.
|
||||
*
|
||||
* This copy of SIP is licensed for use under the terms of the SIP License
|
||||
* Agreement. See the file LICENSE for more details.
|
||||
*
|
||||
* This copy of SIP may also used under the terms of the GNU General Public
|
||||
* License v2 or v3 as published by the Free Software Foundation which can be
|
||||
* found in the files LICENSE-GPL2 and LICENSE-GPL3 included in this package.
|
||||
*
|
||||
* SIP is supplied WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
|
||||
#include <Python.h>
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "sip.h"
|
||||
#include "sipint.h"
|
||||
|
||||
#include "array.h"
|
||||
|
||||
|
||||
/* The object data structure. */
|
||||
typedef struct {
|
||||
PyObject_HEAD
|
||||
void *data;
|
||||
const sipTypeDef *td;
|
||||
const char *format;
|
||||
size_t stride;
|
||||
SIP_SSIZE_T len;
|
||||
int flags;
|
||||
PyObject *owner;
|
||||
} sipArrayObject;
|
||||
|
||||
|
||||
static int check_writable(sipArrayObject *array);
|
||||
static int check_index(sipArrayObject *array, SIP_SSIZE_T idx);
|
||||
static void *get_value(sipArrayObject *array, PyObject *value);
|
||||
static void *get_slice(sipArrayObject *array, PyObject *value,
|
||||
SIP_SSIZE_T len);
|
||||
#if PY_VERSION_HEX < 0x02050000
|
||||
static void fix_bounds(int len, int *left, int *right);
|
||||
#endif
|
||||
#if PY_VERSION_HEX >= 0x02050000
|
||||
static void bad_key(PyObject *key);
|
||||
#endif
|
||||
static void *element(sipArrayObject *array, SIP_SSIZE_T idx);
|
||||
static PyObject *make_array(void *data, const sipTypeDef *td,
|
||||
const char *format, size_t stride, SIP_SSIZE_T len, int flags,
|
||||
PyObject *owner);
|
||||
|
||||
|
||||
/*
|
||||
* Implement len() for the type.
|
||||
*/
|
||||
static SIP_SSIZE_T sipArray_length(PyObject *self)
|
||||
{
|
||||
return ((sipArrayObject *)self)->len;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Implement sequence item sub-script for the type.
|
||||
*/
|
||||
static PyObject *sipArray_item(PyObject *self, SIP_SSIZE_T idx)
|
||||
{
|
||||
sipArrayObject *array = (sipArrayObject *)self;
|
||||
PyObject *py_item;
|
||||
void *data;
|
||||
|
||||
if (check_index(array, idx) < 0)
|
||||
return NULL;
|
||||
|
||||
data = element(array, idx);
|
||||
|
||||
if (array->td != NULL)
|
||||
{
|
||||
py_item = sip_api_convert_from_type(data, array->td, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (*array->format)
|
||||
{
|
||||
case 'b':
|
||||
py_item = SIPLong_FromLong(*(char *)data);
|
||||
break;
|
||||
|
||||
case 'B':
|
||||
py_item = PyLong_FromUnsignedLong(*(unsigned char *)data);
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
py_item = SIPLong_FromLong(*(short *)data);
|
||||
break;
|
||||
|
||||
case 'H':
|
||||
py_item = PyLong_FromUnsignedLong(*(unsigned short *)data);
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
py_item = SIPLong_FromLong(*(int *)data);
|
||||
break;
|
||||
|
||||
case 'I':
|
||||
py_item = PyLong_FromUnsignedLong(*(unsigned int *)data);
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
py_item = PyFloat_FromDouble(*(float *)data);
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
py_item = PyFloat_FromDouble(*(double *)data);
|
||||
break;
|
||||
|
||||
default:
|
||||
py_item = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return py_item;
|
||||
}
|
||||
|
||||
|
||||
#if PY_VERSION_HEX < 0x02050000
|
||||
/*
|
||||
* Implement sequence slice sub-script for the type.
|
||||
*/
|
||||
static PyObject *sipArray_slice(PyObject *self, int left, int right)
|
||||
{
|
||||
sipArrayObject *array = (sipArrayObject *)self;
|
||||
|
||||
fix_bounds(array->len, &left, &right);
|
||||
|
||||
if (left == right)
|
||||
left = right = 0;
|
||||
|
||||
return make_array(element(array, left), array->td, array->format,
|
||||
array->stride, right - left, (array->flags & ~SIP_OWNS_MEMORY),
|
||||
array->owner);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Implement sequence assignment item sub-script for the type.
|
||||
*/
|
||||
static int sipArray_ass_item(PyObject *self, int idx, PyObject *value)
|
||||
{
|
||||
sipArrayObject *array = (sipArrayObject *)self;
|
||||
void *value_data;
|
||||
|
||||
if (check_writable(array) < 0 || check_index(array, idx) < 0)
|
||||
return -1;
|
||||
|
||||
if ((value_data = get_value(array, value)) == NULL)
|
||||
return -1;
|
||||
|
||||
memmove(element(array, idx), value_data, array->stride);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Implement sequence assignment slice sub-script for the type.
|
||||
*/
|
||||
static int sipArray_ass_slice(PyObject *self, int left, int right,
|
||||
PyObject *value)
|
||||
{
|
||||
sipArrayObject *array = (sipArrayObject *)self;
|
||||
void *value_data;
|
||||
|
||||
if (check_writable(array) < 0)
|
||||
return -1;
|
||||
|
||||
fix_bounds(array->len, &left, &right);
|
||||
|
||||
if ((value_data = get_slice(array, value, right - left)) == NULL)
|
||||
return -1;
|
||||
|
||||
memmove(element(array, left), value_data, (right - left) * array->stride);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* The sequence methods data structure. */
|
||||
static PySequenceMethods sipArray_SequenceMethods = {
|
||||
sipArray_length, /* sq_length */
|
||||
0, /* sq_concat */
|
||||
0, /* sq_repeat */
|
||||
sipArray_item, /* sq_item */
|
||||
#if PY_VERSION_HEX >= 0x02050000
|
||||
0, /* sq_slice */
|
||||
0, /* sq_ass_item */
|
||||
0, /* sq_ass_slice */
|
||||
#else
|
||||
sipArray_slice, /* sq_slice */
|
||||
sipArray_ass_item, /* sq_ass_item */
|
||||
sipArray_ass_slice, /* sq_ass_slice */
|
||||
#endif
|
||||
0, /* sq_contains */
|
||||
0, /* sq_inplace_concat */
|
||||
0, /* sq_inplace_repeat */
|
||||
};
|
||||
|
||||
|
||||
#if PY_VERSION_HEX >= 0x02050000
|
||||
/*
|
||||
* Implement mapping sub-script for the type.
|
||||
*/
|
||||
static PyObject *sipArray_subscript(PyObject *self, PyObject *key)
|
||||
{
|
||||
sipArrayObject *array = (sipArrayObject *)self;
|
||||
|
||||
if (PyIndex_Check(key))
|
||||
{
|
||||
Py_ssize_t idx = PyNumber_AsSsize_t(key, PyExc_IndexError);
|
||||
|
||||
if (idx == -1 && PyErr_Occurred())
|
||||
return NULL;
|
||||
|
||||
if (idx < 0)
|
||||
idx += array->len;
|
||||
|
||||
return sipArray_item(self, idx);
|
||||
}
|
||||
|
||||
if (PySlice_Check(key))
|
||||
{
|
||||
Py_ssize_t start, stop, step, slicelength;
|
||||
|
||||
if (sipConvertFromSliceObject(key, array->len, &start, &stop, &step, &slicelength) < 0)
|
||||
return NULL;
|
||||
|
||||
if (step != 1)
|
||||
{
|
||||
PyErr_SetNone(PyExc_NotImplementedError);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return make_array(element(array->data, start), array->td,
|
||||
array->format, array->stride, slicelength,
|
||||
(array->flags & ~SIP_OWNS_MEMORY), array->owner);
|
||||
}
|
||||
|
||||
bad_key(key);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Implement mapping assignment sub-script for the type.
|
||||
*/
|
||||
static int sipArray_ass_subscript(PyObject *self, PyObject *key,
|
||||
PyObject *value)
|
||||
{
|
||||
sipArrayObject *array = (sipArrayObject *)self;
|
||||
SIP_SSIZE_T start, len;
|
||||
void *value_data;
|
||||
|
||||
if (check_writable(array) < 0)
|
||||
return -1;
|
||||
|
||||
if (PyIndex_Check(key))
|
||||
{
|
||||
start = PyNumber_AsSsize_t(key, PyExc_IndexError);
|
||||
|
||||
if (start == -1 && PyErr_Occurred())
|
||||
return -1;
|
||||
|
||||
if (start < 0)
|
||||
start += array->len;
|
||||
|
||||
if (check_index(array, start) < 0)
|
||||
return -1;
|
||||
|
||||
if ((value_data = get_value(array, value)) == NULL)
|
||||
return -1;
|
||||
|
||||
len = 1;
|
||||
}
|
||||
else if (PySlice_Check(key))
|
||||
{
|
||||
Py_ssize_t stop, step;
|
||||
|
||||
if (sipConvertFromSliceObject(key, array->len, &start, &stop, &step, &len) < 0)
|
||||
return -1;
|
||||
|
||||
if (step != 1)
|
||||
{
|
||||
PyErr_SetNone(PyExc_NotImplementedError);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((value_data = get_slice(array, value, len)) == NULL)
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
bad_key(key);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
memmove(element(array, start), value_data, len * array->stride);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* The mapping methods data structure. */
|
||||
static PyMappingMethods sipArray_MappingMethods = {
|
||||
sipArray_length, /* mp_length */
|
||||
sipArray_subscript, /* mp_subscript */
|
||||
sipArray_ass_subscript, /* mp_ass_subscript */
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
#if PY_VERSION_HEX >= 0x02060300
|
||||
/*
|
||||
* The buffer implementation for Python v2.6.3 and later.
|
||||
*/
|
||||
static int sipArray_getbuffer(PyObject *self, Py_buffer *view, int flags)
|
||||
{
|
||||
sipArrayObject *array = (sipArrayObject *)self;
|
||||
|
||||
if (view == NULL)
|
||||
return 0;
|
||||
|
||||
if (((flags & PyBUF_WRITABLE) == PyBUF_WRITABLE) && (array->flags & SIP_READ_ONLY))
|
||||
{
|
||||
PyErr_SetString(PyExc_BufferError, "object is not writable.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
view->obj = self;
|
||||
Py_INCREF(self);
|
||||
|
||||
view->buf = array->data;
|
||||
view->len = array->len;
|
||||
view->readonly = (array->flags & SIP_READ_ONLY);
|
||||
view->itemsize = array->stride;
|
||||
|
||||
view->format = NULL;
|
||||
if ((flags & PyBUF_FORMAT) == PyBUF_FORMAT)
|
||||
view->format = (char *)array->format;
|
||||
|
||||
view->ndim = 1;
|
||||
|
||||
view->shape = NULL;
|
||||
if ((flags & PyBUF_ND) == PyBUF_ND)
|
||||
view->shape = &view->len;
|
||||
|
||||
view->strides = NULL;
|
||||
if ((flags & PyBUF_STRIDES) == PyBUF_STRIDES)
|
||||
view->strides = &view->itemsize;
|
||||
|
||||
view->suboffsets = NULL;
|
||||
view->internal = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if PY_MAJOR_VERSION < 3
|
||||
/*
|
||||
* The read buffer implementation for Python v2.
|
||||
*/
|
||||
static SIP_SSIZE_T sipArray_getreadbuffer(PyObject *self, SIP_SSIZE_T seg,
|
||||
void **ptr)
|
||||
{
|
||||
sipArrayObject *array = (sipArrayObject *)self;
|
||||
|
||||
if (seg != 0)
|
||||
{
|
||||
PyErr_SetString(PyExc_SystemError, "invalid buffer segment");
|
||||
return -1;
|
||||
}
|
||||
|
||||
*ptr = array->data;
|
||||
|
||||
return array->len;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if PY_MAJOR_VERSION < 3
|
||||
/*
|
||||
* The write buffer implementation for Python v2.
|
||||
*/
|
||||
static SIP_SSIZE_T sipArray_getwritebuffer(PyObject *self, SIP_SSIZE_T seg,
|
||||
void **ptr)
|
||||
{
|
||||
if (check_writable((sipArrayObject *)self) < 0)
|
||||
return -1;
|
||||
|
||||
return sipArray_getreadbuffer(self, seg, ptr);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if PY_MAJOR_VERSION < 3
|
||||
/*
|
||||
* The segment count implementation for Python v2.
|
||||
*/
|
||||
static SIP_SSIZE_T sipArray_getsegcount(PyObject *self, SIP_SSIZE_T *lenp)
|
||||
{
|
||||
SIP_SSIZE_T segs, len;
|
||||
|
||||
len = ((sipArrayObject *)self)->len;
|
||||
segs = (len < 0 ? 0 : 1);
|
||||
|
||||
if (lenp != NULL)
|
||||
*lenp = len;
|
||||
|
||||
return segs;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* The buffer methods data structure. */
|
||||
static PyBufferProcs sipArray_BufferProcs = {
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
sipArray_getbuffer, /* bf_getbuffer */
|
||||
0 /* bf_releasebuffer */
|
||||
#else
|
||||
sipArray_getreadbuffer, /* bf_getreadbuffer */
|
||||
sipArray_getwritebuffer, /* bf_getwritebuffer */
|
||||
sipArray_getsegcount, /* bf_getsegcount */
|
||||
#if PY_VERSION_HEX >= 0x02050000
|
||||
(charbufferproc)sipArray_getreadbuffer, /* bf_getcharbuffer */
|
||||
#if PY_VERSION_HEX >= 0x02060300
|
||||
sipArray_getbuffer, /* bf_getbuffer */
|
||||
0 /* bf_releasebuffer */
|
||||
#endif
|
||||
#else
|
||||
(getcharbufferproc)sipArray_getreadbuffer /* bf_getcharbuffer */
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
/* The instance deallocation function. */
|
||||
static void sipArray_dealloc(PyObject *self)
|
||||
{
|
||||
sipArrayObject *array = (sipArrayObject *)self;
|
||||
|
||||
if (array->flags & SIP_OWNS_MEMORY)
|
||||
sip_api_free(array->data);
|
||||
else
|
||||
Py_XDECREF(array->owner);
|
||||
}
|
||||
|
||||
|
||||
/* The type data structure. */
|
||||
PyTypeObject sipArray_Type = {
|
||||
PyVarObject_HEAD_INIT(NULL, 0)
|
||||
"sip.array", /* tp_name */
|
||||
sizeof (sipArrayObject), /* tp_basicsize */
|
||||
0, /* tp_itemsize */
|
||||
sipArray_dealloc, /* tp_dealloc */
|
||||
0, /* tp_print */
|
||||
0, /* tp_getattr */
|
||||
0, /* tp_setattr */
|
||||
0, /* tp_reserved (Python v3), tp_compare (Python v2) */
|
||||
0, /* tp_repr */
|
||||
0, /* tp_as_number */
|
||||
&sipArray_SequenceMethods, /* tp_as_sequence */
|
||||
#if PY_VERSION_HEX >= 0x02050000
|
||||
&sipArray_MappingMethods, /* tp_as_mapping */
|
||||
#else
|
||||
0, /* tp_as_mapping */
|
||||
#endif
|
||||
0, /* tp_hash */
|
||||
0, /* tp_call */
|
||||
0, /* tp_str */
|
||||
0, /* tp_getattro */
|
||||
0, /* tp_setattro */
|
||||
&sipArray_BufferProcs, /* tp_as_buffer */
|
||||
#if defined(Py_TPFLAGS_HAVE_NEWBUFFER)
|
||||
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_NEWBUFFER, /* tp_flags */
|
||||
#else
|
||||
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
|
||||
#endif
|
||||
0, /* 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 */
|
||||
0, /* tp_new */
|
||||
0, /* tp_free */
|
||||
0, /* tp_is_gc */
|
||||
0, /* tp_bases */
|
||||
0, /* tp_mro */
|
||||
0, /* tp_cache */
|
||||
0, /* tp_subclasses */
|
||||
0, /* tp_weaklist */
|
||||
0, /* tp_del */
|
||||
#if PY_VERSION_HEX >= 0x02060000
|
||||
0, /* tp_version_tag */
|
||||
#endif
|
||||
#if PY_VERSION_HEX >= 0x03040000
|
||||
0, /* tp_finalize */
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Check that an array is writable.
|
||||
*/
|
||||
static int check_writable(sipArrayObject *array)
|
||||
{
|
||||
if (array->flags & SIP_READ_ONLY)
|
||||
{
|
||||
PyErr_SetString(PyExc_TypeError, "sip.array object is read-only");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Check that an index is valid for an array.
|
||||
*/
|
||||
static int check_index(sipArrayObject *array, SIP_SSIZE_T idx)
|
||||
{
|
||||
if (idx >= 0 && idx < array->len)
|
||||
return 0;
|
||||
|
||||
PyErr_SetString(PyExc_IndexError, "index out of bounds");
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
#if PY_VERSION_HEX < 0x02050000
|
||||
/*
|
||||
* Fix the bounds of a slice in the same way that the Python buffer object
|
||||
* does.
|
||||
*/
|
||||
static void fix_bounds(int len, int *left, int *right)
|
||||
{
|
||||
if (*left < 0)
|
||||
*left = 0;
|
||||
else if (*left > len)
|
||||
*left = len;
|
||||
|
||||
if (*right < *left)
|
||||
*right = *left;
|
||||
else if (*right > len)
|
||||
*right = len;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if PY_VERSION_HEX >= 0x02050000
|
||||
/*
|
||||
* Raise an exception about a bad sub-script key.
|
||||
*/
|
||||
static void bad_key(PyObject *key)
|
||||
{
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"cannot index a sip.array object using '%s'",
|
||||
Py_TYPE(key)->tp_name);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Get the address of an element of an array.
|
||||
*/
|
||||
static void *element(sipArrayObject *array, SIP_SSIZE_T idx)
|
||||
{
|
||||
return (unsigned char *)(array->data) + idx * array->stride;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Get the address of a value that will be copied to an array.
|
||||
*/
|
||||
static void *get_value(sipArrayObject *array, PyObject *value)
|
||||
{
|
||||
static union {
|
||||
signed char s_char_t;
|
||||
unsigned char u_char_t;
|
||||
signed short s_short_t;
|
||||
unsigned short u_short_t;
|
||||
signed int s_int_t;
|
||||
unsigned int u_int_t;
|
||||
float float_t;
|
||||
double double_t;
|
||||
} static_data;
|
||||
|
||||
void *data;
|
||||
|
||||
if (array->td != NULL)
|
||||
{
|
||||
int iserr = FALSE;
|
||||
|
||||
data = sip_api_force_convert_to_type(value, array->td, NULL,
|
||||
SIP_NOT_NONE|SIP_NO_CONVERTORS, NULL, &iserr);
|
||||
}
|
||||
else
|
||||
{
|
||||
PyErr_Clear();
|
||||
|
||||
switch (*array->format)
|
||||
{
|
||||
case 'b':
|
||||
static_data.s_char_t = (signed char)SIPLong_AsLong(value);
|
||||
data = &static_data.s_char_t;
|
||||
break;
|
||||
|
||||
case 'B':
|
||||
static_data.u_char_t = (unsigned char)sip_api_long_as_unsigned_long(value);
|
||||
data = &static_data.u_char_t;
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
static_data.s_short_t = (signed short)SIPLong_AsLong(value);
|
||||
data = &static_data.s_short_t;
|
||||
break;
|
||||
|
||||
case 'H':
|
||||
static_data.u_short_t = (unsigned short)sip_api_long_as_unsigned_long(value);
|
||||
data = &static_data.u_short_t;
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
static_data.s_int_t = SIPLong_AsLong(value);
|
||||
data = &static_data.s_int_t;
|
||||
break;
|
||||
|
||||
case 'I':
|
||||
static_data.u_int_t = sip_api_long_as_unsigned_long(value);
|
||||
data = &static_data.u_int_t;
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
static_data.float_t = (float)PyFloat_AsDouble(value);
|
||||
data = &static_data.float_t;
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
static_data.double_t = PyFloat_AsDouble(value);
|
||||
data = &static_data.double_t;
|
||||
break;
|
||||
|
||||
default:
|
||||
data = NULL;
|
||||
}
|
||||
|
||||
if (PyErr_Occurred())
|
||||
data = NULL;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Get the address of an value that will be copied to an array slice.
|
||||
*/
|
||||
static void *get_slice(sipArrayObject *array, PyObject *value, SIP_SSIZE_T len)
|
||||
{
|
||||
sipArrayObject *other = (sipArrayObject *)value;
|
||||
|
||||
if (!PyObject_IsInstance(value, (PyObject *)&sipArray_Type) || array->td != other->td || strcmp(array->format, other->format) != 0)
|
||||
{
|
||||
const char *type;
|
||||
|
||||
if (array->td != NULL)
|
||||
{
|
||||
type = sipTypeName(array->td);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (*array->format)
|
||||
{
|
||||
case 'b':
|
||||
type = "char";
|
||||
break;
|
||||
|
||||
case 'B':
|
||||
type = "unsigned char";
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
type = "short";
|
||||
break;
|
||||
|
||||
case 'H':
|
||||
type = "unsigned short";
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
type = "int";
|
||||
break;
|
||||
|
||||
case 'I':
|
||||
type = "unsigned int";
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
type = "float";
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
type = "double";
|
||||
break;
|
||||
|
||||
default:
|
||||
type = "";
|
||||
}
|
||||
}
|
||||
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"can only assign another array of %s to the slice", type);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (other->len != len)
|
||||
{
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"the array being assigned must have length " SIP_SSIZE_T_FORMAT,
|
||||
len);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (other->stride == array->stride)
|
||||
{
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
#if PY_VERSION_HEX >= 0x02050000
|
||||
"the array being assigned must have stride %zu",
|
||||
array->stride);
|
||||
#else
|
||||
"the array being assigned must have stride %ld",
|
||||
(unsigned long)array->stride);
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return other->data;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Do the work of creating an array.
|
||||
*/
|
||||
static PyObject *make_array(void *data, const sipTypeDef *td,
|
||||
const char *format, size_t stride, SIP_SSIZE_T len, int flags,
|
||||
PyObject *owner)
|
||||
{
|
||||
sipArrayObject *array;
|
||||
|
||||
if ((array = PyObject_NEW(sipArrayObject, &sipArray_Type)) == NULL)
|
||||
return NULL;
|
||||
|
||||
array->data = data;
|
||||
array->td = td;
|
||||
array->format = format;
|
||||
array->stride = stride;
|
||||
array->len = len;
|
||||
array->flags = flags;
|
||||
|
||||
if (flags & SIP_OWNS_MEMORY)
|
||||
{
|
||||
/* This is a borrowed reference to itself. */
|
||||
array->owner = (PyObject *)array;
|
||||
}
|
||||
else
|
||||
{
|
||||
Py_XINCREF(owner);
|
||||
array->owner = owner;
|
||||
}
|
||||
|
||||
return (PyObject *)array;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Wrap an array of instances of a fundamental type. At the moment format must
|
||||
* be either "b" (char), "B" (unsigned char), "h" (short), "H" (unsigned
|
||||
* short), "i" (int), "I" (unsigned int), "f" (float) or "d" (double).
|
||||
*/
|
||||
PyObject *sip_api_convert_to_array(void *data, const char *format,
|
||||
SIP_SSIZE_T len, int flags)
|
||||
{
|
||||
size_t stride;
|
||||
|
||||
if (data == NULL)
|
||||
{
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
switch (*format)
|
||||
{
|
||||
case 'b':
|
||||
stride = sizeof (char);
|
||||
break;
|
||||
|
||||
case 'B':
|
||||
stride = sizeof (unsigned char);
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
stride = sizeof (short);
|
||||
break;
|
||||
|
||||
case 'H':
|
||||
stride = sizeof (unsigned short);
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
stride = sizeof (int);
|
||||
break;
|
||||
|
||||
case 'I':
|
||||
stride = sizeof (unsigned int);
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
stride = sizeof (float);
|
||||
break;
|
||||
|
||||
case 'd':
|
||||
stride = sizeof (double);
|
||||
break;
|
||||
|
||||
default:
|
||||
stride = 0;
|
||||
}
|
||||
|
||||
assert(stride > 0);
|
||||
assert(len >= 0);
|
||||
|
||||
return make_array(data, NULL, format, stride, len, flags, NULL);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Wrap an array of instances of a defined type.
|
||||
*/
|
||||
PyObject *sip_api_convert_to_typed_array(void *data, const sipTypeDef *td,
|
||||
const char *format, size_t stride, SIP_SSIZE_T len, int flags)
|
||||
{
|
||||
if (data == NULL)
|
||||
{
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
assert(stride > 0);
|
||||
assert(len >= 0);
|
||||
|
||||
return make_array(data, td, format, stride, len, flags, NULL);
|
||||
}
|
||||
46
sip/siplib/array.h
Normal file
46
sip/siplib/array.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* This file defines the API for the array type.
|
||||
*
|
||||
* Copyright (c) 2015 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
*
|
||||
* This file is part of SIP.
|
||||
*
|
||||
* This copy of SIP is licensed for use under the terms of the SIP License
|
||||
* Agreement. See the file LICENSE for more details.
|
||||
*
|
||||
* This copy of SIP may also used under the terms of the GNU General Public
|
||||
* License v2 or v3 as published by the Free Software Foundation which can be
|
||||
* found in the files LICENSE-GPL2 and LICENSE-GPL3 included in this package.
|
||||
*
|
||||
* SIP is supplied WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _ARRAY_H
|
||||
#define _ARRAY_H
|
||||
|
||||
|
||||
#include <Python.h>
|
||||
|
||||
#include "sip.h"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
extern PyTypeObject sipArray_Type;
|
||||
|
||||
PyObject *sip_api_convert_to_array(void *data, const char *format,
|
||||
SIP_SSIZE_T len, int flags);
|
||||
PyObject *sip_api_convert_to_typed_array(void *data, const sipTypeDef *td,
|
||||
const char *format, size_t stride, SIP_SSIZE_T len, int flags);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,6 +1,6 @@
|
||||
// This contains all the C++ code that is needed by the sip module.
|
||||
//
|
||||
// Copyright (c) 2013 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
// Copyright (c) 2015 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
//
|
||||
// This file is part of SIP.
|
||||
//
|
||||
@@ -18,5 +18,5 @@
|
||||
// Set a C++ bool for the main C implementation of the module.
|
||||
extern "C" void sipSetBool(void *ptr, int val)
|
||||
{
|
||||
*reinterpret_cast<bool *>(ptr) = val;
|
||||
*reinterpret_cast<bool *>(ptr) = !!val;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* The implementation of the different descriptors.
|
||||
*
|
||||
* Copyright (c) 2013 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
* Copyright (c) 2015 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
*
|
||||
* This file is part of SIP.
|
||||
*
|
||||
@@ -25,7 +25,8 @@
|
||||
|
||||
/*****************************************************************************
|
||||
* A method descriptor. We don't use the similar Python descriptor because it
|
||||
* doesn't support a method having static and non-static overloads.
|
||||
* doesn't support a method having static and non-static overloads, and we
|
||||
* handle mixins via a delegate.
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
@@ -33,6 +34,9 @@
|
||||
static PyObject *sipMethodDescr_descr_get(PyObject *self, PyObject *obj,
|
||||
PyObject *type);
|
||||
static PyObject *sipMethodDescr_repr(PyObject *self);
|
||||
static int sipMethodDescr_traverse(PyObject *self, visitproc visit, void *arg);
|
||||
static int sipMethodDescr_clear(PyObject *self);
|
||||
static void sipMethodDescr_dealloc(PyObject *self);
|
||||
|
||||
|
||||
/*
|
||||
@@ -43,6 +47,9 @@ typedef struct _sipMethodDescr {
|
||||
|
||||
/* The method definition. */
|
||||
PyMethodDef *pmd;
|
||||
|
||||
/* The mixin name, if any. */
|
||||
PyObject *mixin_name;
|
||||
} sipMethodDescr;
|
||||
|
||||
|
||||
@@ -54,7 +61,7 @@ PyTypeObject sipMethodDescr_Type = {
|
||||
"sip.methoddescriptor", /* tp_name */
|
||||
sizeof (sipMethodDescr), /* tp_basicsize */
|
||||
0, /* tp_itemsize */
|
||||
0, /* tp_dealloc */
|
||||
sipMethodDescr_dealloc, /* tp_dealloc */
|
||||
0, /* tp_print */
|
||||
0, /* tp_getattr */
|
||||
0, /* tp_setattr */
|
||||
@@ -69,10 +76,10 @@ PyTypeObject sipMethodDescr_Type = {
|
||||
0, /* tp_getattro */
|
||||
0, /* tp_setattro */
|
||||
0, /* tp_as_buffer */
|
||||
Py_TPFLAGS_DEFAULT, /* tp_flags */
|
||||
Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC, /* tp_flags */
|
||||
0, /* tp_doc */
|
||||
0, /* tp_traverse */
|
||||
0, /* tp_clear */
|
||||
sipMethodDescr_traverse,/* tp_traverse */
|
||||
sipMethodDescr_clear, /* tp_clear */
|
||||
0, /* tp_richcompare */
|
||||
0, /* tp_weaklistoffset */
|
||||
0, /* tp_iter */
|
||||
@@ -83,6 +90,25 @@ PyTypeObject sipMethodDescr_Type = {
|
||||
0, /* tp_base */
|
||||
0, /* tp_dict */
|
||||
sipMethodDescr_descr_get, /* tp_descr_get */
|
||||
0, /* tp_descr_set */
|
||||
0, /* tp_dictoffset */
|
||||
0, /* tp_init */
|
||||
0, /* tp_alloc */
|
||||
0, /* tp_new */
|
||||
0, /* tp_free */
|
||||
0, /* tp_is_gc */
|
||||
0, /* tp_bases */
|
||||
0, /* tp_mro */
|
||||
0, /* tp_cache */
|
||||
0, /* tp_subclasses */
|
||||
0, /* tp_weaklist */
|
||||
0, /* tp_del */
|
||||
#if PY_VERSION_HEX >= 0x02060000
|
||||
0, /* tp_version_tag */
|
||||
#endif
|
||||
#if PY_VERSION_HEX >= 0x03040000
|
||||
0, /* tp_finalize */
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@@ -94,7 +120,28 @@ PyObject *sipMethodDescr_New(PyMethodDef *pmd)
|
||||
PyObject *descr = PyType_GenericAlloc(&sipMethodDescr_Type, 0);
|
||||
|
||||
if (descr != NULL)
|
||||
{
|
||||
((sipMethodDescr *)descr)->pmd = pmd;
|
||||
((sipMethodDescr *)descr)->mixin_name = NULL;
|
||||
}
|
||||
|
||||
return descr;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Return a new method descriptor based on an existing one and a mixin name.
|
||||
*/
|
||||
PyObject *sipMethodDescr_Copy(PyObject *orig, PyObject *mixin_name)
|
||||
{
|
||||
PyObject *descr = PyType_GenericAlloc(&sipMethodDescr_Type, 0);
|
||||
|
||||
if (descr != NULL)
|
||||
{
|
||||
((sipMethodDescr *)descr)->pmd = ((sipMethodDescr *)orig)->pmd;
|
||||
((sipMethodDescr *)descr)->mixin_name = mixin_name;
|
||||
Py_INCREF(mixin_name);
|
||||
}
|
||||
|
||||
return descr;
|
||||
}
|
||||
@@ -108,8 +155,12 @@ static PyObject *sipMethodDescr_descr_get(PyObject *self, PyObject *obj,
|
||||
{
|
||||
sipMethodDescr *md = (sipMethodDescr *)self;
|
||||
|
||||
(void)type;
|
||||
|
||||
if (obj == Py_None)
|
||||
obj = NULL;
|
||||
else if (md->mixin_name != NULL)
|
||||
obj = PyObject_GetAttr(obj, md->mixin_name);
|
||||
|
||||
return PyCFunction_New(md->pmd, obj);
|
||||
}
|
||||
@@ -133,6 +184,47 @@ static PyObject *sipMethodDescr_repr(PyObject *self)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The descriptor's traverse slot.
|
||||
*/
|
||||
static int sipMethodDescr_traverse(PyObject *self, visitproc visit, void *arg)
|
||||
{
|
||||
if (((sipMethodDescr *)self)->mixin_name != NULL)
|
||||
{
|
||||
int vret = visit(((sipMethodDescr *)self)->mixin_name, arg);
|
||||
|
||||
if (vret != 0)
|
||||
return vret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The descriptor's clear slot.
|
||||
*/
|
||||
static int sipMethodDescr_clear(PyObject *self)
|
||||
{
|
||||
PyObject *tmp = ((sipMethodDescr *)self)->mixin_name;
|
||||
|
||||
((sipMethodDescr *)self)->mixin_name = NULL;
|
||||
Py_XDECREF(tmp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The descriptor's dealloc slot.
|
||||
*/
|
||||
static void sipMethodDescr_dealloc(PyObject *self)
|
||||
{
|
||||
sipMethodDescr_clear(self);
|
||||
Py_TYPE(self)->tp_free(self);
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* A variable descriptor. We don't use the similar Python descriptor because
|
||||
* it doesn't support static variables.
|
||||
@@ -144,6 +236,10 @@ static PyObject *sipVariableDescr_descr_get(PyObject *self, PyObject *obj,
|
||||
PyObject *type);
|
||||
static int sipVariableDescr_descr_set(PyObject *self, PyObject *obj,
|
||||
PyObject *value);
|
||||
static int sipVariableDescr_traverse(PyObject *self, visitproc visit,
|
||||
void *arg);
|
||||
static int sipVariableDescr_clear(PyObject *self);
|
||||
static void sipVariableDescr_dealloc(PyObject *self);
|
||||
|
||||
|
||||
/*
|
||||
@@ -160,6 +256,9 @@ typedef struct _sipVariableDescr {
|
||||
|
||||
/* The generated container definition. */
|
||||
const sipContainerDef *cod;
|
||||
|
||||
/* The mixin name, if any. */
|
||||
PyObject *mixin_name;
|
||||
} sipVariableDescr;
|
||||
|
||||
|
||||
@@ -171,7 +270,7 @@ PyTypeObject sipVariableDescr_Type = {
|
||||
"sip.variabledescriptor", /* tp_name */
|
||||
sizeof (sipVariableDescr), /* tp_basicsize */
|
||||
0, /* tp_itemsize */
|
||||
0, /* tp_dealloc */
|
||||
sipVariableDescr_dealloc, /* tp_dealloc */
|
||||
0, /* tp_print */
|
||||
0, /* tp_getattr */
|
||||
0, /* tp_setattr */
|
||||
@@ -186,10 +285,10 @@ PyTypeObject sipVariableDescr_Type = {
|
||||
0, /* tp_getattro */
|
||||
0, /* tp_setattro */
|
||||
0, /* tp_as_buffer */
|
||||
Py_TPFLAGS_DEFAULT, /* tp_flags */
|
||||
Py_TPFLAGS_DEFAULT|Py_TPFLAGS_HAVE_GC, /* tp_flags */
|
||||
0, /* tp_doc */
|
||||
0, /* tp_traverse */
|
||||
0, /* tp_clear */
|
||||
sipVariableDescr_traverse, /* tp_traverse */
|
||||
sipVariableDescr_clear, /* tp_clear */
|
||||
0, /* tp_richcompare */
|
||||
0, /* tp_weaklistoffset */
|
||||
0, /* tp_iter */
|
||||
@@ -201,6 +300,24 @@ PyTypeObject sipVariableDescr_Type = {
|
||||
0, /* tp_dict */
|
||||
sipVariableDescr_descr_get, /* tp_descr_get */
|
||||
sipVariableDescr_descr_set, /* tp_descr_set */
|
||||
0, /* tp_dictoffset */
|
||||
0, /* tp_init */
|
||||
0, /* tp_alloc */
|
||||
0, /* tp_new */
|
||||
0, /* tp_free */
|
||||
0, /* tp_is_gc */
|
||||
0, /* tp_bases */
|
||||
0, /* tp_mro */
|
||||
0, /* tp_cache */
|
||||
0, /* tp_subclasses */
|
||||
0, /* tp_weaklist */
|
||||
0, /* tp_del */
|
||||
#if PY_VERSION_HEX >= 0x02060000
|
||||
0, /* tp_version_tag */
|
||||
#endif
|
||||
#if PY_VERSION_HEX >= 0x03040000
|
||||
0, /* tp_finalize */
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@@ -222,6 +339,27 @@ PyObject *sipVariableDescr_New(sipVariableDef *vd, const sipTypeDef *td,
|
||||
((sipVariableDescr *)descr)->vd = vd;
|
||||
((sipVariableDescr *)descr)->td = td;
|
||||
((sipVariableDescr *)descr)->cod = cod;
|
||||
((sipVariableDescr *)descr)->mixin_name = NULL;
|
||||
}
|
||||
|
||||
return descr;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Return a new variable descriptor based on an existing one and a mixin name.
|
||||
*/
|
||||
PyObject *sipVariableDescr_Copy(PyObject *orig, PyObject *mixin_name)
|
||||
{
|
||||
PyObject *descr = PyType_GenericAlloc(&sipVariableDescr_Type, 0);
|
||||
|
||||
if (descr != NULL)
|
||||
{
|
||||
((sipVariableDescr *)descr)->vd = ((sipVariableDescr *)orig)->vd;
|
||||
((sipVariableDescr *)descr)->td = ((sipVariableDescr *)orig)->td;
|
||||
((sipVariableDescr *)descr)->cod = ((sipVariableDescr *)orig)->cod;
|
||||
((sipVariableDescr *)descr)->mixin_name = mixin_name;
|
||||
Py_INCREF(mixin_name);
|
||||
}
|
||||
|
||||
return descr;
|
||||
@@ -294,6 +432,9 @@ static int get_instance_address(sipVariableDescr *vd, PyObject *obj,
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (vd->mixin_name != NULL)
|
||||
obj = PyObject_GetAttr(obj, vd->mixin_name);
|
||||
|
||||
/* Get the C++ instance. */
|
||||
if ((addr = sip_api_get_cpp_ptr((sipSimpleWrapper *)obj, vd->td)) == NULL)
|
||||
return -1;
|
||||
@@ -303,3 +444,44 @@ static int get_instance_address(sipVariableDescr *vd, PyObject *obj,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The descriptor's traverse slot.
|
||||
*/
|
||||
static int sipVariableDescr_traverse(PyObject *self, visitproc visit, void *arg)
|
||||
{
|
||||
if (((sipVariableDescr *)self)->mixin_name != NULL)
|
||||
{
|
||||
int vret = visit(((sipVariableDescr *)self)->mixin_name, arg);
|
||||
|
||||
if (vret != 0)
|
||||
return vret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The descriptor's clear slot.
|
||||
*/
|
||||
static int sipVariableDescr_clear(PyObject *self)
|
||||
{
|
||||
PyObject *tmp = ((sipVariableDescr *)self)->mixin_name;
|
||||
|
||||
((sipVariableDescr *)self)->mixin_name = NULL;
|
||||
Py_XDECREF(tmp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The descriptor's dealloc slot.
|
||||
*/
|
||||
static void sipVariableDescr_dealloc(PyObject *self)
|
||||
{
|
||||
sipVariableDescr_clear(self);
|
||||
Py_TYPE(self)->tp_free(self);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* This module implements a hash table class for mapping C/C++ addresses to the
|
||||
* corresponding wrapped Python object.
|
||||
*
|
||||
* Copyright (c) 2013 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
* Copyright (c) 2015 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
*
|
||||
* This file is part of SIP.
|
||||
*
|
||||
@@ -197,7 +197,7 @@ static void add_aliases(sipObjectMap *om, void *addr, sipSimpleWrapper *val,
|
||||
/* Recurse up the hierachy for the remaining super-classes. */
|
||||
add_aliases(om, addr, val, base_ctd, sup_ctd);
|
||||
|
||||
sup_addr = (*base_ctd->ctd_cast)(addr, sup_ctd);
|
||||
sup_addr = (*base_ctd->ctd_cast)(addr, (sipTypeDef *)sup_ctd);
|
||||
|
||||
if (sup_addr != addr)
|
||||
{
|
||||
@@ -403,7 +403,7 @@ static void remove_aliases(sipObjectMap *om, void *addr, sipSimpleWrapper *val,
|
||||
/* Recurse up the hierachy for the remaining super-classes. */
|
||||
remove_aliases(om, addr, val, base_ctd, sup_ctd);
|
||||
|
||||
sup_addr = (*base_ctd->ctd_cast)(addr, sup_ctd);
|
||||
sup_addr = (*base_ctd->ctd_cast)(addr, (sipTypeDef *)sup_ctd);
|
||||
|
||||
if (sup_addr != addr)
|
||||
remove_object(om, sup_addr, val);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* The SIP library code that implements the interface to the optional module
|
||||
* supplied Qt support.
|
||||
*
|
||||
* Copyright (c) 2013 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
* Copyright (c) 2015 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
*
|
||||
* This file is part of SIP.
|
||||
*
|
||||
@@ -87,9 +87,21 @@ static void *createUniversalSlot(sipWrapper *txSelf, const char *sig,
|
||||
|
||||
|
||||
/*
|
||||
* Invoke a single slot (Qt or Python) and return the result.
|
||||
* Invoke a single slot (Qt or Python) and return the result. Don't check if
|
||||
* any receiver C++ object still exists.
|
||||
*/
|
||||
PyObject *sip_api_invoke_slot(const sipSlot *slot, PyObject *sigargs)
|
||||
{
|
||||
return sip_api_invoke_slot_ex(slot, sigargs, TRUE);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Invoke a single slot (Qt or Python) and return the result. Optionally check
|
||||
* that any receiver C++ object still exist.
|
||||
*/
|
||||
PyObject *sip_api_invoke_slot_ex(const sipSlot *slot, PyObject *sigargs,
|
||||
int no_receiver_check)
|
||||
{
|
||||
PyObject *sa, *oxtype, *oxvalue, *oxtb, *sfunc, *sref;
|
||||
|
||||
@@ -145,11 +157,18 @@ PyObject *sip_api_invoke_slot(const sipSlot *slot, PyObject *sigargs)
|
||||
PyObject *self = (sref != NULL ? sref : slot->meth.mself);
|
||||
|
||||
/*
|
||||
* We used to check that any wrapped C++ object still existed and just
|
||||
* returning None if it didn't. This caused inconsistent behaviour
|
||||
* when the slot was a method connected to its object's destroyed()
|
||||
* signal.
|
||||
* If the receiver wraps a C++ object then ignore the call if it no
|
||||
* longer exists.
|
||||
*/
|
||||
if (!no_receiver_check &&
|
||||
PyObject_TypeCheck(self, (PyTypeObject *)&sipSimpleWrapper_Type) &&
|
||||
sip_api_get_address((sipSimpleWrapper *)self) == NULL)
|
||||
{
|
||||
Py_XDECREF(sref);
|
||||
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
sfunc = PyMethod_New(slot->meth.mfunc, self);
|
||||
|
||||
153
sip/siplib/sip.h
153
sip/siplib/sip.h
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* The SIP module interface.
|
||||
*
|
||||
* Copyright (c) 2013 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
* Copyright (c) 2015 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
*
|
||||
* This file is part of SIP.
|
||||
*
|
||||
@@ -54,8 +54,8 @@ extern "C" {
|
||||
/*
|
||||
* Define the SIP version number.
|
||||
*/
|
||||
#define SIP_VERSION 0x040e07
|
||||
#define SIP_VERSION_STR "4.14.7"
|
||||
#define SIP_VERSION 0x041007
|
||||
#define SIP_VERSION_STR "4.16.7-snapshot-f652446e2462"
|
||||
|
||||
|
||||
/*
|
||||
@@ -68,6 +68,22 @@ extern "C" {
|
||||
*
|
||||
* History:
|
||||
*
|
||||
* 11.1 Added sip_api_invoke_slot_ex().
|
||||
*
|
||||
* 11.0 Added the pyqt5QtSignal and pyqt5ClassTypeDef structures.
|
||||
* Removed qt_interface from pyqt4ClassTypeDef.
|
||||
* Added hack to pyqt4QtSignal.
|
||||
*
|
||||
* 10.1 Added ctd_final to sipClassTypeDef.
|
||||
* Added ctd_init_mixin to sipClassTypeDef.
|
||||
* Added sip_api_get_mixin_address() to the public API.
|
||||
* Added sip_api_convert_from_new_pytype() to the public API.
|
||||
* Added sip_api_convert_to_array() to the public API.
|
||||
* Added sip_api_convert_to_typed_array() to the public API.
|
||||
* Added sip_api_register_proxy_resolver() to the public API.
|
||||
* Added sip_api_init_mixin() to the private API.
|
||||
* Added qt_interface to pyqt4ClassTypeDef.
|
||||
*
|
||||
* 10.0 Added sip_api_set_destroy_on_exit().
|
||||
* Added sip_api_enable_autoconversion().
|
||||
* Removed sip_api_call_error_handler_old().
|
||||
@@ -195,8 +211,8 @@ extern "C" {
|
||||
*
|
||||
* 0.0 Original version.
|
||||
*/
|
||||
#define SIP_API_MAJOR_NR 10
|
||||
#define SIP_API_MINOR_NR 0
|
||||
#define SIP_API_MAJOR_NR 11
|
||||
#define SIP_API_MINOR_NR 1
|
||||
|
||||
|
||||
/* The name of the sip module. */
|
||||
@@ -217,6 +233,7 @@ typedef unsigned int uint;
|
||||
#if PY_VERSION_HEX >= 0x02050000
|
||||
|
||||
#define SIP_SSIZE_T Py_ssize_t
|
||||
#define SIP_SSIZE_T_FORMAT "%zd"
|
||||
|
||||
#define SIP_MLNAME_CAST(s) (s)
|
||||
#define SIP_MLDOC_CAST(s) (s)
|
||||
@@ -225,6 +242,7 @@ typedef unsigned int uint;
|
||||
#else
|
||||
|
||||
#define SIP_SSIZE_T int
|
||||
#define SIP_SSIZE_T_FORMAT "%d"
|
||||
|
||||
#define SIP_MLNAME_CAST(s) ((char *)(s))
|
||||
#define SIP_MLDOC_CAST(s) ((char *)(s))
|
||||
@@ -338,6 +356,7 @@ struct _sipTypeDef;
|
||||
|
||||
typedef void *(*sipInitFunc)(struct _sipSimpleWrapper *, PyObject *,
|
||||
PyObject *, PyObject **, PyObject **, PyObject **);
|
||||
typedef int (*sipFinalFunc)(PyObject *, void *, PyObject *, PyObject **);
|
||||
typedef void *(*sipAccessFunc)(struct _sipSimpleWrapper *, AccessFuncOp);
|
||||
typedef int (*sipTraverseFunc)(void *, visitproc, void *);
|
||||
typedef int (*sipClearFunc)(void *);
|
||||
@@ -365,6 +384,7 @@ typedef PyObject *(*sipPickleFunc)(void *);
|
||||
typedef int (*sipAttrGetterFunc)(const struct _sipTypeDef *, PyObject *);
|
||||
typedef PyObject *(*sipVariableGetterFunc)(void *, PyObject *, PyObject *);
|
||||
typedef int (*sipVariableSetterFunc)(void *, PyObject *, PyObject *);
|
||||
typedef void *(*sipProxyResolverFunc)(void *);
|
||||
|
||||
|
||||
/*
|
||||
@@ -415,6 +435,9 @@ typedef struct _sipSimpleWrapper {
|
||||
/* The instance dictionary. */
|
||||
PyObject *dict;
|
||||
|
||||
/* The main instance if this is a mixin. */
|
||||
PyObject *mixin_main;
|
||||
|
||||
/* Next object at this address. */
|
||||
struct _sipSimpleWrapper *next;
|
||||
} sipSimpleWrapper;
|
||||
@@ -853,7 +876,7 @@ typedef struct _sipClassTypeDef {
|
||||
/* The optional copy function. */
|
||||
sipCopyFunc ctd_copy;
|
||||
|
||||
/* The release function, 0 if a C strict. */
|
||||
/* The release function, 0 if a C struct. */
|
||||
sipReleaseFunc ctd_release;
|
||||
|
||||
/* The cast function, 0 if a C struct. */
|
||||
@@ -870,6 +893,12 @@ typedef struct _sipClassTypeDef {
|
||||
|
||||
/* The pickle function. */
|
||||
sipPickleFunc ctd_pickle;
|
||||
|
||||
/* The finalisation function. */
|
||||
sipFinalFunc ctd_final;
|
||||
|
||||
/* The mixin initialisation function. */
|
||||
initproc ctd_init_mixin;
|
||||
} sipClassTypeDef;
|
||||
|
||||
|
||||
@@ -1471,6 +1500,28 @@ typedef struct _sipAPIDef {
|
||||
const char *fmt, ...);
|
||||
void (*api_call_error_handler)(sipVirtErrorHandlerFunc,
|
||||
sipSimpleWrapper *, sip_gilstate_t);
|
||||
int (*api_init_mixin)(PyObject *self, PyObject *args, PyObject *kwds,
|
||||
const sipClassTypeDef *ctd);
|
||||
/*
|
||||
* The following are part of the public API.
|
||||
*/
|
||||
void *(*api_get_mixin_address)(struct _sipSimpleWrapper *w,
|
||||
const sipTypeDef *td);
|
||||
PyObject *(*api_convert_from_new_pytype)(void *cpp, PyTypeObject *py_type,
|
||||
sipWrapper *owner, sipSimpleWrapper **selfp, const char *fmt, ...);
|
||||
PyObject *(*api_convert_to_typed_array)(void *data, const sipTypeDef *td,
|
||||
const char *format, size_t stride, SIP_SSIZE_T len, int flags);
|
||||
PyObject *(*api_convert_to_array)(void *data, const char *format,
|
||||
SIP_SSIZE_T len, int flags);
|
||||
int (*api_register_proxy_resolver)(const sipTypeDef *td,
|
||||
sipProxyResolverFunc resolver);
|
||||
|
||||
/*
|
||||
* The following may be used by Qt support code but no other handwritten
|
||||
* code.
|
||||
*/
|
||||
PyObject *(*api_invoke_slot_ex)(const sipSlot *slot, PyObject *sigargs,
|
||||
int check_receiver);
|
||||
} sipAPIDef;
|
||||
|
||||
|
||||
@@ -1506,6 +1557,13 @@ typedef struct _sipQtAPI {
|
||||
#define SIP_NO_CONVERTORS 0x02 /* Disable any type convertors. */
|
||||
|
||||
|
||||
/*
|
||||
* These are flags that can be passed to sipConvertToArray().
|
||||
*/
|
||||
#define SIP_READ_ONLY 0x01 /* The array is read-only. */
|
||||
#define SIP_OWNS_MEMORY 0x02 /* The array owns its memory. */
|
||||
|
||||
|
||||
/*
|
||||
* These are the state flags returned by %ConvertToTypeCode. Note that these
|
||||
* share the same "namespace" as the flags below.
|
||||
@@ -1560,6 +1618,7 @@ typedef struct _sipQtAPI {
|
||||
#define SIP_TYPE_ALLOW_NONE 0x0020 /* If the type can handle None. */
|
||||
#define SIP_TYPE_STUB 0x0040 /* If the type is a stub. */
|
||||
#define SIP_TYPE_NONLAZY 0x0080 /* If the type has a non-lazy method. */
|
||||
#define SIP_TYPE_SUPER_INIT 0x0100 /* If the instance's super init should be called. */
|
||||
|
||||
|
||||
/*
|
||||
@@ -1598,6 +1657,7 @@ typedef struct _sipQtAPI {
|
||||
#define sipTypeIsStub(td) ((td)->td_flags & SIP_TYPE_STUB)
|
||||
#define sipTypeSetStub(td) ((td)->td_flags |= SIP_TYPE_STUB)
|
||||
#define sipTypeHasNonlazyMethod(td) ((td)->td_flags & SIP_TYPE_NONLAZY)
|
||||
#define sipTypeCallSuperInit(td) ((td)->td_flags & SIP_TYPE_SUPER_INIT)
|
||||
|
||||
/*
|
||||
* Get various names from the string pool for various data types.
|
||||
@@ -1613,12 +1673,12 @@ typedef struct _sipQtAPI {
|
||||
* out to a plugin supplied by PyQt3.
|
||||
*/
|
||||
|
||||
typedef int (*pyqt3EmitFunc)(sipSimpleWrapper *, PyObject *);
|
||||
|
||||
|
||||
/*
|
||||
* Maps the name of a Qt signal to a wrapper function to emit it.
|
||||
*/
|
||||
typedef int (*pyqt3EmitFunc)(sipSimpleWrapper *, PyObject *);
|
||||
|
||||
typedef struct _pyqt3QtSignal {
|
||||
/* The signal name. */
|
||||
const char *st_name;
|
||||
@@ -1663,6 +1723,16 @@ typedef struct _pyqt4QtSignal {
|
||||
* code that implements those methods.
|
||||
*/
|
||||
PyMethodDef *non_signals;
|
||||
|
||||
/*
|
||||
* The hack to apply when built against Qt5:
|
||||
*
|
||||
* 0 - no hack
|
||||
* 1 - add an optional None
|
||||
* 2 - add an optional []
|
||||
* 3 - add an optional False
|
||||
*/
|
||||
int hack;
|
||||
} pyqt4QtSignal;
|
||||
|
||||
|
||||
@@ -1677,22 +1747,83 @@ typedef struct _pyqt4ClassTypeDef {
|
||||
sipClassTypeDef super;
|
||||
|
||||
/* A pointer to the QObject sub-class's staticMetaObject class variable. */
|
||||
const void *qt4_static_metaobject;
|
||||
const void *static_metaobject;
|
||||
|
||||
/*
|
||||
* A set of flags. At the moment only bit 0 is used to say if the type is
|
||||
* derived from QFlags.
|
||||
*/
|
||||
unsigned qt4_flags;
|
||||
unsigned flags;
|
||||
|
||||
/*
|
||||
* The table of signals emitted by the type. These are grouped by signal
|
||||
* name.
|
||||
*/
|
||||
const pyqt4QtSignal *qt4_signals;
|
||||
const pyqt4QtSignal *qt_signals;
|
||||
} pyqt4ClassTypeDef;
|
||||
|
||||
|
||||
/*
|
||||
* The following are PyQt5-specific extensions. In SIP v5 they will be pushed
|
||||
* out to a plugin supplied by PyQt5.
|
||||
*/
|
||||
|
||||
/*
|
||||
* The description of a Qt signal for PyQt5.
|
||||
*/
|
||||
typedef int (*pyqt5EmitFunc)(void *, PyObject *);
|
||||
|
||||
typedef struct _pyqt5QtSignal {
|
||||
/* The normalised C++ name and signature of the signal. */
|
||||
const char *signature;
|
||||
|
||||
/* The optional docstring. */
|
||||
const char *docstring;
|
||||
|
||||
/*
|
||||
* If the signal is an overload of regular methods then this points to the
|
||||
* code that implements those methods.
|
||||
*/
|
||||
PyMethodDef *non_signals;
|
||||
|
||||
/*
|
||||
* If the signal has optional arguments then this function will implement
|
||||
* emit() for the signal.
|
||||
*/
|
||||
pyqt5EmitFunc emitter;
|
||||
} pyqt5QtSignal;
|
||||
|
||||
|
||||
/*
|
||||
* This is the PyQt5-specific extension to the generated class type structure.
|
||||
*/
|
||||
typedef struct _pyqt5ClassTypeDef {
|
||||
/*
|
||||
* The super-type structure. This must be first in the structure so that
|
||||
* it can be cast to sipClassTypeDef *.
|
||||
*/
|
||||
sipClassTypeDef super;
|
||||
|
||||
/* A pointer to the QObject sub-class's staticMetaObject class variable. */
|
||||
const void *static_metaobject;
|
||||
|
||||
/*
|
||||
* A set of flags. At the moment only bit 0 is used to say if the type is
|
||||
* derived from QFlags.
|
||||
*/
|
||||
unsigned flags;
|
||||
|
||||
/*
|
||||
* The table of signals emitted by the type. These are grouped by signal
|
||||
* name.
|
||||
*/
|
||||
const pyqt5QtSignal *qt_signals;
|
||||
|
||||
/* The name of the interface that the class defines. */
|
||||
const char *qt_interface;
|
||||
} pyqt5ClassTypeDef;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* This file defines the SIP library internal interfaces.
|
||||
*
|
||||
* Copyright (c) 2013 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
* Copyright (c) 2015 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
*
|
||||
* This file is part of SIP.
|
||||
*
|
||||
@@ -61,10 +61,12 @@ typedef struct
|
||||
*/
|
||||
extern PyTypeObject sipMethodDescr_Type;
|
||||
PyObject *sipMethodDescr_New(PyMethodDef *pmd);
|
||||
PyObject *sipMethodDescr_Copy(PyObject *orig, PyObject *mixin_name);
|
||||
|
||||
extern PyTypeObject sipVariableDescr_Type;
|
||||
PyObject *sipVariableDescr_New(sipVariableDef *vd, const sipTypeDef *td,
|
||||
const sipContainerDef *cod);
|
||||
PyObject *sipVariableDescr_Copy(PyObject *orig, PyObject *mixin_name);
|
||||
|
||||
|
||||
/*
|
||||
@@ -112,9 +114,14 @@ PyObject *sip_api_convert_from_type(void *cppPtr, const sipTypeDef *td,
|
||||
PyObject *transferObj);
|
||||
void sip_api_common_dtor(sipSimpleWrapper *sipSelf);
|
||||
void sip_api_end_thread(void);
|
||||
void *sip_api_force_convert_to_type(PyObject *pyObj, const sipTypeDef *td,
|
||||
PyObject *transferObj, int flags, int *statep, int *iserrp);
|
||||
void sip_api_free_sipslot(sipSlot *slot);
|
||||
unsigned long sip_api_long_as_unsigned_long(PyObject *o);
|
||||
int sip_api_same_slot(const sipSlot *sp, PyObject *rxObj, const char *slot);
|
||||
PyObject *sip_api_invoke_slot(const sipSlot *slot, PyObject *sigargs);
|
||||
PyObject *sip_api_invoke_slot_ex(const sipSlot *slot, PyObject *sigargs,
|
||||
int no_receiver_check);
|
||||
void *sip_api_convert_rx(sipWrapper *txSelf, const char *sigargs,
|
||||
PyObject *rxObj, const char *slot, const char **memberp, int flags);
|
||||
int sip_api_save_slot(sipSlot *sp, PyObject *rxObj, const char *slot);
|
||||
@@ -123,13 +130,13 @@ int sip_api_save_slot(sipSlot *sp, PyObject *rxObj, const char *slot);
|
||||
/*
|
||||
* These are not part of the SIP API but are used within the SIP module.
|
||||
*/
|
||||
sipClassTypeDef *sipGetGeneratedClassType(sipEncodedTypeDef *enc,
|
||||
sipClassTypeDef *sipGetGeneratedClassType(const sipEncodedTypeDef *enc,
|
||||
const sipClassTypeDef *ctd);
|
||||
void sipSaveMethod(sipPyMethod *pm,PyObject *meth);
|
||||
int sipGetPending(void **pp, sipWrapper **op, int *fp);
|
||||
int sipIsPending();
|
||||
PyObject *sipWrapSimpleInstance(void *cppPtr, const sipTypeDef *td,
|
||||
sipWrapper *owner, int initflags);
|
||||
PyObject *sipWrapInstance(void *cpp, PyTypeObject *py_type, PyObject *args,
|
||||
sipWrapper *owner, int flags);
|
||||
void *sipConvertRxEx(sipWrapper *txSelf, const char *sigargs,
|
||||
PyObject *rxObj, const char *slot, const char **memberp, int flags);
|
||||
|
||||
|
||||
1299
sip/siplib/siplib.c
1299
sip/siplib/siplib.c
File diff suppressed because it is too large
Load Diff
@@ -3,7 +3,7 @@
|
||||
* C++ classes that provide a thread interface to interact properly with the
|
||||
* Python threading infrastructure.
|
||||
*
|
||||
* Copyright (c) 2013 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
* Copyright (c) 2015 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
*
|
||||
* This file is part of SIP.
|
||||
*
|
||||
@@ -71,6 +71,9 @@ int sipGetPending(void **pp, sipWrapper **op, int *fp)
|
||||
*op = pd->owner;
|
||||
*fp = pd->flags;
|
||||
|
||||
/* Clear in case we execute Python code before finishing this wrapping. */
|
||||
pd->cpp = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -92,18 +95,13 @@ int sipIsPending()
|
||||
/*
|
||||
* Convert a new C/C++ pointer to a Python instance.
|
||||
*/
|
||||
PyObject *sipWrapSimpleInstance(void *cppPtr, const sipTypeDef *td,
|
||||
PyObject *sipWrapInstance(void *cpp, PyTypeObject *py_type, PyObject *args,
|
||||
sipWrapper *owner, int flags)
|
||||
{
|
||||
static PyObject *nullargs = NULL;
|
||||
|
||||
pendingDef old_pending, *pd;
|
||||
PyObject *self;
|
||||
|
||||
if (nullargs == NULL && (nullargs = PyTuple_New(0)) == NULL)
|
||||
return NULL;
|
||||
|
||||
if (cppPtr == NULL)
|
||||
if (cpp == NULL)
|
||||
{
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;
|
||||
@@ -120,11 +118,11 @@ PyObject *sipWrapSimpleInstance(void *cppPtr, const sipTypeDef *td,
|
||||
|
||||
old_pending = *pd;
|
||||
|
||||
pd->cpp = cppPtr;
|
||||
pd->cpp = cpp;
|
||||
pd->owner = owner;
|
||||
pd->flags = flags;
|
||||
|
||||
self = PyObject_Call((PyObject *)sipTypeAsPyTypeObject(td), nullargs, NULL);
|
||||
self = PyObject_Call((PyObject *)py_type, args, NULL);
|
||||
|
||||
*pd = old_pending;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* SIP library code.
|
||||
*
|
||||
* Copyright (c) 2013 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
* Copyright (c) 2015 Riverbank Computing Limited <info@riverbankcomputing.com>
|
||||
*
|
||||
* This file is part of SIP.
|
||||
*
|
||||
@@ -24,6 +24,7 @@
|
||||
|
||||
#include "sip.h"
|
||||
#include "sipint.h"
|
||||
#include "array.h"
|
||||
|
||||
|
||||
/* The object data structure. */
|
||||
@@ -58,6 +59,7 @@ static void bad_key(PyObject *key);
|
||||
static int check_slice_size(SIP_SSIZE_T size, SIP_SSIZE_T value_size);
|
||||
static PyObject *make_voidptr(void *voidptr, SIP_SSIZE_T size, int rw);
|
||||
static int vp_convertor(PyObject *arg, struct vp_values *vp);
|
||||
static SIP_SSIZE_T get_size_from_arg(sipVoidPtrObject *v, SIP_SSIZE_T size);
|
||||
|
||||
|
||||
#if defined(SIP_USE_PYCAPSULE)
|
||||
@@ -66,6 +68,8 @@ static int vp_convertor(PyObject *arg, struct vp_values *vp);
|
||||
*/
|
||||
static PyObject *sipVoidPtr_ascapsule(sipVoidPtrObject *v, PyObject *arg)
|
||||
{
|
||||
(void)arg;
|
||||
|
||||
return PyCapsule_New(v->voidptr, NULL, NULL);
|
||||
}
|
||||
#endif
|
||||
@@ -77,11 +81,40 @@ static PyObject *sipVoidPtr_ascapsule(sipVoidPtrObject *v, PyObject *arg)
|
||||
*/
|
||||
static PyObject *sipVoidPtr_ascobject(sipVoidPtrObject *v, PyObject *arg)
|
||||
{
|
||||
(void)arg;
|
||||
|
||||
return PyCObject_FromVoidPtr(v->voidptr, NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Implement asarray() for the type.
|
||||
*/
|
||||
static PyObject *sipVoidPtr_asarray(sipVoidPtrObject *v, PyObject *args,
|
||||
PyObject *kw)
|
||||
{
|
||||
static char *kwlist[] = {"size", NULL};
|
||||
|
||||
SIP_SSIZE_T size = -1;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kw,
|
||||
#if PY_VERSION_HEX >= 0x02050000
|
||||
"|n:asarray",
|
||||
#else
|
||||
"|i:asarray",
|
||||
#endif
|
||||
kwlist, &size))
|
||||
return NULL;
|
||||
|
||||
if ((size = get_size_from_arg(v, size)) < 0)
|
||||
return NULL;
|
||||
|
||||
return sip_api_convert_to_array(v->voidptr, "B", size,
|
||||
(v->rw ? 0 : SIP_READ_ONLY));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Implement asstring() for the type.
|
||||
*/
|
||||
@@ -101,16 +134,8 @@ static PyObject *sipVoidPtr_asstring(sipVoidPtrObject *v, PyObject *args,
|
||||
kwlist, &size))
|
||||
return NULL;
|
||||
|
||||
/* Use the current size if one wasn't explicitly given. */
|
||||
if (size < 0)
|
||||
size = v->size;
|
||||
|
||||
if (size < 0)
|
||||
{
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"a size must be given or the sip.voidptr object must have a size");
|
||||
if ((size = get_size_from_arg(v, size)) < 0)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return SIPBytes_FromStringAndSize(v->voidptr, size);
|
||||
}
|
||||
@@ -121,6 +146,8 @@ static PyObject *sipVoidPtr_asstring(sipVoidPtrObject *v, PyObject *args,
|
||||
*/
|
||||
static PyObject *sipVoidPtr_getsize(sipVoidPtrObject *v, PyObject *arg)
|
||||
{
|
||||
(void)arg;
|
||||
|
||||
#if PY_MAJOR_VERSION >= 3
|
||||
return PyLong_FromSsize_t(v->size);
|
||||
#elif PY_VERSION_HEX >= 0x02050000
|
||||
@@ -161,6 +188,8 @@ static PyObject *sipVoidPtr_setsize(sipVoidPtrObject *v, PyObject *arg)
|
||||
*/
|
||||
static PyObject *sipVoidPtr_getwriteable(sipVoidPtrObject *v, PyObject *arg)
|
||||
{
|
||||
(void)arg;
|
||||
|
||||
return PyBool_FromLong(v->rw);
|
||||
}
|
||||
|
||||
@@ -186,21 +215,31 @@ static PyObject *sipVoidPtr_setwriteable(sipVoidPtrObject *v, PyObject *arg)
|
||||
|
||||
/* The methods data structure. */
|
||||
static PyMethodDef sipVoidPtr_Methods[] = {
|
||||
{"asarray", (PyCFunction)sipVoidPtr_asarray, METH_VARARGS|METH_KEYWORDS, NULL},
|
||||
#if defined(SIP_USE_PYCAPSULE)
|
||||
{"ascapsule", (PyCFunction)sipVoidPtr_ascapsule, METH_NOARGS, NULL},
|
||||
#endif
|
||||
#if defined(SIP_SUPPORT_PYCOBJECT)
|
||||
{"ascobject", (PyCFunction)sipVoidPtr_ascobject, METH_NOARGS, NULL},
|
||||
#endif
|
||||
{"asstring", (PyCFunction)sipVoidPtr_asstring, METH_KEYWORDS, NULL},
|
||||
{"asstring", (PyCFunction)sipVoidPtr_asstring, METH_VARARGS|METH_KEYWORDS, NULL},
|
||||
{"getsize", (PyCFunction)sipVoidPtr_getsize, METH_NOARGS, NULL},
|
||||
{"setsize", (PyCFunction)sipVoidPtr_setsize, METH_O, NULL},
|
||||
{"getwriteable", (PyCFunction)sipVoidPtr_getwriteable, METH_NOARGS, NULL},
|
||||
{"setwriteable", (PyCFunction)sipVoidPtr_setwriteable, METH_O, NULL},
|
||||
{NULL}
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* Implement bool() for the type.
|
||||
*/
|
||||
static int sipVoidPtr_bool(PyObject *self)
|
||||
{
|
||||
return (((sipVoidPtrObject *)self)->voidptr != NULL);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Implement int() for the type.
|
||||
*/
|
||||
@@ -240,7 +279,7 @@ static PyNumberMethods sipVoidPtr_NumberMethods = {
|
||||
0, /* nb_negative */
|
||||
0, /* nb_positive */
|
||||
0, /* nb_absolute */
|
||||
0, /* nb_bool (Python v3), nb_nonzero (Python v2) */
|
||||
sipVoidPtr_bool, /* nb_bool (Python v3), nb_nonzero (Python v2) */
|
||||
0, /* nb_invert */
|
||||
0, /* nb_lshift */
|
||||
0, /* nb_rshift */
|
||||
@@ -391,11 +430,18 @@ static PySequenceMethods sipVoidPtr_SequenceMethods = {
|
||||
0, /* sq_concat */
|
||||
0, /* sq_repeat */
|
||||
sipVoidPtr_item, /* sq_item */
|
||||
#if PY_VERSION_HEX < 0x02050000
|
||||
#if PY_VERSION_HEX >= 0x02050000
|
||||
0, /* sq_slice */
|
||||
0, /* sq_ass_item */
|
||||
0, /* sq_ass_slice */
|
||||
#else
|
||||
sipVoidPtr_slice, /* sq_slice */
|
||||
sipVoidPtr_ass_item, /* sq_ass_item */
|
||||
sipVoidPtr_ass_slice, /* sq_ass_slice */
|
||||
#endif
|
||||
0, /* sq_contains */
|
||||
0, /* sq_inplace_concat */
|
||||
0, /* sq_inplace_repeat */
|
||||
};
|
||||
|
||||
|
||||
@@ -741,6 +787,20 @@ PyTypeObject sipVoidPtr_Type = {
|
||||
0, /* tp_init */
|
||||
0, /* tp_alloc */
|
||||
sipVoidPtr_new, /* tp_new */
|
||||
0, /* tp_free */
|
||||
0, /* tp_is_gc */
|
||||
0, /* tp_bases */
|
||||
0, /* tp_mro */
|
||||
0, /* tp_cache */
|
||||
0, /* tp_subclasses */
|
||||
0, /* tp_weaklist */
|
||||
0, /* tp_del */
|
||||
#if PY_VERSION_HEX >= 0x02060000
|
||||
0, /* tp_version_tag */
|
||||
#endif
|
||||
#if PY_VERSION_HEX >= 0x03040000
|
||||
0, /* tp_finalize */
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@@ -986,10 +1046,12 @@ static int vp_convertor(PyObject *arg, struct vp_values *vp)
|
||||
ptr = view.buf;
|
||||
size = view.len;
|
||||
rw = !view.readonly;
|
||||
|
||||
PyBuffer_Release(&view);
|
||||
}
|
||||
#endif
|
||||
#if PY_VERSION_HEX < 0x03000000
|
||||
else if (PyObject_AsReadBuffer(arg, &ptr, &size) >= 0)
|
||||
else if (PyObject_AsReadBuffer(arg, (const void **)&ptr, &size) >= 0)
|
||||
{
|
||||
rw = (Py_TYPE(arg)->tp_as_buffer->bf_getwritebuffer != NULL);
|
||||
}
|
||||
@@ -1016,3 +1078,21 @@ static int vp_convertor(PyObject *arg, struct vp_values *vp)
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Get a size possibly supplied as an argument, otherwise get it from the
|
||||
* object. Raise an exception if there was no size specified.
|
||||
*/
|
||||
static SIP_SSIZE_T get_size_from_arg(sipVoidPtrObject *v, SIP_SSIZE_T size)
|
||||
{
|
||||
/* Use the current size if one wasn't explicitly given. */
|
||||
if (size < 0)
|
||||
size = v->size;
|
||||
|
||||
if (size < 0)
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"a size must be given or the sip.voidptr object must have a size");
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user