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.