* Python/import.c: support *.o/*.so as alternative for
        *module.o/*module.so

        * Python/import.c: if initializing a module did not enter the
        module into sys.modules, it may have raised an exception -- don't
        override this exception.

Merged NT changes

        * Python/import.c: add lost NT-specific code back in

Fixed NT changes
diff --git a/Python/import.c b/Python/import.c
index a8cfe5b..980ccd2 100644
--- a/Python/import.c
+++ b/Python/import.c
@@ -1,5 +1,5 @@
 /***********************************************************
-Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum,
+Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
 Amsterdam, The Netherlands.
 
                         All Rights Reserved
@@ -38,9 +38,9 @@
 #include "eval.h"
 #include "osdefs.h"
 
-extern int verbose; /* Defined in pythonmain.c */
+extern int verbose; /* Defined in pythonrun.c */
 
-extern long getmtime(); /* Defined in posixmodule.c */
+extern long getmtime(); /* In getmtime.c */
 
 #ifdef DEBUG
 #define D(x) x
@@ -48,20 +48,114 @@
 #define D(x)
 #endif
 
-#ifdef USE_DL
-#ifdef SUN_SHLIB
-#include <dlfcn.h>
-typedef void (*dl_funcptr)();
-#else
-#include "dl.h"
-#endif /* SUN_SHLIB */
+/* Explanation of some of the the various #defines used by dynamic linking...
 
-extern char *argv0;
+   symbol	-- defined for:
+
+   DYNAMIC_LINK -- any kind of dynamic linking
+   USE_RLD	-- NeXT dynamic linking
+   USE_DL	-- Jack's dl for IRIX 4 or GNU dld with emulation for Jack's dl
+   USE_SHLIB	-- SunOS or IRIX 5 (SVR4?) shared libraries
+   _AIX		-- AIX style dynamic linking
+   NT		-- NT style dynamic linking (using DLLs)
+   _DL_FUNCPTR_DEFINED	-- if the typedef dl_funcptr has been defined
+   WITH_MAC_DL	-- Mac dynamic linking (highly experimental)
+   SHORT_EXT	-- short extension for dynamic module, e.g. ".so"
+   LONG_EXT	-- long extension, e.g. "module.so"
+
+   (The other WITH_* symbols are used only once, to set the
+   appropriate symbols.)
+*/
+
+/* Configure dynamic linking */
+
+#ifdef NT
+#define DYNAMIC_LINK
+#include <windows.h>
+typedef FARPROC dl_funcptr;
+#define _DL_FUNCPTR_DEFINED
+#define SHORT_EXT ".dll"
+#define LONG_EXT "module.dll"
 #endif
 
+#if defined(NeXT) || defined(WITH_RLD)
+#define DYNAMIC_LINK
+#define USE_RLD
+#endif
+
+#ifdef WITH_SGI_DL
+#define DYNAMIC_LINK
+#define USE_DL
+#endif
+
+#ifdef WITH_DL_DLD
+#define DYNAMIC_LINK
+#define USE_DL
+#endif
+
+#ifdef WITH_MAC_DL
+#define DYNAMIC_LINK
+#endif
+
+#if !defined(DYNAMIC_LINK) && defined(HAVE_DLFCN_H) && defined(HAVE_DLOPEN)
+#define DYNAMIC_LINK
+#define USE_SHLIB
+#endif
+
+#ifdef _AIX
+#define DYNAMIC_LINK
+#include <sys/ldr.h>
+typedef void (*dl_funcptr)();
+#define _DL_FUNCPTR_DEFINED
+static void aix_loaderror(char *name);
+#endif
+
+#ifdef DYNAMIC_LINK
+
+#ifdef USE_SHLIB
+#include <dlfcn.h>
+#ifndef _DL_FUNCPTR_DEFINED
+typedef void (*dl_funcptr)();
+#endif
+#ifndef RTLD_LAZY
+#define RTLD_LAZY 1
+#endif
+#define SHORT_EXT ".so"
+#define LONG_EXT "module.so"
+#endif /* USE_SHLIB */
+
+#ifdef USE_DL
+#include "dl.h"
+#endif
+
+#ifdef WITH_MAC_DL
+#include "dynamic_load.h"
+#endif
+
+#ifdef USE_RLD
+#include <mach-o/rld.h>
+#define FUNCNAME_PATTERN "_init%s"
+#ifndef _DL_FUNCPTR_DEFINED
+typedef void (*dl_funcptr)();
+#endif
+#endif /* USE_RLD */
+
+extern char *getprogramname();
+
+#ifndef FUNCNAME_PATTERN
+#define FUNCNAME_PATTERN "init%s"
+#endif
+
+#if !defined(SHORT_EXT) && !defined(LONG_EXT)
+#define SHORT_EXT ".o"
+#define LONG_EXT "module.o"
+#endif /* !SHORT_EXT && !LONG_EXT */
+
+#endif /* DYNAMIC_LINK */
+
 /* Magic word to reject .pyc files generated by other Python versions */
 
