Initial revision
diff --git a/Modules/getpath.c b/Modules/getpath.c
new file mode 100644
index 0000000..8e1c00d
--- /dev/null
+++ b/Modules/getpath.c
@@ -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
index 0000000..4763a59
--- /dev/null
+++ b/Modules/main.c
@@ -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
index 0000000..9e70912
--- /dev/null
+++ b/Modules/objc.c
@@ -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
index 0000000..5c1d3b4
--- /dev/null
+++ b/Python/frozen.c
@@ -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
index 0000000..a65789f
--- /dev/null
+++ b/Python/getcompiler.c
@@ -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
index 0000000..67b67c6
--- /dev/null
+++ b/Python/getcopyright.c
@@ -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
index 0000000..01e6835
--- /dev/null
+++ b/Python/getplatform.c
@@ -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
index 0000000..1f2accc
--- /dev/null
+++ b/Python/getversion.c
@@ -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;
+}