]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Initial revision
authorGuido van Rossum <guido@python.org>
Fri, 4 Aug 1995 04:20:48 +0000 (04:20 +0000)
committerGuido van Rossum <guido@python.org>
Fri, 4 Aug 1995 04:20:48 +0000 (04:20 +0000)
Modules/getpath.c [new file with mode: 0644]
Modules/main.c [new file with mode: 0644]
Modules/objc.c [new file with mode: 0644]
Python/frozen.c [new file with mode: 0644]
Python/getcompiler.c [new file with mode: 0644]
Python/getcopyright.c [new file with mode: 0644]
Python/getplatform.c [new file with mode: 0644]
Python/getversion.c [new file with mode: 0644]

diff --git a/Modules/getpath.c b/Modules/getpath.c
new file mode 100644 (file)
index 0000000..8e1c00d
--- /dev/null
@@ -0,0 +1,41 @@
+#include "Python.h"
+#include "osdefs.h"
+
+
+#ifndef PYTHONPATH
+#define PYTHONPATH ".:/usr/local/lib/python"
+#endif
+
+
+/* Return the initial python search path.  This is called once from
+   initsys() to initialize sys.path.  The environment variable
+   PYTHONPATH is fetched and the default path appended.  The default
+   path may be passed to the preprocessor; if not, a system-dependent
+   default is used. */
+
+char *
+getpythonpath()
+{
+       char *path = getenv("PYTHONPATH");
+       char *defpath = PYTHONPATH;
+       static char *buf = NULL;
+       char *p;
+       int n;
+
+       if (path == NULL)
+               path = "";
+       n = strlen(path) + strlen(defpath) + 2;
+       if (buf != NULL) {
+               free(buf);
+               buf = NULL;
+       }
+       buf = malloc(n);
+       if (buf == NULL)
+               Py_FatalError("not enough memory to copy module search path");
+       strcpy(buf, path);
+       p = buf + strlen(buf);
+       if (p != buf)
+               *p++ = DELIM;
+       strcpy(p, defpath);
+       return buf;
+}
diff --git a/Modules/main.c b/Modules/main.c
new file mode 100644 (file)
index 0000000..4763a59
--- /dev/null
@@ -0,0 +1,246 @@
+/***********************************************************
+Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
+The Netherlands.
+
+                        All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its 
+documentation for any purpose and without fee is hereby granted, 
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in 
+supporting documentation, and that the names of Stichting Mathematisch
+Centrum or CWI not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior permission.
+
+STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
+THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
+FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+******************************************************************/
+
+/* Python interpreter main program */
+
+#include "Python.h"
+
+
+/* Interface to getopt(): */
+extern int optind;
+extern char *optarg;
+extern int getopt(); /* PROTO((int, char **, char *)); -- not standardized */
+
+
+extern int Py_DebugFlag; /* For parser.c, declared in pythonrun.c */
+extern int Py_VerboseFlag; /* For import.c, declared in pythonrun.c */
+extern int Py_SuppressPrintingFlag; /* For ceval.c, declared in pythonrun.c */
+
+
+/* Subroutines that live in their own file */
+extern char *getversion();
+extern char *getcopyright();
+
+
+/* For getprogramname(); set by main() */
+static char *argv0;
+
+/* For getargcargv(); set by main() */
+static char **orig_argv;
+static int  orig_argc;
+
+
+/* Short usage message (with %s for argv0) */
+static char *usage_line =
+"usage: %s [-d] [-i] [-s] [-u ] [-v] [-c cmd | file | -] [arg] ...\n";
+
+/* Long usage message, split into parts < 512 bytes */
+static char *usage_top = "\n\
+Options and arguments (and corresponding environment variables):\n\
+-d     : debug output from parser (also PYTHONDEBUG=x)\n\
+-i     : inspect interactively after running script (also PYTHONINSPECT=x)\n\
+-s     : suppress printing of top level expressions (also PYTHONSUPPRESS=x)\n\
+-u     : unbuffered stdout and stderr (also PYTHONUNBUFFERED=x)\n\
+-v     : verbose (trace import statements) (also PYTHONVERBOSE=x)\n\
+-c cmd : program passed in as string (terminates option list)\n\
+";
+static char *usage_bot = "\
+file   : program read from script file\n\
+-      : program read from stdin (default; interactive mode if a tty)\n\
+arg ...: arguments passed to program in sys.argv[1:]\n\
+\n\
+Other environment variables:\n\
+PYTHONSTARTUP: file executed on interactive startup (no default)\n\
+PYTHONPATH   : colon-separated list of directories prefixed to the\n\
+               default module search path.  The result is sys.path.\n\
+";
+
+
+/* Main program */
+
+int
+main(argc, argv)
+       int argc;
+       char **argv;
+{
+       int c;
+       int sts;
+       char *command = NULL;
+       char *filename = NULL;
+       FILE *fp = stdin;
+       char *p;
+       int inspect = 0;
+       int unbuffered = 0;
+
+       orig_argc = argc;       /* For getargcargv() */
+       orig_argv = argv;
+       argv0 = argv[0];        /* For getprogramname() */
+
+       if ((p = getenv("PYTHONDEBUG")) && *p != '\0')
+               Py_DebugFlag = 1;
+       if ((p = getenv("PYTHONSUPPRESS")) && *p != '\0')
+               Py_SuppressPrintingFlag = 1;
+       if ((p = getenv("PYTHONVERBOSE")) && *p != '\0')
+               Py_VerboseFlag = 1;
+       if ((p = getenv("PYTHONINSPECT")) && *p != '\0')
+               inspect = 1;
+       if ((p = getenv("PYTHONUNBUFFERED")) && *p != '\0')
+               unbuffered = 1;
+
+       while ((c = getopt(argc, argv, "c:disuv")) != EOF) {
+               if (c == 'c') {
+                       /* -c is the last option; following arguments
+                          that look like options are left for the
+                          the command to interpret. */
+                       command = malloc(strlen(optarg) + 2);
+                       if (command == NULL)
+                               Py_FatalError(
+                                  "not enough memory to copy -c argument");
+                       strcpy(command, optarg);
+                       strcat(command, "\n");
+                       break;
+               }
+               
+               switch (c) {
+
+               case 'd':
+                       Py_DebugFlag++;
+                       break;
+
+               case 'i':
+                       inspect++;
+                       break;
+
+               case 's':
+                       Py_SuppressPrintingFlag++;
+                       break;
+
+               case 'u':
+                       unbuffered++;
+                       break;
+
+               case 'v':
+                       Py_VerboseFlag++;
+                       break;
+
+               /* This space reserved for other options */
+
+               default:
+                       fprintf(stderr, usage_line, argv[0]);
+                       fprintf(stderr, usage_top);
+                       fprintf(stderr, usage_bot);
+                       exit(2);
+                       /*NOTREACHED*/
+
+               }
+       }
+
+       if (unbuffered) {
+#ifndef MPW
+               setbuf(stdout, (char *)NULL);
+               setbuf(stderr, (char *)NULL);
+#else
+               /* On MPW (3.2) unbuffered seems to hang */
+               setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ);
+               setvbuf(stderr, (char *)NULL, _IOLBF, BUFSIZ);
+#endif
+       }
+
+       if (command == NULL && optind < argc &&
+           strcmp(argv[optind], "-") != 0)
+               filename = argv[optind];
+
+       if (Py_VerboseFlag ||
+           command == NULL && filename == NULL && isatty((int)fileno(fp)))
+               fprintf(stderr, "Python %s\n%s\n",
+                       getversion(), getcopyright());
+       
+       if (filename != NULL) {
+               if ((fp = fopen(filename, "r")) == NULL) {
+                       fprintf(stderr, "%s: can't open file '%s'\n",
+                               argv[0], filename);
+                       exit(2);
+               }
+       }
+       
+       Py_Initialize();
+       
+       if (command != NULL) {
+               /* Backup optind and force sys.argv[0] = '-c' */
+               optind--;
+               argv[optind] = "-c";
+       }
+
+       PySys_SetArgv(argc-optind, argv+optind);
+
+       if (command) {
+               sts = PyRun_SimpleString(command) != 0;
+       }
+       else {
+               if (filename == NULL && isatty((int)fileno(fp))) {
+                       char *startup = getenv("PYTHONSTARTUP");
+                       if (startup != NULL && startup[0] != '\0') {
+                               FILE *fp = fopen(startup, "r");
+                               if (fp != NULL) {
+                                       (void) PyRun_SimpleFile(fp, startup);
+                                       PyErr_Clear();
+                                       fclose(fp);
+                               }
+                       }
+               }
+               sts = PyRun_AnyFile(
+                       fp, filename == NULL ? "<stdin>" : filename) != 0;
+               if (filename != NULL)
+                       fclose(fp);
+       }
+
+       if (inspect && isatty((int)fileno(stdin)) &&
+           (filename != NULL || command != NULL))
+               sts = PyRun_AnyFile(stdin, "<stdin>") != 0;
+
+       Py_Exit(sts);
+       /*NOTREACHED*/
+}
+
+
+/* Return the program name -- some code out there needs this. */
+
+char *
+getprogramname()
+{
+       return argv0;
+}
+
+
+/* Make the *original* argc/argv available to other modules.
+   This is rare, but it is needed by the secureware extension. */
+
+void
+getargcargv(argc,argv)
+       int *argc;
+       char ***argv;
+{
+       *argc = orig_argc;
+       *argv = orig_argv;
+}
diff --git a/Modules/objc.c b/Modules/objc.c
new file mode 100644 (file)
index 0000000..9e70912
--- /dev/null
@@ -0,0 +1,651 @@
+/***********************************************************
+Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
+The Netherlands.
+
+                        All Rights Reserved
+
+Permission to use, copy, modify, and distribute this software and its 
+documentation for any purpose and without fee is hereby granted, 
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in 
+supporting documentation, and that the names of Stichting Mathematisch
+Centrum or CWI not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior permission.
+
+STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
+THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
+FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+******************************************************************/
+
+/* Objective-C interface for NeXTStep */
+/* Tested with NeXTStep 3.3 on Intel and Sparc architectures */
+
+/* Original author: Jon M. Kutemeier */
+/* Revamped and maintained by: Guido van Rossum */
+
+/* XXX To do:
+   - bug??? x.send('name', []) gives weird error
+   - rename functions from objc_* to ObjC_*
+   - change send(sel, [a, b, c]) to send(self, a, b, c)
+   - call back to Python from Objective-C
+ */
+
+/* Python header file */
+#include "Python.h"
+
+/* NeXT headers */
+#include <sys/param.h>
+#include <mach-o/rld.h>
+#include <objc/objc.h>
+#include <objc/objc-runtime.h>
+#import <remote/NXProxy.h>
+
+/* Distinguish between ObjC classes and instances */
+typedef enum {
+    OBJC_CLASS,
+    OBJC_INSTANCE,
+} ObjC_Typecode;
+
+/* Exception raised for ObjC specific errors */
+static PyObject *ObjC_Error;
+
+/* Python wrapper about ObjC id (instance or class) */
+typedef struct {
+    PyObject_HEAD
+    id             obj;
+    ObjC_Typecode  type;
+    int            owned;
+} ObjCObject;
+
+/* Corresponding Python type object */
+staticforward PyTypeObject ObjC_Type;
+
+/* Corresponding Python type check macro */
+#define ObjC_Check(o) ((o)->ob_type == &ObjC_Type)
+
+/* Create a new ObjCObject */
+static ObjCObject *
+newObjCObject(obj, type, owned)
+    id obj;
+    ObjC_Typecode type;
+    int owned;
+{
+    ObjCObject *self;
+
+    self = PyObject_NEW(ObjCObject, &ObjC_Type);
+    if (self == NULL)
+       return NULL;
+
+    self->obj = obj;
+    self->type = type;
+    self->owned = owned;
+
+    return self;
+}
+
+static void
+objc_sendfree(self)
+    ObjCObject *self;
+{
+    if (self->obj)
+       self->obj = (id)objc_msgSend(self->obj, SELUID("free"));
+}
+
+/* Deallocate an ObjCObject */
+static void
+objc_dealloc(self)
+    ObjCObject *self;
+{
+    if (self->owned)
+       objc_sendfree(self);
+    PyMem_DEL(self);
+}
+
+/* Return a string representation of an ObjCObject */
+static PyObject *
+objc_repr(self)
+    ObjCObject *self;
+{
+    char buffer[512];
+    char *p = buffer;
+    if (self->obj == nil)
+       p = "<Objective-C nil>";
+    else {
+       char *t;
+       switch (self->type) {
+       case OBJC_CLASS: t = "class"; break;
+       case OBJC_INSTANCE: t = "instance"; break;
+       default: t = "???"; break;
+       }
+       sprintf(buffer, "<Objective-C %s %s at %lx>",
+               NAMEOF(self->obj), t, (long)(self->obj));
+    }
+    return PyString_FromString(p);
+}
+
+/*** ObjCObject methods ***/
+
+/* Call an object's free method */
+static PyObject *
+objc_free(self, args)
+    ObjCObject *self;
+    PyObject *args;
+{
+    if (!PyArg_ParseTuple(args, ""))
+       return NULL;
+    objc_sendfree(self);
+}
+
+/* Send a message to an ObjCObject.
+   The Python call looks like e.g. obj.send('moveTo::', [arg1, arg2])
+   which translates into Objective-C as [obj moveTo: arg1 : arg2] */
+static PyObject *
+objc_send(self, args)
+    ObjCObject *self;
+    PyObject *args;
+{
+    char *methodname;
+    char *margBuff = NULL;
+    PyObject *retobject = NULL;
+    PyObject *arglist;
+    id receiver, obj;
+    char *type;
+    SEL sel;
+    Method meth;
+    unsigned int margCount, margSize;
+    int offset, i;
+
+    if (!PyArg_ParseTuple(args, "sO!", &methodname, &PyList_Type, &arglist))
+       return NULL;
+
+    /* Get the method descriptor from the object */
+
+    receiver = self->obj;
+    sel = SELUID(methodname);
+
+    switch(self->type) {
+    case OBJC_CLASS:
+       meth = class_getClassMethod(receiver->isa, sel);
+       break;
+    case OBJC_INSTANCE:
+       meth = class_getInstanceMethod(receiver->isa, sel);
+       break;
+    default:
+       PyErr_SetString(ObjC_Error,
+                       "receiver's type is neither instance not class!?!?");
+       return NULL;
+    }
+
+    if (!meth) {
+       PyErr_SetString(ObjC_Error, "receiver has no method by that name");
+       return NULL;
+    }
+
+    /* Fill in the argument list, type-checking the arguments */
+
+    margCount = method_getNumberOfArguments(meth);
+
+    if (PyList_Size(arglist) + 2 != margCount) {
+       PyErr_SetString(ObjC_Error,
+                       "wrong number of arguments for this method");
+           return NULL;
+    }
+
+    margSize = method_getSizeOfArguments(meth);
+    margBuff = PyMem_NEW(char, margSize+1);
+    if (margBuff == NULL)
+       return PyErr_NoMemory();
+
+    method_getArgumentInfo(meth, 0, &type, &offset);
+    marg_setValue(margBuff, offset, id, receiver);
+
+    method_getArgumentInfo(meth, 1, &type, &offset);
+    marg_setValue(margBuff, offset, SEL, sel);
+
+    for (i = 2; i < margCount; i++) {
+       PyObject *argument;
+       method_getArgumentInfo(meth, i, &type, &offset);
+
+       argument = PyList_GetItem(arglist, i-2);
+
+       /* scan past protocol-type modifiers */
+       while (strchr("rnNoOV", *type) != 0)
+           type++;
+
+       /* common type checks */
+       switch(*type) {
+
+           /* XXX The errors here should point out which argument */
+
+       case 'c':
+       case '*':
+       case 'C':
+           if (!PyString_Check(argument)) {
+               PyErr_SetString(ObjC_Error, "string argument expected");
+               goto error;
+           }
+           break;
+
+       case 'i':
+       case 's':
+       case 'I':
+       case 'S':
+       case 'l':
+       case 'L':
+       case '^':
+           if (!PyInt_Check(argument)) {
+               PyErr_SetString(ObjC_Error, "integer argument expected");
+               goto error;
+           }
+           break;
+
+       case 'f':
+       case 'd':
+           if (!PyFloat_Check(argument)) {
+               PyErr_SetString(ObjC_Error, "float argument expected");
+               goto error;
+           }
+           break;
+
+       }
+
+       /* convert and store the argument */
+       switch (*type) {
+
+       case 'c': /* char */
+           marg_setValue(margBuff, offset, char,
+                         PyString_AsString(argument)[0]);
+           break;
+
+       case 'C': /* unsigned char */
+           marg_setValue(margBuff, offset, unsigned char,
+                         PyString_AsString(argument)[0]);
+           break;
+
+       case '*': /* string */
+           marg_setValue(margBuff, offset, char *,
+                         PyString_AsString(argument));
+           break;
+
+       case 'i': /* int */
+           marg_setValue(margBuff, offset, int,
+                         PyInt_AsLong(argument));
+           break;
+
+       case 'I': /* unsigned int */
+           marg_setValue(margBuff, offset, unsigned int,
+                         PyInt_AsLong(argument));
+           break;
+
+       case 's': /* short */
+           marg_setValue(margBuff, offset, short,
+                         PyInt_AsLong(argument));
+           break;
+
+       case 'S': /* unsigned short */
+           marg_setValue(margBuff, offset, unsigned short,
+                         PyInt_AsLong(argument));
+           break;
+
+       case 'l': /* long */
+           marg_setValue(margBuff, offset, long,
+                         PyInt_AsLong(argument));
+           break;
+
+       case 'L': /* unsigned long */
+           marg_setValue(margBuff, offset, unsigned long,
+                         PyInt_AsLong(argument));
+           break;
+
+       case 'f': /* float */
+           marg_setValue(margBuff, offset, float,
+                         (float)PyFloat_AsDouble(argument));
+           break;
+
+       case 'd': /* double */
+           marg_setValue(margBuff, offset, double,
+                         PyFloat_AsDouble(argument));
+           break;
+
+       case '@': /* id (or None) */
+           if (ObjC_Check(argument))
+               marg_setValue(margBuff, offset, id,
+                             ((ObjCObject *)(argument))->obj);
+           else if (argument == Py_None)
+               marg_setValue(margBuff, offset, id, nil);
+           else {
+               PyErr_SetString(ObjC_Error, "id or None argument expected");
+               goto error;
+           }
+           break;
+
+       case '^': /* void * (use int) */
+           marg_setValue(margBuff, offset, void *,
+                         (void *)PyInt_AsLong(argument));
+           break;
+
+       case ':': /* SEL (use string or int) */
+           if (PyInt_Check(argument))
+               marg_setValue(margBuff, offset, SEL,
+                             (SEL)PyInt_AsLong(argument));
+           else if (PyString_Check(argument))
+               marg_setValue(margBuff, offset, SEL,
+                             SELUID(PyString_AsString(argument)));
+           else {
+               PyErr_SetString(ObjC_Error,
+                               "selector string or int argument expected");
+               goto error;
+           }
+           break;
+
+       case '#': /* Class (may also use int) */
+           if (ObjC_Check(argument) &&
+               ((ObjCObject *)argument)->type == OBJC_INSTANCE)
+               marg_setValue(margBuff, offset, Class *,
+                             (Class *)((ObjCObject *)argument)->obj);
+           else if (PyInt_Check(argument))
+               marg_setValue(margBuff, offset, Class *,
+                             (Class *)PyInt_AsLong(argument));
+           else {
+               PyErr_SetString(ObjC_Error,
+                               "ObjC class object required");
+               goto error;
+           }
+           break;
+
+       default:
+           PyErr_SetString(ObjC_Error, "unknown argument type");
+           goto error;
+
+       }
+    }
+
+    /* Call the method and set the return value */
+
+    type = meth->method_types;
+
+    while (strchr("rnNoOV", *type))
+       type++;
+
+    switch(*type) {
+
+/* Cast objc_msgSendv to a function returning the right thing */
+#define MS_CAST(type) ((type (*)())objc_msgSendv)
+
+    case 'c':
+    case '*':
+    case 'C':
+       retobject = (PyObject *)PyString_FromString(
+           MS_CAST(char *)(receiver, sel, margSize, margBuff));
+       break;
+
+    case 'i':
+    case 's':
+    case 'I':
+    case 'S':
+       retobject = (PyObject *)PyInt_FromLong(
+           MS_CAST(int)(receiver, sel, margSize, margBuff));
+       break;
+
+    case 'l':
+    case 'L':
+    case '^':
+       retobject = (PyObject *)PyInt_FromLong(
+           MS_CAST(long)(receiver, sel, margSize, margBuff));
+       break;
+
+    case 'f':
+       retobject = (PyObject *)PyFloat_FromDouble(
+           MS_CAST(float)(receiver, sel, margSize, margBuff));
+       break;
+
+    case 'd':
+       retobject = (PyObject *)PyFloat_FromDouble(
+           MS_CAST(double)(receiver, sel, margSize, margBuff));
+       break;
+
+    case '@':
+       obj = MS_CAST(id)(receiver, sel, margSize, margBuff);
+       if (obj == nil) {
+           retobject = Py_None;
+           Py_INCREF(retobject);
+       }
+       else if (obj != receiver)
+           retobject = (PyObject *)newObjCObject(obj, OBJC_INSTANCE, 0);
+       else {
+           retobject = (PyObject *)self;
+           Py_INCREF(retobject);
+       }
+       break;
+
+    case ':':
+       retobject = (PyObject *)PyInt_FromLong(
+           (long)MS_CAST(SEL)(receiver, sel, margSize, margBuff));
+       break;
+
+    case '#':
+       retobject = (PyObject *)PyInt_FromLong(
+           (long)MS_CAST(Class *)(receiver, sel, margSize, margBuff));
+       break;
+
+#undef MS_CAST
+
+    }
+
+  error:
+    PyMem_XDEL(margBuff);
+    return retobject;
+}
+
+/* List of methods for ObjCObject */
+static PyMethodDef objc_methods[] = {
+    {"send",   (PyCFunction)objc_send, 1},
+    {"free",   (PyCFunction)objc_free, 1},
+    {NULL,     NULL}           /* sentinel */
+};
+
+/* Get an attribute of an ObjCObject */
+static PyObject *
+objc_getattr(self, name)
+    ObjCObject *self;
+    char *name;
+{
+    PyObject *method;
+
+    /* Try a function method */
+    method = Py_FindMethod(objc_methods, (PyObject *)self, name);
+    if (method != NULL)
+       return method;
+    PyErr_Clear();
+
+    /* Try an instance variable */
+    if (strcmp(name, "obj") == 0)
+       return PyInt_FromLong((long)self->obj);
+    if (strcmp(name, "type") == 0)
+       return PyInt_FromLong((long)self->type);
+    if (strcmp(name, "owned") == 0)
+       return PyInt_FromLong((long)self->owned);
+    if (strcmp(name, "name") == 0)
+       return PyString_FromString(NAMEOF(self->obj));
+    if (strcmp(name, "__members__") == 0)
+       return Py_BuildValue("[sss]", "name", "obj", "owned", "type");
+
+    PyErr_SetString(PyExc_AttributeError, name);
+    return NULL;
+}
+
+/* The type object */
+static PyTypeObject ObjC_Type = {
+    PyObject_HEAD_INIT(&PyType_Type)
+    0,                                  /*ob_size*/
+    "objc",                             /*tp_name*/
+    sizeof(ObjCObject),                 /*tp_basicsize*/
+    0,                                  /*tp_itemsize*/
+    /* methods */
+    (destructor)objc_dealloc,           /*tp_dealloc*/
+    0,                                         /*tp_print*/
+    (getattrfunc)objc_getattr,          /*tp_getattr*/
+    0,                                 /*tp_setattr*/
+    0,                                         /*tp_compare*/
+    (reprfunc)objc_repr,               /*tp_repr*/
+    0,                                  /*tp_as_number*/
+    0,                                  /*tp_as_sequence*/
+    0,                                  /*tp_as_mapping*/
+    0,                                 /*tp_hash*/
+    0,                                 /*tp_call*/
+    0,                                 /*tp_str*/
+    0, 0, 0, 0,                                /*xxx1-4*/
+    "Objective-C id wrapper",          /*tp_doc*/
+};
+
+
+
+/*** Top-level functions ***/
+
+/* Max #files passed to loadobjectfile() */
+#define MAXRLD 128
+
+/* Load a list of object files */
+static PyObject *
+objc_loadobjectfiles(self, args)
+PyObject *self;   /* Not used */
+PyObject *args;
+{
+    NXStream *errorStream;
+    struct mach_header *new_header;
+    const char *filenames[MAXRLD+1];
+    long ret;
+    char *streamBuf;
+    PyObject *filelist, *file;
+    int listsize, len, maxLen, i;
+
+    if (!PyArg_ParseTuple(args, "O!", &PyList_Type, &filelist))
+       return NULL;
+
+    listsize = PyList_Size(filelist);
+
+    if (listsize > MAXRLD) {
+       PyErr_SetString(ObjC_Error, "more than 128 files in list");
+       return NULL;
+    }
+
+    errorStream = NXOpenMemory(NULL, 0, NX_WRITEONLY);
+
+    for (i = 0; i < listsize; i++) {
+       file = PyList_GetItem(filelist, i);
+
+       if (!PyString_Check(file))
+           {
+               PyErr_SetString(ObjC_Error,
+                               "all list items must be strings");
+               return NULL;
+           }
+
+       filenames[i] = PyString_AsString(file);
+    }
+
+    filenames[listsize] = NULL;
+
+    ret = objc_loadModules(filenames, errorStream, NULL, &new_header, NULL);
+
+    /* extract the error messages for the exception */
+
+    if(ret) {
+       NXPutc(errorStream, (char)0);
+
+       NXGetMemoryBuffer(errorStream, &streamBuf, &len, &maxLen);
+       PyErr_SetString(ObjC_Error, streamBuf);
+    }
+
+    NXCloseMemory(errorStream, NX_FREEBUFFER);
+
+    if(ret)
+       return NULL;
+
+    Py_XINCREF(Py_None);
+    return Py_None;
+}
+
+static PyObject *
+objc_lookupclass(self, args)
+PyObject *self;   /* Not used */
+PyObject *args;
+{
+    char *classname;
+    id    class;
+
+    if (!PyArg_ParseTuple(args, "s", &classname))
+       return NULL;
+
+    if (!(class = objc_lookUpClass(classname)))
+       {
+           PyErr_SetString(ObjC_Error, "unknown ObjC class");
+           return NULL;
+       }
+
+    return (PyObject *)newObjCObject(class, OBJC_CLASS, 0);
+}
+
+/* List all classes */
+static PyObject *
+objc_listclasses(self, args)
+    ObjCObject *self;
+    PyObject *args;
+{
+    NXHashTable *class_hash = objc_getClasses();
+    NXHashState state = NXInitHashState(class_hash);
+    Class classid;
+    PyObject *list;
+
+    if (!PyArg_ParseTuple(args, ""))
+       return NULL;
+
+    list = PyList_New(0);
+    if (list == NULL)
+       return NULL;
+  
+    while (NXNextHashState(class_hash, &state, (void**)&classid)) {
+       ObjCObject *item = newObjCObject(classid, OBJC_CLASS, 0);
+       if (item == NULL || PyList_Append(list, (PyObject *)item) < 0) {
+           Py_XDECREF(item);
+           Py_DECREF(list);
+           return NULL;
+       }
+       Py_INCREF(item);
+    }
+
+    return list;
+}
+
+/* List of top-level functions */
+static PyMethodDef objc_class_methods[] = {
+    {"loadobjectfiles",        objc_loadobjectfiles, 1},
+    {"lookupclass",    objc_lookupclass, 1},
+    {"listclasses",    objc_listclasses, 1},
+    {NULL,             NULL}           /* sentinel */
+};
+
+/* Initialize for the module */
+void
+initobjc()
+{
+    PyObject *m, *d;
+
+    m = Py_InitModule("objc", objc_class_methods);
+    d = PyModule_GetDict(m);
+
+    ObjC_Error = PyString_FromString("objc.error");
+    PyDict_SetItemString(d, "error", ObjC_Error);
+
+    if (PyErr_Occurred())
+       Py_FatalError("can't initialize module objc");
+
+#ifdef WITH_THREAD
+    objc_setMultithreaded(1);
+#endif
+}
diff --git a/Python/frozen.c b/Python/frozen.c
new file mode 100644 (file)
index 0000000..5c1d3b4
--- /dev/null
@@ -0,0 +1,21 @@
+/* In order to test the support for frozen modules, by default we
+   define a single frozen module, __hello__.  Loading it will print
+   some famous words... */
+
+static unsigned char M___hello__[] = {
+       99,0,0,0,0,0,0,115,15,0,0,0,127,0,0,127,
+       1,0,100,0,0,71,72,100,1,0,83,40,2,0,0,0,
+       115,14,0,0,0,72,101,108,108,111,32,119,111,114,108,100,
+       46,46,46,78,40,0,0,0,0,40,0,0,0,0,115,8,
+       0,0,0,104,101,108,108,111,46,112,121,115,1,0,0,0,
+       63,
+};
+
+struct frozen {
+       char *name;
+       unsigned char *code;
+       int size;
+} frozen_modules[] = {
+       {"__hello__", M___hello__, 81},
+       {0, 0, 0} /* sentinel */
+};
diff --git a/Python/getcompiler.c b/Python/getcompiler.c
new file mode 100644 (file)
index 0000000..a65789f
--- /dev/null
@@ -0,0 +1,17 @@
+#ifdef __GNUC__
+#define COMPILER " [GCC " __VERSION__ "]"
+#endif
+
+#ifndef COMPILER
+#ifdef __cplusplus
+#define COMPILER "[C++]"
+#else
+#define COMPILER "[C]"
+#endif
+#endif
+
+char *
+getcompiler()
+{
+       return COMPILER;
+}
diff --git a/Python/getcopyright.c b/Python/getcopyright.c
new file mode 100644 (file)
index 0000000..67b67c6
--- /dev/null
@@ -0,0 +1,7 @@
+/* Return the copyright string.  This is updated manually. */
+
+const char *
+getcopyright()
+{
+       return "Copyright 1991-1995 Stichting Mathematisch Centrum, Amsterdam";
+}
diff --git a/Python/getplatform.c b/Python/getplatform.c
new file mode 100644 (file)
index 0000000..01e6835
--- /dev/null
@@ -0,0 +1,9 @@
+#ifndef PLATFORM
+#define PLATFORM "unknown"
+#endif
+
+char *
+getplatform()
+{
+       return PLATFORM;
+}
diff --git a/Python/getversion.c b/Python/getversion.c
new file mode 100644 (file)
index 0000000..1f2accc
--- /dev/null
@@ -0,0 +1,21 @@
+/* Return the full version string. */
+
+#include "patchlevel.h"
+
+#define VERSION "%s (%s) %s"
+
+#ifdef __DATE__
+#define DATE __DATE__
+#else
+#define DATE "August 1 1995"
+#endif
+
+extern const char *getcompiler();
+
+const char *
+getversion()
+{
+       static char version[80];
+       sprintf(version, VERSION, PATCHLEVEL, DATE, getcompiler());
+       return version;
+}