-#define MAGIC 0x999902L /* Increment by one for each incompatible change */
+#define MAGIC 0x999903L /* Increment by one for each incompatible change */
 
 static object *modules;
 
@@ -108,18 +202,145 @@
 	char *mode;
 	enum filetype type;
 } filetab[] = {
-#ifdef USE_DL
-#ifdef SUN_SHLIB
-	{"module.so", "rb", C_EXTENSION},
-#else
-	{"module.o", "rb", C_EXTENSION},
-#endif /* SUN_SHLIB */
-#endif /* USE_DL */
+#ifdef DYNAMIC_LINK
+#ifdef SHORT_EXT
+	{SHORT_EXT, "rb", C_EXTENSION},
+#endif /* !SHORT_EXT */
+#ifdef LONG_EXT
+	{LONG_EXT, "rb", C_EXTENSION},
+#endif /* !LONG_EXT */
+#endif /* DYNAMIC_LINK */
 	{".py", "r", PY_SOURCE},
 	{".pyc", "rb", PY_COMPILED},
 	{0, 0}
 };
 
+#ifdef DYNAMIC_LINK
+static object *
+load_dynamic_module(name, namebuf, m, m_ret)
+	char *name;
+	char *namebuf;
+	object *m;
+	object **m_ret;
+{
+	char funcname[258];
+	dl_funcptr p = NULL;
+	if (m != NULL) {
+		err_setstr(ImportError,
+			   "cannot reload dynamically loaded module");
+		return NULL;
+	}
+	sprintf(funcname, FUNCNAME_PATTERN, name);
+#ifdef WITH_MAC_DL
+	{
+		object *v = dynamic_load(namebuf);
+		if (v == NULL)
+			return NULL;
+	}
+#else /* !WITH_MAC_DL */
+#ifdef USE_SHLIB
+	{
+#ifdef RTLD_NOW
+		/* RTLD_NOW: resolve externals now
+		   (i.e. core dump now if some are missing) */
+		void *handle = dlopen(namebuf, RTLD_NOW);
+#else
+		void *handle;
+		if (verbose)
+			printf("dlopen(\"%s\", %d);\n", namebuf, RTLD_LAZY);
+		handle = dlopen(namebuf, RTLD_LAZY);
+#endif /* RTLD_NOW */
+		if (handle == NULL) {
+			err_setstr(ImportError, dlerror());
+			return NULL;
+		}
+		p = (dl_funcptr) dlsym(handle, funcname);
+	}
+#endif /* USE_SHLIB */
+#ifdef _AIX
+	p = (dl_funcptr) load(namebuf, 1, 0);
+	if (p == NULL) {
+		aix_loaderror(namebuf);
+		return NULL;
+	}
+#endif /* _AIX */
+#ifdef NT
+	{
+		HINSTANCE hDLL;
+		hDLL = LoadLibrary(namebuf);
+		if (hDLL==NULL){
+			char errBuf[64];
+			sprintf(errBuf, "DLL load failed with error code %d",
+				GetLastError());
+			err_setstr(ImportError, errBuf);
+		return NULL;
+		}
+		p = GetProcAddress(hDLL, funcname);
+	}
+#endif /* NT */
+#ifdef USE_DL
+	p =  dl_loadmod(getprogramname(), namebuf, funcname);
+#endif /* USE_DL */
+#ifdef USE_RLD
+	{
+		NXStream *errorStream;
+		struct mach_header *new_header;
+		const char *filenames[2];
+		long ret;
+		unsigned long ptr;
+
+		errorStream = NXOpenMemory(NULL, 0, NX_WRITEONLY);
+		filenames[0] = namebuf;
+		filenames[1] = NULL;
+		ret = rld_load(errorStream, &new_header, 
+				filenames, NULL);
+
+		/* extract the error messages for the exception */
+		if(!ret) {
+			char *streamBuf;
+			int len, maxLen;
+
+			NXPutc(errorStream, (char)0);
+
+			NXGetMemoryBuffer(errorStream,
+				&streamBuf, &len, &maxLen);
+			err_setstr(ImportError, streamBuf);
+		}
+
+		if(ret && rld_lookup(errorStream, funcname, &ptr))
+			p = (dl_funcptr) ptr;
+
+		NXCloseMemory(errorStream, NX_FREEBUFFER);
+
+		if(!ret)
+			return NULL;
+	}
+#endif /* USE_RLD */
+
+	if (p == NULL) {
+		err_setstr(ImportError,
+		   "dynamic module does not define init function");
+		return NULL;
+	}
+	(*p)();
+
+#endif /* !WITH_MAC_DL */
+	*m_ret = m = dictlookup(modules, name);
+	if (m == NULL) {
+		if (err_occurred() == NULL)
+			err_setstr(SystemError,
+				   "dynamic module not initialized properly");
+		return NULL;
+	}
+	if (verbose)
+		fprintf(stderr,
+			"import %s # dynamically loaded from %s\n",
+			name, namebuf);
+	INCREF(None);
+	return None;
+}
+#endif /* DYNAMIC_LINK */
+
 static object *
 get_module(m, name, m_ret)
 	/*module*/object *m;
