
/* Module definition and import implementation */

#include "Python.h"

#include "Python-ast.h"
#undef Yield /* undefine macro conflicting with winbase.h */
#include "pyarena.h"
#include "pythonrun.h"
#include "errcode.h"
#include "marshal.h"
#include "code.h"
#include "compile.h"
#include "eval.h"
#include "osdefs.h"
#include "importdl.h"

#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
#ifdef __cplusplus
extern "C" { 
#endif

#ifdef MS_WINDOWS
/* for stat.st_mode */
typedef unsigned short mode_t;
#endif


/* Magic word to reject .pyc files generated by other Python versions.
   It should change for each incompatible change to the bytecode.

   The value of CR and LF is incorporated so if you ever read or write
   a .pyc file in text mode the magic number will be wrong; also, the
   Apple MPW compiler swaps their values, botching string constants.

   The magic numbers must be spaced apart at least 2 values, as the
   -U interpeter flag will cause MAGIC+1 being used. They have been
   odd numbers for some time now.

   There were a variety of old schemes for setting the magic number.
   The current working scheme is to increment the previous value by
   10.

   Known values:
       Python 1.5:   20121
       Python 1.5.1: 20121
       Python 1.5.2: 20121
       Python 1.6:   50428
       Python 2.0:   50823
       Python 2.0.1: 50823
       Python 2.1:   60202
       Python 2.1.1: 60202
       Python 2.1.2: 60202
       Python 2.2:   60717
       Python 2.3a0: 62011
       Python 2.3a0: 62021
       Python 2.3a0: 62011 (!)
       Python 2.4a0: 62041
       Python 2.4a3: 62051
       Python 2.4b1: 62061
       Python 2.5a0: 62071
       Python 2.5a0: 62081 (ast-branch)
       Python 2.5a0: 62091 (with)
       Python 2.5a0: 62092 (changed WITH_CLEANUP opcode)
       Python 2.5b3: 62101 (fix wrong code: for x, in ...)
       Python 2.5b3: 62111 (fix wrong code: x += yield)
       Python 2.5c1: 62121 (fix wrong lnotab with for loops and
       			    storing constants that should have been removed)
       Python 2.5c2: 62131 (fix wrong code: for x, in ... in listcomp/genexp)
       Python 2.6a0: 62151 (peephole optimizations and STORE_MAP opcode)
       Python 2.6a1: 62161 (WITH_CLEANUP optimization)
       Python 3000:   3000
       	              3010 (removed UNARY_CONVERT)
		      3020 (added BUILD_SET)
		      3030 (added keyword-only parameters)
		      3040 (added signature annotations)
		      3050 (print becomes a function)
		      3060 (PEP 3115 metaclass syntax)
		      3061 (string literals become unicode)
		      3071 (PEP 3109 raise changes)
		      3081 (PEP 3137 make __file__ and __name__ unicode)
		      3091 (kill str8 interning)
		      3101 (merge from 2.6a0, see 62151)
		      3103 (__file__ points to source file)
       Python 3.0a4: 3111 (WITH_CLEANUP optimization).
       Python 3.0a5: 3131 (lexical exception stacking, including POP_EXCEPT)
       Python 3.1a0: 3141 (optimize list, set and dict comprehensions:
			   change LIST_APPEND and SET_ADD, add MAP_ADD)
       Python 3.1a0: 3151 (optimize conditional branches:
			   introduce POP_JUMP_IF_FALSE and POP_JUMP_IF_TRUE)
       Python 3.2a0: 3160 (add SETUP_WITH)
*/

#define MAGIC (3160 | ((long)'\r'<<16) | ((long)'\n'<<24))
/* Magic word as global */
static long pyc_magic = MAGIC;

/* See _PyImport_FixupExtension() below */
static PyObject *extensions = NULL;

/* This table is defined in config.c: */
extern struct _inittab _PyImport_Inittab[];

/* Method from Parser/tokenizer.c */
extern char * PyTokenizer_FindEncoding(int);

struct _inittab *PyImport_Inittab = _PyImport_Inittab;

/* these tables define the module suffixes that Python recognizes */
struct filedescr * _PyImport_Filetab = NULL;

static const struct filedescr _PyImport_StandardFiletab[] = {
	{".py", "U", PY_SOURCE},
#ifdef MS_WINDOWS
	{".pyw", "U", PY_SOURCE},
#endif
	{".pyc", "rb", PY_COMPILED},
	{0, 0}
};


/* Initialize things */

void
_PyImport_Init(void)
{
	const struct filedescr *scan;
	struct filedescr *filetab;
	int countD = 0;
	int countS = 0;

	/* prepare _PyImport_Filetab: copy entries from
	   _PyImport_DynLoadFiletab and _PyImport_StandardFiletab.
	 */
#ifdef HAVE_DYNAMIC_LOADING
	for (scan = _PyImport_DynLoadFiletab; scan->suffix != NULL; ++scan)
		++countD;
#endif
	for (scan = _PyImport_StandardFiletab; scan->suffix != NULL; ++scan)
		++countS;
	filetab = PyMem_NEW(struct filedescr, countD + countS + 1);
	if (filetab == NULL)
		Py_FatalError("Can't initialize import file table.");
#ifdef HAVE_DYNAMIC_LOADING
	memcpy(filetab, _PyImport_DynLoadFiletab,
	       countD * sizeof(struct filedescr));
#endif
	memcpy(filetab + countD, _PyImport_StandardFiletab,
	       countS * sizeof(struct filedescr));
	filetab[countD + countS].suffix = NULL;

	_PyImport_Filetab = filetab;

	if (Py_OptimizeFlag) {
		/* Replace ".pyc" with ".pyo" in _PyImport_Filetab */
		for (; filetab->suffix != NULL; filetab++) {
			if (strcmp(filetab->suffix, ".pyc") == 0)
				filetab->suffix = ".pyo";
		}
	}
}

void
_PyImportHooks_Init(void)
{
	PyObject *v, *path_hooks = NULL, *zimpimport;
	int err = 0;

	/* adding sys.path_hooks and sys.path_importer_cache, setting up
	   zipimport */
	if (PyType_Ready(&PyNullImporter_Type) < 0)
		goto error;

	if (Py_VerboseFlag)
		PySys_WriteStderr("# installing zipimport hook\n");

	v = PyList_New(0);
	if (v == NULL)
		goto error;
	err = PySys_SetObject("meta_path", v);
	Py_DECREF(v);
	if (err)
		goto error;
	v = PyDict_New();
	if (v == NULL)
		goto error;
	err = PySys_SetObject("path_importer_cache", v);
	Py_DECREF(v);
	if (err)
		goto error;
	path_hooks = PyList_New(0);
	if (path_hooks == NULL)
		goto error;
	err = PySys_SetObject("path_hooks", path_hooks);
	if (err) {
  error:
		PyErr_Print();
		Py_FatalError("initializing sys.meta_path, sys.path_hooks, "
			      "path_importer_cache, or NullImporter failed"
			      );
	}

	zimpimport = PyImport_ImportModule("zipimport");
	if (zimpimport == NULL) {
		PyErr_Clear(); /* No zip import module -- okay */
		if (Py_VerboseFlag)
			PySys_WriteStderr("# can't import zipimport\n");
	}
	else {
		PyObject *zipimporter = PyObject_GetAttrString(zimpimport,
							       "zipimporter");
		Py_DECREF(zimpimport);
		if (zipimporter == NULL) {
			PyErr_Clear(); /* No zipimporter object -- okay */
			if (Py_VerboseFlag)
				PySys_WriteStderr(
				    "# can't import zipimport.zipimporter\n");
		}
		else {
			/* sys.path_hooks.append(zipimporter) */
			err = PyList_Append(path_hooks, zipimporter);
			Py_DECREF(zipimporter);
			if (err)
				goto error;
			if (Py_VerboseFlag)
				PySys_WriteStderr(
					"# installed zipimport hook\n");
		}
	}
	Py_DECREF(path_hooks);
}

void
_PyImport_Fini(void)
{
	Py_XDECREF(extensions);
	extensions = NULL;
	PyMem_DEL(_PyImport_Filetab);
	_PyImport_Filetab = NULL;
}


/* Locking primitives to prevent parallel imports of the same module
   in different threads to return with a partially loaded module.
   These calls are serialized by the global interpreter lock. */

#ifdef WITH_THREAD

#include "pythread.h"

static PyThread_type_lock import_lock = 0;
static long import_lock_thread = -1;
static int import_lock_level = 0;

void
_PyImport_AcquireLock(void)
{
	long me = PyThread_get_thread_ident();
	if (me == -1)
		return; /* Too bad */
	if (import_lock == NULL) {
		import_lock = PyThread_allocate_lock();
		if (import_lock == NULL)
			return;  /* Nothing much we can do. */
	}
	if (import_lock_thread == me) {
		import_lock_level++;
		return;
	}
	if (import_lock_thread != -1 || !PyThread_acquire_lock(import_lock, 0))
	{
		PyThreadState *tstate = PyEval_SaveThread();
		PyThread_acquire_lock(import_lock, 1);
		PyEval_RestoreThread(tstate);
	}
	import_lock_thread = me;
	import_lock_level = 1;
}

int
_PyImport_ReleaseLock(void)
{
	long me = PyThread_get_thread_ident();
	if (me == -1 || import_lock == NULL)
		return 0; /* Too bad */
	if (import_lock_thread != me)
		return -1;
	import_lock_level--;
	if (import_lock_level == 0) {
		import_lock_thread = -1;
		PyThread_release_lock(import_lock);
	}
	return 1;
}

/* This function used to be called from PyOS_AfterFork to ensure that newly
   created child processes do not share locks with the parent, but for some
   reason only on AIX systems. Instead of re-initializing the lock, we now
   acquire the import lock around fork() calls. */

void
_PyImport_ReInitLock(void)
{
}

#endif

static PyObject *
imp_lock_held(PyObject *self, PyObject *noargs)
{
#ifdef WITH_THREAD
	return PyBool_FromLong(import_lock_thread != -1);
#else
	return PyBool_FromLong(0);
#endif
}

static PyObject *
imp_acquire_lock(PyObject *self, PyObject *noargs)
{
#ifdef WITH_THREAD
	_PyImport_AcquireLock();
#endif
	Py_INCREF(Py_None);
	return Py_None;
}

static PyObject *
imp_release_lock(PyObject *self, PyObject *noargs)
{
#ifdef WITH_THREAD
	if (_PyImport_ReleaseLock() < 0) {
		PyErr_SetString(PyExc_RuntimeError,
				"not holding the import lock");
		return NULL;
	}
#endif
	Py_INCREF(Py_None);
	return Py_None;
}

static void
imp_modules_reloading_clear(void)
{
	PyInterpreterState *interp = PyThreadState_Get()->interp;
	if (interp->modules_reloading != NULL)
		PyDict_Clear(interp->modules_reloading);
}

/* Helper for sys */

PyObject *
PyImport_GetModuleDict(void)
{
	PyInterpreterState *interp = PyThreadState_GET()->interp;
	if (interp->modules == NULL)
		Py_FatalError("PyImport_GetModuleDict: no module dictionary!");
	return interp->modules;
}


/* List of names to clear in sys */
static char* sys_deletes[] = {
	"path", "argv", "ps1", "ps2",
	"last_type", "last_value", "last_traceback",
	"path_hooks", "path_importer_cache", "meta_path",
	/* misc stuff */
	"flags", "float_info",
	NULL
};

static char* sys_files[] = {
	"stdin", "__stdin__",
	"stdout", "__stdout__",
	"stderr", "__stderr__",
	NULL
};


/* Un-initialize things, as good as we can */

void
PyImport_Cleanup(void)
{
	Py_ssize_t pos, ndone;
	char *name;
	PyObject *key, *value, *dict;
	PyInterpreterState *interp = PyThreadState_GET()->interp;
	PyObject *modules = interp->modules;

	if (modules == NULL)
		return; /* Already done */

	/* Delete some special variables first.  These are common
	   places where user values hide and people complain when their
	   destructors fail.  Since the modules containing them are
	   deleted *last* of all, they would come too late in the normal
	   destruction order.  Sigh. */

	value = PyDict_GetItemString(modules, "builtins");
	if (value != NULL && PyModule_Check(value)) {
		dict = PyModule_GetDict(value);
		if (Py_VerboseFlag)
			PySys_WriteStderr("# clear builtins._\n");
		PyDict_SetItemString(dict, "_", Py_None);
	}
	value = PyDict_GetItemString(modules, "sys");
	if (value != NULL && PyModule_Check(value)) {
		char **p;
		PyObject *v;
		dict = PyModule_GetDict(value);
		for (p = sys_deletes; *p != NULL; p++) {
			if (Py_VerboseFlag)
				PySys_WriteStderr("# clear sys.%s\n", *p);
			PyDict_SetItemString(dict, *p, Py_None);
		}
		for (p = sys_files; *p != NULL; p+=2) {
			if (Py_VerboseFlag)
				PySys_WriteStderr("# restore sys.%s\n", *p);
			v = PyDict_GetItemString(dict, *(p+1));
			if (v == NULL)
				v = Py_None;
			PyDict_SetItemString(dict, *p, v);
		}
	}

	/* First, delete __main__ */
	value = PyDict_GetItemString(modules, "__main__");
	if (value != NULL && PyModule_Check(value)) {
		if (Py_VerboseFlag)
			PySys_WriteStderr("# cleanup __main__\n");
		_PyModule_Clear(value);
		PyDict_SetItemString(modules, "__main__", Py_None);
	}

	/* The special treatment of "builtins" here is because even
	   when it's not referenced as a module, its dictionary is
	   referenced by almost every module's __builtins__.  Since
	   deleting a module clears its dictionary (even if there are
	   references left to it), we need to delete the "builtins"
	   module last.  Likewise, we don't delete sys until the very
	   end because it is implicitly referenced (e.g. by print).

	   Also note that we 'delete' modules by replacing their entry
	   in the modules dict with None, rather than really deleting
	   them; this avoids a rehash of the modules dictionary and
	   also marks them as "non existent" so they won't be
	   re-imported. */

	/* Next, repeatedly delete modules with a reference count of
	   one (skipping builtins and sys) and delete them */
	do {
		ndone = 0;
		pos = 0;
		while (PyDict_Next(modules, &pos, &key, &value)) {
			if (value->ob_refcnt != 1)
				continue;
			if (PyUnicode_Check(key) && PyModule_Check(value)) {
				name = _PyUnicode_AsString(key);
				if (strcmp(name, "builtins") == 0)
					continue;
				if (strcmp(name, "sys") == 0)
					continue;
				if (Py_VerboseFlag)
					PySys_WriteStderr(
						"# cleanup[1] %s\n", name);
				_PyModule_Clear(value);
				PyDict_SetItem(modules, key, Py_None);
				ndone++;
			}
		}
	} while (ndone > 0);

	/* Next, delete all modules (still skipping builtins and sys) */
	pos = 0;
	while (PyDict_Next(modules, &pos, &key, &value)) {
		if (PyUnicode_Check(key) && PyModule_Check(value)) {
			name = _PyUnicode_AsString(key);
			if (strcmp(name, "builtins") == 0)
				continue;
			if (strcmp(name, "sys") == 0)
				continue;
			if (Py_VerboseFlag)
				PySys_WriteStderr("# cleanup[2] %s\n", name);
			_PyModule_Clear(value);
			PyDict_SetItem(modules, key, Py_None);
		}
	}

	/* Next, delete sys and builtins (in that order) */
	value = PyDict_GetItemString(modules, "sys");
	if (value != NULL && PyModule_Check(value)) {
		if (Py_VerboseFlag)
			PySys_WriteStderr("# cleanup sys\n");
		_PyModule_Clear(value);
		PyDict_SetItemString(modules, "sys", Py_None);
	}
	value = PyDict_GetItemString(modules, "builtins");
	if (value != NULL && PyModule_Check(value)) {
		if (Py_VerboseFlag)
			PySys_WriteStderr("# cleanup builtins\n");
		_PyModule_Clear(value);
		PyDict_SetItemString(modules, "builtins", Py_None);
	}

	/* Finally, clear and delete the modules directory */
	PyDict_Clear(modules);
	interp->modules = NULL;
	Py_DECREF(modules);
	Py_CLEAR(interp->modules_reloading);
}


/* Helper for pythonrun.c -- return magic number */

long
PyImport_GetMagicNumber(void)
{
	return pyc_magic;
}


/* Magic for extension modules (built-in as well as dynamically
   loaded).  To prevent initializing an extension module more than
   once, we keep a static dictionary 'extensions' keyed by module name
   (for built-in modules) or by filename (for dynamically loaded
   modules), containing these modules.  A copy of the module's
   dictionary is stored by calling _PyImport_FixupExtension()
   immediately after the module initialization function succeeds.  A
   copy can be retrieved from there by calling
   _PyImport_FindExtension(). 

   Modules which do support multiple multiple initialization set
   their m_size field to a non-negative number (indicating the size
   of the module-specific state). They are still recorded in the
   extensions dictionary, to avoid loading shared libraries twice.
*/

int
_PyImport_FixupExtension(PyObject *mod, char *name, char *filename)
{
	PyObject *modules, *dict;
	struct PyModuleDef *def;
	if (extensions == NULL) {
		extensions = PyDict_New();
		if (extensions == NULL)
			return -1;
	}
	if (mod == NULL || !PyModule_Check(mod)) {
		PyErr_BadInternalCall();
		return -1;
	}
	def = PyModule_GetDef(mod);
	if (!def) {
		PyErr_BadInternalCall();
		return -1;
	}
	modules = PyImport_GetModuleDict();
	if (PyDict_SetItemString(modules, name, mod) < 0)
		return -1;
	if (_PyState_AddModule(mod, def) < 0) {
		PyDict_DelItemString(modules, name);
		return -1;
	}
	if (def->m_size == -1) {
		if (def->m_base.m_copy) {
			/* Somebody already imported the module, 
			   likely under a different name.
			   XXX this should really not happen. */
			Py_DECREF(def->m_base.m_copy);
			def->m_base.m_copy = NULL;
		}
		dict = PyModule_GetDict(mod);
		if (dict == NULL)
			return -1;
		def->m_base.m_copy = PyDict_Copy(dict);
		if (def->m_base.m_copy == NULL)
			return -1;
	}
	PyDict_SetItemString(extensions, filename, (PyObject*)def);
	return 0;
}

PyObject *
_PyImport_FindExtension(char *name, char *filename)
{
	PyObject *mod, *mdict;
	PyModuleDef* def;
	if (extensions == NULL)
		return NULL;
	def = (PyModuleDef*)PyDict_GetItemString(extensions, filename);
	if (def == NULL)
		return NULL;
	if (def->m_size == -1) {
		/* Module does not support repeated initialization */
		if (def->m_base.m_copy == NULL)
			return NULL;
		mod = PyImport_AddModule(name);
		if (mod == NULL)
			return NULL;
		mdict = PyModule_GetDict(mod);
		if (mdict == NULL)
			return NULL;
		if (PyDict_Update(mdict, def->m_base.m_copy))
			return NULL;
	}
	else {
		if (def->m_base.m_init == NULL)
			return NULL;
		mod = def->m_base.m_init();
		if (mod == NULL)
			return NULL;
		PyDict_SetItemString(PyImport_GetModuleDict(), name, mod);
		Py_DECREF(mod);
	}
	if (_PyState_AddModule(mod, def) < 0) {
		PyDict_DelItemString(PyImport_GetModuleDict(), name);
		Py_DECREF(mod);
		return NULL;
	}
	if (Py_VerboseFlag)
		PySys_WriteStderr("import %s # previously loaded (%s)\n",
				  name, filename);
	return mod;
	
}


/* Get the module object corresponding to a module name.
   First check the modules dictionary if there's one there,
   if not, create a new one and insert it in the modules dictionary.
   Because the former action is most common, THIS DOES NOT RETURN A
   'NEW' REFERENCE! */

PyObject *
PyImport_AddModule(const char *name)
{
	PyObject *modules = PyImport_GetModuleDict();
	PyObject *m;

	if ((m = PyDict_GetItemString(modules, name)) != NULL &&
	    PyModule_Check(m))
		return m;
	m = PyModule_New(name);
	if (m == NULL)
		return NULL;
	if (PyDict_SetItemString(modules, name, m) != 0) {
		Py_DECREF(m);
		return NULL;
	}
	Py_DECREF(m); /* Yes, it still exists, in modules! */

	return m;
}

/* Remove name from sys.modules, if it's there. */
static void
_RemoveModule(const char *name)
{
	PyObject *modules = PyImport_GetModuleDict();
	if (PyDict_GetItemString(modules, name) == NULL)
		return;
	if (PyDict_DelItemString(modules, name) < 0)
		Py_FatalError("import:  deleting existing key in"
			      "sys.modules failed");
}

static PyObject * get_sourcefile(const char *file);

/* Execute a code object in a module and return the module object
 * WITH INCREMENTED REFERENCE COUNT.  If an error occurs, name is
 * removed from sys.modules, to avoid leaving damaged module objects
 * in sys.modules.  The caller may wish to restore the original
 * module object (if any) in this case; PyImport_ReloadModule is an
 * example.
 */
PyObject *
PyImport_ExecCodeModule(char *name, PyObject *co)
{
	return PyImport_ExecCodeModuleEx(name, co, (char *)NULL);
}

PyObject *
PyImport_ExecCodeModuleEx(char *name, PyObject *co, char *pathname)
{
	PyObject *modules = PyImport_GetModuleDict();
	PyObject *m, *d, *v;

	m = PyImport_AddModule(name);
	if (m == NULL)
		return NULL;
	/* If the module is being reloaded, we get the old module back
	   and re-use its dict to exec the new code. */
	d = PyModule_GetDict(m);
	if (PyDict_GetItemString(d, "__builtins__") == NULL) {
		if (PyDict_SetItemString(d, "__builtins__",
					 PyEval_GetBuiltins()) != 0)
			goto error;
	}
	/* Remember the filename as the __file__ attribute */
	v = NULL;
	if (pathname != NULL) {
		v = get_sourcefile(pathname);
		if (v == NULL)
			PyErr_Clear();
	}
	if (v == NULL) {
		v = ((PyCodeObject *)co)->co_filename;
		Py_INCREF(v);
	}
	if (PyDict_SetItemString(d, "__file__", v) != 0)
		PyErr_Clear(); /* Not important enough to report */
	Py_DECREF(v);

	v = PyEval_EvalCode((PyCodeObject *)co, d, d);
	if (v == NULL)
		goto error;
	Py_DECREF(v);

	if ((m = PyDict_GetItemString(modules, name)) == NULL) {
		PyErr_Format(PyExc_ImportError,
			     "Loaded module %.200s not found in sys.modules",
			     name);
		return NULL;
	}

	Py_INCREF(m);

	return m;

  error:
	_RemoveModule(name);
	return NULL;
}


/* Given a pathname for a Python source file, fill a buffer with the
   pathname for the corresponding compiled file.  Return the pathname
   for the compiled file, or NULL if there's no space in the buffer.
   Doesn't set an exception. */

static char *
make_compiled_pathname(char *pathname, char *buf, size_t buflen)
{
	size_t len = strlen(pathname);
	if (len+2 > buflen)
		return NULL;

#ifdef MS_WINDOWS
	/* Treat .pyw as if it were .py.  The case of ".pyw" must match
	   that used in _PyImport_StandardFiletab. */
	if (len >= 4 && strcmp(&pathname[len-4], ".pyw") == 0)
		--len;	/* pretend 'w' isn't there */
#endif
	memcpy(buf, pathname, len);
	buf[len] = Py_OptimizeFlag ? 'o' : 'c';
	buf[len+1] = '\0';

	return buf;
}


/* Given a pathname for a Python source file, its time of last
   modification, and a pathname for a compiled file, check whether the
   compiled file represents the same version of the source.  If so,
   return a FILE pointer for the compiled file, positioned just after
   the header; if not, return NULL.
   Doesn't set an exception. */

static FILE *
check_compiled_module(char *pathname, time_t mtime, char *cpathname)
{
	FILE *fp;
	long magic;
	long pyc_mtime;

	fp = fopen(cpathname, "rb");
	if (fp == NULL)
		return NULL;
	magic = PyMarshal_ReadLongFromFile(fp);
	if (magic != pyc_magic) {
		if (Py_VerboseFlag)
			PySys_WriteStderr("# %s has bad magic\n", cpathname);
		fclose(fp);
		return NULL;
	}
	pyc_mtime = PyMarshal_ReadLongFromFile(fp);
	if (pyc_mtime != mtime) {
		if (Py_VerboseFlag)
			PySys_WriteStderr("# %s has bad mtime\n", cpathname);
		fclose(fp);
		return NULL;
	}
	if (Py_VerboseFlag)
		PySys_WriteStderr("# %s matches %s\n", cpathname, pathname);
	return fp;
}


/* Read a code object from a file and check it for validity */

static PyCodeObject *
read_compiled_module(char *cpathname, FILE *fp)
{
	PyObject *co;

	co = PyMarshal_ReadLastObjectFromFile(fp);
	if (co == NULL)
		return NULL;
	if (!PyCode_Check(co)) {
		PyErr_Format(PyExc_ImportError,
			     "Non-code object in %.200s", cpathname);
		Py_DECREF(co);
		return NULL;
	}
	return (PyCodeObject *)co;
}


/* Load a module from a compiled file, execute it, and return its
   module object WITH INCREMENTED REFERENCE COUNT */

static PyObject *
load_compiled_module(char *name, char *cpathname, FILE *fp)
{
	long magic;
	PyCodeObject *co;
	PyObject *m;

	magic = PyMarshal_ReadLongFromFile(fp);
	if (magic != pyc_magic) {
		PyErr_Format(PyExc_ImportError,
			     "Bad magic number in %.200s", cpathname);
		return NULL;
	}
	(void) PyMarshal_ReadLongFromFile(fp);
	co = read_compiled_module(cpathname, fp);
	if (co == NULL)
		return NULL;
	if (Py_VerboseFlag)
		PySys_WriteStderr("import %s # precompiled from %s\n",
			name, cpathname);
	m = PyImport_ExecCodeModuleEx(name, (PyObject *)co, cpathname);
	Py_DECREF(co);

	return m;
}

/* Parse a source file and return the corresponding code object */

static PyCodeObject *
parse_source_module(const char *pathname, FILE *fp)
{
	PyCodeObject *co = NULL;
	mod_ty mod;
	PyCompilerFlags flags;
	PyArena *arena = PyArena_New();
	if (arena == NULL)
		return NULL;

	flags.cf_flags = 0;
	mod = PyParser_ASTFromFile(fp, pathname, NULL,
				   Py_file_input, 0, 0, &flags, 
				   NULL, arena);
	if (mod) {
		co = PyAST_Compile(mod, pathname, NULL, arena);
	}
	PyArena_Free(arena);
	return co;
}


/* Helper to open a bytecode file for writing in exclusive mode */

static FILE *
open_exclusive(char *filename, mode_t mode)
{
#if defined(O_EXCL)&&defined(O_CREAT)&&defined(O_WRONLY)&&defined(O_TRUNC)
	/* Use O_EXCL to avoid a race condition when another process tries to
	   write the same file.  When that happens, our open() call fails,
	   which is just fine (since it's only a cache).
	   XXX If the file exists and is writable but the directory is not
	   writable, the file will never be written.  Oh well.
	*/
	int fd;
	(void) unlink(filename);
	fd = open(filename, O_EXCL|O_CREAT|O_WRONLY|O_TRUNC
#ifdef O_BINARY
				|O_BINARY   /* necessary for Windows */
#endif
#ifdef __VMS
                        , mode, "ctxt=bin", "shr=nil"
#else
                        , mode
#endif
		  );
	if (fd < 0)
		return NULL;
	return fdopen(fd, "wb");
#else
	/* Best we can do -- on Windows this can't happen anyway */
	return fopen(filename, "wb");
#endif
}


/* Write a compiled module to a file, placing the time of last
   modification of its source into the header.
   Errors are ignored, if a write error occurs an attempt is made to
   remove the file. */

static void
write_compiled_module(PyCodeObject *co, char *cpathname, struct stat *srcstat)
{
	FILE *fp;
	time_t mtime = srcstat->st_mtime;
#ifdef MS_WINDOWS   /* since Windows uses different permissions  */
	mode_t mode = srcstat->st_mode & ~S_IEXEC;
#else
	mode_t mode = srcstat->st_mode & ~S_IXUSR & ~S_IXGRP & ~S_IXOTH;
#endif 

	fp = open_exclusive(cpathname, mode);
	if (fp == NULL) {
		if (Py_VerboseFlag)
			PySys_WriteStderr(
				"# can't create %s\n", cpathname);
		return;
	}
	PyMarshal_WriteLongToFile(pyc_magic, fp, Py_MARSHAL_VERSION);
	/* First write a 0 for mtime */
	PyMarshal_WriteLongToFile(0L, fp, Py_MARSHAL_VERSION);
	PyMarshal_WriteObjectToFile((PyObject *)co, fp, Py_MARSHAL_VERSION);
	if (fflush(fp) != 0 || ferror(fp)) {
		if (Py_VerboseFlag)
			PySys_WriteStderr("# can't write %s\n", cpathname);
		/* Don't keep partial file */
		fclose(fp);
		(void) unlink(cpathname);
		return;
	}
	/* Now write the true mtime */
	fseek(fp, 4L, 0);
	assert(mtime < LONG_MAX);
	PyMarshal_WriteLongToFile((long)mtime, fp, Py_MARSHAL_VERSION);
	fflush(fp);
	fclose(fp);
	if (Py_VerboseFlag)
		PySys_WriteStderr("# wrote %s\n", cpathname);
}

static void
update_code_filenames(PyCodeObject *co, PyObject *oldname, PyObject *newname)
{
	PyObject *constants, *tmp;
	Py_ssize_t i, n;

	if (PyUnicode_Compare(co->co_filename, oldname))
		return;

	tmp = co->co_filename;
	co->co_filename = newname;
	Py_INCREF(co->co_filename);
	Py_DECREF(tmp);

	constants = co->co_consts;
	n = PyTuple_GET_SIZE(constants);
	for (i = 0; i < n; i++) {
		tmp = PyTuple_GET_ITEM(constants, i);
		if (PyCode_Check(tmp))
			update_code_filenames((PyCodeObject *)tmp,
					      oldname, newname);
	}
}

static int
update_compiled_module(PyCodeObject *co, char *pathname)
{
	PyObject *oldname, *newname;

	newname = PyUnicode_DecodeFSDefault(pathname);
	if (newname == NULL)
		return -1;

	if (!PyUnicode_Compare(co->co_filename, newname)) {
		Py_DECREF(newname);
		return 0;
	}

	oldname = co->co_filename;
	Py_INCREF(oldname);
	update_code_filenames(co, oldname, newname);
	Py_DECREF(oldname);
	Py_DECREF(newname);
	return 1;
}

/* Load a source module from a given file and return its module
   object WITH INCREMENTED REFERENCE COUNT.  If there's a matching
   byte-compiled file, use that instead. */

static PyObject *
load_source_module(char *name, char *pathname, FILE *fp)
{
	struct stat st;
	FILE *fpc;
	char buf[MAXPATHLEN+1];
	char *cpathname;
	PyCodeObject *co;
	PyObject *m;
	
	if (fstat(fileno(fp), &st) != 0) {
		PyErr_Format(PyExc_RuntimeError,
			     "unable to get file status from '%s'",
			     pathname);
		return NULL;
	}
#if SIZEOF_TIME_T > 4
	/* Python's .pyc timestamp handling presumes that the timestamp fits
	   in 4 bytes. This will be fine until sometime in the year 2038,
	   when a 4-byte signed time_t will overflow.
	 */
	if (st.st_mtime >> 32) {
		PyErr_SetString(PyExc_OverflowError,
			"modification time overflows a 4 byte field");
		return NULL;
	}
#endif
	cpathname = make_compiled_pathname(pathname, buf,
					   (size_t)MAXPATHLEN + 1);
	if (cpathname != NULL &&
	    (fpc = check_compiled_module(pathname, st.st_mtime, cpathname))) {
		co = read_compiled_module(cpathname, fpc);
		fclose(fpc);
		if (co == NULL)
			return NULL;
		if (update_compiled_module(co, pathname) < 0)
			return NULL;
		if (Py_VerboseFlag)
			PySys_WriteStderr("import %s # precompiled from %s\n",
				name, cpathname);
		pathname = cpathname;
	}
	else {
		co = parse_source_module(pathname, fp);
		if (co == NULL)
			return NULL;
		if (Py_VerboseFlag)
			PySys_WriteStderr("import %s # from %s\n",
				name, pathname);
		if (cpathname) {
			PyObject *ro = PySys_GetObject("dont_write_bytecode");
			if (ro == NULL || !PyObject_IsTrue(ro))
				write_compiled_module(co, cpathname, &st);
		}
	}
	m = PyImport_ExecCodeModuleEx(name, (PyObject *)co, pathname);
	Py_DECREF(co);

	return m;
}

/* Get source file -> unicode or None
 * Returns the path to the py file if available, else the given path
 */
static PyObject *
get_sourcefile(const char *file)
{
	char py[MAXPATHLEN + 1];
	Py_ssize_t len;
	PyObject *u;
	struct stat statbuf;

	if (!file || !*file) {
		Py_RETURN_NONE;
	}

	len = strlen(file);
        /* match '*.py?' */
	if (len > MAXPATHLEN || PyOS_strnicmp(&file[len-4], ".py", 3) != 0) {
		return PyUnicode_DecodeFSDefault(file);
	}

	strncpy(py, file, len-1);
	py[len-1] = '\0';
	if (stat(py, &statbuf) == 0 &&
		S_ISREG(statbuf.st_mode)) {
		u = PyUnicode_DecodeFSDefault(py);
	}
	else {
		u = PyUnicode_DecodeFSDefault(file);
	}
	return u;
}

/* Forward */
static PyObject *load_module(char *, FILE *, char *, int, PyObject *);
static struct filedescr *find_module(char *, char *, PyObject *,
				     char *, size_t, FILE **, PyObject **);
static struct _frozen * find_frozen(char *);

/* Load a package and return its module object WITH INCREMENTED
   REFERENCE COUNT */

static PyObject *
load_package(char *name, char *pathname)
{
	PyObject *m, *d;
	PyObject *file = NULL;
	PyObject *path = NULL;
	int err;
	char buf[MAXPATHLEN+1];
	FILE *fp = NULL;
	struct filedescr *fdp;

	m = PyImport_AddModule(name);
	if (m == NULL)
		return NULL;
	if (Py_VerboseFlag)
		PySys_WriteStderr("import %s # directory %s\n",
			name, pathname);
	d = PyModule_GetDict(m);
	file = get_sourcefile(pathname);
	if (file == NULL)
		goto error;
	path = Py_BuildValue("[O]", file);
	if (path == NULL)
		goto error;
	err = PyDict_SetItemString(d, "__file__", file);
	if (err == 0)
		err = PyDict_SetItemString(d, "__path__", path);
	if (err != 0)
		goto error;
	buf[0] = '\0';
	fdp = find_module(name, "__init__", path, buf, sizeof(buf), &fp, NULL);
	if (fdp == NULL) {
		if (PyErr_ExceptionMatches(PyExc_ImportError)) {
			PyErr_Clear();
			Py_INCREF(m);
		}
		else
			m = NULL;
		goto cleanup;
	}
	m = load_module(name, fp, buf, fdp->type, NULL);
	if (fp != NULL)
		fclose(fp);
	goto cleanup;

  error:
  	m = NULL;
  cleanup:
	Py_XDECREF(path);
	Py_XDECREF(file);
	return m;
}


/* Helper to test for built-in module */

static int
is_builtin(char *name)
{
	int i;
	for (i = 0; PyImport_Inittab[i].name != NULL; i++) {
		if (strcmp(name, PyImport_Inittab[i].name) == 0) {
			if (PyImport_Inittab[i].initfunc == NULL)
				return -1;
			else
				return 1;
		}
	}
	return 0;
}


/* Return an importer object for a sys.path/pkg.__path__ item 'p',
   possibly by fetching it from the path_importer_cache dict. If it
   wasn't yet cached, traverse path_hooks until a hook is found
   that can handle the path item. Return None if no hook could;
   this tells our caller it should fall back to the builtin
   import mechanism. Cache the result in path_importer_cache.
   Returns a borrowed reference. */

static PyObject *
get_path_importer(PyObject *path_importer_cache, PyObject *path_hooks,
		  PyObject *p)
{
	PyObject *importer;
	Py_ssize_t j, nhooks;

	/* These conditions are the caller's responsibility: */
	assert(PyList_Check(path_hooks));
	assert(PyDict_Check(path_importer_cache));

	nhooks = PyList_Size(path_hooks);
	if (nhooks < 0)
		return NULL; /* Shouldn't happen */

	importer = PyDict_GetItem(path_importer_cache, p);
	if (importer != NULL)
		return importer;

	/* set path_importer_cache[p] to None to avoid recursion */
	if (PyDict_SetItem(path_importer_cache, p, Py_None) != 0)
		return NULL;

	for (j = 0; j < nhooks; j++) {
		PyObject *hook = PyList_GetItem(path_hooks, j);
		if (hook == NULL)
			return NULL;
		importer = PyObject_CallFunctionObjArgs(hook, p, NULL);
		if (importer != NULL)
			break;

		if (!PyErr_ExceptionMatches(PyExc_ImportError)) {
			return NULL;
		}
		PyErr_Clear();
	}
	if (importer == NULL) {
		importer = PyObject_CallFunctionObjArgs(
			(PyObject *)&PyNullImporter_Type, p, NULL
		);
		if (importer == NULL) {
			if (PyErr_ExceptionMatches(PyExc_ImportError)) {
				PyErr_Clear();
				return Py_None;
			}
		}
	}
	if (importer != NULL) {
		int err = PyDict_SetItem(path_importer_cache, p, importer);
		Py_DECREF(importer);
		if (err != 0)
			return NULL;
	}
	return importer;
}

PyAPI_FUNC(PyObject *)
PyImport_GetImporter(PyObject *path) {
        PyObject *importer=NULL, *path_importer_cache=NULL, *path_hooks=NULL;

	if ((path_importer_cache = PySys_GetObject("path_importer_cache"))) {
		if ((path_hooks = PySys_GetObject("path_hooks"))) {
			importer = get_path_importer(path_importer_cache,
			                             path_hooks, path);
		}
	}
	Py_XINCREF(importer); /* get_path_importer returns a borrowed reference */
	return importer;
}

/* Search the path (default sys.path) for a module.  Return the
   corresponding filedescr struct, and (via return arguments) the
   pathname and an open file.  Return NULL if the module is not found. */

#ifdef MS_COREDLL
extern FILE *PyWin_FindRegisteredModule(const char *, struct filedescr **,
					char *, Py_ssize_t);
#endif

static int case_ok(char *, Py_ssize_t, Py_ssize_t, char *);
static int find_init_module(char *); /* Forward */
static struct filedescr importhookdescr = {"", "", IMP_HOOK};

static struct filedescr *
find_module(char *fullname, char *subname, PyObject *path, char *buf,
	    size_t buflen, FILE **p_fp, PyObject **p_loader)
{
	Py_ssize_t i, npath;
	size_t len, namelen;
	struct filedescr *fdp = NULL;
	char *filemode;
	FILE *fp = NULL;
	PyObject *path_hooks, *path_importer_cache;
	struct stat statbuf;
	static struct filedescr fd_frozen = {"", "", PY_FROZEN};
	static struct filedescr fd_builtin = {"", "", C_BUILTIN};
	static struct filedescr fd_package = {"", "", PKG_DIRECTORY};
	char name[MAXPATHLEN+1];
#if defined(PYOS_OS2)
	size_t saved_len;
	size_t saved_namelen;
	char *saved_buf = NULL;
#endif
	if (p_loader != NULL)
		*p_loader = NULL;

	if (strlen(subname) > MAXPATHLEN) {
		PyErr_SetString(PyExc_OverflowError,
				"module name is too long");
		return NULL;
	}
	strcpy(name, subname);

	/* sys.meta_path import hook */
	if (p_loader != NULL) {
		PyObject *meta_path;

		meta_path = PySys_GetObject("meta_path");
		if (meta_path == NULL || !PyList_Check(meta_path)) {
			PyErr_SetString(PyExc_ImportError,
					"sys.meta_path must be a list of "
					"import hooks");
			return NULL;
		}
		Py_INCREF(meta_path);  /* zap guard */
		npath = PyList_Size(meta_path);
		for (i = 0; i < npath; i++) {
			PyObject *loader;
			PyObject *hook = PyList_GetItem(meta_path, i);
			loader = PyObject_CallMethod(hook, "find_module",
						     "sO", fullname,
						     path != NULL ?
						     path : Py_None);
			if (loader == NULL) {
				Py_DECREF(meta_path);
				return NULL;  /* true error */
			}
			if (loader != Py_None) {
				/* a loader was found */
				*p_loader = loader;
				Py_DECREF(meta_path);
				return &importhookdescr;
			}
			Py_DECREF(loader);
		}
		Py_DECREF(meta_path);
	}

	if (find_frozen(fullname) != NULL) {
		strcpy(buf, fullname);
		return &fd_frozen;
	}

	if (path == NULL) {
		if (is_builtin(name)) {
			strcpy(buf, name);
			return &fd_builtin;
		}
#ifdef MS_COREDLL
		fp = PyWin_FindRegisteredModule(name, &fdp, buf, buflen);
		if (fp != NULL) {
			*p_fp = fp;
			return fdp;
		}
#endif
		path = PySys_GetObject("path");
	}

	if (path == NULL || !PyList_Check(path)) {
		PyErr_SetString(PyExc_ImportError,
				"sys.path must be a list of directory names");
		return NULL;
	}

	path_hooks = PySys_GetObject("path_hooks");
	if (path_hooks == NULL || !PyList_Check(path_hooks)) {
		PyErr_SetString(PyExc_ImportError,
				"sys.path_hooks must be a list of "
				"import hooks");
		return NULL;
	}
	path_importer_cache = PySys_GetObject("path_importer_cache");
	if (path_importer_cache == NULL ||
	    !PyDict_Check(path_importer_cache)) {
		PyErr_SetString(PyExc_ImportError,
				"sys.path_importer_cache must be a dict");
		return NULL;
	}

	npath = PyList_Size(path);
	namelen = strlen(name);
	for (i = 0; i < npath; i++) {
		PyObject *v = PyList_GetItem(path, i);
		PyObject *origv = v;
		const char *base;
		Py_ssize_t size;
		if (!v)
			return NULL;
		if (PyUnicode_Check(v)) {
			v = PyUnicode_AsEncodedString(v, 
			    Py_FileSystemDefaultEncoding, NULL);
			if (v == NULL)
				return NULL;
		}
		else if (!PyBytes_Check(v))
			continue;
		else
			Py_INCREF(v);

		base = PyBytes_AS_STRING(v);
		size = PyBytes_GET_SIZE(v);
		len = size;
		if (len + 2 + namelen + MAXSUFFIXSIZE >= buflen) {
			Py_DECREF(v);
			continue; /* Too long */
		}
		strcpy(buf, base);
		Py_DECREF(v);

		if (strlen(buf) != len) {
			continue; /* v contains '\0' */
		}

		/* sys.path_hooks import hook */
		if (p_loader != NULL) {
			PyObject *importer;

			importer = get_path_importer(path_importer_cache,
						     path_hooks, origv);
			if (importer == NULL) {
				return NULL;
			}
			/* Note: importer is a borrowed reference */
			if (importer != Py_None) {
				PyObject *loader;
				loader = PyObject_CallMethod(importer,
							     "find_module",
							     "s", fullname);
				if (loader == NULL)
					return NULL;  /* error */
				if (loader != Py_None) {
					/* a loader was found */
					*p_loader = loader;
					return &importhookdescr;
				}
				Py_DECREF(loader);
				continue;
			}
		}
		/* no hook was found, use builtin import */

		if (len > 0 && buf[len-1] != SEP
#ifdef ALTSEP
		    && buf[len-1] != ALTSEP
#endif
		    )
			buf[len++] = SEP;
		strcpy(buf+len, name);
		len += namelen;

		/* Check for package import (buf holds a directory name,
		   and there's an __init__ module in that directory */
#ifdef HAVE_STAT
		if (stat(buf, &statbuf) == 0 &&         /* it exists */
		    S_ISDIR(statbuf.st_mode) &&         /* it's a directory */
		    case_ok(buf, len, namelen, name)) { /* case matches */
			if (find_init_module(buf)) { /* and has __init__.py */
				return &fd_package;
			}
			else {
				char warnstr[MAXPATHLEN+80];
				sprintf(warnstr, "Not importing directory "
					"'%.*s': missing __init__.py", 
					MAXPATHLEN, buf);
				if (PyErr_WarnEx(PyExc_ImportWarning,
						 warnstr, 1)) {
					return NULL;
				}
			}
		}
#endif
#if defined(PYOS_OS2)
		/* take a snapshot of the module spec for restoration
		 * after the 8 character DLL hackery
		 */
		saved_buf = strdup(buf);
		saved_len = len;
		saved_namelen = namelen;
#endif /* PYOS_OS2 */
		for (fdp = _PyImport_Filetab; fdp->suffix != NULL; fdp++) {
#if defined(PYOS_OS2) && defined(HAVE_DYNAMIC_LOADING)
			/* OS/2 limits DLLs to 8 character names (w/o
			   extension)
			 * so if the name is longer than that and its a
			 * dynamically loaded module we're going to try,
			 * truncate the name before trying
			 */
			if (strlen(subname) > 8) {
				/* is this an attempt to load a C extension? */
				const struct filedescr *scan;
				scan = _PyImport_DynLoadFiletab;
				while (scan->suffix != NULL) {
					if (!strcmp(scan->suffix, fdp->suffix))
						break;
					else
						scan++;
				}
				if (scan->suffix != NULL) {
					/* yes, so truncate the name */
					namelen = 8;
					len -= strlen(subname) - namelen;
					buf[len] = '\0';
				}
			}
#endif /* PYOS_OS2 */
			strcpy(buf+len, fdp->suffix);
			if (Py_VerboseFlag > 1)
				PySys_WriteStderr("# trying %s\n", buf);
			filemode = fdp->mode;
			if (filemode[0] == 'U')
				filemode = "r" PY_STDIOTEXTMODE;
			fp = fopen(buf, filemode);
			if (fp != NULL) {
				if (case_ok(buf, len, namelen, name))
					break;
				else {	 /* continue search */
					fclose(fp);
					fp = NULL;
				}
			}
#if defined(PYOS_OS2)
			/* restore the saved snapshot */
			strcpy(buf, saved_buf);
			len = saved_len;
			namelen = saved_namelen;
#endif
		}
#if defined(PYOS_OS2)
		/* don't need/want the module name snapshot anymore */
		if (saved_buf)
		{
			free(saved_buf);
			saved_buf = NULL;
		}
#endif
		if (fp != NULL)
			break;
	}
	if (fp == NULL) {
		PyErr_Format(PyExc_ImportError,
			     "No module named %.200s", name);
		return NULL;
	}
	*p_fp = fp;
	return fdp;
}

/* Helpers for main.c
 *  Find the source file corresponding to a named module
 */
struct filedescr *
_PyImport_FindModule(const char *name, PyObject *path, char *buf,
	    size_t buflen, FILE **p_fp, PyObject **p_loader)
{
	return find_module((char *) name, (char *) name, path,
			   buf, buflen, p_fp, p_loader);
}

PyAPI_FUNC(int) _PyImport_IsScript(struct filedescr * fd)
{
	return fd->type == PY_SOURCE || fd->type == PY_COMPILED;
}

/* case_ok(char* buf, Py_ssize_t len, Py_ssize_t namelen, char* name)
 * The arguments here are tricky, best shown by example:
 *    /a/b/c/d/e/f/g/h/i/j/k/some_long_module_name.py\0
 *    ^                      ^                   ^    ^
 *    |--------------------- buf ---------------------|
 *    |------------------- len ------------------|
 *                           |------ name -------|
 *                           |----- namelen -----|
 * buf is the full path, but len only counts up to (& exclusive of) the
 * extension.  name is the module name, also exclusive of extension.
 *
 * We've already done a successful stat() or fopen() on buf, so know that
 * there's some match, possibly case-insensitive.
 *
 * case_ok() is to return 1 if there's a case-sensitive match for
 * name, else 0.  case_ok() is also to return 1 if envar PYTHONCASEOK
 * exists.
 *
 * case_ok() is used to implement case-sensitive import semantics even
 * on platforms with case-insensitive filesystems.  It's trivial to implement
 * for case-sensitive filesystems.  It's pretty much a cross-platform
 * nightmare for systems with case-insensitive filesystems.
 */

/* First we may need a pile of platform-specific header files; the sequence
 * of #if's here should match the sequence in the body of case_ok().
 */
#if defined(MS_WINDOWS)
#include <windows.h>

#elif defined(DJGPP)
#include <dir.h>

#elif (defined(__MACH__) && defined(__APPLE__) || defined(__CYGWIN__)) && defined(HAVE_DIRENT_H)
#include <sys/types.h>
#include <dirent.h>

#elif defined(PYOS_OS2)
#define INCL_DOS
#define INCL_DOSERRORS
#define INCL_NOPMAPI
#include <os2.h>
#endif

static int
case_ok(char *buf, Py_ssize_t len, Py_ssize_t namelen, char *name)
{
/* Pick a platform-specific implementation; the sequence of #if's here should
 * match the sequence just above.
 */

/* MS_WINDOWS */
#if defined(MS_WINDOWS)
	WIN32_FIND_DATA data;
	HANDLE h;

	if (Py_GETENV("PYTHONCASEOK") != NULL)
		return 1;

	h = FindFirstFile(buf, &data);
	if (h == INVALID_HANDLE_VALUE) {
		PyErr_Format(PyExc_NameError,
		  "Can't find file for module %.100s\n(filename %.300s)",
		  name, buf);
		return 0;
	}
	FindClose(h);
	return strncmp(data.cFileName, name, namelen) == 0;

/* DJGPP */
#elif defined(DJGPP)
	struct ffblk ffblk;
	int done;

	if (Py_GETENV("PYTHONCASEOK") != NULL)
		return 1;

	done = findfirst(buf, &ffblk, FA_ARCH|FA_RDONLY|FA_HIDDEN|FA_DIREC);
	if (done) {
		PyErr_Format(PyExc_NameError,
		  "Can't find file for module %.100s\n(filename %.300s)",
		  name, buf);
		return 0;
	}
	return strncmp(ffblk.ff_name, name, namelen) == 0;

/* new-fangled macintosh (macosx) or Cygwin */
#elif (defined(__MACH__) && defined(__APPLE__) || defined(__CYGWIN__)) && defined(HAVE_DIRENT_H)
	DIR *dirp;
	struct dirent *dp;
	char dirname[MAXPATHLEN + 1];
	const int dirlen = len - namelen - 1; /* don't want trailing SEP */

	if (Py_GETENV("PYTHONCASEOK") != NULL)
		return 1;

	/* Copy the dir component into dirname; substitute "." if empty */
	if (dirlen <= 0) {
		dirname[0] = '.';
		dirname[1] = '\0';
	}
	else {
		assert(dirlen <= MAXPATHLEN);
		memcpy(dirname, buf, dirlen);
		dirname[dirlen] = '\0';
	}
	/* Open the directory and search the entries for an exact match. */
	dirp = opendir(dirname);
	if (dirp) {
		char *nameWithExt = buf + len - namelen;
		while ((dp = readdir(dirp)) != NULL) {
			const int thislen =
#ifdef _DIRENT_HAVE_D_NAMELEN
						dp->d_namlen;
#else
						strlen(dp->d_name);
#endif
			if (thislen >= namelen &&
			    strcmp(dp->d_name, nameWithExt) == 0) {
				(void)closedir(dirp);
				return 1; /* Found */
			}
		}
		(void)closedir(dirp);
	}
	return 0 ; /* Not found */

/* OS/2 */
#elif defined(PYOS_OS2)
	HDIR hdir = 1;
	ULONG srchcnt = 1;
	FILEFINDBUF3 ffbuf;
	APIRET rc;

	if (Py_GETENV("PYTHONCASEOK") != NULL)
		return 1;

	rc = DosFindFirst(buf,
			  &hdir,
			  FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
			  &ffbuf, sizeof(ffbuf),
			  &srchcnt,
			  FIL_STANDARD);
	if (rc != NO_ERROR)
		return 0;
	return strncmp(ffbuf.achName, name, namelen) == 0;

/* assuming it's a case-sensitive filesystem, so there's nothing to do! */
#else
	return 1;

#endif
}


#ifdef HAVE_STAT
/* Helper to look for __init__.py or __init__.py[co] in potential package */
static int
find_init_module(char *buf)
{
	const size_t save_len = strlen(buf);
	size_t i = save_len;
	char *pname;  /* pointer to start of __init__ */
	struct stat statbuf;

/*	For calling case_ok(buf, len, namelen, name):
 *	/a/b/c/d/e/f/g/h/i/j/k/some_long_module_name.py\0
 *	^                      ^                   ^    ^
 *	|--------------------- buf ---------------------|
 *	|------------------- len ------------------|
 *	                       |------ name -------|
 *	                       |----- namelen -----|
 */
	if (save_len + 13 >= MAXPATHLEN)
		return 0;
	buf[i++] = SEP;
	pname = buf + i;
	strcpy(pname, "__init__.py");
	if (stat(buf, &statbuf) == 0) {
		if (case_ok(buf,
			    save_len + 9,	/* len("/__init__") */
		            8,   		/* len("__init__") */
		            pname)) {
			buf[save_len] = '\0';
			return 1;
		}
	}
	i += strlen(pname);
	strcpy(buf+i, Py_OptimizeFlag ? "o" : "c");
	if (stat(buf, &statbuf) == 0) {
		if (case_ok(buf,
			    save_len + 9,	/* len("/__init__") */
		            8,   		/* len("__init__") */
		            pname)) {
			buf[save_len] = '\0';
			return 1;
		}
	}
	buf[save_len] = '\0';
	return 0;
}

#endif /* HAVE_STAT */


static int init_builtin(char *); /* Forward */

/* Load an external module using the default search path and return
   its module object WITH INCREMENTED REFERENCE COUNT */

static PyObject *
load_module(char *name, FILE *fp, char *pathname, int type, PyObject *loader)
{
	PyObject *modules;
	PyObject *m;
	int err;

	/* First check that there's an open file (if we need one)  */
	switch (type) {
	case PY_SOURCE:
	case PY_COMPILED:
		if (fp == NULL) {
			PyErr_Format(PyExc_ValueError,
			   "file object required for import (type code %d)",
				     type);
			return NULL;
		}
	}

	switch (type) {

	case PY_SOURCE:
		m = load_source_module(name, pathname, fp);
		break;

	case PY_COMPILED:
		m = load_compiled_module(name, pathname, fp);
		break;

#ifdef HAVE_DYNAMIC_LOADING
	case C_EXTENSION:
		m = _PyImport_LoadDynamicModule(name, pathname, fp);
		break;
#endif

	case PKG_DIRECTORY:
		m = load_package(name, pathname);
		break;

	case C_BUILTIN:
	case PY_FROZEN:
		if (pathname != NULL && pathname[0] != '\0')
			name = pathname;
		if (type == C_BUILTIN)
			err = init_builtin(name);
		else
			err = PyImport_ImportFrozenModule(name);
		if (err < 0)
			return NULL;
		if (err == 0) {
			PyErr_Format(PyExc_ImportError,
				     "Purported %s module %.200s not found",
				     type == C_BUILTIN ?
						"builtin" : "frozen",
				     name);
			return NULL;
		}
		modules = PyImport_GetModuleDict();
		m = PyDict_GetItemString(modules, name);
		if (m == NULL) {
			PyErr_Format(
				PyExc_ImportError,
				"%s module %.200s not properly initialized",
				type == C_BUILTIN ?
					"builtin" : "frozen",
				name);
			return NULL;
		}
		Py_INCREF(m);
		break;

	case IMP_HOOK: {
		if (loader == NULL) {
			PyErr_SetString(PyExc_ImportError,
					"import hook without loader");
			return NULL;
		}
		m = PyObject_CallMethod(loader, "load_module", "s", name);
		break;
	}

	default:
		PyErr_Format(PyExc_ImportError,
			     "Don't know how to import %.200s (type code %d)",
			      name, type);
		m = NULL;

	}

	return m;
}


/* Initialize a built-in module.
   Return 1 for success, 0 if the module is not found, and -1 with
   an exception set if the initialization failed. */

static int
init_builtin(char *name)
{
	struct _inittab *p;

	if (_PyImport_FindExtension(name, name) != NULL)
		return 1;

	for (p = PyImport_Inittab; p->name != NULL; p++) {
		PyObject *mod;
		if (strcmp(name, p->name) == 0) {
			if (p->initfunc == NULL) {
				PyErr_Format(PyExc_ImportError,
				    "Cannot re-init internal module %.200s",
				    name);
				return -1;
			}
			if (Py_VerboseFlag)
				PySys_WriteStderr("import %s # builtin\n", name);
			mod = (*p->initfunc)();
			if (mod == 0)
				return -1;
			if (_PyImport_FixupExtension(mod, name, name) < 0)
				return -1;
			/* FixupExtension has put the module into sys.modules,
			   so we can release our own reference. */
			Py_DECREF(mod);
			return 1;
		}
	}
	return 0;
}


/* Frozen modules */

static struct _frozen *
find_frozen(char *name)
{
	struct _frozen *p;

	if (!name)
		return NULL;

	for (p = PyImport_FrozenModules; ; p++) {
		if (p->name == NULL)
			return NULL;
		if (strcmp(p->name, name) == 0)
			break;
	}
	return p;
}

static PyObject *
get_frozen_object(char *name)
{
	struct _frozen *p = find_frozen(name);
	int size;

	if (p == NULL) {
		PyErr_Format(PyExc_ImportError,
			     "No such frozen object named %.200s",
			     name);
		return NULL;
	}
	if (p->code == NULL) {
		PyErr_Format(PyExc_ImportError,
			     "Excluded frozen object named %.200s",
			     name);
		return NULL;
	}
	size = p->size;
	if (size < 0)
		size = -size;
	return PyMarshal_ReadObjectFromString((char *)p->code, size);
}

static PyObject *
is_frozen_package(char *name)
{
	struct _frozen *p = find_frozen(name);
	int size;

	if (p == NULL) {
		PyErr_Format(PyExc_ImportError,
			     "No such frozen object named %.200s",
			     name);
		return NULL;
	}

	size = p->size;

	if (size < 0)
		Py_RETURN_TRUE;
	else
		Py_RETURN_FALSE;
}


/* Initialize a frozen module.
   Return 1 for success, 0 if the module is not found, and -1 with
   an exception set if the initialization failed.
   This function is also used from frozenmain.c */

int
PyImport_ImportFrozenModule(char *name)
{
	struct _frozen *p = find_frozen(name);
	PyObject *co;
	PyObject *m;
	int ispackage;
	int size;

	if (p == NULL)
		return 0;
	if (p->code == NULL) {
		PyErr_Format(PyExc_ImportError,
			     "Excluded frozen object named %.200s",
			     name);
		return -1;
	}
	size = p->size;
	ispackage = (size < 0);
	if (ispackage)
		size = -size;
	if (Py_VerboseFlag)
		PySys_WriteStderr("import %s # frozen%s\n",
			name, ispackage ? " package" : "");
	co = PyMarshal_ReadObjectFromString((char *)p->code, size);
	if (co == NULL)
		return -1;
	if (!PyCode_Check(co)) {
		PyErr_Format(PyExc_TypeError,
			     "frozen object %.200s is not a code object",
			     name);
		goto err_return;
	}
	if (ispackage) {
		/* Set __path__ to the package name */
		PyObject *d, *s, *l;
		int err;
		m = PyImport_AddModule(name);
		if (m == NULL)
			goto err_return;
		d = PyModule_GetDict(m);
		s = PyUnicode_InternFromString(name);
		if (s == NULL)
			goto err_return;
		l = PyList_New(1);
		if (l == NULL) {
			Py_DECREF(s);
			goto err_return;
		}
		PyList_SET_ITEM(l, 0, s);
		err = PyDict_SetItemString(d, "__path__", l);
		Py_DECREF(l);
		if (err != 0)
			goto err_return;
	}
	m = PyImport_ExecCodeModuleEx(name, co, "<frozen>");
	if (m == NULL)
		goto err_return;
	Py_DECREF(co);
	Py_DECREF(m);
	return 1;
err_return:
	Py_DECREF(co);
	return -1;
}


/* Import a module, either built-in, frozen, or external, and return
   its module object WITH INCREMENTED REFERENCE COUNT */

PyObject *
PyImport_ImportModule(const char *name)
{
	PyObject *pname;
	PyObject *result;

	pname = PyUnicode_FromString(name);
	if (pname == NULL)
		return NULL;
	result = PyImport_Import(pname);
	Py_DECREF(pname);
	return result;
}

/* Import a module without blocking
 *
 * At first it tries to fetch the module from sys.modules. If the module was
 * never loaded before it loads it with PyImport_ImportModule() unless another
 * thread holds the import lock. In the latter case the function raises an
 * ImportError instead of blocking.
 *
 * Returns the module object with incremented ref count.
 */
PyObject *
PyImport_ImportModuleNoBlock(const char *name)
{
	PyObject *result;
	PyObject *modules;
	long me;

	/* Try to get the module from sys.modules[name] */
	modules = PyImport_GetModuleDict();
	if (modules == NULL)
		return NULL;

	result = PyDict_GetItemString(modules, name);
	if (result != NULL) {
		Py_INCREF(result);
		return result;
	}
	else {
		PyErr_Clear();
	}
#ifdef WITH_THREAD
	/* check the import lock
	 * me might be -1 but I ignore the error here, the lock function
	 * takes care of the problem */
	me = PyThread_get_thread_ident();
	if (import_lock_thread == -1 || import_lock_thread == me) {
		/* no thread or me is holding the lock */
		return PyImport_ImportModule(name);
	}
	else {
		PyErr_Format(PyExc_ImportError,
			     "Failed to import %.200s because the import lock"
			     "is held by another thread.",
			     name);
		return NULL;
	}
#else
	return PyImport_ImportModule(name);
#endif
}

/* Forward declarations for helper routines */
static PyObject *get_parent(PyObject *globals, char *buf,
			    Py_ssize_t *p_buflen, int level);
static PyObject *load_next(PyObject *mod, PyObject *altmod,
			   char **p_name, char *buf, Py_ssize_t *p_buflen);
static int mark_miss(char *name);
static int ensure_fromlist(PyObject *mod, PyObject *fromlist,
			   char *buf, Py_ssize_t buflen, int recursive);
static PyObject * import_submodule(PyObject *mod, char *name, char *fullname);

/* The Magnum Opus of dotted-name import :-) */

static PyObject *
import_module_level(char *name, PyObject *globals, PyObject *locals,
		    PyObject *fromlist, int level)
{
	char buf[MAXPATHLEN+1];
	Py_ssize_t buflen = 0;
	PyObject *parent, *head, *next, *tail;

	if (strchr(name, '/') != NULL
#ifdef MS_WINDOWS
	    || strchr(name, '\\') != NULL
#endif
		) {
		PyErr_SetString(PyExc_ImportError,
				"Import by filename is not supported.");
		return NULL;
	}

	parent = get_parent(globals, buf, &buflen, level);
	if (parent == NULL)
		return NULL;

	head = load_next(parent, Py_None, &name, buf, &buflen);
	if (head == NULL)
		return NULL;

	tail = head;
	Py_INCREF(tail);
	while (name) {
		next = load_next(tail, tail, &name, buf, &buflen);
		Py_DECREF(tail);
		if (next == NULL) {
			Py_DECREF(head);
			return NULL;
		}
		tail = next;
	}
	if (tail == Py_None) {
		/* If tail is Py_None, both get_parent and load_next found
		   an empty module name: someone called __import__("") or
		   doctored faulty bytecode */
		Py_DECREF(tail);
		Py_DECREF(head);
		PyErr_SetString(PyExc_ValueError,
				"Empty module name");
		return NULL;
	}

	if (fromlist != NULL) {
		if (fromlist == Py_None || !PyObject_IsTrue(fromlist))
			fromlist = NULL;
	}

	if (fromlist == NULL) {
		Py_DECREF(tail);
		return head;
	}

	Py_DECREF(head);
	if (!ensure_fromlist(tail, fromlist, buf, buflen, 0)) {
		Py_DECREF(tail);
		return NULL;
	}

	return tail;
}

PyObject *
PyImport_ImportModuleLevel(char *name, PyObject *globals, PyObject *locals,
			 PyObject *fromlist, int level)
{
	PyObject *result;
	_PyImport_AcquireLock();
	result = import_module_level(name, globals, locals, fromlist, level);
	if (_PyImport_ReleaseLock() < 0) {
		Py_XDECREF(result);
		PyErr_SetString(PyExc_RuntimeError,
				"not holding the import lock");
		return NULL;
	}
	return result;
}

/* Return the package that an import is being performed in.  If globals comes
   from the module foo.bar.bat (not itself a package), this returns the
   sys.modules entry for foo.bar.  If globals is from a package's __init__.py,
   the package's entry in sys.modules is returned, as a borrowed reference.

   The *name* of the returned package is returned in buf, with the length of
   the name in *p_buflen.

   If globals doesn't come from a package or a module in a package, or a
   corresponding entry is not found in sys.modules, Py_None is returned.
*/
static PyObject *
get_parent(PyObject *globals, char *buf, Py_ssize_t *p_buflen, int level)
{
	static PyObject *namestr = NULL;
	static PyObject *pathstr = NULL;
	static PyObject *pkgstr = NULL;
	PyObject *pkgname, *modname, *modpath, *modules, *parent;
	int orig_level = level;

	if (globals == NULL || !PyDict_Check(globals) || !level)
		return Py_None;

	if (namestr == NULL) {
		namestr = PyUnicode_InternFromString("__name__");
		if (namestr == NULL)
			return NULL;
	}
	if (pathstr == NULL) {
		pathstr = PyUnicode_InternFromString("__path__");
		if (pathstr == NULL)
			return NULL;
	}
	if (pkgstr == NULL) {
		pkgstr = PyUnicode_InternFromString("__package__");
		if (pkgstr == NULL)
			return NULL;
	}

	*buf = '\0';
	*p_buflen = 0;
	pkgname = PyDict_GetItem(globals, pkgstr);

	if ((pkgname != NULL) && (pkgname != Py_None)) {
		/* __package__ is set, so use it */
		char *pkgname_str;
		Py_ssize_t len;

		if (!PyUnicode_Check(pkgname)) {
			PyErr_SetString(PyExc_ValueError,
					"__package__ set to non-string");
			return NULL;
		}
		pkgname_str = _PyUnicode_AsStringAndSize(pkgname, &len);
		if (len == 0) {
			if (level > 0) {
				PyErr_SetString(PyExc_ValueError,
					"Attempted relative import in non-package");
				return NULL;
			}
			return Py_None;
		}
		if (len > MAXPATHLEN) {
			PyErr_SetString(PyExc_ValueError,
					"Package name too long");
			return NULL;
		}
		strcpy(buf, pkgname_str);
	} else {
		/* __package__ not set, so figure it out and set it */
		modname = PyDict_GetItem(globals, namestr);
		if (modname == NULL || !PyUnicode_Check(modname))
			return Py_None;
	
		modpath = PyDict_GetItem(globals, pathstr);
		if (modpath != NULL) {
			/* __path__ is set, so modname is already the package name */
			char *modname_str;
			Py_ssize_t len;
			int error;

			modname_str = _PyUnicode_AsStringAndSize(modname, &len);
			if (len > MAXPATHLEN) {
				PyErr_SetString(PyExc_ValueError,
						"Module name too long");
				return NULL;
			}
			strcpy(buf, modname_str);
			error = PyDict_SetItem(globals, pkgstr, modname);
			if (error) {
				PyErr_SetString(PyExc_ValueError,
						"Could not set __package__");
				return NULL;
			}
		} else {
			/* Normal module, so work out the package name if any */
			char *start = _PyUnicode_AsString(modname);
			char *lastdot = strrchr(start, '.');
			size_t len;
			int error;
			if (lastdot == NULL && level > 0) {
				PyErr_SetString(PyExc_ValueError,
					"Attempted relative import in non-package");
				return NULL;
			}
			if (lastdot == NULL) {
				error = PyDict_SetItem(globals, pkgstr, Py_None);
				if (error) {
					PyErr_SetString(PyExc_ValueError,
						"Could not set __package__");
					return NULL;
				}
				return Py_None;
			}
			len = lastdot - start;
			if (len >= MAXPATHLEN) {
				PyErr_SetString(PyExc_ValueError,
						"Module name too long");
				return NULL;
			}
			strncpy(buf, start, len);
			buf[len] = '\0';
			pkgname = PyUnicode_FromString(buf);
			if (pkgname == NULL) {
				return NULL;
			}
			error = PyDict_SetItem(globals, pkgstr, pkgname);
			Py_DECREF(pkgname);
			if (error) {
				PyErr_SetString(PyExc_ValueError,
						"Could not set __package__");
				return NULL;
			}
		}
	}
	while (--level > 0) {
		char *dot = strrchr(buf, '.');
		if (dot == NULL) {
			PyErr_SetString(PyExc_ValueError,
				"Attempted relative import beyond "
				"toplevel package");
			return NULL;
		}
		*dot = '\0';
	}
	*p_buflen = strlen(buf);

	modules = PyImport_GetModuleDict();
	parent = PyDict_GetItemString(modules, buf);
	if (parent == NULL) {
		if (orig_level < 1) {
			PyObject *err_msg = PyBytes_FromFormat(
				"Parent module '%.200s' not found "
				"while handling absolute import", buf);
			if (err_msg == NULL) {
				return NULL;
			}
			if (!PyErr_WarnEx(PyExc_RuntimeWarning,
					  PyBytes_AsString(err_msg), 1)) {
				*buf = '\0';
				*p_buflen = 0;
				parent = Py_None;
			}
			Py_DECREF(err_msg);
		} else {
			PyErr_Format(PyExc_SystemError,
				"Parent module '%.200s' not loaded, "
				"cannot perform relative import", buf);
		}
	}
	return parent;
	/* We expect, but can't guarantee, if parent != None, that:
	   - parent.__name__ == buf
	   - parent.__dict__ is globals
	   If this is violated...  Who cares? */
}

/* altmod is either None or same as mod */
static PyObject *
load_next(PyObject *mod, PyObject *altmod, char **p_name, char *buf,
	  Py_ssize_t *p_buflen)
{
	char *name = *p_name;
	char *dot = strchr(name, '.');
	size_t len;
	char *p;
	PyObject *result;

	if (strlen(name) == 0) {
		/* completely empty module name should only happen in
		   'from . import' (or '__import__("")')*/
		Py_INCREF(mod);
		*p_name = NULL;
		return mod;
	}

	if (dot == NULL) {
		*p_name = NULL;
		len = strlen(name);
	}
	else {
		*p_name = dot+1;
		len = dot-name;
	}
	if (len == 0) {
		PyErr_SetString(PyExc_ValueError,
				"Empty module name");
		return NULL;
	}

	p = buf + *p_buflen;
	if (p != buf)
		*p++ = '.';
	if (p+len-buf >= MAXPATHLEN) {
		PyErr_SetString(PyExc_ValueError,
				"Module name too long");
		return NULL;
	}
	strncpy(p, name, len);
	p[len] = '\0';
	*p_buflen = p+len-buf;

	result = import_submodule(mod, p, buf);
	if (result == Py_None && altmod != mod) {
		Py_DECREF(result);
		/* Here, altmod must be None and mod must not be None */
		result = import_submodule(altmod, p, p);
		if (result != NULL && result != Py_None) {
			if (mark_miss(buf) != 0) {
				Py_DECREF(result);
				return NULL;
			}
			strncpy(buf, name, len);
			buf[len] = '\0';
			*p_buflen = len;
		}
	}
	if (result == NULL)
		return NULL;

	if (result == Py_None) {
		Py_DECREF(result);
		PyErr_Format(PyExc_ImportError,
			     "No module named %.200s", name);
		return NULL;
	}

	return result;
}

static int
mark_miss(char *name)
{
	PyObject *modules = PyImport_GetModuleDict();
	return PyDict_SetItemString(modules, name, Py_None);
}

static int
ensure_fromlist(PyObject *mod, PyObject *fromlist, char *buf, Py_ssize_t buflen,
		int recursive)
{
	int i;

	if (!PyObject_HasAttrString(mod, "__path__"))
		return 1;

	for (i = 0; ; i++) {
		PyObject *item = PySequence_GetItem(fromlist, i);
		int hasit;
		if (item == NULL) {
			if (PyErr_ExceptionMatches(PyExc_IndexError)) {
				PyErr_Clear();
				return 1;
			}
			return 0;
		}
		if (!PyUnicode_Check(item)) {
			PyErr_SetString(PyExc_TypeError,
					"Item in ``from list'' not a string");
			Py_DECREF(item);
			return 0;
		}
		if (PyUnicode_AS_UNICODE(item)[0] == '*') {
			PyObject *all;
			Py_DECREF(item);
			/* See if the package defines __all__ */
			if (recursive)
				continue; /* Avoid endless recursion */
			all = PyObject_GetAttrString(mod, "__all__");
			if (all == NULL)
				PyErr_Clear();
			else {
				int ret = ensure_fromlist(mod, all, buf, buflen, 1);
				Py_DECREF(all);
				if (!ret)
					return 0;
			}
			continue;
		}
		hasit = PyObject_HasAttr(mod, item);
		if (!hasit) {
			PyObject *item8;
			char *subname;
			PyObject *submod;
			char *p;
			if (!Py_FileSystemDefaultEncoding) {
				item8 = PyUnicode_EncodeASCII(PyUnicode_AsUnicode(item),
							      PyUnicode_GetSize(item),
							      NULL);
			} else {
				item8 = PyUnicode_AsEncodedString(item,
					Py_FileSystemDefaultEncoding, NULL);
			}
			if (!item8) {
				PyErr_SetString(PyExc_ValueError, "Cannot encode path item");
				return 0;
			}
			subname = PyBytes_AS_STRING(item8);
			if (buflen + strlen(subname) >= MAXPATHLEN) {
				PyErr_SetString(PyExc_ValueError,
						"Module name too long");
				Py_DECREF(item);
				return 0;
			}
			p = buf + buflen;
			*p++ = '.';
			strcpy(p, subname);
			submod = import_submodule(mod, subname, buf);
			Py_DECREF(item8);
			Py_XDECREF(submod);
			if (submod == NULL) {
				Py_DECREF(item);
				return 0;
			}
		}
		Py_DECREF(item);
	}

	/* NOTREACHED */
}

static int
add_submodule(PyObject *mod, PyObject *submod, char *fullname, char *subname,
	      PyObject *modules)
{
	if (mod == Py_None)
		return 1;
	/* Irrespective of the success of this load, make a
	   reference to it in the parent package module.  A copy gets
	   saved in the modules dictionary under the full name, so get a
	   reference from there, if need be.  (The exception is when the
	   load failed with a SyntaxError -- then there's no trace in
	   sys.modules.  In that case, of course, do nothing extra.) */
	if (submod == NULL) {
		submod = PyDict_GetItemString(modules, fullname);
		if (submod == NULL)
			return 1;
	}
	if (PyModule_Check(mod)) {
		/* We can't use setattr here since it can give a
		 * spurious warning if the submodule name shadows a
		 * builtin name */
		PyObject *dict = PyModule_GetDict(mod);
		if (!dict)
			return 0;
		if (PyDict_SetItemString(dict, subname, submod) < 0)
			return 0;
	}
	else {
		if (PyObject_SetAttrString(mod, subname, submod) < 0)
			return 0;
	}
	return 1;
}

static PyObject *
import_submodule(PyObject *mod, char *subname, char *fullname)
{
	PyObject *modules = PyImport_GetModuleDict();
	PyObject *m = NULL;

	/* Require:
	   if mod == None: subname == fullname
	   else: mod.__name__ + "." + subname == fullname
	*/

	if ((m = PyDict_GetItemString(modules, fullname)) != NULL) {
		Py_INCREF(m);
	}
	else {
		PyObject *path, *loader = NULL;
		char buf[MAXPATHLEN+1];
		struct filedescr *fdp;
		FILE *fp = NULL;

		if (mod == Py_None)
			path = NULL;
		else {
			path = PyObject_GetAttrString(mod, "__path__");
			if (path == NULL) {
				PyErr_Clear();
				Py_INCREF(Py_None);
				return Py_None;
			}
		}

		buf[0] = '\0';
		fdp = find_module(fullname, subname, path, buf, MAXPATHLEN+1,
				  &fp, &loader);
		Py_XDECREF(path);
		if (fdp == NULL) {
			if (!PyErr_ExceptionMatches(PyExc_ImportError))
				return NULL;
			PyErr_Clear();
			Py_INCREF(Py_None);
			return Py_None;
		}
		m = load_module(fullname, fp, buf, fdp->type, loader);
		Py_XDECREF(loader);
		if (fp)
			fclose(fp);
		if (!add_submodule(mod, m, fullname, subname, modules)) {
			Py_XDECREF(m);
			m = NULL;
		}
	}

	return m;
}


/* Re-import a module of any kind and return its module object, WITH
   INCREMENTED REFERENCE COUNT */

PyObject *
PyImport_ReloadModule(PyObject *m)
{
	PyInterpreterState *interp = PyThreadState_Get()->interp;
	PyObject *modules_reloading = interp->modules_reloading;
	PyObject *modules = PyImport_GetModuleDict();
	PyObject *path = NULL, *loader = NULL, *existing_m = NULL;
	char *name, *subname;
	char buf[MAXPATHLEN+1];
	struct filedescr *fdp;
	FILE *fp = NULL;
	PyObject *newm;
    
	if (modules_reloading == NULL) {
		Py_FatalError("PyImport_ReloadModule: "
			      "no modules_reloading dictionary!");
		return NULL;
	}

	if (m == NULL || !PyModule_Check(m)) {
		PyErr_SetString(PyExc_TypeError,
				"reload() argument must be module");
		return NULL;
	}
	name = (char*)PyModule_GetName(m);
	if (name == NULL)
		return NULL;
	if (m != PyDict_GetItemString(modules, name)) {
		PyErr_Format(PyExc_ImportError,
			     "reload(): module %.200s not in sys.modules",
			     name);
		return NULL;
	}
	existing_m = PyDict_GetItemString(modules_reloading, name);
	if (existing_m != NULL) {
		/* Due to a recursive reload, this module is already
		   being reloaded. */
		Py_INCREF(existing_m);
		return existing_m;
 	}
 	if (PyDict_SetItemString(modules_reloading, name, m) < 0)
		return NULL;

	subname = strrchr(name, '.');
	if (subname == NULL)
		subname = name;
	else {
		PyObject *parentname, *parent;
		parentname = PyUnicode_FromStringAndSize(name, (subname-name));
		if (parentname == NULL) {
			imp_modules_reloading_clear();
			return NULL;
        	}
		parent = PyDict_GetItem(modules, parentname);
		if (parent == NULL) {
			PyErr_Format(PyExc_ImportError,
			    "reload(): parent %.200s not in sys.modules",
			     _PyUnicode_AsString(parentname));
			Py_DECREF(parentname);
			imp_modules_reloading_clear();
			return NULL;
		}
		Py_DECREF(parentname);
		subname++;
		path = PyObject_GetAttrString(parent, "__path__");
		if (path == NULL)
			PyErr_Clear();
	}
	buf[0] = '\0';
	fdp = find_module(name, subname, path, buf, MAXPATHLEN+1, &fp, &loader);
	Py_XDECREF(path);

	if (fdp == NULL) {
		Py_XDECREF(loader);
		imp_modules_reloading_clear();
		return NULL;
	}

	newm = load_module(name, fp, buf, fdp->type, loader);
	Py_XDECREF(loader);

	if (fp)
		fclose(fp);
	if (newm == NULL) {
		/* load_module probably removed name from modules because of
		 * the error.  Put back the original module object.  We're
		 * going to return NULL in this case regardless of whether
		 * replacing name succeeds, so the return value is ignored.
		 */
		PyDict_SetItemString(modules, name, m);
	}
	imp_modules_reloading_clear();
	return newm;
}


/* Higher-level import emulator which emulates the "import" statement
   more accurately -- it invokes the __import__() function from the
   builtins of the current globals.  This means that the import is
   done using whatever import hooks are installed in the current
   environment, e.g. by "rexec".
   A dummy list ["__doc__"] is passed as the 4th argument so that
   e.g. PyImport_Import(PyUnicode_FromString("win32com.client.gencache"))
   will return <module "gencache"> instead of <module "win32com">. */

PyObject *
PyImport_Import(PyObject *module_name)
{
	static PyObject *silly_list = NULL;
	static PyObject *builtins_str = NULL;
	static PyObject *import_str = NULL;
	PyObject *globals = NULL;
	PyObject *import = NULL;
	PyObject *builtins = NULL;
	PyObject *r = NULL;

	/* Initialize constant string objects */
	if (silly_list == NULL) {
		import_str = PyUnicode_InternFromString("__import__");
		if (import_str == NULL)
			return NULL;
		builtins_str = PyUnicode_InternFromString("__builtins__");
		if (builtins_str == NULL)
			return NULL;
		silly_list = Py_BuildValue("[s]", "__doc__");
		if (silly_list == NULL)
			return NULL;
	}

	/* Get the builtins from current globals */
	globals = PyEval_GetGlobals();
	if (globals != NULL) {
	        Py_INCREF(globals);
		builtins = PyObject_GetItem(globals, builtins_str);
		if (builtins == NULL)
			goto err;
	}
	else {
		/* No globals -- use standard builtins, and fake globals */
		PyErr_Clear();

		builtins = PyImport_ImportModuleLevel("builtins",
						      NULL, NULL, NULL, 0);
		if (builtins == NULL)
			return NULL;
		globals = Py_BuildValue("{OO}", builtins_str, builtins);
		if (globals == NULL)
			goto err;
	}

	/* Get the __import__ function from the builtins */
	if (PyDict_Check(builtins)) {
		import = PyObject_GetItem(builtins, import_str);
		if (import == NULL)
			PyErr_SetObject(PyExc_KeyError, import_str);
	}
	else
		import = PyObject_GetAttr(builtins, import_str);
	if (import == NULL)
		goto err;

	/* Call the __import__ function with the proper argument list
	 * Always use absolute import here. */
	r = PyObject_CallFunction(import, "OOOOi", module_name, globals,
				  globals, silly_list, 0, NULL);

  err:
	Py_XDECREF(globals);
	Py_XDECREF(builtins);
	Py_XDECREF(import);

	return r;
}


/* Module 'imp' provides Python access to the primitives used for
   importing modules.
*/

static PyObject *
imp_get_magic(PyObject *self, PyObject *noargs)
{
	char buf[4];

	buf[0] = (char) ((pyc_magic >>  0) & 0xff);
	buf[1] = (char) ((pyc_magic >>  8) & 0xff);
	buf[2] = (char) ((pyc_magic >> 16) & 0xff);
	buf[3] = (char) ((pyc_magic >> 24) & 0xff);

	return PyBytes_FromStringAndSize(buf, 4);
}

static PyObject *
imp_get_suffixes(PyObject *self, PyObject *noargs)
{
	PyObject *list;
	struct filedescr *fdp;

	list = PyList_New(0);
	if (list == NULL)
		return NULL;
	for (fdp = _PyImport_Filetab; fdp->suffix != NULL; fdp++) {
		PyObject *item = Py_BuildValue("ssi",
				       fdp->suffix, fdp->mode, fdp->type);
		if (item == NULL) {
			Py_DECREF(list);
			return NULL;
		}
		if (PyList_Append(list, item) < 0) {
			Py_DECREF(list);
			Py_DECREF(item);
			return NULL;
		}
		Py_DECREF(item);
	}
	return list;
}

static PyObject *
call_find_module(char *name, PyObject *path)
{
	extern int fclose(FILE *);
	PyObject *fob, *ret;
	PyObject *pathobj;
	struct filedescr *fdp;
	char pathname[MAXPATHLEN+1];
	FILE *fp = NULL;
	int fd = -1;
	char *found_encoding = NULL;
	char *encoding = NULL;

	pathname[0] = '\0';
	if (path == Py_None)
		path = NULL;
	fdp = find_module(NULL, name, path, pathname, MAXPATHLEN+1, &fp, NULL);
	if (fdp == NULL)
		return NULL;
	if (fp != NULL) {
		fd = fileno(fp);
		if (fd != -1)
			fd = dup(fd);
		fclose(fp);
		fp = NULL;
	}
	if (fd != -1) {
		if (strchr(fdp->mode, 'b') == NULL) {
			/* PyTokenizer_FindEncoding() returns PyMem_MALLOC'ed
			   memory. */
			found_encoding = PyTokenizer_FindEncoding(fd);
			lseek(fd, 0, 0); /* Reset position */
			if (found_encoding == NULL && PyErr_Occurred())
				return NULL;
			encoding = (found_encoding != NULL) ? found_encoding :
				   (char*)PyUnicode_GetDefaultEncoding();
		}
		fob = PyFile_FromFd(fd, pathname, fdp->mode, -1,
				    (char*)encoding, NULL, NULL, 1);
		if (fob == NULL) {
			close(fd);
			PyMem_FREE(found_encoding);
			return NULL;
		}
	}
	else {
		fob = Py_None;
		Py_INCREF(fob);
	}
	pathobj = PyUnicode_DecodeFSDefault(pathname);
	ret = Py_BuildValue("NN(ssi)",
		      fob, pathobj, fdp->suffix, fdp->mode, fdp->type);
	PyMem_FREE(found_encoding);

	return ret;
}

static PyObject *
imp_find_module(PyObject *self, PyObject *args)
{
	char *name;
	PyObject *ret, *path = NULL;
	if (!PyArg_ParseTuple(args, "es|O:find_module",
	                      Py_FileSystemDefaultEncoding, &name,
	                      &path))
		return NULL;
	ret = call_find_module(name, path);
	PyMem_Free(name);
	return ret;
}

static PyObject *
imp_init_builtin(PyObject *self, PyObject *args)
{
	char *name;
	int ret;
	PyObject *m;
	if (!PyArg_ParseTuple(args, "s:init_builtin", &name))
		return NULL;
	ret = init_builtin(name);
	if (ret < 0)
		return NULL;
	if (ret == 0) {
		Py_INCREF(Py_None);
		return Py_None;
	}
	m = PyImport_AddModule(name);
	Py_XINCREF(m);
	return m;
}

static PyObject *
imp_init_frozen(PyObject *self, PyObject *args)
{
	char *name;
	int ret;
	PyObject *m;
	if (!PyArg_ParseTuple(args, "s:init_frozen", &name))
		return NULL;
	ret = PyImport_ImportFrozenModule(name);
	if (ret < 0)
		return NULL;
	if (ret == 0) {
		Py_INCREF(Py_None);
		return Py_None;
	}
	m = PyImport_AddModule(name);
	Py_XINCREF(m);
	return m;
}

static PyObject *
imp_get_frozen_object(PyObject *self, PyObject *args)
{
	char *name;

	if (!PyArg_ParseTuple(args, "s:get_frozen_object", &name))
		return NULL;
	return get_frozen_object(name);
}

static PyObject *
imp_is_frozen_package(PyObject *self, PyObject *args)
{
	char *name;

	if (!PyArg_ParseTuple(args, "s:is_frozen_package", &name))
		return NULL;
	return is_frozen_package(name);
}

static PyObject *
imp_is_builtin(PyObject *self, PyObject *args)
{
	char *name;
	if (!PyArg_ParseTuple(args, "s:is_builtin", &name))
		return NULL;
	return PyLong_FromLong(is_builtin(name));
}

static PyObject *
imp_is_frozen(PyObject *self, PyObject *args)
{
	char *name;
	struct _frozen *p;
	if (!PyArg_ParseTuple(args, "s:is_frozen", &name))
		return NULL;
	p = find_frozen(name);
	return PyBool_FromLong((long) (p == NULL ? 0 : p->size));
}

static FILE *
get_file(char *pathname, PyObject *fob, char *mode)
{
	FILE *fp;
	if (mode[0] == 'U')
		mode = "r" PY_STDIOTEXTMODE;
	if (fob == NULL) {
		fp = fopen(pathname, mode);
	}
	else {
		int fd = PyObject_AsFileDescriptor(fob);
		if (fd == -1)
			return NULL;
		if (!_PyVerify_fd(fd))
			goto error;
		/* the FILE struct gets a new fd, so that it can be closed
		 * independently of the file descriptor given
		 */
		fd = dup(fd);
		if (fd == -1)
			goto error;
		fp = fdopen(fd, mode);
	}
	if (fp)
		return fp;
error:
	PyErr_SetFromErrno(PyExc_IOError);
	return NULL;
}

static PyObject *
imp_load_compiled(PyObject *self, PyObject *args)
{
	char *name;
	char *pathname;
	PyObject *fob = NULL;
	PyObject *m;
	FILE *fp;
	if (!PyArg_ParseTuple(args, "ses|O:load_compiled",
			      &name, 
			      Py_FileSystemDefaultEncoding, &pathname, 
			      &fob))
		return NULL;
	fp = get_file(pathname, fob, "rb");
	if (fp == NULL) {
		PyMem_Free(pathname);
		return NULL;
	}
	m = load_compiled_module(name, pathname, fp);
	fclose(fp);
	PyMem_Free(pathname);
	return m;
}

#ifdef HAVE_DYNAMIC_LOADING

static PyObject *
imp_load_dynamic(PyObject *self, PyObject *args)
{
	char *name;
	char *pathname;
	PyObject *fob = NULL;
	PyObject *m;
	FILE *fp = NULL;
	if (!PyArg_ParseTuple(args, "ses|O:load_dynamic",
			      &name, 
			      Py_FileSystemDefaultEncoding, &pathname, 
			      &fob))
		return NULL;
	if (fob) {
		fp = get_file(pathname, fob, "r");
		if (fp == NULL) {
			PyMem_Free(pathname);
			return NULL;
		}
	}
	m = _PyImport_LoadDynamicModule(name, pathname, fp);
	PyMem_Free(pathname);
	if (fp)
		fclose(fp);
	return m;
}

#endif /* HAVE_DYNAMIC_LOADING */

static PyObject *
imp_load_source(PyObject *self, PyObject *args)
{
	char *name;
	char *pathname;
	PyObject *fob = NULL;
	PyObject *m;
	FILE *fp;
	if (!PyArg_ParseTuple(args, "ses|O:load_source",
			      &name, 
			      Py_FileSystemDefaultEncoding, &pathname,
			      &fob))
		return NULL;
	fp = get_file(pathname, fob, "r");
	if (fp == NULL) {
		PyMem_Free(pathname);
		return NULL;
	}
	m = load_source_module(name, pathname, fp);
	PyMem_Free(pathname);
	fclose(fp);
	return m;
}

static PyObject *
imp_load_module(PyObject *self, PyObject *args)
{
	char *name;
	PyObject *fob;
	char *pathname;
	PyObject * ret;
	char *suffix; /* Unused */
	char *mode;
	int type;
	FILE *fp;

	if (!PyArg_ParseTuple(args, "sOes(ssi):load_module",
			      &name, &fob, 
			      Py_FileSystemDefaultEncoding, &pathname,
			      &suffix, &mode, &type))
		return NULL;
	if (*mode) {
		/* Mode must start with 'r' or 'U' and must not contain '+'.
		   Implicit in this test is the assumption that the mode
		   may contain other modifiers like 'b' or 't'. */

		if (!(*mode == 'r' || *mode == 'U') || strchr(mode, '+')) {
			PyErr_Format(PyExc_ValueError,
				     "invalid file open mode %.200s", mode);
			PyMem_Free(pathname);
			return NULL;
		}
	}
	if (fob == Py_None)
		fp = NULL;
	else {
		fp = get_file(NULL, fob, mode);
		if (fp == NULL) {
			PyMem_Free(pathname);
			return NULL;
		}
	} 
	ret = load_module(name, fp, pathname, type, NULL);
	PyMem_Free(pathname);
	if (fp)
		fclose(fp);
	return ret;
}

static PyObject *
imp_load_package(PyObject *self, PyObject *args)
{
	char *name;
	char *pathname;
	PyObject * ret;
	if (!PyArg_ParseTuple(args, "ses:load_package", 
			      &name, Py_FileSystemDefaultEncoding, &pathname))
		return NULL;
	ret = load_package(name, pathname);
	PyMem_Free(pathname);
	return ret;
}

static PyObject *
imp_new_module(PyObject *self, PyObject *args)
{
	char *name;
	if (!PyArg_ParseTuple(args, "s:new_module", &name))
		return NULL;
	return PyModule_New(name);
}

static PyObject *
imp_reload(PyObject *self, PyObject *v)
{
        return PyImport_ReloadModule(v);
}

PyDoc_STRVAR(doc_reload,
"reload(module) -> module\n\
\n\
Reload the module.  The module must have been successfully imported before.");

/* Doc strings */

PyDoc_STRVAR(doc_imp,
"This module provides the components needed to build your own\n\
__import__ function.  Undocumented functions are obsolete.");

PyDoc_STRVAR(doc_find_module,
"find_module(name, [path]) -> (file, filename, (suffix, mode, type))\n\
Search for a module.  If path is omitted or None, search for a\n\
built-in, frozen or special module and continue search in sys.path.\n\
The module name cannot contain '.'; to search for a submodule of a\n\
package, pass the submodule name and the package's __path__.");

PyDoc_STRVAR(doc_load_module,
"load_module(name, file, filename, (suffix, mode, type)) -> module\n\
Load a module, given information returned by find_module().\n\
The module name must include the full package name, if any.");

PyDoc_STRVAR(doc_get_magic,
"get_magic() -> string\n\
Return the magic number for .pyc or .pyo files.");

PyDoc_STRVAR(doc_get_suffixes,
"get_suffixes() -> [(suffix, mode, type), ...]\n\
Return a list of (suffix, mode, type) tuples describing the files\n\
that find_module() looks for.");

PyDoc_STRVAR(doc_new_module,
"new_module(name) -> module\n\
Create a new module.  Do not enter it in sys.modules.\n\
The module name must include the full package name, if any.");

PyDoc_STRVAR(doc_lock_held,
"lock_held() -> boolean\n\
Return True if the import lock is currently held, else False.\n\
On platforms without threads, return False.");

PyDoc_STRVAR(doc_acquire_lock,
"acquire_lock() -> None\n\
Acquires the interpreter's import lock for the current thread.\n\
This lock should be used by import hooks to ensure thread-safety\n\
when importing modules.\n\
On platforms without threads, this function does nothing.");

PyDoc_STRVAR(doc_release_lock,
"release_lock() -> None\n\
Release the interpreter's import lock.\n\
On platforms without threads, this function does nothing.");

static PyMethodDef imp_methods[] = {
	{"find_module",	 imp_find_module,  METH_VARARGS, doc_find_module},
	{"get_magic",	 imp_get_magic,	   METH_NOARGS,  doc_get_magic},
	{"get_suffixes", imp_get_suffixes, METH_NOARGS,  doc_get_suffixes},
	{"load_module",	 imp_load_module,  METH_VARARGS, doc_load_module},
	{"new_module",	 imp_new_module,   METH_VARARGS, doc_new_module},
	{"lock_held",	 imp_lock_held,	   METH_NOARGS,  doc_lock_held},
	{"acquire_lock", imp_acquire_lock, METH_NOARGS,  doc_acquire_lock},
	{"release_lock", imp_release_lock, METH_NOARGS,  doc_release_lock},
	{"reload",       imp_reload,       METH_O,       doc_reload},
	/* The rest are obsolete */
	{"get_frozen_object",	imp_get_frozen_object,	METH_VARARGS},
	{"is_frozen_package",   imp_is_frozen_package,  METH_VARARGS},
	{"init_builtin",	imp_init_builtin,	METH_VARARGS},
	{"init_frozen",		imp_init_frozen,	METH_VARARGS},
	{"is_builtin",		imp_is_builtin,		METH_VARARGS},
	{"is_frozen",		imp_is_frozen,		METH_VARARGS},
	{"load_compiled",	imp_load_compiled,	METH_VARARGS},
#ifdef HAVE_DYNAMIC_LOADING
	{"load_dynamic",	imp_load_dynamic,	METH_VARARGS},
#endif
	{"load_package",	imp_load_package,	METH_VARARGS},
	{"load_source",		imp_load_source,	METH_VARARGS},
	{NULL,			NULL}		/* sentinel */
};

static int
setint(PyObject *d, char *name, int value)
{
	PyObject *v;
	int err;

	v = PyLong_FromLong((long)value);
	err = PyDict_SetItemString(d, name, v);
	Py_XDECREF(v);
	return err;
}

typedef struct {
    PyObject_HEAD
} NullImporter;

static int
NullImporter_init(NullImporter *self, PyObject *args, PyObject *kwds)
{
	char *path;
	Py_ssize_t pathlen;

	if (!_PyArg_NoKeywords("NullImporter()", kwds))
		return -1;

	if (!PyArg_ParseTuple(args, "es:NullImporter",
			      Py_FileSystemDefaultEncoding, &path))
		return -1;

	pathlen = strlen(path);
	if (pathlen == 0) {
		PyMem_Free(path);
		PyErr_SetString(PyExc_ImportError, "empty pathname");
		return -1;
	} else {
#ifndef MS_WINDOWS
		struct stat statbuf;
		int rv;

		rv = stat(path, &statbuf);
		PyMem_Free(path);
		if (rv == 0) {
			/* it exists */
			if (S_ISDIR(statbuf.st_mode)) {
				/* it's a directory */
				PyErr_SetString(PyExc_ImportError,
						"existing directory");
				return -1;
			}
		}
#else /* MS_WINDOWS */
		DWORD rv;
		/* see issue1293 and issue3677:
		 * stat() on Windows doesn't recognise paths like
		 * "e:\\shared\\" and "\\\\whiterab-c2znlh\\shared" as dirs.
		 */
		rv = GetFileAttributesA(path);
		PyMem_Free(path);
		if (rv != INVALID_FILE_ATTRIBUTES) {
			/* it exists */
			if (rv & FILE_ATTRIBUTE_DIRECTORY) {
				/* it's a directory */
				PyErr_SetString(PyExc_ImportError,
						"existing directory");
				return -1;
			}
		}
#endif
	}
	return 0;
}

static PyObject *
NullImporter_find_module(NullImporter *self, PyObject *args)
{
	Py_RETURN_NONE;
}

static PyMethodDef NullImporter_methods[] = {
	{"find_module", (PyCFunction)NullImporter_find_module, METH_VARARGS,
	 "Always return None"
	},
	{NULL}  /* Sentinel */
};


PyTypeObject PyNullImporter_Type = {
	PyVarObject_HEAD_INIT(NULL, 0)
	"imp.NullImporter",        /*tp_name*/
	sizeof(NullImporter),      /*tp_basicsize*/
	0,                         /*tp_itemsize*/
	0,                         /*tp_dealloc*/
	0,                         /*tp_print*/
	0,                         /*tp_getattr*/
	0,                         /*tp_setattr*/
	0,                         /*tp_reserved*/
	0,                         /*tp_repr*/
	0,                         /*tp_as_number*/
	0,                         /*tp_as_sequence*/
	0,                         /*tp_as_mapping*/
	0,                         /*tp_hash */
	0,                         /*tp_call*/
	0,                         /*tp_str*/
	0,                         /*tp_getattro*/
	0,                         /*tp_setattro*/
	0,                         /*tp_as_buffer*/
	Py_TPFLAGS_DEFAULT,        /*tp_flags*/
	"Null importer object",    /* tp_doc */
	0,	                   /* tp_traverse */
	0,	                   /* tp_clear */
	0,	                   /* tp_richcompare */
	0,	                   /* tp_weaklistoffset */
	0,	                   /* tp_iter */
	0,	                   /* tp_iternext */
	NullImporter_methods,      /* tp_methods */
	0,                         /* tp_members */
	0,                         /* tp_getset */
	0,                         /* tp_base */
	0,                         /* tp_dict */
	0,                         /* tp_descr_get */
	0,                         /* tp_descr_set */
	0,                         /* tp_dictoffset */
	(initproc)NullImporter_init,      /* tp_init */
	0,                         /* tp_alloc */
	PyType_GenericNew          /* tp_new */
};

static struct PyModuleDef impmodule = {
	PyModuleDef_HEAD_INIT,
	"imp",
	doc_imp,
	0,
	imp_methods,
	NULL,
	NULL,
	NULL,
	NULL
};

PyMODINIT_FUNC
PyInit_imp(void)
{
	PyObject *m, *d;

	if (PyType_Ready(&PyNullImporter_Type) < 0)
		return NULL;

	m = PyModule_Create(&impmodule);
	if (m == NULL)
		goto failure;
	d = PyModule_GetDict(m);
	if (d == NULL)
		goto failure;

	if (setint(d, "SEARCH_ERROR", SEARCH_ERROR) < 0) goto failure;
	if (setint(d, "PY_SOURCE", PY_SOURCE) < 0) goto failure;
	if (setint(d, "PY_COMPILED", PY_COMPILED) < 0) goto failure;
	if (setint(d, "C_EXTENSION", C_EXTENSION) < 0) goto failure;
	if (setint(d, "PY_RESOURCE", PY_RESOURCE) < 0) goto failure;
	if (setint(d, "PKG_DIRECTORY", PKG_DIRECTORY) < 0) goto failure;
	if (setint(d, "C_BUILTIN", C_BUILTIN) < 0) goto failure;
	if (setint(d, "PY_FROZEN", PY_FROZEN) < 0) goto failure;
	if (setint(d, "PY_CODERESOURCE", PY_CODERESOURCE) < 0) goto failure;
	if (setint(d, "IMP_HOOK", IMP_HOOK) < 0) goto failure;

	Py_INCREF(&PyNullImporter_Type);
	PyModule_AddObject(m, "NullImporter", (PyObject *)&PyNullImporter_Type);
	return m;
  failure:
	Py_XDECREF(m);
	return NULL;

}


/* API for embedding applications that want to add their own entries
   to the table of built-in modules.  This should normally be called
   *before* Py_Initialize().  When the table resize fails, -1 is
   returned and the existing table is unchanged.

   After a similar function by Just van Rossum. */

int
PyImport_ExtendInittab(struct _inittab *newtab)
{
	static struct _inittab *our_copy = NULL;
	struct _inittab *p;
	int i, n;

	/* Count the number of entries in both tables */
	for (n = 0; newtab[n].name != NULL; n++)
		;
	if (n == 0)
		return 0; /* Nothing to do */
	for (i = 0; PyImport_Inittab[i].name != NULL; i++)
		;

	/* Allocate new memory for the combined table */
	p = our_copy;
	PyMem_RESIZE(p, struct _inittab, i+n+1);
	if (p == NULL)
		return -1;

	/* Copy the tables into the new memory */
	if (our_copy != PyImport_Inittab)
		memcpy(p, PyImport_Inittab, (i+1) * sizeof(struct _inittab));
	PyImport_Inittab = our_copy = p;
	memcpy(p+i, newtab, (n+1) * sizeof(struct _inittab));

	return 0;
}

/* Shorthand to add a single entry given a name and a function */

int
PyImport_AppendInittab(const char *name, PyObject* (*initfunc)(void))
{
	struct _inittab newtab[2];

	memset(newtab, '\0', sizeof newtab);

	newtab[0].name = (char *)name;
	newtab[0].initfunc = initfunc;

	return PyImport_ExtendInittab(newtab);
}

#ifdef __cplusplus
}
#endif
