1/*
2 * Helper methods for the XML metadata testcases - global function edition
3 *
4 * This file has the same structure as generated for inline function by
5 * the metadata tool.
6 */
7#include "Python.h"
8#include "pyobjc-api.h"
9#include <stdarg.h>
10
11#import <Foundation/Foundation.h>
12
13static int* makeIntArrayOf5(void)
14{
15	static int result[5];
16	int i;
17	for (i = 0; i < 5; i++) {
18		result[i] = i*i;
19	}
20	return result;
21}
22
23static char** makeStringArray(void)
24{
25	static char* result[] = {
26		"hello",
27		"world",
28		"out",
29		"there",
30		NULL
31	};
32	return result;
33}
34
35
36static int* makeIntArrayOf_(int count)
37{
38	static int* result = NULL;
39	int i;
40
41	if (result) {
42		free(result);
43	}
44	result = malloc(sizeof(int) * count);
45	if (result == NULL) {
46		return NULL;
47	}
48	for (i = 0; i < count; i++) {
49		result[i] = i * i * i;
50	}
51	return result;
52}
53
54static int* nullIntArrayOf5(void)
55{
56	return NULL;
57}
58
59static char** nullStringArray(void)
60{
61	return NULL;
62}
63
64static int* nullIntArrayOf_(int count __attribute__((__unused__)))
65{
66	return NULL;
67}
68
69static NSArray* makeIntArray_count_(int* data, unsigned count)
70{
71	NSMutableArray* array;
72	unsigned i;
73
74	array = [NSMutableArray arrayWithCapacity:count];
75
76	for (i = 0; i < count; i++) {
77		[array addObject: [NSNumber numberWithInt:data[i]]];
78	}
79	return array;
80}
81
82static NSArray* nullIntArray_count_(int* data, unsigned count)
83{
84	if (data) {
85		return makeIntArray_count_(data, count);
86	} else {
87		return nil;
88	}
89}
90
91static NSArray* makeIntArray_countPtr_(int* data, unsigned* countPtr)
92{
93	return makeIntArray_count_(data, *countPtr);
94}
95
96
97static NSArray* make4Tuple_(double* data)
98{
99	NSMutableArray* array;
100	unsigned i;
101
102	array = [NSMutableArray array];
103
104	for (i = 0; i < 4; i++) {
105		[array addObject: [NSNumber numberWithDouble:data[i]]];
106	}
107	return array;
108}
109
110static NSArray* null4Tuple_(double* data)
111{
112	if (data)  {
113		return make4Tuple_(data);
114	} else {
115		return nil;
116	}
117}
118
119
120
121static NSArray* makeStringArray_(char** data)
122{
123	NSMutableArray* array;
124
125	array = [NSMutableArray array];
126
127	while (*data != NULL) {
128		[array addObject: [NSString stringWithUTF8String: *data]];
129		data ++;
130	}
131	return array;
132}
133
134static NSArray* nullStringArray_(char** data)
135{
136	if (data) {
137		return makeStringArray_(data);
138	} else {
139		return nil;
140	}
141}
142
143static NSArray* makeObjectArray_(id* data)
144{
145	NSMutableArray* array;
146
147	array = [NSMutableArray array];
148
149	while (*data != NULL) {
150		[array addObject: *data];
151		data ++;
152	}
153	return array;
154}
155
156static void fillArray_count_(int* data, int count)
157{
158	int i;
159	for (i = 0; i < count; i++) {
160		data[i] = i*i;
161	}
162}
163
164static int nullfillArray_count_(int* data, int count)
165{
166	if (data == NULL) {
167		return 0;
168	} else {
169		fillArray_count_(data, count);
170		return 1;
171	}
172}
173
174static void fill4Tuple_(int* data)
175{
176	int i;
177	for (i = 0; i < 4; i++) {
178		data[i] = - i * i * i;
179	}
180}
181
182static int nullfill4Tuple_(int* data)
183{
184	if (data == NULL) {
185		return 0;
186	} else {
187		fill4Tuple_(data);
188		return 1;
189	}
190}
191
192static int fillStringArray_(char** data __attribute__((__unused__)))
193{
194	return -1;
195}
196
197static int nullfillStringArray_(char** data)
198{
199	if (data == NULL) return 0;
200	fillStringArray_(data);
201	return 1;
202}
203
204static void reverseArray_count_(float* data, int count)
205{
206	float t;
207	int i;
208	for (i = 0; i < count / 2; i++) {
209		t = data[i];
210		data[i] = data[count - 1 - i];
211		data[count - 1 -i] = t;
212	}
213}
214
215static int nullreverseArray_count_(float* data, int count)
216{
217	if (data == NULL) return 0;
218	reverseArray_count_(data, count);
219	return 1;
220}
221
222static void reverseStrings_(char** data)
223{
224	int count, i;
225	char* t;
226
227	for (count = 0; data[count] != NULL; count++) {
228		;
229	}
230
231	for (i = 0; i < count / 2 ; i++) {
232		t = data[i];
233		data[i] = data[count-1-i];
234		data[count-1-i] = t;
235	}
236}
237
238static int nullreverseStrings_(char** data)
239{
240	if (data == NULL) return 0;
241	reverseStrings_(data);
242	return 1;
243}
244
245static void reverse4Tuple_(short* data)
246{
247	short t;
248
249	t = data[0];
250	data[0] = data[3];
251	data[3] = t;
252
253	t = data[1];
254	data[1] = data[2];
255	data[2] = t;
256}
257
258static int nullreverse4Tuple_(short* data)
259{
260	if (data == NULL) return 0;
261	reverse4Tuple_(data);
262	return 1;
263}
264
265
266static int sumX_andY_(int* x, int* y)
267{
268	return *x + *y;
269}
270
271static int divBy5_remainder_(int x, int* r)
272{
273	*r = x % 5;
274	return x / 5;
275}
276
277static void swapX_andY_(double* x, double* y)
278{
279	int t = *x;
280	*x = *y;
281	*y = t;
282}
283
284static NSArray* input_output_inputAndOutput_(int* x, int* y, int* z)
285{
286	char buf[64];
287	NSMutableArray* result = [NSMutableArray array];
288
289	snprintf(buf, sizeof(buf), "%p", x);
290	[result addObject: [NSString stringWithUTF8String:buf]];
291
292	snprintf(buf, sizeof(buf), "%p", y);
293	[result addObject: [NSString stringWithUTF8String:buf]];
294
295	snprintf(buf, sizeof(buf), "%p", z);
296	[result addObject: [NSString stringWithUTF8String:buf]];
297
298	if (y) {
299		if (x) {
300			if (z) {
301				*y = *x + *z;
302			} else {
303				*y = *x + 42;
304			}
305		} else if (z) {
306			*y = 42 - *z;
307		} else {
308			*y = -1;
309		}
310	}
311
312	if (z) {
313		if (x) {
314			*z = *x - *z;
315		} else {
316			*z = -*z;
317		}
318	}
319
320	return result;
321}
322
323static int fillArray_uptoCount_(int* data, int count)
324{
325	int i;
326	for (i = 0; i < count / 2; i++) {
327		data[i] = i + 2;
328	}
329	for (i = count/2; i < count; i++) {
330		data[i] = -42;
331	}
332	return count/2;
333}
334
335static int maybyFillArray_(int *data)
336{
337	int i;
338	for (i = 0; i < 2; i++) {
339		data[i] = i + 10;
340	}
341	for (i = 2; i < 4; i++) {
342		data[i] = -42;
343	}
344	return 2;
345}
346
347static int reverseArray_uptoCount_(float* data, int count)
348{
349	reverseArray_count_(data, count);
350	return count/2;
351}
352
353static int maybeReverseArray_(short* data)
354{
355	reverse4Tuple_(data);
356	return 2;
357}
358
359
360static NSArray* makeArrayWithFormat_(NSString* fmt, ...)
361{
362	va_list ap;
363	char buffer[2048];
364
365	va_start(ap, fmt);
366#pragma clang diagnostic push
367#pragma clang diagnostic ignored "-Wformat-nonliteral"
368
369	vsnprintf(buffer, sizeof(buffer), [fmt UTF8String], ap);
370#pragma clang diagnostic pop
371	va_end(ap);
372
373	return [NSArray arrayWithObjects:
374			fmt,
375			[NSString stringWithUTF8String:buffer],
376			NULL];
377}
378
379#pragma GCC   diagnostic push
380#pragma clang   diagnostic push
381#pragma GCC   diagnostic ignored "-Wformat-nonliteral"
382#pragma clang diagnostic ignored "-Wformat-nonliteral"
383
384static NSArray* makeArrayWithCFormat_(char* fmt, ...)
385{
386	va_list ap;
387	char buffer[2048];
388
389	va_start(ap, fmt);
390	vsnprintf(buffer, sizeof(buffer), fmt, ap);
391	va_end(ap);
392
393	return [NSArray arrayWithObjects:
394			[NSString stringWithUTF8String:fmt],
395			[NSString stringWithUTF8String:buffer],
396			NULL];
397}
398
399#pragma GCC   diagnostic pop
400#pragma clang   diagnostic pop
401
402static int maybeFillArray_(int* data)
403{
404	int i;
405	for (i = 0; i < 2; i++) {
406		data[i] = i + 10;
407	}
408	for (i = 2; i < 4; i++) {
409		data[i] = -42;
410	}
411	return 2;
412}
413
414
415typedef void (*F)(void);
416static struct function {
417	char* name;
418	F	function;
419} gFunctionMap[] = {
420	{ "makeIntArrayOf5", (F)makeIntArrayOf5 },
421	{ "makeStringArray", (F)makeStringArray },
422	{ "makeIntArrayOf_", (F)makeIntArrayOf_ },
423	{ "nullIntArrayOf5", (F)nullIntArrayOf5 },
424	{ "nullStringArray", (F)nullStringArray },
425	{ "nullIntArrayOf_", (F)nullIntArrayOf_ },
426	{ "nullIntArray_count_", (F)nullIntArray_count_ },
427	{ "makeIntArray_countPtr_", (F)makeIntArray_countPtr_ },
428	{ "makeIntArray_count_", (F)makeIntArray_count_ },
429	{ "make4Tuple_", (F)make4Tuple_ },
430	{ "null4Tuple_", (F)null4Tuple_ },
431	{ "nullStringArray_", (F)nullStringArray_ },
432	{ "makeStringArray_", (F)makeStringArray_ },
433	{ "makeObjectArray_", (F)makeObjectArray_ },
434	{ "fillArray_count_", (F)fillArray_count_ },
435	{ "nullfillArray_count_", (F)nullfillArray_count_ },
436	{ "fill4Tuple_", (F)fill4Tuple_ },
437	{ "nullfill4Tuple_", (F)nullfill4Tuple_ },
438	{ "fillStringArray_", (F)fillStringArray_ },
439	{ "nullfillStringArray_", (F)nullfillStringArray_ },
440	{ "reverseArray_count_", (F)reverseArray_count_ },
441	{ "nullreverseArray_count_", (F)nullreverseArray_count_ },
442	{ "reverseStrings_", (F)reverseStrings_ },
443	{ "nullreverseStrings_", (F)nullreverseStrings_ },
444	{ "reverse4Tuple_", (F)reverse4Tuple_ },
445	{ "nullreverse4Tuple_", (F)nullreverse4Tuple_ },
446	{ "sumX_andY_", (F)sumX_andY_ },
447	{ "divBy5_remainder_", (F)divBy5_remainder_ },
448	{ "swapX_andY_", (F)swapX_andY_ },
449	{ "input_output_inputAndOutput_", (F)input_output_inputAndOutput_ },
450	{ "fillArray_uptoCount_", (F)fillArray_uptoCount_ },
451	{ "maybyFillArray_", (F)maybyFillArray_ },
452	{ "reverseArray_uptoCount_", (F)reverseArray_uptoCount_ },
453	{ "maybeReverseArray_", (F)maybeReverseArray_ },
454	{ "makeArrayWithFormat_", (F)makeArrayWithFormat_ },
455	{ "makeArrayWithCFormat_", (F)makeArrayWithCFormat_ },
456	{ "maybeFillArray_", (F)maybeFillArray_ },
457
458	{ NULL, NULL }
459};
460
461
462static PyMethodDef mod_methods[] = {
463	        { 0, 0, 0, 0 }
464};
465
466#if PY_VERSION_HEX >= 0x03000000
467
468static struct PyModuleDef mod_module = {
469	PyModuleDef_HEAD_INIT,
470	"metadatafunction",
471	NULL,
472	0,
473	mod_methods,
474	NULL,
475	NULL,
476	NULL,
477	NULL
478};
479
480#define INITERROR() return NULL
481#define INITDONE() return m
482
483PyObject* PyInit_metadatafunction(void);
484
485PyObject*
486PyInit_metadatafunction(void)
487
488#else
489
490#define INITERROR() return
491#define INITDONE() return
492
493void initmetadatafunction(void);
494
495void
496initmetadatafunction(void)
497#endif
498{
499	PyObject* m;
500	PyObject* v;
501
502
503#if PY_VERSION_HEX >= 0x03000000
504	m = PyModule_Create(&mod_module);
505#else
506	m = Py_InitModule4("metadatafunction", mod_methods,
507		NULL, NULL, PYTHON_API_VERSION);
508#endif
509	if (!m) {
510		INITERROR();
511	}
512
513	if (PyObjC_ImportAPI(m) < 0) {
514		INITERROR();
515	}
516
517#if PY_VERSION_MAJOR == 2 && PY_VERSION_MINOR < 7
518	v = PyCObject_FromVoidPtr(gFunctionMap, NULL);
519#else
520	v = PyCapsule_New(gFunctionMap, "objc.__inline__", NULL);
521#endif
522	if (v == NULL) {
523		INITERROR();
524	}
525	if (PyModule_AddObject(m, "function_list", v) < 0) {
526		INITERROR();
527	}
528	INITDONE();
529}
530