@@ -182,35 +403,34 @@
 			if (magic != MAGIC) {
 				if (verbose)
 					fprintf(stderr,
-						"# %s.pyc has bad magic\n",
-						name);
+						"# %s has bad magic\n",
+						namebuf);
 			}
 			else {
 				pyc_mtime = rd_long(fpc);
 				if (pyc_mtime != mtime) {
 					if (verbose)
 						fprintf(stderr,
-						  "# %s.pyc has bad mtime\n",
-						  name);
+						  "# %s has bad mtime\n",
+						  namebuf);
 				}
 				else {
 					fclose(fp);
 					fp = fpc;
 					if (verbose)
 					   fprintf(stderr,
-					     "# %s.pyc matches %s.py\n",
-						   name, name);
+					     "# %s matches %s.py\n",
+						   namebuf, name);
 					goto use_compiled;
 				}
 			}
 			fclose(fpc);
 		}
 		namebuf[len] = '\0';
-		err = parse_file(fp, namebuf, file_input, &n);
-		if (err != E_DONE) {
-			err_input(err);
+		n = parse_file(fp, namebuf, file_input);
+		fclose(fp);
+		if (n == NULL)
 			return NULL;
-		}
 		co = compile(n, namebuf);
 		freetree(n);
 		if (co == NULL)
@@ -254,8 +474,8 @@
 
 	case PY_COMPILED:
 		if (verbose)
