1#ifndef PyObjC_API_H
2#define PyObjC_API_H
3
4/*
5 * Use this in helper modules for the objc package, and in wrappers
6 * for functions that deal with objective-C objects/classes
7 *
8 * This header defines some utility wrappers for importing and using
9 * the core bridge.
10 *
11 * This is the *only* header file that should be used to access
12 * functionality in the core bridge.
13 *
14 * WARNING: this file is not part of the public interface of PyObjC and
15 * might change or be removed without warning or regard for backward
16 * compatibility.
17 */
18
19#include "Python.h"
20#include <objc/objc.h>
21
22#ifndef PyObjC_COMPAT_H
23#if (PY_VERSION_HEX < 0x02050000)
24typedef int Py_ssize_t;
25#define PY_FORMAT_SIZE_T ""
26#define Py_ARG_SIZE_T "n"
27#define PY_SSIZE_T_MAX INT_MAX
28
29#else
30
31#define Py_ARG_SIZE_T "i"
32#endif
33#endif
34
35
36#import <Foundation/NSException.h>
37
38struct PyObjC_WeakLink {
39	const char* name;
40	void (*func)(void);
41};
42
43
44/* threading support */
45#define PyObjC_DURING \
46		Py_BEGIN_ALLOW_THREADS \
47		NS_DURING
48
49#define PyObjC_HANDLER NS_HANDLER
50
51#define PyObjC_ENDHANDLER \
52		NS_ENDHANDLER \
53		Py_END_ALLOW_THREADS
54
55#define PyObjC_BEGIN_WITH_GIL \
56	{ \
57		PyGILState_STATE _GILState; \
58		_GILState = PyGILState_Ensure();
59
60#define PyObjC_GIL_FORWARD_EXC() \
61		do { \
62            PyObjCErr_ToObjCWithGILState(&_GILState); \
63		} while (0)
64
65
66#define PyObjC_GIL_RETURN(val) \
67		do { \
68			PyGILState_Release(_GILState); \
69			return (val); \
70		} while (0)
71
72#define PyObjC_GIL_RETURNVOID \
73		do { \
74			PyGILState_Release(_GILState); \
75			return; \
76		} while (0)
77
78
79#define PyObjC_END_WITH_GIL \
80		PyGILState_Release(_GILState); \
81	}
82
83
84
85#include <objc/objc-runtime.h>
86
87/* On 10.1 there are no defines for the OS version. */
88#ifndef MAC_OS_X_VERSION_10_1
89#define MAC_OS_X_VERSION_10_1 1010
90#define MAC_OS_X_VERSION_MAX_ALLOWED MAC_OS_X_VERSION_10_1
91
92#error "MAC_OS_X_VERSION_10_1 not defined. You aren't running 10.1 are you?"
93
94#endif
95
96#ifndef MAC_OS_X_VERSION_10_2
97#define MAC_OS_X_VERSION_10_2 1020
98#endif
99
100#ifndef MAC_OS_X_VERSION_10_3
101#define MAC_OS_X_VERSION_10_3 1030
102#endif
103
104#ifndef MAC_OS_X_VERSION_10_4
105#define MAC_OS_X_VERSION_10_4 1040
106#endif
107
108#ifndef MAC_OS_X_VERSION_10_5
109#define MAC_OS_X_VERSION_10_5 1050
110#endif
111
112/* Current API version, increase whenever:
113 * - Semantics of current functions change
114 * - Functions are removed
115 * Do not increase when adding a new function, the struct_len field
116 * can be used for detecting if a function has been added.
117 *
118 * HISTORY:
119 * - Version 2.2 adds PyObjCUnsupportedMethod_IMP
120 *       and PyObjCUnsupportedMethod_Caller
121 * - Version 2.1 adds PyObjCPointerWrapper_Register
122 * - Version 2 adds an argument to PyObjC_InitSuper
123 * - Version 3 adds another argument to PyObjC_CallPython
124 * - Version 4 adds PyObjCErr_ToObjCGILState
125 * - Version 4.1 adds PyObjCRT_AlignOfType and PyObjCRT_SizeOfType
126 *         (PyObjC_SizeOfType is now deprecated)
127 * - Version 4.2 adds PyObjCRT_SELName
128 * - Version 4.3 adds PyObjCRT_SimplifySignature
129 * - Version 4.4 adds PyObjC_FreeCArray, PyObjC_PythonToCArray and
130 *   		PyObjC_CArrayToPython
131 * - Version 5 modifies the signature for PyObjC_RegisterMethodMapping,
132 *	PyObjC_RegisterSignatureMapping and PyObjCUnsupportedMethod_IMP,
133 *      adds PyObjC_RegisterStructType and removes PyObjC_CallPython
134 * - Version 6 adds PyObjCIMP_Type, PyObjCIMP_GetIMP and PyObjCIMP_GetSelector
135 * - Version 7 adds PyObjCErr_AsExc, PyGILState_Ensure
136 * - Version 8 adds PyObjCObject_IsUninitialized,
137        removes PyObjCSelector_IsInitializer
138 * - Version 9 (???)
139 * - Version 10 changes the signature of PyObjCRT_SimplifySignature
140 * - Version 11 adds PyObjCObject_Convert, PyObjCSelector_Convert,
141     PyObjCClass_Convert, PyObjC_ConvertBOOL, and PyObjC_ConvertChar
142 * - Version 12 adds PyObjCObject_New
143 * - Version 13 adds PyObjCCreateOpaquePointerType
144 * - Version 14 adds PyObjCObject_NewTransient, PyObjCObject_ReleaseTransient
145 * - Version 15 changes the interface of PyObjCObject_New
146 * - Version 16 adds PyObjC_PerformWeaklinking
147 * - Version 17 introduces Py_ssize_t support
148 * - Version 18 introduces several API incompatibilities
149 */
150#define PYOBJC_API_VERSION 18
151
152#define PYOBJC_API_NAME "__C_API__"
153
154/*
155 * Only add items to the end of this list!
156 */
157typedef int (RegisterMethodMappingFunctionType)(
158			Class,
159			SEL,
160			PyObject *(*)(PyObject*, PyObject*, PyObject*),
161			void (*)(void*, void*, void**, void*));
162
163struct pyobjc_api {
164	int	      api_version;	/* API version */
165	size_t	      struct_len;	/* Length of this struct */
166	PyTypeObject* class_type;	/* PyObjCClass_Type    */
167	PyTypeObject* object_type;	/* PyObjCObject_Type   */
168	PyTypeObject* select_type;	/* PyObjCSelector_Type */
169
170	/* PyObjC_RegisterMethodMapping */
171	RegisterMethodMappingFunctionType *register_method_mapping;
172
173	/* PyObjC_RegisterSignatureMapping */
174	int (*register_signature_mapping)(
175			char*,
176			PyObject *(*)(PyObject*, PyObject*, PyObject*),
177			void (*)(void*, void*, void**, void*));
178
179	/* PyObjCObject_GetObject */
180	id (*obj_get_object)(PyObject*);
181
182	/* PyObjCObject_ClearObject */
183	void (*obj_clear_object)(PyObject*);
184
185	/* PyObjCClass_GetClass */
186	Class (*cls_get_class)(PyObject*);
187
188	/* PyObjCClass_New */
189	PyObject* (*cls_to_python)(Class cls);
190
191	/* PyObjC_PythonToId */
192	id (*python_to_id)(PyObject*);
193
194	/* PyObjC_IdToPython */
195	PyObject* (*id_to_python)(id);
196
197	/* PyObjCErr_FromObjC */
198	void (*err_objc_to_python)(NSException*);
199
200	/* PyObjCErr_ToObjC */
201	void (*err_python_to_objc)(void);
202
203	/* PyObjC_PythonToObjC */
204	int (*py_to_objc)(const char*, PyObject*, void*);
205
206	/* PyObjC_ObjCToPython */
207	PyObject* (*objc_to_py)(const char*, void*);
208
209	/* PyObjC_SizeOfType */
210	Py_ssize_t   (*sizeof_type)(const char*);
211
212	/* PyObjCSelector_GetClass */
213	Class	   (*sel_get_class)(PyObject* sel);
214
215	/* PyObjCSelector_GetSelector */
216	SEL	   (*sel_get_sel)(PyObject* sel);
217
218	/* PyObjC_InitSuper */
219	void	(*fill_super)(struct objc_super*, Class, id);
220
221	/* PyObjC_InitSuperCls */
222	void	(*fill_super_cls)(struct objc_super*, Class, Class);
223
224	/* PyObjCPointerWrapper_Register */
225	int  (*register_pointer_wrapper)(
226		        const char*, PyObject* (*pythonify)(void*),
227			int (*depythonify)(PyObject*, void*)
228		);
229
230	void (*unsupported_method_imp)(void*, void*, void**, void*);
231	PyObject* (*unsupported_method_caller)(PyObject*, PyObject*, PyObject*);
232
233	/* PyObjCErr_ToObjCWithGILState */
234	void (*err_python_to_objc_gil)(PyGILState_STATE* state);
235
236	/* PyObjCRT_AlignOfType */
237	Py_ssize_t (*alignof_type)(const char* typestr);
238
239	/* PyObjCRT_SELName */
240	const char* (*selname)(SEL sel);
241
242	/* PyObjCRT_SimplifySignature */
243	int (*simplify_sig)(char* signature, char* buf, size_t buflen);
244
245	/* PyObjC_FreeCArray */
246	void    (*free_c_array)(int,void*);
247
248	/* PyObjC_PythonToCArray */
249	int     (*py_to_c_array)(BOOL, BOOL, const char*, PyObject*, void**, Py_ssize_t*, PyObject**);
250
251	/* PyObjC_CArrayToPython */
252	PyObject* (*c_array_to_py)(const char*, void*, Py_ssize_t);
253
254	/* PyObjC_RegisterStructType */
255	PyObject* (*register_struct)(const char*, const char*, const char*, initproc, Py_ssize_t, const char**);
256
257	/* PyObjCIMP_Type */
258	PyTypeObject* imp_type;
259
260	/* PyObjCIMP_GetIMP */
261	IMP  (*imp_get_imp)(PyObject*);
262
263	/* PyObjCIMP_GetSelector */
264	SEL  (*imp_get_sel)(PyObject*);
265
266	/* PyObjCErr_AsExc */
267	NSException* (*err_python_to_nsexception)(void);
268
269	/* PyGILState_Ensure */
270	PyGILState_STATE (*gilstate_ensure)(void);
271
272	/* PyObjCObject_IsUninitialized */
273	int (*obj_is_uninitialized)(PyObject*);
274
275	/* PyObjCObject_Convert */
276	int (*pyobjcobject_convert)(PyObject*,void*);
277
278	/* PyObjCSelector_Convert */
279	int (*pyobjcselector_convert)(PyObject*,void*);
280
281	/* PyObjCClass_Convert */
282	int (*pyobjcclass_convert)(PyObject*,void*);
283
284	/* PyObjC_ConvertBOOL */
285	int (*pyobjc_convertbool)(PyObject*,void*);
286
287	/* PyObjC_ConvertChar */
288	int (*pyobjc_convertchar)(PyObject*,void*);
289
290	/* PyObjCObject_New */
291	PyObject* (*pyobjc_object_new)(id, int , int);
292
293	/* PyObjCCreateOpaquePointerType */
294	PyObject* (*pointer_type_new)(const char*, const char*, const char*);
295
296	/* PyObject* PyObjCObject_NewTransient(id objc_object, int* cookie); */
297	PyObject* (*newtransient)(id objc_object, int* cookie);
298
299	/* void PyObjCObject_ReleaseTransient(PyObject* proxy, int cookie); */
300	void (*releasetransient)(PyObject* proxy, int cookie);
301
302	void (*doweaklink)(PyObject*, struct PyObjC_WeakLink*);
303
304	const char* (*removefields)(char*, const char*);
305
306	PyObject** pyobjc_null;
307
308	int (*dep_c_array_count)(const char* type, Py_ssize_t count, BOOL strict, PyObject* value, void* datum);
309
310	PyObject* (*varlistnew)(const char* tp, void* array);
311};
312
313#ifndef PYOBJC_BUILD
314
315#ifndef PYOBJC_METHOD_STUB_IMPL
316static struct pyobjc_api*	PyObjC_API;
317#endif /* PYOBJC_METHOD_STUB_IMPL */
318
319#define PyObjCObject_Check(obj) PyObject_TypeCheck(obj, PyObjC_API->object_type)
320#define PyObjCClass_Check(obj)  PyObject_TypeCheck(obj, PyObjC_API->class_type)
321#define PyObjCSelector_Check(obj)  PyObject_TypeCheck(obj, PyObjC_API->select_type)
322#define PyObjCIMP_Check(obj)  PyObject_TypeCheck(obj, PyObjC_API->imp_type)
323#define PyObjCObject_GetObject (PyObjC_API->obj_get_object)
324#define PyObjCObject_ClearObject (PyObjC_API->obj_clear_object)
325#define PyObjCClass_GetClass   (PyObjC_API->cls_get_class)
326#define PyObjCClass_New 	     (PyObjC_API->cls_to_python)
327#define PyObjCSelector_GetClass (PyObjC_API->sel_get_class)
328#define PyObjCSelector_GetSelector (PyObjC_API->sel_get_sel)
329#define PyObjC_PythonToId      (PyObjC_API->python_to_id)
330#define PyObjC_IdToPython      (PyObjC_API->id_to_python)
331#define PyObjCErr_FromObjC     (PyObjC_API->err_objc_to_python)
332#define PyObjCErr_ToObjC       (PyObjC_API->err_python_to_objc)
333#define PyObjCErr_ToObjCWithGILState       (PyObjC_API->err_python_to_objc_gil)
334#define PyObjCErr_AsExc        (PyObjC_API->err_python_to_nsexception)
335#define PyObjC_PythonToObjC    (PyObjC_API->py_to_objc)
336#define PyObjC_ObjCToPython    (PyObjC_API->objc_to_py)
337#define PyObjC_RegisterMethodMapping (PyObjC_API->register_method_mapping)
338#define PyObjC_RegisterSignatureMapping (PyObjC_API->register_signature_mapping)
339#define PyObjC_SizeOfType      (PyObjC_API->sizeof_type)
340#define PyObjC_PythonToObjC   (PyObjC_API->py_to_objc)
341#define PyObjC_ObjCToPython   (PyObjC_API->objc_to_py)
342#define PyObjC_InitSuper	(PyObjC_API->fill_super)
343#define PyObjC_InitSuperCls	(PyObjC_API->fill_super_cls)
344#define PyObjCPointerWrapper_Register (PyObjC_API->register_pointer_wrapper)
345#define PyObjCUnsupportedMethod_IMP (PyObjC_API->unsupported_method_imp)
346#define PyObjCUnsupportedMethod_Caller (PyObjC_API->unsupported_method_caller)
347#define PyObjCRT_SizeOfType      (PyObjC_API->sizeof_type)
348#define PyObjCRT_AlignOfType	(PyObjC_API->alignof_type)
349#define PyObjCRT_SELName	(PyObjC_API->selname)
350#define PyObjCRT_SimplifySignature	(PyObjC_API->simplify_sig)
351#define PyObjC_FreeCArray	(PyObjC_API->free_c_array)
352#define PyObjC_PythonToCArray	(PyObjC_API->py_to_c_array)
353#define PyObjC_CArrayToPython	(PyObjC_API->c_array_to_py)
354#define PyObjC_RegisterStructType   (PyObjC_API->register_struct)
355#define PyObjCIMP_GetIMP   (PyObjC_API->imp_get_imp)
356#define PyObjCIMP_GetSelector   (PyObjC_API->imp_get_sel)
357#define PyObjCObject_IsUninitialized (PyObjC_API->obj_is_uninitialized)
358#define PyObjCObject_Convert (PyObjC_API->pyobjcobject_convert)
359#define PyObjCSelector_Convert (PyObjC_API->pyobjcselector_convert)
360#define PyObjCClass_Convert (PyObjC_API->pyobjcselector_convert)
361#define PyObjC_ConvertBOOL (PyObjC_API->pyobjc_convertbool)
362#define PyObjC_ConvertChar (PyObjC_API->pyobjc_convertchar)
363#define PyObjCObject_New (PyObjC_API->pyobjc_object_new)
364#define PyObjCCreateOpaquePointerType (PyObjC_API->pointer_type_new)
365#define PyObjCObject_NewTransient (PyObjC_API->newtransient)
366#define PyObjCObject_ReleaseTransient (PyObjC_API->releasetransient)
367#define PyObjC_PerformWeaklinking (PyObjC_API->doweaklink)
368#define PyObjCRT_RemoveFieldNames (PyObjC_API->removefields)
369#define PyObjC_NULL		  (*(PyObjC_API->pyobjc_null))
370#define PyObjC_DepythonifyCArray  (PyObjC_API->dep_c_array_count)
371#define PyObjC_VarList_New  (PyObjC_API->varlistnew)
372
373
374#ifndef PYOBJC_METHOD_STUB_IMPL
375
376static int
377PyObjC_ImportAPI(PyObject* calling_module)
378{
379	PyObject* m;
380	PyObject* d;
381	PyObject* api_obj;
382	PyObject* name = PyString_FromString("objc");
383
384	m = PyImport_Import(name);
385	Py_DECREF(name);
386	if (m == NULL) {
387		return -1;
388	}
389
390	d = PyModule_GetDict(m);
391	if (d == NULL) {
392		PyErr_SetString(PyExc_RuntimeError,
393			"No dict in objc module");
394		return -1;
395	}
396
397	api_obj = PyDict_GetItemString(d, PYOBJC_API_NAME);
398	if (api_obj == NULL) {
399		PyErr_SetString(PyExc_RuntimeError,
400			"No C_API in objc module");
401		return -1;
402	}
403	PyObjC_API = PyCObject_AsVoidPtr(api_obj);
404	if (PyObjC_API == NULL) {
405		return 0;
406	}
407	if (PyObjC_API->api_version != PYOBJC_API_VERSION) {
408		PyErr_SetString(PyExc_RuntimeError,
409			"Wrong version of PyObjC C API");
410		return -1;
411	}
412
413	if (PyObjC_API->struct_len < sizeof(struct pyobjc_api)) {
414		PyErr_SetString(PyExc_RuntimeError,
415			"Wrong struct-size of PyObjC C API");
416		return -1;
417	}
418
419	Py_INCREF(api_obj);
420
421	/* Current pyobjc implementation doesn't allow deregistering
422	 * information, avoid unloading of users of the C-API.
423	 * (Yes this is ugle, patches to fix this situation are apriciated)
424	 */
425	Py_INCREF(calling_module);
426
427	return 0;
428}
429#endif /* PYOBJC_METHOD_STUB_IMPL */
430
431#else /* PyObjC_BUILD */
432
433extern struct pyobjc_api	objc_api;
434
435#endif /* !PYOBJC_BUILD */
436
437#endif /*  PyObjC_API_H */
438