mirror of https://github.com/python/cpython
135 lines
3.3 KiB
C
135 lines
3.3 KiB
C
#ifndef __CAPSULETHUNK_H
|
|
#define __CAPSULETHUNK_H
|
|
|
|
#if ( (PY_VERSION_HEX < 0x02070000) \
|
|
|| ((PY_VERSION_HEX >= 0x03000000) \
|
|
&& (PY_VERSION_HEX < 0x03010000)) )
|
|
|
|
#define __PyCapsule_GetField(capsule, field, default_value) \
|
|
( PyCapsule_CheckExact(capsule) \
|
|
? (((PyCObject *)capsule)->field) \
|
|
: (default_value) \
|
|
) \
|
|
|
|
#define __PyCapsule_SetField(capsule, field, value) \
|
|
( PyCapsule_CheckExact(capsule) \
|
|
? (((PyCObject *)capsule)->field = value), 1 \
|
|
: 0 \
|
|
) \
|
|
|
|
|
|
#define PyCapsule_Type PyCObject_Type
|
|
|
|
#define PyCapsule_CheckExact(capsule) (PyCObject_Check(capsule))
|
|
#define PyCapsule_IsValid(capsule, name) (PyCObject_Check(capsule))
|
|
|
|
|
|
#define PyCapsule_New(pointer, name, destructor) \
|
|
(PyCObject_FromVoidPtr(pointer, destructor))
|
|
|
|
|
|
#define PyCapsule_GetPointer(capsule, name) \
|
|
(PyCObject_AsVoidPtr(capsule))
|
|
|
|
/* Don't call PyCObject_SetPointer here, it fails if there's a destructor */
|
|
#define PyCapsule_SetPointer(capsule, pointer) \
|
|
__PyCapsule_SetField(capsule, cobject, pointer)
|
|
|
|
|
|
#define PyCapsule_GetDestructor(capsule) \
|
|
__PyCapsule_GetField(capsule, destructor)
|
|
|
|
#define PyCapsule_SetDestructor(capsule, dtor) \
|
|
__PyCapsule_SetField(capsule, destructor, dtor)
|
|
|
|
|
|
/*
|
|
* Sorry, there's simply no place
|
|
* to store a Capsule "name" in a CObject.
|
|
*/
|
|
#define PyCapsule_GetName(capsule) NULL
|
|
|
|
static int
|
|
PyCapsule_SetName(PyObject *capsule, const char *unused)
|
|
{
|
|
unused = unused;
|
|
PyErr_SetString(PyExc_NotImplementedError,
|
|
"can't use PyCapsule_SetName with CObjects");
|
|
return 1;
|
|
}
|
|
|
|
|
|
|
|
#define PyCapsule_GetContext(capsule) \
|
|
__PyCapsule_GetField(capsule, descr)
|
|
|
|
#define PyCapsule_SetContext(capsule, context) \
|
|
__PyCapsule_SetField(capsule, descr, context)
|
|
|
|
|
|
static void *
|
|
PyCapsule_Import(const char *name, int no_block)
|
|
{
|
|
PyObject *object = NULL;
|
|
void *return_value = NULL;
|
|
char *trace;
|
|
size_t name_length = (strlen(name) + 1) * sizeof(char);
|
|
char *name_dup = (char *)PyMem_MALLOC(name_length);
|
|
|
|
if (!name_dup) {
|
|
return NULL;
|
|
}
|
|
|
|
memcpy(name_dup, name, name_length);
|
|
|
|
trace = name_dup;
|
|
while (trace) {
|
|
char *dot = strchr(trace, '.');
|
|
if (dot) {
|
|
*dot++ = '\0';
|
|
}
|
|
|
|
if (object == NULL) {
|
|
if (no_block) {
|
|
object = PyImport_ImportModuleNoBlock(trace);
|
|
} else {
|
|
object = PyImport_ImportModule(trace);
|
|
if (!object) {
|
|
PyErr_Format(PyExc_ImportError,
|
|
"PyCapsule_Import could not "
|
|
"import module \"%s\"", trace);
|
|
}
|
|
}
|
|
} else {
|
|
PyObject *object2 = PyObject_GetAttrString(object, trace);
|
|
Py_DECREF(object);
|
|
object = object2;
|
|
}
|
|
if (!object) {
|
|
goto EXIT;
|
|
}
|
|
|
|
trace = dot;
|
|
}
|
|
|
|
if (PyCObject_Check(object)) {
|
|
PyCObject *cobject = (PyCObject *)object;
|
|
return_value = cobject->cobject;
|
|
} else {
|
|
PyErr_Format(PyExc_AttributeError,
|
|
"PyCapsule_Import \"%s\" is not valid",
|
|
name);
|
|
}
|
|
|
|
EXIT:
|
|
Py_XDECREF(object);
|
|
if (name_dup) {
|
|
PyMem_FREE(name_dup);
|
|
}
|
|
return return_value;
|
|
}
|
|
|
|
#endif /* #if PY_VERSION_HEX < 0x02070000 */
|
|
|
|
#endif /* __CAPSULETHUNK_H */
|