-			fprintf(stderr, "# %s.pyc without %s.py\n",
-				name, name);
+			fprintf(stderr, "# %s without %s.py\n",
+				namebuf, name);
 		magic = rd_long(fp);
 		if (magic != MAGIC) {
 			err_setstr(ImportError,
@@ -279,44 +499,11 @@
 				name, namebuf);
 		break;
 
-#ifdef USE_DL
+#ifdef DYNAMIC_LINK
 	case C_EXTENSION:
-	      {
-		char funcname[258];
-		dl_funcptr p;
 		fclose(fp);
-		sprintf(funcname, "init%s", name);
-#ifdef SUN_SHLIB
-		{
-		  void *handle = dlopen (namebuf, 1);
-		  p = (dl_funcptr) dlsym(handle, funcname);
-		}
-#else
-		p =  dl_loadmod(argv0, namebuf, funcname);
-#endif /* SUN_SHLIB */
-		if (p == NULL) {
-			err_setstr(ImportError,
-			   "dynamic module does not define init function");
-			return NULL;
-		} else {
-			(*p)();
-			*m_ret = m = dictlookup(modules, name);
-			if (m == NULL) {
-				err_setstr(SystemError,
-				   "dynamic module not initialized properly");
-				return NULL;
-			} else {
-				if (verbose)
-					fprintf(stderr,
-				"import %s # dynamically loaded from %s\n",
-						name, namebuf);
-				INCREF(None);
-				return None;
-			}
-		}
-		break;
-	      }
-#endif /* USE_DL */
+		return load_dynamic_module(name, namebuf, m, m_ret);
+#endif /* DYNAMIC_LINK */
 
 	default:
 		fclose(fp);
@@ -363,9 +550,11 @@
 		if ((n = init_builtin(name)) || (n = init_frozen(name))) {
 			if (n < 0)
 				return NULL;
-			if ((m = dictlookup(modules, name)) == NULL)
-				err_setstr(SystemError,
-					   "builtin module missing");
+			if ((m = dictlookup(modules, name)) == NULL) {
+				if (err_occurred() == NULL)
+					err_setstr(SystemError,
+				   "builtin module not initialized properly");
+			}
 		}
 		else {
 			m = load_module(name);
@@ -379,6 +568,7 @@
 	object *m;
 {
 	char *name;
+	int i;
 	if (m == NULL || !is_moduleobject(m)) {
 		err_setstr(TypeError, "reload() argument must be module");
 		return NULL;
@@ -386,7 +576,21 @@
 	name = getmodulename(m);
 	if (name == NULL)
 		return NULL;
-	/* XXX Ought to check for builtin modules -- can't reload these... */
+	/* Check for built-in modules */
+	for (i = 0; inittab[i].name != NULL; i++) {
+		if (strcmp(name, inittab[i].name) == 0) {
+			err_setstr(ImportError,
+				   "cannot reload built-in module");
+			return NULL;
+		}
+	}
+	/* Check for frozen modules */
+	if ((i = init_frozen(name)) != 0) {
+		if (i < 0)
+			return NULL;
+		INCREF(None);
+		return None;
+	}
 	return get_module(m, name, (object **)NULL);
 }
 
@@ -423,6 +627,11 @@
 	int i;
 	for (i = 0; inittab[i].name != NULL; i++) {
 		if (strcmp(name, inittab[i].name) == 0) {
+			if (inittab[i].initfunc == NULL) {
+				err_setstr(ImportError,
+					   "cannot re-init internal module");
+				return -1;
+			}
 			if (verbose)
 				fprintf(stderr, "import %s # builtin\n",
 					name);
@@ -467,3 +676,58 @@
 	DECREF(v);
 	return 1;
 }
+
+
+#ifdef _AIX
+
+#include <ctype.h>	/* for isdigit()	*/
+#include <errno.h>	/* for global errno	*/
+#include <string.h>	/* for strerror()	*/
+
+void aix_loaderror(char *namebuf)
+{
+
+	char *message[8], errbuf[1024];
+	int i,j;
+
+	struct errtab { 
+		int errno;
+		char *errstr;
+	} load_errtab[] = {
+		{L_ERROR_TOOMANY,	"to many errors, rest skipped."},
+		{L_ERROR_NOLIB,		"can't load library:"},
+		{L_ERROR_UNDEF,		"can't find symbol in library:"},
+		{L_ERROR_RLDBAD,
+		 "RLD index out of range or bad relocation type:"},
+		{L_ERROR_FORMAT,	"not a valid, executable xcoff file:"},
+		{L_ERROR_MEMBER,
+		 "file not an archive or does not contain requested member:"},
+		{L_ERROR_TYPE,		"symbol table mismatch:"},
+		{L_ERROR_ALIGN,		"text allignment in file is wrong."},
+		{L_ERROR_SYSTEM,	"System error:"},
+		{L_ERROR_ERRNO,		NULL}
+	};
+
+#define LOAD_ERRTAB_LEN	(sizeof(load_errtab)/sizeof(load_errtab[0]))
+#define ERRBUF_APPEND(s)	strncat(errbuf, s, sizeof(errbuf))
+
+	sprintf(errbuf, " from module %s ", namebuf);
+
+	if (!loadquery(1, &message[0], sizeof(message))) 
+		ERRBUF_APPEND(strerror(errno));
+	for(i = 0; message[i] && *message[i]; i++) {
+		int nerr = atoi(message[i]);
+		for (j=0; j<LOAD_ERRTAB_LEN ; j++) {
+		    if (nerr == load_errtab[i].errno && load_errtab[i].errstr)
+			ERRBUF_APPEND(load_errtab[i].errstr);
+		}
+		while (isdigit(*message[i])) message[i]++ ; 
+		ERRBUF_APPEND(message[i]);
+		ERRBUF_APPEND("\n");
+	}
+	errbuf[strlen(errbuf)-1] = '\0' ;	/* trim off last newline */
+	err_setstr(ImportError, errbuf); 
+	return; 
+}
+
+#endif /* _AIX */