1/*
2 * Helper methods for the XML metadata testcases.
3 *
4 * - add global functions
5 */
6#include "Python.h"
7#include "pyobjc-api.h"
8#include <stdarg.h>
9
10#import <Foundation/Foundation.h>
11
12static void use_int(int x __attribute__((__unused__))) { };
13static void use_charpp(char** x __attribute__((__unused__))) { };
14static void use_id(id x __attribute__((__unused__))) { };
15
16@interface OC_MetaDataTest : NSObject
17{
18}
19+(BOOL)   boolClassMethod;
20/* Return value arrays: */
21-(int*)   makeIntArrayOf5;
22-(char**) makeStringArray;
23-(int*)   makeIntArrayOf:(int)count;
24-(const int*)   nullIntArrayOf5;
25-(char**) nullStringArray;
26-(int*)   nullIntArrayOf:(int)count;
27-(int*)   unknownLengthArray;
28
29/* In arrays: */
30-(NSArray*)makeIntArray:(int*) data count:(unsigned)count;
31-(NSArray*)makeIntArray:(int*) data halfCount:(unsigned)count;
32-(NSArray*)makeIntArray:(int*) data countPtr:(unsigned*)countPtr;
33-(NSArray*)nullIntArray:(int*) data count:(unsigned)count;
34-(NSArray*)makeStringArray:(char**)data;
35-(NSArray*)makeObjectArray:(id*)data;
36-(NSArray*)nullStringArray:(char**)data;
37-(NSArray*)make4Tuple:(double*)data;
38-(NSArray*)null4Tuple:(double*)data;
39-(NSArray*) makeVariableLengthArray:(int*)array halfCount:(int)cnt;
40
41/* Out arrays: */
42-(void)fillArray:(int*)data count:(int)count;
43-(int)nullfillArray:(int*)data count:(int)count;
44-(void)fill4Tuple:(int*)data;
45-(int)nullfill4Tuple:(int*)data;
46-(int)fillArray:(int*)data uptoCount:(int)count;
47-(int)maybeFillArray:(int*)data;
48
49/* NULL-terminated output arrays can't work, these are just here to check that the
50 * bridge knows this too.
51 */
52-(void)fillStringArray:(char**)data;
53-(int)nullfillStringArray:(char**)data;
54
55/* In/out arrays: */
56-(void)reverseArray:(float*)data count:(int)count;
57-(int)nullreverseArray:(float*)data count:(int)count;
58-(void)reverseStrings:(char**)data;
59-(int)nullreverseStrings:(char**)data;
60-(void)reverse4Tuple:(short*)data;
61-(int)nullreverse4Tuple:(short*)data;
62-(int)reverseArray:(float*)data uptoCount:(int)count;
63-(int)maybeReverseArray:(short*)data;
64
65
66/* pass-by-reference */
67-(int)sumX:(int*)x andY:(int*)y;		/* in */
68-(int)divBy5:(int)x remainder:(int*)r;		/* out */
69-(void)swapX:(double*)x andY:(double*)y; 	/* inout */
70-(NSArray*)input:(int*)x output:(int*)y inputAndOutput:(int*)z;
71
72-(NSArray*)makeArrayWithFormat:(NSString*)fmt, ...;
73-(NSArray*)makeArrayWithCFormat:(char*)fmt, ...;
74-(NSArray*)makeArrayWithArguments:(id)arg, ...;
75
76/* Helpers for calling back into python: */
77
78+(int*)   makeIntArrayOf5On:(OC_MetaDataTest*)obj;
79+(char**) makeStringArrayOn:(OC_MetaDataTest*)obj;
80+(int*)   makeIntArrayOf:(int)count on:(OC_MetaDataTest*)obj;
81+(const int*)   nullIntArrayOf5On:(OC_MetaDataTest*)obj;
82+(char**) nullStringArrayOn:(OC_MetaDataTest*)obj;
83+(int*)   nullIntArrayOf:(int)count on:(OC_MetaDataTest*)obj;
84+(NSArray*)makeIntArray:(int*) data count:(unsigned)count on:(OC_MetaDataTest*)obj;
85+(NSArray*)makeIntArray:(int*) data countPtr:(unsigned*)countPtr on:(OC_MetaDataTest*)obj;
86+(NSArray*)nullIntArray:(int*) data count:(unsigned)count on:(OC_MetaDataTest*)obj;
87+(NSArray*)makeStringArray:(char**)data on:(OC_MetaDataTest*)obj;
88+(NSArray*)makeObjectArray:(id*)data on:(OC_MetaDataTest*)obj;
89+(NSArray*)nullStringArray:(char**)data on:(OC_MetaDataTest*)obj;
90+(NSArray*)make4Tuple:(double*)data on:(OC_MetaDataTest*)obj;
91+(NSArray*)null4Tuple:(double*)data on:(OC_MetaDataTest*)obj;
92+(void)fillArray:(int*)data count:(int)count on:(OC_MetaDataTest*)obj;
93+(int)nullfillArray:(int*)data count:(int)count on:(OC_MetaDataTest*)obj;
94+(void)fill4Tuple:(int*)data on:(OC_MetaDataTest*)obj;
95+(int)nullfill4Tuple:(int*)data on:(OC_MetaDataTest*)obj;
96+(int)fillArray:(int*)data uptoCount:(int)count on:(OC_MetaDataTest*)obj;
97+(int)maybeFillArray:(int*)data on:(OC_MetaDataTest*)obj;
98+(void)fillStringArray:(char**)data on:(OC_MetaDataTest*)obj;
99+(int)nullfillStringArray:(char**)data on:(OC_MetaDataTest*)obj;
100+(void)reverseArray:(float*)data count:(int)count on:(OC_MetaDataTest*)obj;
101+(int)nullreverseArray:(float*)data count:(int)count on:(OC_MetaDataTest*)obj;
102+(void)reverseStrings:(char**)data on:(OC_MetaDataTest*)obj;
103+(int)nullreverseStrings:(char**)data on:(OC_MetaDataTest*)obj;
104+(void)reverse4Tuple:(short*)data on:(OC_MetaDataTest*)obj;
105+(int)nullreverse4Tuple:(short*)data on:(OC_MetaDataTest*)obj;
106+(int)reverseArray:(float*)data uptoCount:(int)count on:(OC_MetaDataTest*)obj;
107+(int)maybeReverseArray:(short*)data on:(OC_MetaDataTest*)obj;
108+(int)sumX:(int*)x andY:(int*)y on:(OC_MetaDataTest*)obj;
109+(int)divBy5:(int)x remainder:(int*)r on:(OC_MetaDataTest*)obj;
110+(void)swapX:(double*)x andY:(double*)y on:(OC_MetaDataTest*)obj;
111+(NSArray*)input:(int*)x output:(int*)y inputAndOutput:(int*)z on:(OC_MetaDataTest*)obj;
112
113/* Various */
114-(void)varargsMethodWithObjects:(id)first, ...;
115-(int)ignoreMethod;
116
117/* Byte arrays and C-strings */
118-(NSData*)makeDataForBytes:(char*)data count:(int)count;
119-(NSData*)makeDataForVoids:(void*)data count:(int)count;
120-(void)addOneToBytes:(char*)data count:(int)count;
121-(void)addOneToVoids:(void*)data count:(int)count;
122-(void)fillBuffer:(char*)data count:(int)count;
123-(void)fillVoids:(void*)data count:(int)count;
124
125@end
126
127@implementation OC_MetaDataTest
128
129+(BOOL) boolClassMethod
130{
131	return YES;
132}
133
134
135-(int*)   makeIntArrayOf5
136{
137	static int result[5];
138	int i;
139	for (i = 0; i < 5; i++) {
140		result[i] = i*i;
141	}
142	return result;
143}
144
145-(char**) makeStringArray
146{
147	static char* result[] = {
148		"hello",
149		"world",
150		"out",
151		"there",
152		NULL
153	};
154	return result;
155}
156
157
158-(int*)   makeIntArrayOf:(int)count
159{
160	static int* result = NULL;
161	int i;
162
163	if (result) {
164		free(result);
165	}
166	result = malloc(sizeof(int) * count);
167	if (result == NULL) {
168		return NULL;
169	}
170	for (i = 0; i < count; i++) {
171		result[i] = i * i * i;
172	}
173	return result;
174}
175-(int*)   nullIntArrayOf5
176{
177	return NULL;
178}
179
180-(char**) nullStringArray
181{
182	return NULL;
183}
184
185-(int*)   nullIntArrayOf:(int)count
186{
187	use_int(count);
188	return NULL;
189}
190
191
192-(NSArray*)nullIntArray:(int*) data count:(unsigned)count
193{
194	if (data) {
195		return [self makeIntArray:data count:count];
196	} else {
197		return nil;
198	}
199}
200
201-(NSArray*)makeIntArray:(int*) data countPtr:(unsigned*)countPtr
202{
203	return [self makeIntArray:data count:*countPtr];
204}
205
206-(NSArray*)makeIntArray:(int*) data halfCount:(unsigned)count
207{
208	return [self makeIntArray:data count:count*2];
209}
210
211-(NSArray*)makeIntArray:(int*) data count:(unsigned)count
212{
213	NSMutableArray* array;
214	unsigned i;
215
216	array = [NSMutableArray arrayWithCapacity:count];
217
218	for (i = 0; i < count; i++) {
219		[array addObject: [NSNumber numberWithInt:data[i]]];
220	}
221	return array;
222}
223
224-(NSArray*)make4Tuple:(double*)data
225{
226	NSMutableArray* array;
227	unsigned i;
228
229	array = [NSMutableArray array];
230
231	for (i = 0; i < 4; i++) {
232		[array addObject: [NSNumber numberWithDouble:data[i]]];
233	}
234	return array;
235}
236
237-(NSArray*)null4Tuple:(double*)data
238{
239	if (data)  {
240		return [self make4Tuple:data];
241	} else {
242		return nil;
243	}
244}
245
246
247-(NSArray*)nullStringArray:(char**)data
248{
249	if (data) {
250		return [self makeStringArray:data];
251	} else {
252		return nil;
253	}
254}
255
256-(NSArray*)makeStringArray:(char**)data
257{
258	NSMutableArray* array;
259
260	array = [NSMutableArray array];
261
262	while (*data != NULL) {
263		[array addObject: [NSString stringWithUTF8String: *data]];
264		data ++;
265	}
266	return array;
267}
268
269-(NSArray*)makeObjectArray:(id*)data;
270{
271	NSMutableArray* array;
272
273	array = [NSMutableArray array];
274
275	while (*data != NULL) {
276		[array addObject: *data];
277		data ++;
278	}
279	return array;
280}
281
282-(void)fillArray:(int*)data count:(int)count
283{
284	int i;
285	for (i = 0; i < count; i++) {
286		data[i] = i*i;
287	}
288}
289
290-(int)nullfillArray:(int*)data count:(int)count
291{
292	if (data == NULL) {
293		return 0;
294	} else {
295		[self fillArray:data count:count];
296		return 1;
297	}
298}
299
300-(void)fill4Tuple:(int*)data;
301{
302	int i;
303	for (i = 0; i < 4; i++) {
304		data[i] = - i * i * i;
305	}
306}
307
308-(int)nullfill4Tuple:(int*)data;
309{
310	if (data == NULL) {
311		return 0;
312	} else {
313		[self fill4Tuple:data];
314		return 1;
315	}
316}
317
318-(void)fillStringArray:(char**)data
319{
320	use_charpp(data);
321	/* NULL-terminated output arrays can't work */
322}
323
324-(int)nullfillStringArray:(char**)data
325{
326	if (data == NULL) return 0;
327	[self fillStringArray:data];
328	return 1;
329}
330
331-(void)reverseArray:(float*)data count:(int)count;
332{
333	float t;
334	int i;
335	for (i = 0; i < count / 2; i++) {
336		t = data[i];
337		data[i] = data[count - 1 - i];
338		data[count - 1 -i] = t;
339	}
340}
341
342-(int)nullreverseArray:(float*)data count:(int)count;
343{
344	if (data == NULL) return 0;
345	[self reverseArray:data count:count];
346	return 1;
347}
348
349-(void)reverseStrings:(char**)data;
350{
351	int count, i;
352	char* t;
353
354	for (count = 0; data[count] != NULL; count++) {
355		;
356	}
357
358	for (i = 0; i < count / 2 ; i++) {
359		t = data[i];
360		data[i] = data[count-1-i];
361		data[count-1-i] = t;
362	}
363}
364
365-(int)nullreverseStrings:(char**)data;
366{
367	if (data == NULL) return 0;
368	[self reverseStrings:data];
369	return 1;
370}
371
372-(void)reverse4Tuple:(short*)data
373{
374	short t;
375
376	t = data[0];
377	data[0] = data[3];
378	data[3] = t;
379
380	t = data[1];
381	data[1] = data[2];
382	data[2] = t;
383}
384
385-(int)nullreverse4Tuple:(short*)data
386{
387	if (data == NULL) return 0;
388	[self reverse4Tuple:data];
389	return 1;
390}
391
392-(int)sumX:(int*)x andY:(int*)y		/* in */
393{
394	return *x + *y;
395}
396
397-(int)divBy5:(int)x remainder:(int*)r	/* out */
398{
399	*r = x % 5;
400	return x / 5;
401}
402
403-(void)swapX:(double*)x andY:(double*)y /* inout */
404{
405	int t = *x;
406	*x = *y;
407	*y = t;
408}
409
410-(NSArray*)input:(int*)x output:(int*)y inputAndOutput:(int*)z
411{
412	char buf[64];
413	NSMutableArray* result = [NSMutableArray array];
414
415	snprintf(buf, sizeof(buf), "%p", x);
416	[result addObject: [NSString stringWithUTF8String:buf]];
417
418	snprintf(buf, sizeof(buf), "%p", y);
419	[result addObject: [NSString stringWithUTF8String:buf]];
420
421	snprintf(buf, sizeof(buf), "%p", z);
422	[result addObject: [NSString stringWithUTF8String:buf]];
423
424	if (y) {
425		if (x) {
426			if (z) {
427				*y = *x + *z;
428			} else {
429				*y = *x + 42;
430			}
431		} else if (z) {
432			*y = 42 - *z;
433		} else {
434			*y = -1;
435		}
436	}
437
438	if (z) {
439		if (x) {
440			*z = *x - *z;
441		} else {
442			*z = -*z;
443		}
444	}
445
446	return result;
447}
448
449-(int)fillArray:(int*)data uptoCount:(int)count
450{
451	int i;
452	for (i = 0; i < count / 2; i++) {
453		data[i] = i + 2;
454	}
455	for (i = count/2; i < count; i++) {
456		data[i] = -42;
457	}
458	return count/2;
459}
460
461-(int)maybeFillArray:(int*)data
462{
463	int i;
464	for (i = 0; i < 2; i++) {
465		data[i] = i + 10;
466	}
467	for (i = 2; i < 4; i++) {
468		data[i] = -42;
469	}
470	return 2;
471}
472
473-(int)reverseArray:(float*)data uptoCount:(int)count
474{
475	[self reverseArray:data count:count];
476	return count/2;
477}
478
479-(int)maybeReverseArray:(short*)data;
480{
481	[self reverse4Tuple:data];
482	return 2;
483}
484
485
486+(int*)   makeIntArrayOf5On:(OC_MetaDataTest*)obj
487{
488	return [obj makeIntArrayOf5];
489}
490
491+(char**) makeStringArrayOn:(OC_MetaDataTest*)obj
492{
493	return [obj makeStringArray];
494}
495
496+(int*)   makeIntArrayOf:(int)count on:(OC_MetaDataTest*)obj
497{
498	return [obj makeIntArrayOf:count];
499}
500
501+(const int*)   nullIntArrayOf5On:(OC_MetaDataTest*)obj
502{
503	return [obj nullIntArrayOf5];
504}
505
506+(char**) nullStringArrayOn:(OC_MetaDataTest*)obj
507{
508	return [obj nullStringArray];
509}
510
511+(int*)   nullIntArrayOf:(int)count on:(OC_MetaDataTest*)obj
512{
513	return [obj nullIntArrayOf:count];
514}
515
516+(NSArray*)makeIntArray:(int*) data count:(unsigned)count on:(OC_MetaDataTest*)obj
517{
518	return [obj makeIntArray:data count:count];
519}
520
521+(NSArray*)makeIntArray:(int*) data countPtr:(unsigned*)countPtr on:(OC_MetaDataTest*)obj
522{
523	return [obj makeIntArray:data countPtr:countPtr];
524}
525
526+(NSArray*)nullIntArray:(int*) data count:(unsigned)count on:(OC_MetaDataTest*)obj
527{
528	return [obj nullIntArray:data count:count];
529}
530
531+(NSArray*)makeStringArray:(char**)data on:(OC_MetaDataTest*)obj
532{
533	return [obj makeStringArray:data];
534}
535
536+(NSArray*)makeObjectArray:(id*)data on:(OC_MetaDataTest*)obj
537{
538	return [obj makeObjectArray:data];
539}
540
541+(NSArray*)nullStringArray:(char**)data on:(OC_MetaDataTest*)obj
542{
543	return [obj nullStringArray:data];
544}
545
546+(NSArray*)make4Tuple:(double*)data on:(OC_MetaDataTest*)obj
547{
548	return [obj make4Tuple:data];
549}
550
551+(NSArray*)null4Tuple:(double*)data on:(OC_MetaDataTest*)obj
552{
553	return [obj null4Tuple:data];
554}
555
556+(void)fillArray:(int*)data count:(int)count on:(OC_MetaDataTest*)obj
557{
558	return [obj fillArray:data count:count];
559}
560
561+(int)nullfillArray:(int*)data count:(int)count on:(OC_MetaDataTest*)obj
562{
563	return [obj nullfillArray:data count:count];
564}
565
566+(void)fill4Tuple:(int*)data on:(OC_MetaDataTest*)obj
567{
568	return [obj fill4Tuple:data];
569}
570
571+(int)nullfill4Tuple:(int*)data on:(OC_MetaDataTest*)obj
572{
573	return [obj nullfill4Tuple:data];
574}
575
576+(int)fillArray:(int*)data uptoCount:(int)count on:(OC_MetaDataTest*)obj
577{
578	return [obj fillArray:data uptoCount:count];
579}
580
581+(int)maybeFillArray:(int*)data on:(OC_MetaDataTest*)obj
582{
583	return [obj maybeFillArray:data];
584}
585
586+(void)fillStringArray:(char**)data on:(OC_MetaDataTest*)obj
587{
588	[obj fillStringArray:data];
589}
590
591+(int)nullfillStringArray:(char**)data on:(OC_MetaDataTest*)obj
592{
593	return [obj nullfillStringArray:data];
594}
595
596+(void)reverseArray:(float*)data count:(int)count on:(OC_MetaDataTest*)obj
597{
598	[obj reverseArray:data count:count];
599}
600
601+(int)nullreverseArray:(float*)data count:(int)count on:(OC_MetaDataTest*)obj
602{
603	return [obj nullreverseArray:data count:count];
604}
605
606+(void)reverseStrings:(char**)data on:(OC_MetaDataTest*)obj
607{
608	[obj reverseStrings:data];
609}
610
611+(int)nullreverseStrings:(char**)data on:(OC_MetaDataTest*)obj
612{
613	return [obj nullreverseStrings:data];
614}
615
616+(void)reverse4Tuple:(short*)data on:(OC_MetaDataTest*)obj
617{
618	[obj reverse4Tuple:data];
619}
620
621+(int)nullreverse4Tuple:(short*)data on:(OC_MetaDataTest*)obj
622{
623	return [obj nullreverse4Tuple:data];
624}
625
626+(int)reverseArray:(float*)data uptoCount:(int)count on:(OC_MetaDataTest*)obj
627{
628	return [obj reverseArray:data uptoCount:count];
629}
630
631+(int)maybeReverseArray:(short*)data on:(OC_MetaDataTest*)obj
632{
633	return [obj maybeReverseArray:data];
634}
635
636+(int)sumX:(int*)x andY:(int*)y on:(OC_MetaDataTest*)obj
637{
638	return [obj sumX:x andY:y];
639}
640
641+(int)divBy5:(int)x remainder:(int*)r on:(OC_MetaDataTest*)obj
642{
643	return [obj divBy5:x remainder:r];
644}
645
646+(void)swapX:(double*)x andY:(double*)y on:(OC_MetaDataTest*)obj
647{
648	return [obj swapX:x andY:y];
649}
650
651+(NSArray*)input:(int*)x output:(int*)y inputAndOutput:(int*)z on:(OC_MetaDataTest*)obj
652{
653	return [obj input:x output:y inputAndOutput:z];
654}
655
656-(NSArray*)makeArrayWithFormat:(NSString*)fmt, ...
657{
658	va_list ap;
659	char buffer[2048];
660
661	va_start(ap, fmt);
662	vsnprintf(buffer, sizeof(buffer), [fmt UTF8String], ap);
663	va_end(ap);
664
665	return [NSArray arrayWithObjects:
666			fmt,
667			[NSString stringWithUTF8String:buffer],
668			NULL];
669}
670
671-(NSArray*)makeArrayWithCFormat:(char*)fmt, ...
672{
673	va_list ap;
674	char  buffer[2048];
675
676	va_start(ap, fmt);
677	vsnprintf(buffer, sizeof(buffer), fmt, ap);
678	va_end(ap);
679
680	return [NSArray arrayWithObjects:
681			[NSString stringWithUTF8String:fmt],
682			[NSString stringWithUTF8String:buffer],
683			NULL];
684}
685
686-(NSArray*)makeArrayWithArguments:(id)arg, ...;
687{
688	va_list ap;
689	NSMutableArray* array = [[NSMutableArray alloc] init];
690	if (arg == NULL) {
691		return array;
692	}
693
694
695	va_start(ap, arg);
696	do {
697		[array addObject:arg];
698		arg = va_arg(ap, id);
699	} while (arg != NULL);
700
701	va_end(ap);
702	return array;
703}
704
705-(void)varargsMethodWithObjects:(id)first, ...
706{
707	use_id(first);
708}
709
710-(int)ignoreMethod
711{
712	return 42;
713}
714
715-(NSData*)makeDataForBytes:(char*)data count:(int)count
716{
717	return [NSData dataWithBytes:data length:count];
718}
719
720-(NSData*)makeDataForVoids:(void*)data count:(int)count
721{
722	return [NSData dataWithBytes:data length:count];
723}
724
725-(void)addOneToBytes:(char*)data count:(int)count
726{
727	int i;
728	for (i = 0;i < count; i++) {
729		data[i] += 1;
730	}
731}
732
733-(void)addOneToVoids:(void*)data count:(int)count
734{
735	int i;
736	for (i = 0; i < count; i++) {
737		((char*)data)[i] += 2;
738	}
739}
740
741-(void)fillBuffer:(char*)data count:(int)count
742{
743	memset(data, '\xfe', count);
744}
745
746-(void)fillVoids:(void*)data count:(int)count
747{
748	memset(data, '\xab', count);
749}
750
751-(int*)   unknownLengthArray
752{
753static  int theValue[] = { 1, 3, 5, 7, 11, 13, 17, 19 };
754	return theValue;
755}
756
757-(int*)  unknownLengthMutable
758{
759static  int theValue[20];
760	return theValue;
761}
762
763-(NSArray*) makeVariableLengthArray:(int*)array halfCount:(int)cnt
764{
765	cnt *= 2;
766
767	NSMutableArray* result;
768	int i;
769
770	result = [NSMutableArray arrayWithCapacity:cnt];
771
772	for (i = 0; i < cnt; i++) {
773		[result addObject: [NSNumber numberWithFloat:array[i]]];
774	}
775	return result;
776}
777
778
779@end
780
781
782static PyMethodDef mod_methods[] = {
783	        { 0, 0, 0, 0 }
784};
785
786#if PY_VERSION_HEX >= 0x03000000
787
788static struct PyModuleDef mod_module = {
789	PyModuleDef_HEAD_INIT,
790	"metadata",
791	NULL,
792	0,
793	mod_methods,
794	NULL,
795	NULL,
796	NULL,
797	NULL
798};
799
800#define INITERROR() return NULL
801#define INITDONE() return m
802
803PyObject* PyInit_metadata(void);
804
805PyObject*
806PyInit_metadata(void)
807
808#else
809
810#define INITERROR() return
811#define INITDONE() return
812
813void initmetadata(void);
814
815void
816initmetadata(void)
817#endif
818
819{
820	PyObject* m;
821
822
823#if PY_VERSION_HEX >= 0x03000000
824	m = PyModule_Create(&mod_module);
825#else
826	m = Py_InitModule4("metadata", mod_methods,
827		NULL, NULL, PYTHON_API_VERSION);
828#endif
829	if (!m) {
830		INITERROR();
831	}
832
833	if (PyObjC_ImportAPI(m) < 0) {
834		INITERROR();
835	}
836
837	if (PyModule_AddObject(m, "OC_MetaDataTest",
838		PyObjCClass_New([OC_MetaDataTest class])) < 0) {
839
840		INITERROR();
841	}
842
843	INITDONE();
844}
845