/* Copyright (c) 1996,97,98 by Lele Gaifax. All Rights Reserved * * This software may be used and distributed freely for any purpose * provided that this notice is included unchanged on any and all * copies. The author does not warrant or guarantee this software in * any way. * * This file is part of the PyObjC package. * * RCSfile: ObjC.m,v * Revision: 1.38 * Date: 1998/08/18 15:41:13 * * Created Tue Jun 18 12:28:42 1996. */ /* Long time ago, Jon M. Kutemeier wrote a module to interface Python with Objective-C and for a while Guido van Rossum "revamped and maintained" it. Sadly, on Mon, 22 Jul 1996 Guido announced the he will drop that module from the Python distribution. Since I'm a NeXTSTEP fan(atic), I considered that a bad news: for months I dreamed about working on its beautiful UI from Python; more than that, the two languages are so similar that Objective-C may be viewed as the compiled cousin of Guido's creation, at least while we all wait for a Python compiler... So I rewrote it: it provides an easier way of sending messages to Objective-C objects, and (will) support(s) the GNU Objective-C runtime. Now I just hope Guido will reconsider his decision... */ #include "ObjC.h" #include "objc_support.h" #include "osdefs.h" #ifndef STRINGIFY // GNUstep defines it. #define STRINGIFY(a) _STRINGIFY(a) #define _STRINGIFY(a) #a #endif static char ObjC_doc[] = "\ Objective-C Interface module Version " STRINGIFY(PyObjC_VERSION) ".\n\ Copyright (C) 1996,97,98 - Lele Gaifax \n\n\ This module implements an Objective-C interface layer, allowing the use\n\ of Objective-C functionalities from Python scripts.\n\n\ You can access any known Objective-C class as a member of the `.runtime'\n\ object. The Python idiom ``ClassName()'' gets translated in the equivalent\n\ Objective-C ``[[ClassName alloc] init]''.\n\n\ You can use specialized initializers by specifying the name of the ``init''\n\ selector you want as a keyword parameter of the same name, as in\n\ \tma=ObjC.runtime.NSMutableArray (10, init='initWithCapacity:')\n\ Since Python has a different calling syntax, Objective-C method names\n\ change slightly: given the method ``-initId:(int)i andName:(NSString *)n''\n\ you can call it within Python as ``o.initId_andName_ (1, \"Lele Gaifax\")''.\n\ In other words, if the signature of an Objective-C method is\n\ `someMethod:withSecondArg:andAnother:', which takes three arguments, the\n\ Python equivalent results by replacing each colon `:' with an underscore\n\ `_', then feeding the arguments in row, as usual.\n\ "; static char ObjC_lookup_class_doc[] = FUNDOC("Locate a class in the Objective-C runtime", ".lookup_class (CLASS)", "CLASS\t: the name of an Objective-C class", "An ObjCObject wrapping the given class"); static PyObject * ObjC_lookup_class (PyObject *self, PyObject *args) { char *classname; id class; if (!PyArg_ParseTuple (args, "s;class name", &classname)) return NULL; if (!(class = LOOKUPCLASS(classname))) { #define ERRMSG "Objective-C class `%s' is unknown to the runtime" char errmsg[sizeof ERRMSG + strlen (classname)]; sprintf (errmsg, ERRMSG, classname); PyErr_SetString (ObjC_Error, errmsg); #undef ERRMSG return NULL; } return (PyObject *) ObjCObject_new (class); } static char ObjC_make_pointer_doc[] = FUNDOC("Cast an integer value to a generic pointer.", ".make_pointer (INT)", "INT\t: the integer value", "An ObjCPointer instance"); static PyObject * ObjC_make_pointer (PyObject *self, PyObject *args) { long value; if (PyArg_ParseTuple (args, "l;an integer", &value)) return (PyObject *) ObjCPointer_new ((void *) value, @encode (void)); return NULL; } static PyMethodDef ObjC_methods[] = { { "lookup_class", (PyCFunction) ObjC_lookup_class, METH_VARARGS, ObjC_lookup_class_doc }, { "make_pointer", (PyCFunction) ObjC_make_pointer, METH_VARARGS, ObjC_make_pointer_doc }, { 0, 0, 0, 0 } }; PyObject *ObjC_Error; NSString *PyObjCException = @"PyObjCException"; #include "OC_PythonBundle.h" #if 0 #include @interface PyObjCModule : PyNSBundledModule @end @implementation PyObjCModule + (void) initModule #else void initObjC (void) #endif { PyObject *m, *d; extern void ObjCObject_initialize (void); m = Py_InitModule4 ("ObjC", ObjC_methods, ObjC_doc, NULL, PYTHON_API_VERSION); d = PyModule_GetDict (m); ObjC_Error = PyString_FromString ("ObjC.error"); PyDict_SetItemString (d, "error", ObjC_Error); PyDict_SetItemString (d, "runtime", (PyObject *) ObjCRuntime_new()); PyDict_SetItemString (d, "__version__", PyFloat_FromDouble (PyObjC_VERSION)); // Force the load of these classes/categories [OC_PythonBundle class]; ObjCObject_initialize(); if (PyErr_Occurred()) Py_FatalError ("can't initialize module ObjC"); #if defined(WITH_THREAD) && !defined(GNU_RUNTIME) objc_setMultithreaded (1); #endif } #if 0 @end #endif