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