|  | 
 | /* Module definition and import implementation */ | 
 |  | 
 | #include "Python.h" | 
 |  | 
 | #include "node.h" | 
 | #include "token.h" | 
 | #include "errcode.h" | 
 | #include "marshal.h" | 
 | #include "compile.h" | 
 | #include "eval.h" | 
 | #include "osdefs.h" | 
 | #include "importdl.h" | 
 | #ifdef macintosh | 
 | #include "macglue.h" | 
 | #endif | 
 |  | 
 | #ifdef HAVE_FCNTL_H | 
 | #include <fcntl.h> | 
 | #endif | 
 |  | 
 | extern time_t PyOS_GetLastModificationTime(char *, FILE *); | 
 | 						/* In getmtime.c */ | 
 |  | 
 | /* Magic word to reject .pyc files generated by other Python versions */ | 
 | /* Change for each incompatible change */ | 
 | /* 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. | 
 |    XXX That probably isn't important anymore. | 
 | */ | 
 | /* XXX Perhaps the magic number should be frozen and a version field | 
 |    added to the .pyc file header? */ | 
 | /* New way to come up with the low 16 bits of the magic number: | 
 |       (YEAR-1995) * 10000 +  MONTH * 100 + DAY | 
 |    where MONTH and DAY are 1-based. | 
 |    XXX Whatever the "old way" may have been isn't documented. | 
 |    XXX This scheme breaks in 2002, as (2002-1995)*10000 = 70000 doesn't | 
 |        fit in 16 bits. | 
 |    XXX Later, sometimes 1 gets added to MAGIC in order to record that | 
 |        the Unicode -U option is in use.  IMO (Tim's), that's a Bad Idea | 
 |        (quite apart from that the -U option doesn't work so isn't used | 
 |        anyway). | 
 |  | 
 |    XXX MAL, 2002-02-07: I had to modify the MAGIC due to a fix of the | 
 |        UTF-8 encoder (it previously produced invalid UTF-8 for unpaired | 
 |        high surrogates), so I simply bumped the month value to 20 (invalid | 
 |        month) and set the day to 1.  This should be recognizable by any | 
 |        algorithm relying on the above scheme. Perhaps we should simply | 
 |        start counting in increments of 10 from now on ?! | 
 |  | 
 |        MWH, 2002-08-03: Removed SET_LINENO.  Couldn't be bothered figuring | 
 |        out the MAGIC schemes, so just incremented it by 10. | 
 |  | 
 |        GvR, 2002-08-31: Because MWH changed the bytecode again, moved the | 
 |        magic number *back* to 62011.  This should get the snake-farm to | 
 |        throw away its old .pyc files, amongst others. | 
 |  | 
 |    Known values: | 
 |        Python 1.5:   20121 | 
 |        Python 1.5.1: 20121 | 
 |        Python 1.5.2: 20121 | 
 |        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 (!) | 
 | */ | 
 | #define MAGIC (62011 | ((long)'\r'<<16) | ((long)'\n'<<24)) | 
 |  | 
 | /* Magic word as global; note that _PyImport_Init() can change the | 
 |    value of this global to accommodate for alterations of how the | 
 |    compiler works which are enabled by command line switches. */ | 
 | 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[]; | 
 |  | 
 | struct _inittab *PyImport_Inittab = _PyImport_Inittab; | 
 |  | 
 | /* these tables define the module suffixes that Python recognizes */ | 
 | struct filedescr * _PyImport_Filetab = NULL; | 
 |  | 
 | #ifdef RISCOS | 
 | static const struct filedescr _PyImport_StandardFiletab[] = { | 
 | 	{"/py", "U", PY_SOURCE}, | 
 | 	{"/pyc", "rb", PY_COMPILED}, | 
 | 	{0, 0} | 
 | }; | 
 | #else | 
 | static const struct filedescr _PyImport_StandardFiletab[] = { | 
 | 	{".py", "U", PY_SOURCE}, | 
 | #ifdef MS_WINDOWS | 
 | 	{".pyw", "U", PY_SOURCE}, | 
 | #endif | 
 | 	{".pyc", "rb", PY_COMPILED}, | 
 | 	{0, 0} | 
 | }; | 
 | #endif | 
 |  | 
 | /* 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. | 
 | 	 */ | 
 | 	for (scan = _PyImport_DynLoadFiletab; scan->suffix != NULL; ++scan) | 
 | 		++countD; | 
 | 	for (scan = _PyImport_StandardFiletab; scan->suffix != NULL; ++scan) | 
 | 		++countS; | 
 | 	filetab = PyMem_NEW(struct filedescr, countD + countS + 1); | 
 | 	memcpy(filetab, _PyImport_DynLoadFiletab, | 
 | 	       countD * sizeof(struct filedescr)); | 
 | 	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++) { | 
 | #ifndef RISCOS | 
 | 			if (strcmp(filetab->suffix, ".pyc") == 0) | 
 | 				filetab->suffix = ".pyo"; | 
 | #else | 
 | 			if (strcmp(filetab->suffix, "/pyc") == 0) | 
 | 				filetab->suffix = "/pyo"; | 
 | #endif | 
 | 		} | 
 | 	} | 
 |  | 
 | 	if (Py_UnicodeFlag) { | 
 | 		/* Fix the pyc_magic so that byte compiled code created | 
 | 		   using the all-Unicode method doesn't interfere with | 
 | 		   code created in normal operation mode. */ | 
 | 		pyc_magic = MAGIC + 1; | 
 | 	} | 
 | } | 
 |  | 
 | 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 (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 or " | 
 | 			      "path_importer_cache 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; | 
 |  | 
 | static void | 
 | lock_import(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_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; | 
 | } | 
 |  | 
 | static int | 
 | unlock_import(void) | 
 | { | 
 | 	long me = PyThread_get_thread_ident(); | 
 | 	if (me == -1) | 
 | 		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; | 
 | } | 
 |  | 
 | #else | 
 |  | 
 | #define lock_import() | 
 | #define unlock_import() 0 | 
 |  | 
 | #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 | 
 | 	lock_import(); | 
 | #endif | 
 | 	Py_INCREF(Py_None); | 
 | 	return Py_None; | 
 | } | 
 |  | 
 | static PyObject * | 
 | imp_release_lock(PyObject *self, PyObject *noargs) | 
 | { | 
 | #ifdef WITH_THREAD | 
 | 	if (unlock_import() < 0) { | 
 | 		PyErr_SetString(PyExc_RuntimeError, | 
 | 				"not holding the import lock"); | 
 | 		return NULL; | 
 | 	} | 
 | #endif | 
 | 	Py_INCREF(Py_None); | 
 | 	return Py_None; | 
 | } | 
 |  | 
 | /* 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", "exitfunc", | 
 | 	"exc_type", "exc_value", "exc_traceback", | 
 | 	"last_type", "last_value", "last_traceback", | 
 | 	"path_hooks", "path_importer_cache", "meta_path", | 
 | 	NULL | 
 | }; | 
 |  | 
 | static char* sys_files[] = { | 
 | 	"stdin", "__stdin__", | 
 | 	"stdout", "__stdout__", | 
 | 	"stderr", "__stderr__", | 
 | 	NULL | 
 | }; | 
 |  | 
 |  | 
 | /* Un-initialize things, as good as we can */ | 
 |  | 
 | void | 
 | PyImport_Cleanup(void) | 
 | { | 
 | 	int 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, "__builtin__"); | 
 | 	if (value != NULL && PyModule_Check(value)) { | 
 | 		dict = PyModule_GetDict(value); | 
 | 		if (Py_VerboseFlag) | 
 | 			PySys_WriteStderr("# clear __builtin__._\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 __builtin__ 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 __builtin__ | 
 | 	   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 __builtin__ and sys) and delete them */ | 
 | 	do { | 
 | 		ndone = 0; | 
 | 		pos = 0; | 
 | 		while (PyDict_Next(modules, &pos, &key, &value)) { | 
 | 			if (value->ob_refcnt != 1) | 
 | 				continue; | 
 | 			if (PyString_Check(key) && PyModule_Check(value)) { | 
 | 				name = PyString_AS_STRING(key); | 
 | 				if (strcmp(name, "__builtin__") == 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 __builtin__ and sys) */ | 
 | 	pos = 0; | 
 | 	while (PyDict_Next(modules, &pos, &key, &value)) { | 
 | 		if (PyString_Check(key) && PyModule_Check(value)) { | 
 | 			name = PyString_AS_STRING(key); | 
 | 			if (strcmp(name, "__builtin__") == 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 __builtin__ (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, "__builtin__"); | 
 | 	if (value != NULL && PyModule_Check(value)) { | 
 | 		if (Py_VerboseFlag) | 
 | 			PySys_WriteStderr("# cleanup __builtin__\n"); | 
 | 		_PyModule_Clear(value); | 
 | 		PyDict_SetItemString(modules, "__builtin__", Py_None); | 
 | 	} | 
 |  | 
 | 	/* Finally, clear and delete the modules directory */ | 
 | 	PyDict_Clear(modules); | 
 | 	interp->modules = NULL; | 
 | 	Py_DECREF(modules); | 
 | } | 
 |  | 
 |  | 
 | /* 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(). */ | 
 |  | 
 | PyObject * | 
 | _PyImport_FixupExtension(char *name, char *filename) | 
 | { | 
 | 	PyObject *modules, *mod, *dict, *copy; | 
 | 	if (extensions == NULL) { | 
 | 		extensions = PyDict_New(); | 
 | 		if (extensions == NULL) | 
 | 			return NULL; | 
 | 	} | 
 | 	modules = PyImport_GetModuleDict(); | 
 | 	mod = PyDict_GetItemString(modules, name); | 
 | 	if (mod == NULL || !PyModule_Check(mod)) { | 
 | 		PyErr_Format(PyExc_SystemError, | 
 | 		  "_PyImport_FixupExtension: module %.200s not loaded", name); | 
 | 		return NULL; | 
 | 	} | 
 | 	dict = PyModule_GetDict(mod); | 
 | 	if (dict == NULL) | 
 | 		return NULL; | 
 | 	copy = PyDict_Copy(dict); | 
 | 	if (copy == NULL) | 
 | 		return NULL; | 
 | 	PyDict_SetItemString(extensions, filename, copy); | 
 | 	Py_DECREF(copy); | 
 | 	return copy; | 
 | } | 
 |  | 
 | PyObject * | 
 | _PyImport_FindExtension(char *name, char *filename) | 
 | { | 
 | 	PyObject *dict, *mod, *mdict; | 
 | 	if (extensions == NULL) | 
 | 		return NULL; | 
 | 	dict = PyDict_GetItemString(extensions, filename); | 
 | 	if (dict == 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, dict)) | 
 | 		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 in in the modules dictionary. | 
 |    Because the former action is most common, THIS DOES NOT RETURN A | 
 |    'NEW' REFERENCE! */ | 
 |  | 
 | PyObject * | 
 | PyImport_AddModule(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; | 
 | } | 
 |  | 
 |  | 
 | /* Execute a code object in a module and return the module object | 
 |    WITH INCREMENTED REFERENCE COUNT */ | 
 |  | 
 | 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; | 
 | 	d = PyModule_GetDict(m); | 
 | 	if (PyDict_GetItemString(d, "__builtins__") == NULL) { | 
 | 		if (PyDict_SetItemString(d, "__builtins__", | 
 | 					 PyEval_GetBuiltins()) != 0) | 
 | 			return NULL; | 
 | 	} | 
 | 	/* Remember the filename as the __file__ attribute */ | 
 | 	v = NULL; | 
 | 	if (pathname != NULL) { | 
 | 		v = PyString_FromString(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) | 
 | 		return NULL; | 
 | 	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; | 
 | } | 
 |  | 
 |  | 
 | /* 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, long 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); | 
 | 	/* Ugly: rd_object() may return NULL with or without error */ | 
 | 	if (co == NULL || !PyCode_Check(co)) { | 
 | 		if (!PyErr_Occurred()) | 
 | 			PyErr_Format(PyExc_ImportError, | 
 | 			    "Non-code object in %.200s", cpathname); | 
 | 		Py_XDECREF(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(char *pathname, FILE *fp) | 
 | { | 
 | 	PyCodeObject *co; | 
 | 	node *n; | 
 |  | 
 | 	n = PyParser_SimpleParseFile(fp, pathname, Py_file_input); | 
 | 	if (n == NULL) | 
 | 		return NULL; | 
 | 	co = PyNode_Compile(n, pathname); | 
 | 	PyNode_Free(n); | 
 |  | 
 | 	return co; | 
 | } | 
 |  | 
 |  | 
 | /* Helper to open a bytecode file for writing in exclusive mode */ | 
 |  | 
 | static FILE * | 
 | open_exclusive(char *filename) | 
 | { | 
 | #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 | 
 |                         , 0666, "ctxt=bin", "shr=nil"); | 
 | #else | 
 |                         , 0666); | 
 | #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, long mtime) | 
 | { | 
 | 	FILE *fp; | 
 |  | 
 | 	fp = open_exclusive(cpathname); | 
 | 	if (fp == NULL) { | 
 | 		if (Py_VerboseFlag) | 
 | 			PySys_WriteStderr( | 
 | 				"# can't create %s\n", cpathname); | 
 | 		return; | 
 | 	} | 
 | 	PyMarshal_WriteLongToFile(pyc_magic, fp); | 
 | 	/* First write a 0 for mtime */ | 
 | 	PyMarshal_WriteLongToFile(0L, fp); | 
 | 	PyMarshal_WriteObjectToFile((PyObject *)co, fp); | 
 | 	if (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); | 
 | 	PyMarshal_WriteLongToFile(mtime, fp); | 
 | 	fflush(fp); | 
 | 	fclose(fp); | 
 | 	if (Py_VerboseFlag) | 
 | 		PySys_WriteStderr("# wrote %s\n", cpathname); | 
 | #ifdef macintosh | 
 | 	PyMac_setfiletype(cpathname, 'Pyth', 'PYC '); | 
 | #endif | 
 | } | 
 |  | 
 |  | 
 | /* 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) | 
 | { | 
 | 	time_t mtime; | 
 | 	FILE *fpc; | 
 | 	char buf[MAXPATHLEN+1]; | 
 | 	char *cpathname; | 
 | 	PyCodeObject *co; | 
 | 	PyObject *m; | 
 |  | 
 | 	mtime = PyOS_GetLastModificationTime(pathname, fp); | 
 | 	if (mtime == (time_t)(-1)) | 
 | 		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 (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, mtime, cpathname))) { | 
 | 		co = read_compiled_module(cpathname, fpc); | 
 | 		fclose(fpc); | 
 | 		if (co == NULL) | 
 | 			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); | 
 | 		write_compiled_module(co, cpathname, mtime); | 
 | 	} | 
 | 	m = PyImport_ExecCodeModuleEx(name, (PyObject *)co, pathname); | 
 | 	Py_DECREF(co); | 
 |  | 
 | 	return m; | 
 | } | 
 |  | 
 |  | 
 | /* 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 *name); | 
 |  | 
 | /* Load a package and return its module object WITH INCREMENTED | 
 |    REFERENCE COUNT */ | 
 |  | 
 | static PyObject * | 
 | load_package(char *name, char *pathname) | 
 | { | 
 | 	PyObject *m, *d, *file, *path; | 
 | 	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 = PyString_FromString(pathname); | 
 | 	if (file == NULL) | 
 | 		return NULL; | 
 | 	path = Py_BuildValue("[O]", file); | 
 | 	if (path == NULL) { | 
 | 		Py_DECREF(file); | 
 | 		return NULL; | 
 | 	} | 
 | 	err = PyDict_SetItemString(d, "__file__", file); | 
 | 	if (err == 0) | 
 | 		err = PyDict_SetItemString(d, "__path__", path); | 
 | 	if (err != 0) { | 
 | 		m = NULL; | 
 | 		goto cleanup; | 
 | 	} | 
 | 	buf[0] = '\0'; | 
 | 	fdp = find_module(name, "__init__", path, buf, sizeof(buf), &fp, NULL); | 
 | 	if (fdp == NULL) { | 
 | 		if (PyErr_ExceptionMatches(PyExc_ImportError)) { | 
 | 			PyErr_Clear(); | 
 | 		} | 
 | 		else | 
 | 			m = NULL; | 
 | 		goto cleanup; | 
 | 	} | 
 | 	m = load_module(name, fp, buf, fdp->type, NULL); | 
 | 	if (fp != NULL) | 
 | 		fclose(fp); | 
 |   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 it 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; | 
 | 	int 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_CallFunction(hook, "O", p); | 
 | 		if (importer != NULL) | 
 | 			break; | 
 |  | 
 | 		if (!PyErr_ExceptionMatches(PyExc_ImportError)) { | 
 | 			return NULL; | 
 | 		} | 
 | 		PyErr_Clear(); | 
 | 	} | 
 | 	if (importer == NULL) | 
 | 		importer = Py_None; | 
 | 	else if (importer != Py_None) { | 
 | 		int err = PyDict_SetItem(path_importer_cache, p, importer); | 
 | 		Py_DECREF(importer); | 
 | 		if (err != 0) | 
 | 			return NULL; | 
 | 	} | 
 | 	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 *, int); | 
 | #endif | 
 |  | 
 | static int case_ok(char *, int, int, 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) | 
 | { | 
 | 	int i, npath; | 
 | 	size_t len, namelen; | 
 | 	struct filedescr *fdp = NULL; | 
 | 	char *filemode; | 
 | 	FILE *fp = NULL; | 
 | 	PyObject *path_hooks, *path_importer_cache; | 
 | #ifndef RISCOS | 
 | 	struct stat statbuf; | 
 | #endif | 
 | 	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 (path != NULL && PyString_Check(path)) { | 
 | 		/* The only type of submodule allowed inside a "frozen" | 
 | 		   package are other frozen modules or packages. */ | 
 | 		if (PyString_Size(path) + 1 + strlen(name) >= (size_t)buflen) { | 
 | 			PyErr_SetString(PyExc_ImportError, | 
 | 					"full frozen module name too long"); | 
 | 			return NULL; | 
 | 		} | 
 | 		strcpy(buf, PyString_AsString(path)); | 
 | 		strcat(buf, "."); | 
 | 		strcat(buf, name); | 
 | 		strcpy(name, buf); | 
 | #ifdef macintosh | 
 | 		/* Freezing on the mac works different, and the modules are | 
 | 		** actually on sys.path. So we don't take the quick exit but | 
 | 		** continue with the normal flow. | 
 | 		*/ | 
 | 		path = NULL; | 
 | #else | 
 | 		if (find_frozen(name) != NULL) { | 
 | 			strcpy(buf, name); | 
 | 			return &fd_frozen; | 
 | 		} | 
 | 		PyErr_Format(PyExc_ImportError, | 
 | 			     "No frozen submodule named %.200s", name); | 
 | 		return NULL; | 
 | #endif | 
 | 	} | 
 | 	if (path == NULL) { | 
 | 		if (is_builtin(name)) { | 
 | 			strcpy(buf, name); | 
 | 			return &fd_builtin; | 
 | 		} | 
 | 		if ((find_frozen(name)) != NULL) { | 
 | 			strcpy(buf, name); | 
 | 			return &fd_frozen; | 
 | 		} | 
 |  | 
 | #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 *copy = NULL; | 
 | 		PyObject *v = PyList_GetItem(path, i); | 
 | #ifdef Py_USING_UNICODE | 
 | 		if (PyUnicode_Check(v)) { | 
 | 			copy = PyUnicode_Encode(PyUnicode_AS_UNICODE(v), | 
 | 				PyUnicode_GET_SIZE(v), Py_FileSystemDefaultEncoding, NULL); | 
 | 			if (copy == NULL) | 
 | 				return NULL; | 
 | 			v = copy; | 
 | 		} | 
 | 		else | 
 | #endif | 
 | 		if (!PyString_Check(v)) | 
 | 			continue; | 
 | 		len = PyString_Size(v); | 
 | 		if (len + 2 + namelen + MAXSUFFIXSIZE >= buflen) { | 
 | 			Py_XDECREF(copy); | 
 | 			continue; /* Too long */ | 
 | 		} | 
 | 		strcpy(buf, PyString_AsString(v)); | 
 | 		if (strlen(buf) != len) { | 
 | 			Py_XDECREF(copy); | 
 | 			continue; /* v contains '\0' */ | 
 | 		} | 
 |  | 
 | 		/* sys.path_hooks import hook */ | 
 | 		if (p_loader != NULL) { | 
 | 			PyObject *importer; | 
 |  | 
 | 			importer = get_path_importer(path_importer_cache, | 
 | 						     path_hooks, v); | 
 | 			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); | 
 | 			} | 
 | 			/* no hook was successful, use builtin import */ | 
 | 		} | 
 |  | 
 | #ifdef macintosh | 
 | 		/* | 
 | 		** Speedup: each sys.path item is interned, and | 
 | 		** FindResourceModule remembers which items refer to | 
 | 		** folders (so we don't have to bother trying to look | 
 | 		** into them for resources). We only do this for string | 
 | 		** items. | 
 | 		*/ | 
 | 		if (PyString_Check(PyList_GET_ITEM(path, i))) { | 
 | 			PyString_InternInPlace(&PyList_GET_ITEM(path, i)); | 
 | 			v = PyList_GET_ITEM(path, i); | 
 | 			if (PyMac_FindResourceModule((PyStringObject *)v, name, buf)) { | 
 | 				static struct filedescr resfiledescr = | 
 | 					{"", "", PY_RESOURCE}; | 
 |  | 
 | 				Py_XDECREF(copy); | 
 | 				return &resfiledescr; | 
 | 			} | 
 | 			if (PyMac_FindCodeResourceModule((PyStringObject *)v, name, buf)) { | 
 | 				static struct filedescr resfiledescr = | 
 | 					{"", "", PY_CODERESOURCE}; | 
 |  | 
 | 				Py_XDECREF(copy); | 
 | 				return &resfiledescr; | 
 | 			} | 
 | 		} | 
 | #endif | 
 | 		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 */ | 
 | 		    find_init_module(buf) &&            /* it has __init__.py */ | 
 | 		    case_ok(buf, len, namelen, name)) { /* and case matches */ | 
 | 			Py_XDECREF(copy); | 
 | 			return &fd_package; | 
 | 		} | 
 | #else | 
 | 		/* XXX How are you going to test for directories? */ | 
 | #ifdef RISCOS | 
 | 		if (isdir(buf) && | 
 | 		    find_init_module(buf) && | 
 | 		    case_ok(buf, len, namelen, name)) { | 
 | 			Py_XDECREF(copy); | 
 | 			return &fd_package; | 
 | 		} | 
 | #endif | 
 | #endif | 
 | #ifdef macintosh | 
 | 		fdp = PyMac_FindModuleExtension(buf, &len, name); | 
 | 		if (fdp) { | 
 | #else | 
 | #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) | 
 | 			/* 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); | 
 | #endif /* !macintosh */ | 
 | 			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 | 
 | 		Py_XDECREF(copy); | 
 | 		if (fp != NULL) | 
 | 			break; | 
 | 	} | 
 | 	if (fp == NULL) { | 
 | 		PyErr_Format(PyExc_ImportError, | 
 | 			     "No module named %.200s", name); | 
 | 		return NULL; | 
 | 	} | 
 | 	*p_fp = fp; | 
 | 	return fdp; | 
 | } | 
 |  | 
 | /* case_ok(char* buf, int len, int 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) || defined(__CYGWIN__) | 
 | #include <windows.h> | 
 | #ifdef __CYGWIN__ | 
 | #include <sys/cygwin.h> | 
 | #endif | 
 |  | 
 | #elif defined(DJGPP) | 
 | #include <dir.h> | 
 |  | 
 | #elif defined(macintosh) | 
 | #include <TextUtils.h> | 
 |  | 
 | #elif defined(__MACH__) && defined(__APPLE__) && 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> | 
 |  | 
 | #elif defined(RISCOS) | 
 | #include "oslib/osfscontrol.h" | 
 | #endif | 
 |  | 
 | static int | 
 | case_ok(char *buf, int len, int namelen, char *name) | 
 | { | 
 | /* Pick a platform-specific implementation; the sequence of #if's here should | 
 |  * match the sequence just above. | 
 |  */ | 
 |  | 
 | /* MS_WINDOWS || __CYGWIN__ */ | 
 | #if defined(MS_WINDOWS) || defined(__CYGWIN__) | 
 | 	WIN32_FIND_DATA data; | 
 | 	HANDLE h; | 
 | #ifdef __CYGWIN__ | 
 | 	char tempbuf[MAX_PATH]; | 
 | #endif | 
 |  | 
 | 	if (Py_GETENV("PYTHONCASEOK") != NULL) | 
 | 		return 1; | 
 |  | 
 | #ifdef __CYGWIN__ | 
 | 	cygwin32_conv_to_win32_path(buf, tempbuf); | 
 | 	h = FindFirstFile(tempbuf, &data); | 
 | #else | 
 | 	h = FindFirstFile(buf, &data); | 
 | #endif | 
 | 	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; | 
 |  | 
 | /* macintosh */ | 
 | #elif defined(macintosh) | 
 | 	FSSpec fss; | 
 | 	OSErr err; | 
 |  | 
 | 	if (Py_GETENV("PYTHONCASEOK") != NULL) | 
 | 		return 1; | 
 |  | 
 | 	err = FSMakeFSSpec(0, 0, Pstring(buf), &fss); | 
 | 	if (err) { | 
 | 		PyErr_Format(PyExc_NameError, | 
 | 		     "Can't find file for module %.100s\n(filename %.300s)", | 
 | 		     name, buf); | 
 | 		return 0; | 
 | 	} | 
 | 	return fss.name[0] >= namelen && | 
 | 	       strncmp(name, (char *)fss.name+1, namelen) == 0; | 
 |  | 
 | /* new-fangled macintosh (macosx) */ | 
 | #elif defined(__MACH__) && defined(__APPLE__) && 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 */ | 
 |  | 
 | /* RISC OS */ | 
 | #elif defined(RISCOS) | 
 | 	char canon[MAXPATHLEN+1]; /* buffer for the canonical form of the path */ | 
 | 	char buf2[MAXPATHLEN+2]; | 
 | 	char *nameWithExt = buf+len-namelen; | 
 | 	int canonlen; | 
 | 	os_error *e; | 
 |  | 
 | 	if (Py_GETENV("PYTHONCASEOK") != NULL) | 
 | 		return 1; | 
 |  | 
 | 	/* workaround: | 
 | 	   append wildcard, otherwise case of filename wouldn't be touched */ | 
 | 	strcpy(buf2, buf); | 
 | 	strcat(buf2, "*"); | 
 |  | 
 | 	e = xosfscontrol_canonicalise_path(buf2,canon,0,0,MAXPATHLEN+1,&canonlen); | 
 | 	canonlen = MAXPATHLEN+1-canonlen; | 
 | 	if (e || canonlen<=0 || canonlen>(MAXPATHLEN+1) ) | 
 | 		return 0; | 
 | 	if (strcmp(nameWithExt, canon+canonlen-strlen(nameWithExt))==0) | 
 | 		return 1; /* match */ | 
 |  | 
 | 	return 0; | 
 |  | 
 | /* OS/2 */ | 
 | #elif defined(PYOS_OS2) | 
 | 	HDIR hdir = 1; | 
 | 	ULONG srchcnt = 1; | 
 | 	FILEFINDBUF3 ffbuf; | 
 | 	APIRET rc; | 
 |  | 
 | 	if (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; | 
 | } | 
 |  | 
 | #else | 
 |  | 
 | #ifdef RISCOS | 
 | static int | 
 | find_init_module(buf) | 
 | 	char *buf; | 
 | { | 
 | 	int save_len = strlen(buf); | 
 | 	int i = save_len; | 
 |  | 
 | 	if (save_len + 13 >= MAXPATHLEN) | 
 | 		return 0; | 
 | 	buf[i++] = SEP; | 
 | 	strcpy(buf+i, "__init__/py"); | 
 | 	if (isfile(buf)) { | 
 | 		buf[save_len] = '\0'; | 
 | 		return 1; | 
 | 	} | 
 |  | 
 | 	if (Py_OptimizeFlag) | 
 | 		strcpy(buf+i, "o"); | 
 | 	else | 
 | 		strcpy(buf+i, "c"); | 
 | 	if (isfile(buf)) { | 
 | 		buf[save_len] = '\0'; | 
 | 		return 1; | 
 | 	} | 
 | 	buf[save_len] = '\0'; | 
 | 	return 0; | 
 | } | 
 | #endif /*RISCOS*/ | 
 |  | 
 | #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 *buf, 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, buf, fp); | 
 | 		break; | 
 |  | 
 | 	case PY_COMPILED: | 
 | 		m = load_compiled_module(name, buf, fp); | 
 | 		break; | 
 |  | 
 | #ifdef HAVE_DYNAMIC_LOADING | 
 | 	case C_EXTENSION: | 
 | 		m = _PyImport_LoadDynamicModule(name, buf, fp); | 
 | 		break; | 
 | #endif | 
 |  | 
 | #ifdef macintosh | 
 | 	case PY_RESOURCE: | 
 | 		m = PyMac_LoadResourceModule(name, buf); | 
 | 		break; | 
 | 	case PY_CODERESOURCE: | 
 | 		m = PyMac_LoadCodeResourceModule(name, buf); | 
 | 		break; | 
 | #endif | 
 |  | 
 | 	case PKG_DIRECTORY: | 
 | 		m = load_package(name, buf); | 
 | 		break; | 
 |  | 
 | 	case C_BUILTIN: | 
 | 	case PY_FROZEN: | 
 | 		if (buf != NULL && buf[0] != '\0') | 
 | 			name = buf; | 
 | 		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 succes, 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++) { | 
 | 		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); | 
 | 			(*p->initfunc)(); | 
 | 			if (PyErr_Occurred()) | 
 | 				return -1; | 
 | 			if (_PyImport_FixupExtension(name, name) == NULL) | 
 | 				return -1; | 
 | 			return 1; | 
 | 		} | 
 | 	} | 
 | 	return 0; | 
 | } | 
 |  | 
 |  | 
 | /* Frozen modules */ | 
 |  | 
 | static struct _frozen * | 
 | find_frozen(char *name) | 
 | { | 
 | 	struct _frozen *p; | 
 |  | 
 | 	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); | 
 | } | 
 |  | 
 | /* Initialize a frozen module. | 
 |    Return 1 for succes, 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)) { | 
 | 		Py_DECREF(co); | 
 | 		PyErr_Format(PyExc_TypeError, | 
 | 			     "frozen object %.200s is not a code object", | 
 | 			     name); | 
 | 		return -1; | 
 | 	} | 
 | 	if (ispackage) { | 
 | 		/* Set __path__ to the package name */ | 
 | 		PyObject *d, *s; | 
 | 		int err; | 
 | 		m = PyImport_AddModule(name); | 
 | 		if (m == NULL) | 
 | 			return -1; | 
 | 		d = PyModule_GetDict(m); | 
 | 		s = PyString_InternFromString(name); | 
 | 		if (s == NULL) | 
 | 			return -1; | 
 | 		err = PyDict_SetItemString(d, "__path__", s); | 
 | 		Py_DECREF(s); | 
 | 		if (err != 0) | 
 | 			return err; | 
 | 	} | 
 | 	m = PyImport_ExecCodeModuleEx(name, co, "<frozen>"); | 
 | 	Py_DECREF(co); | 
 | 	if (m == NULL) | 
 | 		return -1; | 
 | 	Py_DECREF(m); | 
 | 	return 1; | 
 | } | 
 |  | 
 |  | 
 | /* Import a module, either built-in, frozen, or external, and return | 
 |    its module object WITH INCREMENTED REFERENCE COUNT */ | 
 |  | 
 | PyObject * | 
 | PyImport_ImportModule(char *name) | 
 | { | 
 | 	PyObject *pname; | 
 | 	PyObject *result; | 
 |  | 
 | 	pname = PyString_FromString(name); | 
 | 	if (pname == NULL) | 
 | 		return NULL; | 
 | 	result = PyImport_Import(pname); | 
 | 	Py_DECREF(pname); | 
 | 	return result; | 
 | } | 
 |  | 
 | /* Forward declarations for helper routines */ | 
 | static PyObject *get_parent(PyObject *globals, char *buf, int *p_buflen); | 
 | static PyObject *load_next(PyObject *mod, PyObject *altmod, | 
 | 			   char **p_name, char *buf, int *p_buflen); | 
 | static int mark_miss(char *name); | 
 | static int ensure_fromlist(PyObject *mod, PyObject *fromlist, | 
 | 			   char *buf, int buflen, int recursive); | 
 | static PyObject * import_submodule(PyObject *mod, char *name, char *fullname); | 
 |  | 
 | /* The Magnum Opus of dotted-name import :-) */ | 
 |  | 
 | static PyObject * | 
 | import_module_ex(char *name, PyObject *globals, PyObject *locals, | 
 | 		 PyObject *fromlist) | 
 | { | 
 | 	char buf[MAXPATHLEN+1]; | 
 | 	int buflen = 0; | 
 | 	PyObject *parent, *head, *next, *tail; | 
 |  | 
 | 	parent = get_parent(globals, buf, &buflen); | 
 | 	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 (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_ImportModuleEx(char *name, PyObject *globals, PyObject *locals, | 
 | 			PyObject *fromlist) | 
 | { | 
 | 	PyObject *result; | 
 | 	lock_import(); | 
 | 	result = import_module_ex(name, globals, locals, fromlist); | 
 | 	if (unlock_import() < 0) { | 
 | 		Py_XDECREF(result); | 
 | 		PyErr_SetString(PyExc_RuntimeError, | 
 | 				"not holding the import lock"); | 
 | 		return NULL; | 
 | 	} | 
 | 	return result; | 
 | } | 
 |  | 
 | static PyObject * | 
 | get_parent(PyObject *globals, char *buf, int *p_buflen) | 
 | { | 
 | 	static PyObject *namestr = NULL; | 
 | 	static PyObject *pathstr = NULL; | 
 | 	PyObject *modname, *modpath, *modules, *parent; | 
 |  | 
 | 	if (globals == NULL || !PyDict_Check(globals)) | 
 | 		return Py_None; | 
 |  | 
 | 	if (namestr == NULL) { | 
 | 		namestr = PyString_InternFromString("__name__"); | 
 | 		if (namestr == NULL) | 
 | 			return NULL; | 
 | 	} | 
 | 	if (pathstr == NULL) { | 
 | 		pathstr = PyString_InternFromString("__path__"); | 
 | 		if (pathstr == NULL) | 
 | 			return NULL; | 
 | 	} | 
 |  | 
 | 	*buf = '\0'; | 
 | 	*p_buflen = 0; | 
 | 	modname = PyDict_GetItem(globals, namestr); | 
 | 	if (modname == NULL || !PyString_Check(modname)) | 
 | 		return Py_None; | 
 |  | 
 | 	modpath = PyDict_GetItem(globals, pathstr); | 
 | 	if (modpath != NULL) { | 
 | 		int len = PyString_GET_SIZE(modname); | 
 | 		if (len > MAXPATHLEN) { | 
 | 			PyErr_SetString(PyExc_ValueError, | 
 | 					"Module name too long"); | 
 | 			return NULL; | 
 | 		} | 
 | 		strcpy(buf, PyString_AS_STRING(modname)); | 
 | 		*p_buflen = len; | 
 | 	} | 
 | 	else { | 
 | 		char *start = PyString_AS_STRING(modname); | 
 | 		char *lastdot = strrchr(start, '.'); | 
 | 		size_t len; | 
 | 		if (lastdot == 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'; | 
 | 		*p_buflen = len; | 
 | 	} | 
 |  | 
 | 	modules = PyImport_GetModuleDict(); | 
 | 	parent = PyDict_GetItemString(modules, buf); | 
 | 	if (parent == NULL) | 
 | 		parent = Py_None; | 
 | 	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, | 
 | 	  int *p_buflen) | 
 | { | 
 | 	char *name = *p_name; | 
 | 	char *dot = strchr(name, '.'); | 
 | 	size_t len; | 
 | 	char *p; | 
 | 	PyObject *result; | 
 |  | 
 | 	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, int 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 (!PyString_Check(item)) { | 
 | 			PyErr_SetString(PyExc_TypeError, | 
 | 					"Item in ``from list'' not a string"); | 
 | 			Py_DECREF(item); | 
 | 			return 0; | 
 | 		} | 
 | 		if (PyString_AS_STRING(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 { | 
 | 				if (!ensure_fromlist(mod, all, buf, buflen, 1)) | 
 | 					return 0; | 
 | 				Py_DECREF(all); | 
 | 			} | 
 | 			continue; | 
 | 		} | 
 | 		hasit = PyObject_HasAttr(mod, item); | 
 | 		if (!hasit) { | 
 | 			char *subname = PyString_AS_STRING(item); | 
 | 			PyObject *submod; | 
 | 			char *p; | 
 | 			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_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) | 
 | { | 
 | 	PyObject *modules = PyImport_GetModuleDict(); | 
 | 	PyObject *path = NULL; | 
 | 	char *name, *subname; | 
 | 	char buf[MAXPATHLEN+1]; | 
 | 	struct filedescr *fdp; | 
 | 	FILE *fp = NULL; | 
 |  | 
 | 	if (m == NULL || !PyModule_Check(m)) { | 
 | 		PyErr_SetString(PyExc_TypeError, | 
 | 				"reload() argument must be module"); | 
 | 		return NULL; | 
 | 	} | 
 | 	name = 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; | 
 | 	} | 
 | 	subname = strrchr(name, '.'); | 
 | 	if (subname == NULL) | 
 | 		subname = name; | 
 | 	else { | 
 | 		PyObject *parentname, *parent; | 
 | 		parentname = PyString_FromStringAndSize(name, (subname-name)); | 
 | 		if (parentname == NULL) | 
 | 			return NULL; | 
 | 		parent = PyDict_GetItem(modules, parentname); | 
 | 		Py_DECREF(parentname); | 
 | 		if (parent == NULL) { | 
 | 			PyErr_Format(PyExc_ImportError, | 
 | 			    "reload(): parent %.200s not in sys.modules", | 
 | 			    name); | 
 | 			return NULL; | 
 | 		} | 
 | 		subname++; | 
 | 		path = PyObject_GetAttrString(parent, "__path__"); | 
 | 		if (path == NULL) | 
 | 			PyErr_Clear(); | 
 | 	} | 
 | 	buf[0] = '\0'; | 
 | 	fdp = find_module(name, subname, path, buf, MAXPATHLEN+1, &fp, NULL); | 
 | 	Py_XDECREF(path); | 
 | 	if (fdp == NULL) | 
 | 		return NULL; | 
 | 	m = load_module(name, fp, buf, fdp->type, NULL); | 
 | 	if (fp) | 
 | 		fclose(fp); | 
 | 	return m; | 
 | } | 
 |  | 
 |  | 
 | /* 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(PyString_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 = PyString_InternFromString("__import__"); | 
 | 		if (import_str == NULL) | 
 | 			return NULL; | 
 | 		builtins_str = PyString_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_ImportModuleEx("__builtin__", | 
 | 						   NULL, NULL, NULL); | 
 | 		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 */ | 
 | 	r = PyObject_CallFunction(import, "OOOO", | 
 | 				  module_name, globals, globals, silly_list); | 
 |  | 
 |   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 PyString_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; | 
 | 	struct filedescr *fdp; | 
 | 	char pathname[MAXPATHLEN+1]; | 
 | 	FILE *fp = 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) { | 
 | 		fob = PyFile_FromFile(fp, pathname, fdp->mode, fclose); | 
 | 		if (fob == NULL) { | 
 | 			fclose(fp); | 
 | 			return NULL; | 
 | 		} | 
 | 	} | 
 | 	else { | 
 | 		fob = Py_None; | 
 | 		Py_INCREF(fob); | 
 | 	} | 
 | 	ret = Py_BuildValue("Os(ssi)", | 
 | 		      fob, pathname, fdp->suffix, fdp->mode, fdp->type); | 
 | 	Py_DECREF(fob); | 
 | 	return ret; | 
 | } | 
 |  | 
 | static PyObject * | 
 | imp_find_module(PyObject *self, PyObject *args) | 
 | { | 
 | 	char *name; | 
 | 	PyObject *path = NULL; | 
 | 	if (!PyArg_ParseTuple(args, "s|O:find_module", &name, &path)) | 
 | 		return NULL; | 
 | 	return call_find_module(name, path); | 
 | } | 
 |  | 
 | 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_builtin(PyObject *self, PyObject *args) | 
 | { | 
 | 	char *name; | 
 | 	if (!PyArg_ParseTuple(args, "s:is_builtin", &name)) | 
 | 		return NULL; | 
 | 	return PyInt_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 (fob == NULL) { | 
 | 		if (mode[0] == 'U')  | 
 | 			mode = "r" PY_STDIOTEXTMODE; | 
 | 		fp = fopen(pathname, mode); | 
 | 		if (fp == NULL) | 
 | 			PyErr_SetFromErrno(PyExc_IOError); | 
 | 	} | 
 | 	else { | 
 | 		fp = PyFile_AsFile(fob); | 
 | 		if (fp == NULL) | 
 | 			PyErr_SetString(PyExc_ValueError, | 
 | 					"bad/closed file object"); | 
 | 	} | 
 | 	return fp; | 
 | } | 
 |  | 
 | static PyObject * | 
 | imp_load_compiled(PyObject *self, PyObject *args) | 
 | { | 
 | 	char *name; | 
 | 	char *pathname; | 
 | 	PyObject *fob = NULL; | 
 | 	PyObject *m; | 
 | 	FILE *fp; | 
 | 	if (!PyArg_ParseTuple(args, "ss|O!:load_compiled", &name, &pathname, | 
 | 			      &PyFile_Type, &fob)) | 
 | 		return NULL; | 
 | 	fp = get_file(pathname, fob, "rb"); | 
 | 	if (fp == NULL) | 
 | 		return NULL; | 
 | 	m = load_compiled_module(name, pathname, fp); | 
 | 	if (fob == NULL) | 
 | 		fclose(fp); | 
 | 	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, "ss|O!:load_dynamic", &name, &pathname, | 
 | 			      &PyFile_Type, &fob)) | 
 | 		return NULL; | 
 | 	if (fob) { | 
 | 		fp = get_file(pathname, fob, "r"); | 
 | 		if (fp == NULL) | 
 | 			return NULL; | 
 | 	} | 
 | 	m = _PyImport_LoadDynamicModule(name, pathname, 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, "ss|O!:load_source", &name, &pathname, | 
 | 			      &PyFile_Type, &fob)) | 
 | 		return NULL; | 
 | 	fp = get_file(pathname, fob, "r"); | 
 | 	if (fp == NULL) | 
 | 		return NULL; | 
 | 	m = load_source_module(name, pathname, fp); | 
 | 	if (fob == NULL) | 
 | 		fclose(fp); | 
 | 	return m; | 
 | } | 
 |  | 
 | #ifdef macintosh | 
 | static PyObject * | 
 | imp_load_resource(PyObject *self, PyObject *args) | 
 | { | 
 | 	char *name; | 
 | 	char *pathname; | 
 | 	PyObject *m; | 
 |  | 
 | 	if (!PyArg_ParseTuple(args, "ss:load_resource", &name, &pathname)) | 
 | 		return NULL; | 
 | 	m = PyMac_LoadResourceModule(name, pathname); | 
 | 	return m; | 
 | } | 
 | #endif /* macintosh */ | 
 |  | 
 | static PyObject * | 
 | imp_load_module(PyObject *self, PyObject *args) | 
 | { | 
 | 	char *name; | 
 | 	PyObject *fob; | 
 | 	char *pathname; | 
 | 	char *suffix; /* Unused */ | 
 | 	char *mode; | 
 | 	int type; | 
 | 	FILE *fp; | 
 |  | 
 | 	if (!PyArg_ParseTuple(args, "sOs(ssi):load_module", | 
 | 			      &name, &fob, &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); | 
 | 			return NULL; | 
 | 		} | 
 | 	} | 
 | 	if (fob == Py_None) | 
 | 		fp = NULL; | 
 | 	else { | 
 | 		if (!PyFile_Check(fob)) { | 
 | 			PyErr_SetString(PyExc_ValueError, | 
 | 				"load_module arg#2 should be a file or None"); | 
 | 			return NULL; | 
 | 		} | 
 | 		fp = get_file(pathname, fob, mode); | 
 | 		if (fp == NULL) | 
 | 			return NULL; | 
 | 	} | 
 | 	return load_module(name, fp, pathname, type, NULL); | 
 | } | 
 |  | 
 | static PyObject * | 
 | imp_load_package(PyObject *self, PyObject *args) | 
 | { | 
 | 	char *name; | 
 | 	char *pathname; | 
 | 	if (!PyArg_ParseTuple(args, "ss:load_package", &name, &pathname)) | 
 | 		return NULL; | 
 | 	return load_package(name, pathname); | 
 | } | 
 |  | 
 | 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); | 
 | } | 
 |  | 
 | /* 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() -> 0 or 1\n\ | 
 | Return 1 if the import lock is currently held.\n\ | 
 | On platforms without threads, return 0."); | 
 |  | 
 | 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}, | 
 | 	/* The rest are obsolete */ | 
 | 	{"get_frozen_object",	imp_get_frozen_object,	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}, | 
 | #ifdef macintosh | 
 | 	{"load_resource",	imp_load_resource,	METH_VARARGS}, | 
 | #endif | 
 | 	{"load_source",		imp_load_source,	METH_VARARGS}, | 
 | 	{NULL,			NULL}		/* sentinel */ | 
 | }; | 
 |  | 
 | static int | 
 | setint(PyObject *d, char *name, int value) | 
 | { | 
 | 	PyObject *v; | 
 | 	int err; | 
 |  | 
 | 	v = PyInt_FromLong((long)value); | 
 | 	err = PyDict_SetItemString(d, name, v); | 
 | 	Py_XDECREF(v); | 
 | 	return err; | 
 | } | 
 |  | 
 | void | 
 | initimp(void) | 
 | { | 
 | 	PyObject *m, *d; | 
 |  | 
 | 	m = Py_InitModule4("imp", imp_methods, doc_imp, | 
 | 			   NULL, PYTHON_API_VERSION); | 
 | 	d = PyModule_GetDict(m); | 
 |  | 
 | 	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; | 
 |  | 
 |   failure: | 
 | 	; | 
 | } | 
 |  | 
 |  | 
 | /* 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(char *name, void (*initfunc)(void)) | 
 | { | 
 | 	struct _inittab newtab[2]; | 
 |  | 
 | 	memset(newtab, '\0', sizeof newtab); | 
 |  | 
 | 	newtab[0].name = name; | 
 | 	newtab[0].initfunc = initfunc; | 
 |  | 
 | 	return PyImport_ExtendInittab(newtab); | 
 | } |