| /***************************************************************** |
| This file contains remnant Python 2.3 compatibility code that is no longer |
| strictly required. |
| *****************************************************************/ |
| |
| #if defined (__SVR4) && defined (__sun) |
| # include <alloca.h> |
| #endif |
| |
| #if (PY_VERSION_HEX < 0x02040000) |
| #define PyDict_CheckExact(ob) (Py_TYPE(ob) == &PyDict_Type) |
| #endif |
| |
| #if (PY_VERSION_HEX < 0x02050000) |
| typedef int Py_ssize_t; |
| #define PyInt_FromSsize_t PyInt_FromLong |
| #define PyNumber_AsSsize_t(ob, exc) PyInt_AsLong(ob) |
| #define PyIndex_Check(ob) PyInt_Check(ob) |
| typedef Py_ssize_t (*readbufferproc)(PyObject *, Py_ssize_t, void **); |
| typedef Py_ssize_t (*writebufferproc)(PyObject *, Py_ssize_t, void **); |
| typedef Py_ssize_t (*segcountproc)(PyObject *, Py_ssize_t *); |
| typedef Py_ssize_t (*charbufferproc)(PyObject *, Py_ssize_t, char **); |
| #endif |
| |
| #if (PY_VERSION_HEX < 0x02060000) |
| #define Py_TYPE(ob) (((PyObject*)(ob))->ob_type) |
| #define PyVarObject_HEAD_INIT(type, size) \ |
| PyObject_HEAD_INIT(type) size, |
| #define PyImport_ImportModuleNoBlock PyImport_ImportModule |
| #define PyLong_FromSsize_t PyInt_FromLong |
| #define Py_TPFLAGS_HAVE_NEWBUFFER 0 |
| #endif |
| |
| |
| #ifndef MS_WIN32 |
| #define max(a, b) ((a) > (b) ? (a) : (b)) |
| #define min(a, b) ((a) < (b) ? (a) : (b)) |
| |
| #define PARAMFLAG_FIN 0x1 |
| #define PARAMFLAG_FOUT 0x2 |
| #define PARAMFLAG_FLCID 0x4 |
| #endif |
| |
| /* |
| Backwards compatibility: |
| Python2.2 used LONG_LONG instead of PY_LONG_LONG |
| */ |
| #if defined(HAVE_LONG_LONG) && !defined(PY_LONG_LONG) |
| #define PY_LONG_LONG LONG_LONG |
| #endif |
| |
| typedef struct tagPyCArgObject PyCArgObject; |
| typedef struct tagCDataObject CDataObject; |
| typedef PyObject *(* GETFUNC)(void *, Py_ssize_t size); |
| typedef PyObject *(* SETFUNC)(void *, PyObject *value, Py_ssize_t size); |
| typedef PyCArgObject *(* PARAMFUNC)(CDataObject *obj); |
| |
| /* A default buffer in CDataObject, which can be used for small C types. If |
| this buffer is too small, PyMem_Malloc will be called to create a larger one, |
| and this one is not used. |
| |
| Making CDataObject a variable size object would be a better solution, but more |
| difficult in the presence of PyCFuncPtrObject. Maybe later. |
| */ |
| union value { |
| char c[16]; |
| short s; |
| int i; |
| long l; |
| float f; |
| double d; |
| #ifdef HAVE_LONG_LONG |
| PY_LONG_LONG ll; |
| #endif |
| long double D; |
| }; |
| |
| /* |
| Hm. Are there CDataObject's which do not need the b_objects member? In |
| this case we probably should introduce b_flags to mark it as present... If |
| b_objects is not present/unused b_length is unneeded as well. |
| */ |
| |
| struct tagCDataObject { |
| PyObject_HEAD |
| char *b_ptr; /* pointer to memory block */ |
| int b_needsfree; /* need _we_ free the memory? */ |
| CDataObject *b_base; /* pointer to base object or NULL */ |
| Py_ssize_t b_size; /* size of memory block in bytes */ |
| Py_ssize_t b_length; /* number of references we need */ |
| Py_ssize_t b_index; /* index of this object into base's |
| b_object list */ |
| PyObject *b_objects; /* dictionary of references we need to keep, or Py_None */ |
| union value b_value; |
| }; |
| |
| typedef struct { |
| PyObject_VAR_HEAD |
| ffi_closure *pcl_write; /* the C callable, writeable */ |
| void *pcl_exec; /* the C callable, executable */ |
| ffi_cif cif; |
| int flags; |
| PyObject *converters; |
| PyObject *callable; |
| PyObject *restype; |
| SETFUNC setfunc; |
| ffi_type *ffi_restype; |
| ffi_type *atypes[1]; |
| } CThunkObject; |
| extern PyTypeObject PyCThunk_Type; |
| #define CThunk_CheckExact(v) ((v)->ob_type == &PyCThunk_Type) |
| |
| typedef struct { |
| /* First part identical to tagCDataObject */ |
| PyObject_HEAD |
| char *b_ptr; /* pointer to memory block */ |
| int b_needsfree; /* need _we_ free the memory? */ |
| CDataObject *b_base; /* pointer to base object or NULL */ |
| Py_ssize_t b_size; /* size of memory block in bytes */ |
| Py_ssize_t b_length; /* number of references we need */ |
| Py_ssize_t b_index; /* index of this object into base's |
| b_object list */ |
| PyObject *b_objects; /* list of references we need to keep */ |
| union value b_value; |
| /* end of tagCDataObject, additional fields follow */ |
| |
| CThunkObject *thunk; |
| PyObject *callable; |
| |
| /* These two fields will override the ones in the type's stgdict if |
| they are set */ |
| PyObject *converters; |
| PyObject *argtypes; |
| PyObject *restype; |
| PyObject *checker; |
| PyObject *errcheck; |
| #ifdef MS_WIN32 |
| int index; |
| GUID *iid; |
| #endif |
| PyObject *paramflags; |
| } PyCFuncPtrObject; |
| |
| extern PyTypeObject PyCStgDict_Type; |
| #define PyCStgDict_CheckExact(v) ((v)->ob_type == &PyCStgDict_Type) |
| #define PyCStgDict_Check(v) PyObject_TypeCheck(v, &PyCStgDict_Type) |
| |
| extern int PyCStructUnionType_update_stgdict(PyObject *fields, PyObject *type, int isStruct); |
| extern int PyType_stginfo(PyTypeObject *self, Py_ssize_t *psize, Py_ssize_t *palign, Py_ssize_t *plength); |
| extern int PyObject_stginfo(PyObject *self, Py_ssize_t *psize, Py_ssize_t *palign, Py_ssize_t *plength); |
| |
| |
| |
| extern PyTypeObject PyCData_Type; |
| #define CDataObject_CheckExact(v) ((v)->ob_type == &PyCData_Type) |
| #define CDataObject_Check(v) PyObject_TypeCheck(v, &PyCData_Type) |
| #define _CDataObject_HasExternalBuffer(v) ((v)->b_ptr != (char *)&(v)->b_value) |
| |
| extern PyTypeObject PyCSimpleType_Type; |
| #define PyCSimpleTypeObject_CheckExact(v) ((v)->ob_type == &PyCSimpleType_Type) |
| #define PyCSimpleTypeObject_Check(v) PyObject_TypeCheck(v, &PyCSimpleType_Type) |
| |
| extern PyTypeObject PyCField_Type; |
| extern struct fielddesc *_ctypes_get_fielddesc(char *fmt); |
| |
| |
| extern PyObject * |
| PyCField_FromDesc(PyObject *desc, Py_ssize_t index, |
| Py_ssize_t *pfield_size, int bitsize, int *pbitofs, |
| Py_ssize_t *psize, Py_ssize_t *poffset, Py_ssize_t *palign, |
| int pack, int is_big_endian); |
| |
| extern PyObject *PyCData_AtAddress(PyObject *type, void *buf); |
| extern PyObject *PyCData_FromBytes(PyObject *type, char *data, Py_ssize_t length); |
| |
| extern PyTypeObject PyCArrayType_Type; |
| extern PyTypeObject PyCArray_Type; |
| extern PyTypeObject PyCPointerType_Type; |
| extern PyTypeObject PyCPointer_Type; |
| extern PyTypeObject PyCFuncPtr_Type; |
| extern PyTypeObject PyCFuncPtrType_Type; |
| extern PyTypeObject PyCStructType_Type; |
| |
| #define PyCArrayTypeObject_Check(v) PyObject_TypeCheck(v, &PyCArrayType_Type) |
| #define ArrayObject_Check(v) PyObject_TypeCheck(v, &PyCArray_Type) |
| #define PointerObject_Check(v) PyObject_TypeCheck(v, &PyCPointer_Type) |
| #define PyCPointerTypeObject_Check(v) PyObject_TypeCheck(v, &PyCPointerType_Type) |
| #define PyCFuncPtrObject_Check(v) PyObject_TypeCheck(v, &PyCFuncPtr_Type) |
| #define PyCFuncPtrTypeObject_Check(v) PyObject_TypeCheck(v, &PyCFuncPtrType_Type) |
| #define PyCStructTypeObject_Check(v) PyObject_TypeCheck(v, &PyCStructType_Type) |
| |
| extern PyObject * |
| PyCArrayType_from_ctype(PyObject *itemtype, Py_ssize_t length); |
| |
| extern PyMethodDef _ctypes_module_methods[]; |
| |
| extern CThunkObject *_ctypes_alloc_callback(PyObject *callable, |
| PyObject *converters, |
| PyObject *restype, |
| int flags); |
| /* a table entry describing a predefined ctypes type */ |
| struct fielddesc { |
| char code; |
| SETFUNC setfunc; |
| GETFUNC getfunc; |
| ffi_type *pffi_type; /* always statically allocated */ |
| SETFUNC setfunc_swapped; |
| GETFUNC getfunc_swapped; |
| }; |
| |
| typedef struct { |
| PyObject_HEAD |
| Py_ssize_t offset; |
| Py_ssize_t size; |
| Py_ssize_t index; /* Index into CDataObject's |
| object array */ |
| PyObject *proto; /* a type or NULL */ |
| GETFUNC getfunc; /* getter function if proto is NULL */ |
| SETFUNC setfunc; /* setter function if proto is NULL */ |
| int anonymous; |
| } CFieldObject; |
| |
| /* A subclass of PyDictObject, used as the instance dictionary of ctypes |
| metatypes */ |
| typedef struct { |
| PyDictObject dict; /* first part identical to PyDictObject */ |
| /* The size and align fields are unneeded, they are in ffi_type as well. As |
| an experiment shows, it's trivial to get rid of them, the only thing to |
| remember is that in PyCArrayType_new the ffi_type fields must be filled in - |
| so far it was unneeded because libffi doesn't support arrays at all |
| (because they are passed as pointers to function calls anyway). But it's |
| too much risk to change that now, and there are other fields which doesn't |
| belong into this structure anyway. Maybe in ctypes 2.0... (ctypes 2000?) |
| */ |
| Py_ssize_t size; /* number of bytes */ |
| Py_ssize_t align; /* alignment requirements */ |
| Py_ssize_t length; /* number of fields */ |
| ffi_type ffi_type_pointer; |
| PyObject *proto; /* Only for Pointer/ArrayObject */ |
| SETFUNC setfunc; /* Only for simple objects */ |
| GETFUNC getfunc; /* Only for simple objects */ |
| PARAMFUNC paramfunc; |
| |
| /* Following fields only used by PyCFuncPtrType_Type instances */ |
| PyObject *argtypes; /* tuple of CDataObjects */ |
| PyObject *converters; /* tuple([t.from_param for t in argtypes]) */ |
| PyObject *restype; /* CDataObject or NULL */ |
| PyObject *checker; |
| int flags; /* calling convention and such */ |
| |
| /* pep3118 fields, pointers neeed PyMem_Free */ |
| char *format; |
| int ndim; |
| Py_ssize_t *shape; |
| /* Py_ssize_t *strides; */ /* unused in ctypes */ |
| /* Py_ssize_t *suboffsets; */ /* unused in ctypes */ |
| |
| } StgDictObject; |
| |
| /**************************************************************** |
| StgDictObject fields |
| |
| setfunc and getfunc is only set for simple data types, it is copied from the |
| corresponding fielddesc entry. These are functions to set and get the value |
| in a memory block. |
| They should probably by used by other types as well. |
| |
| proto is only used for Pointer and Array types - it points to the item type |
| object. |
| |
| Probably all the magic ctypes methods (like from_param) should have C |
| callable wrappers in the StgDictObject. For simple data type, for example, |
| the fielddesc table could have entries for C codec from_param functions or |
| other methods as well, if a subtype overrides this method in Python at |
| construction time, or assigns to it later, tp_setattro should update the |
| StgDictObject function to a generic one. |
| |
| Currently, PyCFuncPtr types have 'converters' and 'checker' entries in their |
| type dict. They are only used to cache attributes from other entries, which |
| is wrong. |
| |
| One use case is the .value attribute that all simple types have. But some |
| complex structures, like VARIANT, represent a single value also, and should |
| have this attribute. |
| |
| Another use case is a _check_retval_ function, which is called when a ctypes |
| type is used as return type of a function to validate and compute the return |
| value. |
| |
| Common ctypes protocol: |
| |
| - setfunc: store a python value in a memory block |
| - getfunc: convert data from a memory block into a python value |
| |
| - checkfunc: validate and convert a return value from a function call |
| - toparamfunc: convert a python value into a function argument |
| |
| *****************************************************************/ |
| |
| /* May return NULL, but does not set an exception! */ |
| extern StgDictObject *PyType_stgdict(PyObject *obj); |
| |
| /* May return NULL, but does not set an exception! */ |
| extern StgDictObject *PyObject_stgdict(PyObject *self); |
| |
| extern int PyCStgDict_clone(StgDictObject *src, StgDictObject *dst); |
| |
| typedef int(* PPROC)(void); |
| |
| PyObject *_ctypes_callproc(PPROC pProc, |
| PyObject *arguments, |
| #ifdef MS_WIN32 |
| IUnknown *pIUnk, |
| GUID *iid, |
| #endif |
| int flags, |
| PyObject *argtypes, |
| PyObject *restype, |
| PyObject *checker); |
| |
| |
| #define FUNCFLAG_STDCALL 0x0 |
| #define FUNCFLAG_CDECL 0x1 |
| #define FUNCFLAG_HRESULT 0x2 |
| #define FUNCFLAG_PYTHONAPI 0x4 |
| #define FUNCFLAG_USE_ERRNO 0x8 |
| #define FUNCFLAG_USE_LASTERROR 0x10 |
| |
| #define TYPEFLAG_ISPOINTER 0x100 |
| #define TYPEFLAG_HASPOINTER 0x200 |
| |
| #define DICTFLAG_FINAL 0x1000 |
| |
| struct tagPyCArgObject { |
| PyObject_HEAD |
| ffi_type *pffi_type; |
| char tag; |
| union { |
| char c; |
| char b; |
| short h; |
| int i; |
| long l; |
| #ifdef HAVE_LONG_LONG |
| PY_LONG_LONG q; |
| #endif |
| long double D; |
| double d; |
| float f; |
| void *p; |
| } value; |
| PyObject *obj; |
| Py_ssize_t size; /* for the 'V' tag */ |
| }; |
| |
| extern PyTypeObject PyCArg_Type; |
| #define PyCArg_CheckExact(v) ((v)->ob_type == &PyCArg_Type) |
| extern PyCArgObject *PyCArgObject_new(void); |
| |
| extern PyObject * |
| PyCData_get(PyObject *type, GETFUNC getfunc, PyObject *src, |
| Py_ssize_t index, Py_ssize_t size, char *ptr); |
| |
| extern int |
| PyCData_set(PyObject *dst, PyObject *type, SETFUNC setfunc, PyObject *value, |
| Py_ssize_t index, Py_ssize_t size, char *ptr); |
| |
| extern void _ctypes_extend_error(PyObject *exc_class, char *fmt, ...); |
| |
| struct basespec { |
| CDataObject *base; |
| Py_ssize_t index; |
| char *adr; |
| }; |
| |
| extern char basespec_string[]; |
| |
| extern ffi_type *_ctypes_get_ffi_type(PyObject *obj); |
| |
| /* exception classes */ |
| extern PyObject *PyExc_ArgError; |
| |
| extern char *_ctypes_conversion_encoding; |
| extern char *_ctypes_conversion_errors; |
| |
| /* Python 2.4 macros, which are not available in Python 2.3 */ |
| |
| #ifndef Py_CLEAR |
| #define Py_CLEAR(op) \ |
| do { \ |
| if (op) { \ |
| PyObject *tmp = (PyObject *)(op); \ |
| (op) = NULL; \ |
| Py_DECREF(tmp); \ |
| } \ |
| } while (0) |
| #endif |
| |
| #ifndef Py_VISIT |
| /* Utility macro to help write tp_traverse functions. |
| * To use this macro, the tp_traverse function must name its arguments |
| * "visit" and "arg". This is intended to keep tp_traverse functions |
| * looking as much alike as possible. |
| */ |
| #define Py_VISIT(op) \ |
| do { \ |
| if (op) { \ |
| int vret = visit((op), arg); \ |
| if (vret) \ |
| return vret; \ |
| } \ |
| } while (0) |
| #endif |
| |
| /* Python's PyUnicode_*WideChar functions are broken ... */ |
| #if defined(Py_USING_UNICODE) && defined(HAVE_WCHAR_H) |
| # define CTYPES_UNICODE |
| #endif |
| |
| |
| #if (PY_VERSION_HEX < 0x02040000) |
| #ifdef CTYPES_UNICODE |
| # undef PyUnicode_FromWideChar |
| # define PyUnicode_FromWideChar PyUnicode_FromWideChar_fixed |
| |
| # undef PyUnicode_AsWideChar |
| # define PyUnicode_AsWideChar PyUnicode_AsWideChar_fixed |
| |
| extern PyObject *PyUnicode_FromWideChar_fixed(const wchar_t *, Py_ssize_t); |
| extern Py_ssize_t PyUnicode_AsWideChar_fixed(PyUnicodeObject *, wchar_t *, Py_ssize_t); |
| #endif |
| #endif |
| |
| extern void _ctypes_add_traceback(char *, char *, int); |
| |
| extern PyObject *PyCData_FromBaseObj(PyObject *type, PyObject *base, Py_ssize_t index, char *adr); |
| extern char *_ctypes_alloc_format_string(const char *prefix, const char *suffix); |
| extern char *_ctypes_alloc_format_string_with_shape(int ndim, |
| const Py_ssize_t *shape, |
| const char *prefix, const char *suffix); |
| |
| extern int _ctypes_simple_instance(PyObject *obj); |
| |
| extern PyObject *_ctypes_ptrtype_cache; |
| PyObject *_ctypes_get_errobj(int **pspace); |
| |
| #ifdef MS_WIN32 |
| extern PyObject *ComError; |
| #endif |
| |
| #if PY_VERSION_HEX >= 0x020700A4 |
| /* Use PyCapsule for 2.7 */ |
| |
| #define CTYPES_USING_CAPSULE |
| |
| #define CTYPES_CAPSULE_INSTANTIATE_DESTRUCTOR(name) \ |
| static void capsule_destructor_ ## name(PyObject *ptr) \ |
| { \ |
| void *p = PyCapsule_GetPointer(ptr, name); \ |
| if (p) { \ |
| PyMem_Free(p); \ |
| } \ |
| } \ |
| |
| #define CAPSULE_NEW(pointer, name) \ |
| (PyCapsule_New(pointer, name, capsule_destructor_ ## name)) |
| |
| #define CAPSULE_DEREFERENCE(capsule, name) \ |
| (PyCapsule_GetPointer(capsule, name)) |
| |
| #else /* PY_VERSION_HEX >= 0x020700A4 */ |
| /* Use CObject for 2.6 and before */ |
| |
| #define CTYPES_CAPSULE_INSTANTIATE_DESTRUCTOR(name) |
| |
| #define CAPSULE_NEW(pointer, name) \ |
| (PyCObject_FromVoidPtr(pointer, PyMem_Free)) |
| |
| #define CAPSULE_DEREFERENCE(capsule, name) \ |
| (PyCObject_AsVoidPtr(capsule)) |
| |
| #endif /* PY_VERSION_HEX >= 0x020700A4 */ |
| |
| |
| /* |
| Local Variables: |
| compile-command: "python setup.py -q build install --home ~" |
| End: |
| */ |