[PyObjC-svn] r2059 - trunk/pyobjc/pyobjc-core/Modules/objc

[email protected]
Newsgroups gmane.comp.python.pyobjc.cvs
Message-ID <[email protected]>
Author: ronaldoussoren
Date: Tue Feb 17 15:12:58 2009
New Revision: 2059

Log:
Initial support for functions with a variable number of
arguments where the amount of arguments is one of
the other arguments of the function (like 
CGEventCreateScrollWheelEvent)



Modified:
   trunk/pyobjc/pyobjc-core/Modules/objc/OC_PythonString.m
   trunk/pyobjc/pyobjc-core/Modules/objc/function.m
   trunk/pyobjc/pyobjc-core/Modules/objc/libffi_support.m
   trunk/pyobjc/pyobjc-core/Modules/objc/method-signature.h
   trunk/pyobjc/pyobjc-core/Modules/objc/method-signature.m
   trunk/pyobjc/pyobjc-core/Modules/objc/parsexml.m

Modified: trunk/pyobjc/pyobjc-core/Modules/objc/OC_PythonString.m
==============================================================================
--- trunk/pyobjc/pyobjc-core/Modules/objc/OC_PythonString.m	(original)
+++ trunk/pyobjc/pyobjc-core/Modules/objc/OC_PythonString.m	Tue Feb 17 15:12:58 2009
@@ -189,17 +189,17 @@
 				PyObject* selfAsPython = PyObjCObject_New(self, 0, YES);
 				setValue = PyObject_GetAttrString(selfAsPython, "pyobjcSetValue_");
 
-				PyObject* v = PyObject_CallFunction(PyObjC_Decoder, "OO", cdr, setValue);
+				PyObject* v2 = PyObject_CallFunction(PyObjC_Decoder, "OO", cdr, setValue);
 				Py_DECREF(cdr);
 				Py_DECREF(setValue);
 				Py_DECREF(selfAsPython);
 
-				if (v == NULL) {
+				if (v2 == NULL) {
 					PyObjC_GIL_FORWARD_EXC();
 				}
 
 				Py_XDECREF(value);
-				value = v;
+				value = v2;
 
 				NSObject* proxy = PyObjC_FindObjCProxy(value);
 				if (proxy == NULL) {
@@ -207,7 +207,7 @@
 				} else {
 					[self release];
 					[proxy retain];
-					self = (OC_PythonObject*)proxy;
+					self = (OC_PythonString*)proxy;
 				}
 
 

Modified: trunk/pyobjc/pyobjc-core/Modules/objc/function.m
==============================================================================
--- trunk/pyobjc/pyobjc-core/Modules/objc/function.m	(original)
+++ trunk/pyobjc/pyobjc-core/Modules/objc/function.m	Tue Feb 17 15:12:58 2009
@@ -151,6 +151,8 @@
 		return NULL;
 	}
 
