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