+	variadicAllArgs = self->methinfo->variadic && (self->methinfo->null_terminated_array || self->methinfo->arrayArg != -1);
+
 	if (variadicAllArgs) {
 		if (byref_in_count != 0 || byref_out_count != 0) {
 			PyErr_Format(PyExc_TypeError, "Sorry, printf format with by-ref args not supported");

Modified: trunk/pyobjc/pyobjc-core/Modules/objc/libffi_support.m
==============================================================================
--- trunk/pyobjc/pyobjc-core/Modules/objc/libffi_support.m	(original)
+++ trunk/pyobjc/pyobjc-core/Modules/objc/libffi_support.m	Tue Feb 17 15:12:58 2009
@@ -910,22 +910,35 @@
 	PyObjCMethodSignature* methinfo,
 	PyObject* argtuple, Py_ssize_t argoffset,
 	void** byref,
-	ffi_type** arglist, void** values)
+	ffi_type** arglist, void** values, int count)
 {
 	Py_ssize_t curarg = methinfo->ob_size-1;
 	Py_ssize_t maxarg = PyTuple_Size(argtuple);
+	Py_ssize_t argSize;
+
+	if (count != -1) {
+		if (maxarg - curarg != count) {
+			PyErr_Format(PyExc_ValueError, "Wrong number of variadic arguments, need %d, got %d",
+					count, (maxarg - curarg));
+			return -1;
+		}
+	}
 
 	struct _PyObjC_ArgDescr* argType = (
 			methinfo->argtype + methinfo->ob_size - 1);
 
-	if (argType->type[0] != _C_ID) {
-		PyErr_Format(PyExc_TypeError,
-			"variadic null-terminated arrays only supported for type '%c', not '%s' || %s", _C_ID, argType->type, PyObject_REPR((PyObject*)methinfo));
-		return -1;
+	argSize = PyObjCRT_SizeOfType(argType->type);
+
+	if (count == -1) {
+		if (argType->type[0] != _C_ID) {
+			PyErr_Format(PyExc_TypeError,
+				"variadic null-terminated arrays only supported for type '%c', not '%s' || %s", _C_ID, argType->type, PyObject_REPR((PyObject*)methinfo));
+			return -1;
+		}
 	}
 
 	for (;argoffset < maxarg; curarg++, argoffset++) {
-		byref[curarg]  = PyMem_Malloc(sizeof(id));
+		byref[curarg]  = PyMem_Malloc(argSize);
 		if (byref[curarg] == NULL) {
 			return -1;
 		}
@@ -2169,7 +2182,7 @@
 	 */
 
 	Py_ssize_t meth_arg_count;
-	if (methinfo->variadic && methinfo->null_terminated_array) {
+	if (methinfo->variadic && (methinfo->null_terminated_array || (methinfo->arrayArg != -1))) {
 		meth_arg_count = methinfo->ob_size - 1;
 	}  else {
 		meth_arg_count = methinfo->ob_size;
@@ -2931,7 +2944,24 @@
 		r = parse_varargs_array(
 				methinfo,
 				args, py_arg, byref, 
-				arglist, values);
+				arglist, values, -1);
+		if (r == -1) {
+			return -1;
+		}
+		return r;
+	} else if (methinfo->variadic && methinfo->arrayArg != -1) {
+		int r;
+		Py_ssize_t cnt = extract_count(
+			methinfo->argtype[methinfo->arrayArg].type,
+			values[methinfo->arrayArg]);
+		if (cnt == -1) {
+			return -1;
+		}
+
+		r = parse_varargs_array(
+				methinfo,
+				args, py_arg, byref, 
+				arglist, values, cnt);
 		if (r == -1) {
 			return -1;
 		}
@@ -3395,7 +3425,7 @@
 		flags = meth->sel_flags;
 	}
 	rettype = methinfo->rettype.type;
-	variadicAllArgs = methinfo->variadic && methinfo->null_terminated_array;
+	variadicAllArgs = methinfo->variadic && (methinfo->null_terminated_array || methinfo->arrayArg != -1);
 
 	if (methinfo->suggestion != NULL) {
 		PyErr_SetObject(PyExc_TypeError, methinfo->suggestion);

Modified: trunk/pyobjc/pyobjc-core/Modules/objc/method-signature.h
==============================================================================
--- trunk/pyobjc/pyobjc-core/Modules/objc/method-signature.h	(original)
+++ trunk/pyobjc/pyobjc-core/Modules/objc/method-signature.h	Tue Feb 17 15:12:58 2009
@@ -52,6 +52,7 @@
 	PyObject_VAR_HEAD
 
 	const char* signature;
+	int  arrayArg;
 	BOOL variadic:1;
 	BOOL null_terminated_array:1;
 	BOOL		free_result:1;

Modified: trunk/pyobjc/pyobjc-core/Modules/objc/method-signature.m
==============================================================================
--- trunk/pyobjc/pyobjc-core/Modules/objc/method-signature.m	(original)
+++ trunk/pyobjc/pyobjc-core/Modules/objc/method-signature.m	Tue Feb 17 15:12:58 2009
@@ -574,14 +574,20 @@
 		methinfo->null_terminated_array = YES;
 	}
 
+	methinfo->arrayArg = -1;
+	v = PyDict_GetItemString(metadata, "c_array_length_in_arg");
+	if (v && PyInt_Check(v)) {
+		methinfo->arrayArg = PyInt_AsLong(v);
+	}
 
 	methinfo->variadic = NO;
 	v = PyDict_GetItemString(metadata, "variadic");
 	if (v && PyObject_IsTrue(v)) {
 		methinfo->variadic = YES;
 
-		if (methinfo->suggestion == NULL 
-					&& !methinfo->null_terminated_array) {
+		if ((methinfo->suggestion == NULL)
+					&& (!methinfo->null_terminated_array)
+					&& (methinfo->arrayArg == -1)) {
 			for (i = 0; i < methinfo->ob_size; i++) {
 				if (methinfo->argtype[i].printfFormat) {
 					return methinfo;
@@ -761,8 +767,13 @@
 		Py_DECREF(v);
 		if (r == -1) goto error;
 	}
-
-
+	if (methinfo->variadic && methinfo->arrayArg != -1) {
+		v = PyInt_FromLong(methinfo->arrayArg);
+		if (v == NULL) goto error;
+		r = PyDict_SetItemString(result, "c_array_length_in_arg", v);
+		Py_DECREF(v);
+		if (r == -1) goto error;
+	}
 
 	if (methinfo->suggestion) {
 		r = PyDict_SetItemString(result, "suggestion", 

Modified: trunk/pyobjc/pyobjc-core/Modules/objc/parsexml.m
==============================================================================
--- trunk/pyobjc/pyobjc-core/Modules/objc/parsexml.m	(original)
+++ trunk/pyobjc/pyobjc-core/Modules/objc/parsexml.m	Tue Feb 17 15:12:58 2009
@@ -847,6 +847,7 @@
 
 		BOOL variadic = attribute_bool(method, "variadic", NULL, NO);
 		BOOL c_array = attribute_bool(method, "c_array_delimited_by_null", NULL, NO);
+		char* c_length = attribute_string(method, "c_array_length_in_arg", NULL);
 		BOOL ignore = attribute_bool(method, "ignore", NULL, NO);
 
 		PyObject* metadata = PyDict_New();
@@ -920,6 +921,27 @@
 				xmlFree(classname);
 				return -1;
 			}
+
+			if (c_length != NULL) {
+				long cnt = strtol(c_length, NULL, 10);
+
+				v = PyInt_FromLong(cnt);
+				if (v == NULL) {
+					Py_DECREF(metadata);
+					Py_XDECREF(pyClassname);
+					xmlFree(selname);
+					xmlFree(classname);
+					return -1;
+				}
+				r = PyDict_SetItemString(metadata, "c_array_length_in_arg", v);
+				if (r == -1) {
+					Py_DECREF(metadata);
+					Py_XDECREF(pyClassname);
+					xmlFree(selname);
+					xmlFree(classname);
+					return -1;
+				}
+			}
 		}
 
 		PyObject* arguments = PyDict_New();
@@ -1123,6 +1145,26 @@
 			return -1;
 		}
 		Py_DECREF(v);
+
+		char* ch = attribute_string(cur_node, "c_array_length_in_arg", NULL);
+		if (ch) {
+			long count = strtol(ch, NULL, 10);
+			v = PyInt_FromLong(count);
+			if (v == NULL) {
+				xmlFree(name);
+				Py_DECREF(metadata);
+				Py_DECREF(arguments);
+				return -1;
+			}
+
+			if (PyDict_SetItemString(metadata, "c_array_length_in_arg", v) < 0)  {
+				xmlFree(name);
+				Py_DECREF(metadata);
+				Py_DECREF(v);
+				return -1;
+			}
+			Py_DECREF(v);
+		}
 	}
 
 	PyObject* siglist = PyList_New(0);

------------------------------------------------------------------------------
Open Source Business Conference (OSBC), March 24-25, 2009, San Francisco, CA
-OSBC tackles the biggest issue in open source: Open Sourcing the Enterprise
-Strategies to boost innovation and cut costs with open source participation
-Receive a $600 discount off the registration fee with the source code: SFAD
http://p.sf.net/sfu/XcvMzF8H
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.