14710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
24710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* Module definition and import implementation */
34710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
44710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#include "Python.h"
54710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
64710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#include "Python-ast.h"
74710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#undef Yield /* undefine macro conflicting with winbase.h */
84710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#include "pyarena.h"
94710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#include "pythonrun.h"
104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#include "errcode.h"
114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#include "marshal.h"
124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#include "code.h"
134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#include "compile.h"
144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#include "eval.h"
154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#include "osdefs.h"
164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#include "importdl.h"
174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef HAVE_FCNTL_H
194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#include <fcntl.h>
204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif
214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef __cplusplus
224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmextern "C" {
234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif
244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef MS_WINDOWS
264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* for stat.st_mode */
274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtypedef unsigned short mode_t;
284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif
294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* Magic word to reject .pyc files generated by other Python versions.
324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   It should change for each incompatible change to the bytecode.
334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   The value of CR and LF is incorporated so if you ever read or write
354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   a .pyc file in text mode the magic number will be wrong; also, the
364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   Apple MPW compiler swaps their values, botching string constants.
374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   The magic numbers must be spaced apart atleast 2 values, as the
394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   -U interpeter flag will cause MAGIC+1 being used. They have been
404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   odd numbers for some time now.
414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   There were a variety of old schemes for setting the magic number.
434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   The current working scheme is to increment the previous value by
444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   10.
454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   Known values:
474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       Python 1.5:   20121
484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       Python 1.5.1: 20121
494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       Python 1.5.2: 20121
504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       Python 1.6:   50428
514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       Python 2.0:   50823
524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       Python 2.0.1: 50823
534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       Python 2.1:   60202
544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       Python 2.1.1: 60202
554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       Python 2.1.2: 60202
564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       Python 2.2:   60717
574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       Python 2.3a0: 62011
584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       Python 2.3a0: 62021
594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       Python 2.3a0: 62011 (!)
604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       Python 2.4a0: 62041
614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       Python 2.4a3: 62051
624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       Python 2.4b1: 62061
634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       Python 2.5a0: 62071
644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       Python 2.5a0: 62081 (ast-branch)
654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       Python 2.5a0: 62091 (with)
664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       Python 2.5a0: 62092 (changed WITH_CLEANUP opcode)
674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       Python 2.5b3: 62101 (fix wrong code: for x, in ...)
684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       Python 2.5b3: 62111 (fix wrong code: x += yield)
694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       Python 2.5c1: 62121 (fix wrong lnotab with for loops and
704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                            storing constants that should have been removed)
714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       Python 2.5c2: 62131 (fix wrong code: for x, in ... in listcomp/genexp)
724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       Python 2.6a0: 62151 (peephole optimizations and STORE_MAP opcode)
734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       Python 2.6a1: 62161 (WITH_CLEANUP optimization)
744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       Python 2.7a0: 62171 (optimize list comprehensions/change LIST_APPEND)
754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       Python 2.7a0: 62181 (optimize conditional branches:
764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                introduce POP_JUMP_IF_FALSE and POP_JUMP_IF_TRUE)
774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       Python 2.7a0  62191 (introduce SETUP_WITH)
784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       Python 2.7a0  62201 (introduce BUILD_SET)
794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       Python 2.7a0  62211 (introduce MAP_ADD and SET_ADD)
804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm.
814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm*/
824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#define MAGIC (62211 | ((long)'\r'<<16) | ((long)'\n'<<24))
834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* Magic word as global; note that _PyImport_Init() can change the
854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   value of this global to accommodate for alterations of how the
864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   compiler works which are enabled by command line switches. */
874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic long pyc_magic = MAGIC;
884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* See _PyImport_FixupExtension() below */
904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject *extensions = NULL;
914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* This table is defined in config.c: */
934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmextern struct _inittab _PyImport_Inittab[];
944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstruct _inittab *PyImport_Inittab = _PyImport_Inittab;
964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* these tables define the module suffixes that Python recognizes */
984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstruct filedescr * _PyImport_Filetab = NULL;
994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef RISCOS
1014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic const struct filedescr _PyImport_StandardFiletab[] = {
1024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    {"/py", "U", PY_SOURCE},
1034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    {"/pyc", "rb", PY_COMPILED},
1044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    {0, 0}
1054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm};
1064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#else
1074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic const struct filedescr _PyImport_StandardFiletab[] = {
1084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    {".py", "U", PY_SOURCE},
1094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef MS_WINDOWS
1104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    {".pyw", "U", PY_SOURCE},
1114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif
1124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    {".pyc", "rb", PY_COMPILED},
1134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    {0, 0}
1144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm};
1154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif
1164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* Initialize things */
1194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmvoid
1214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm_PyImport_Init(void)
1224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
1234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    const struct filedescr *scan;
1244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    struct filedescr *filetab;
1254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    int countD = 0;
1264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    int countS = 0;
1274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* prepare _PyImport_Filetab: copy entries from
1294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       _PyImport_DynLoadFiletab and _PyImport_StandardFiletab.
1304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm     */
1314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef HAVE_DYNAMIC_LOADING
1324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    for (scan = _PyImport_DynLoadFiletab; scan->suffix != NULL; ++scan)
1334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        ++countD;
1344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif
1354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    for (scan = _PyImport_StandardFiletab; scan->suffix != NULL; ++scan)
1364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        ++countS;
1374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    filetab = PyMem_NEW(struct filedescr, countD + countS + 1);
1384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (filetab == NULL)
1394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        Py_FatalError("Can't initialize import file table.");
1404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef HAVE_DYNAMIC_LOADING
1414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    memcpy(filetab, _PyImport_DynLoadFiletab,
1424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm           countD * sizeof(struct filedescr));
1434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif
1444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    memcpy(filetab + countD, _PyImport_StandardFiletab,
1454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm           countS * sizeof(struct filedescr));
1464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    filetab[countD + countS].suffix = NULL;
1474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    _PyImport_Filetab = filetab;
1494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (Py_OptimizeFlag) {
1514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        /* Replace ".pyc" with ".pyo" in _PyImport_Filetab */
1524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        for (; filetab->suffix != NULL; filetab++) {
1534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifndef RISCOS
1544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (strcmp(filetab->suffix, ".pyc") == 0)
1554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                filetab->suffix = ".pyo";
1564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#else
1574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (strcmp(filetab->suffix, "/pyc") == 0)
1584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                filetab->suffix = "/pyo";
1594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif
1604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
1614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
1624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (Py_UnicodeFlag) {
1644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        /* Fix the pyc_magic so that byte compiled code created
1654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm           using the all-Unicode method doesn't interfere with
1664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm           code created in normal operation mode. */
1674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        pyc_magic = MAGIC + 1;
1684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
1694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
1704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmvoid
1724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm_PyImportHooks_Init(void)
1734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
1744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *v, *path_hooks = NULL, *zimpimport;
1754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    int err = 0;
1764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* adding sys.path_hooks and sys.path_importer_cache, setting up
1784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       zipimport */
1794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (PyType_Ready(&PyNullImporter_Type) < 0)
1804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        goto error;
1814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (Py_VerboseFlag)
1834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PySys_WriteStderr("# installing zipimport hook\n");
1844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
1854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    v = PyList_New(0);
1864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (v == NULL)
1874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        goto error;
1884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    err = PySys_SetObject("meta_path", v);
1894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_DECREF(v);
1904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (err)
1914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        goto error;
1924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    v = PyDict_New();
1934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (v == NULL)
1944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        goto error;
1954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    err = PySys_SetObject("path_importer_cache", v);
1964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_DECREF(v);
1974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (err)
1984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        goto error;
1994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    path_hooks = PyList_New(0);
2004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (path_hooks == NULL)
2014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        goto error;
2024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    err = PySys_SetObject("path_hooks", path_hooks);
2034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (err) {
2044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm  error:
2054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyErr_Print();
2064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        Py_FatalError("initializing sys.meta_path, sys.path_hooks, "
2074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                      "path_importer_cache, or NullImporter failed"
2084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                      );
2094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
2104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    zimpimport = PyImport_ImportModule("zipimport");
2124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (zimpimport == NULL) {
2134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyErr_Clear(); /* No zip import module -- okay */
2144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (Py_VerboseFlag)
2154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PySys_WriteStderr("# can't import zipimport\n");
2164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
2174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    else {
2184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyObject *zipimporter = PyObject_GetAttrString(zimpimport,
2194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                                       "zipimporter");
2204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        Py_DECREF(zimpimport);
2214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (zipimporter == NULL) {
2224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PyErr_Clear(); /* No zipimporter object -- okay */
2234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (Py_VerboseFlag)
2244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                PySys_WriteStderr(
2254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    "# can't import zipimport.zipimporter\n");
2264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
2274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else {
2284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            /* sys.path_hooks.append(zipimporter) */
2294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            err = PyList_Append(path_hooks, zipimporter);
2304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            Py_DECREF(zipimporter);
2314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (err)
2324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                goto error;
2334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (Py_VerboseFlag)
2344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                PySys_WriteStderr(
2354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    "# installed zipimport hook\n");
2364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
2374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
2384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_DECREF(path_hooks);
2394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
2404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmvoid
2424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm_PyImport_Fini(void)
2434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
2444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_XDECREF(extensions);
2454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    extensions = NULL;
2464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyMem_DEL(_PyImport_Filetab);
2474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    _PyImport_Filetab = NULL;
2484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
2494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* Locking primitives to prevent parallel imports of the same module
2524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   in different threads to return with a partially loaded module.
2534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   These calls are serialized by the global interpreter lock. */
2544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef WITH_THREAD
2564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#include "pythread.h"
2584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyThread_type_lock import_lock = 0;
2604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic long import_lock_thread = -1;
2614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic int import_lock_level = 0;
2624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmvoid
2644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm_PyImport_AcquireLock(void)
2654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
2664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    long me = PyThread_get_thread_ident();
2674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (me == -1)
2684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return; /* Too bad */
2694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (import_lock == NULL) {
2704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        import_lock = PyThread_allocate_lock();
2714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (import_lock == NULL)
2724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return;  /* Nothing much we can do. */
2734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
2744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (import_lock_thread == me) {
2754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        import_lock_level++;
2764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return;
2774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
2784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (import_lock_thread != -1 || !PyThread_acquire_lock(import_lock, 0))
2794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    {
2804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyThreadState *tstate = PyEval_SaveThread();
2814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyThread_acquire_lock(import_lock, 1);
2824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyEval_RestoreThread(tstate);
2834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
2844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    import_lock_thread = me;
2854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    import_lock_level = 1;
2864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
2874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
2884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmint
2894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm_PyImport_ReleaseLock(void)
2904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
2914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    long me = PyThread_get_thread_ident();
2924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (me == -1 || import_lock == NULL)
2934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return 0; /* Too bad */
2944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (import_lock_thread != me)
2954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return -1;
2964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    import_lock_level--;
2974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (import_lock_level == 0) {
2984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        import_lock_thread = -1;
2994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyThread_release_lock(import_lock);
3004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
3014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return 1;
3024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
3034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* This function is called from PyOS_AfterFork to ensure that newly
3054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   created child processes do not share locks with the parent.
3064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   We now acquire the import lock around fork() calls but on some platforms
3074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   (Solaris 9 and earlier? see isue7242) that still left us with problems. */
3084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmvoid
3104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm_PyImport_ReInitLock(void)
3114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
3124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (import_lock != NULL)
3134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        import_lock = PyThread_allocate_lock();
3144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    import_lock_thread = -1;
3154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    import_lock_level = 0;
3164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
3174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif
3194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject *
3214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimp_lock_held(PyObject *self, PyObject *noargs)
3224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
3234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef WITH_THREAD
3244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return PyBool_FromLong(import_lock_thread != -1);
3254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#else
3264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return PyBool_FromLong(0);
3274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif
3284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
3294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject *
3314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimp_acquire_lock(PyObject *self, PyObject *noargs)
3324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
3334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef WITH_THREAD
3344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    _PyImport_AcquireLock();
3354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif
3364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_INCREF(Py_None);
3374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return Py_None;
3384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
3394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject *
3414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimp_release_lock(PyObject *self, PyObject *noargs)
3424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
3434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef WITH_THREAD
3444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (_PyImport_ReleaseLock() < 0) {
3454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyErr_SetString(PyExc_RuntimeError,
3464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        "not holding the import lock");
3474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
3484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
3494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif
3504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_INCREF(Py_None);
3514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return Py_None;
3524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
3534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic void
3554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimp_modules_reloading_clear(void)
3564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
3574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyInterpreterState *interp = PyThreadState_Get()->interp;
3584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (interp->modules_reloading != NULL)
3594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyDict_Clear(interp->modules_reloading);
3604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
3614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* Helper for sys */
3634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyObject *
3654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyImport_GetModuleDict(void)
3664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
3674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyInterpreterState *interp = PyThreadState_GET()->interp;
3684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (interp->modules == NULL)
3694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        Py_FatalError("PyImport_GetModuleDict: no module dictionary!");
3704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return interp->modules;
3714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
3724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* List of names to clear in sys */
3754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic char* sys_deletes[] = {
3764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    "path", "argv", "ps1", "ps2", "exitfunc",
3774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    "exc_type", "exc_value", "exc_traceback",
3784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    "last_type", "last_value", "last_traceback",
3794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    "path_hooks", "path_importer_cache", "meta_path",
3804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* misc stuff */
3814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    "flags", "float_info",
3824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    NULL
3834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm};
3844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic char* sys_files[] = {
3864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    "stdin", "__stdin__",
3874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    "stdout", "__stdout__",
3884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    "stderr", "__stderr__",
3894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    NULL
3904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm};
3914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* Un-initialize things, as good as we can */
3944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
3954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmvoid
3964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyImport_Cleanup(void)
3974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
3984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_ssize_t pos, ndone;
3994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    char *name;
4004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *key, *value, *dict;
4014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyInterpreterState *interp = PyThreadState_GET()->interp;
4024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *modules = interp->modules;
4034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (modules == NULL)
4054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return; /* Already done */
4064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* Delete some special variables first.  These are common
4084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       places where user values hide and people complain when their
4094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       destructors fail.  Since the modules containing them are
4104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       deleted *last* of all, they would come too late in the normal
4114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       destruction order.  Sigh. */
4124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    value = PyDict_GetItemString(modules, "__builtin__");
4144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (value != NULL && PyModule_Check(value)) {
4154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        dict = PyModule_GetDict(value);
4164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (Py_VerboseFlag)
4174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PySys_WriteStderr("# clear __builtin__._\n");
4184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyDict_SetItemString(dict, "_", Py_None);
4194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
4204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    value = PyDict_GetItemString(modules, "sys");
4214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (value != NULL && PyModule_Check(value)) {
4224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        char **p;
4234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyObject *v;
4244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        dict = PyModule_GetDict(value);
4254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        for (p = sys_deletes; *p != NULL; p++) {
4264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (Py_VerboseFlag)
4274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                PySys_WriteStderr("# clear sys.%s\n", *p);
4284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PyDict_SetItemString(dict, *p, Py_None);
4294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
4304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        for (p = sys_files; *p != NULL; p+=2) {
4314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (Py_VerboseFlag)
4324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                PySys_WriteStderr("# restore sys.%s\n", *p);
4334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            v = PyDict_GetItemString(dict, *(p+1));
4344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (v == NULL)
4354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                v = Py_None;
4364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PyDict_SetItemString(dict, *p, v);
4374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
4384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
4394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* First, delete __main__ */
4414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    value = PyDict_GetItemString(modules, "__main__");
4424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (value != NULL && PyModule_Check(value)) {
4434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (Py_VerboseFlag)
4444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PySys_WriteStderr("# cleanup __main__\n");
4454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        _PyModule_Clear(value);
4464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyDict_SetItemString(modules, "__main__", Py_None);
4474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
4484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* The special treatment of __builtin__ here is because even
4504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       when it's not referenced as a module, its dictionary is
4514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       referenced by almost every module's __builtins__.  Since
4524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       deleting a module clears its dictionary (even if there are
4534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       references left to it), we need to delete the __builtin__
4544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       module last.  Likewise, we don't delete sys until the very
4554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       end because it is implicitly referenced (e.g. by print).
4564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       Also note that we 'delete' modules by replacing their entry
4584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       in the modules dict with None, rather than really deleting
4594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       them; this avoids a rehash of the modules dictionary and
4604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       also marks them as "non existent" so they won't be
4614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       re-imported. */
4624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* Next, repeatedly delete modules with a reference count of
4644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       one (skipping __builtin__ and sys) and delete them */
4654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    do {
4664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        ndone = 0;
4674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        pos = 0;
4684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        while (PyDict_Next(modules, &pos, &key, &value)) {
4694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (value->ob_refcnt != 1)
4704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                continue;
4714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (PyString_Check(key) && PyModule_Check(value)) {
4724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                name = PyString_AS_STRING(key);
4734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                if (strcmp(name, "__builtin__") == 0)
4744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    continue;
4754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                if (strcmp(name, "sys") == 0)
4764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    continue;
4774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                if (Py_VerboseFlag)
4784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    PySys_WriteStderr(
4794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        "# cleanup[1] %s\n", name);
4804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                _PyModule_Clear(value);
4814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                PyDict_SetItem(modules, key, Py_None);
4824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                ndone++;
4834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
4844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
4854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    } while (ndone > 0);
4864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
4874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* Next, delete all modules (still skipping __builtin__ and sys) */
4884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    pos = 0;
4894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    while (PyDict_Next(modules, &pos, &key, &value)) {
4904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (PyString_Check(key) && PyModule_Check(value)) {
4914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            name = PyString_AS_STRING(key);
4924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (strcmp(name, "__builtin__") == 0)
4934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                continue;
4944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (strcmp(name, "sys") == 0)
4954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                continue;
4964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (Py_VerboseFlag)
4974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                PySys_WriteStderr("# cleanup[2] %s\n", name);
4984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            _PyModule_Clear(value);
4994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PyDict_SetItem(modules, key, Py_None);
5004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
5014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
5024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* Next, delete sys and __builtin__ (in that order) */
5044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    value = PyDict_GetItemString(modules, "sys");
5054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (value != NULL && PyModule_Check(value)) {
5064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (Py_VerboseFlag)
5074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PySys_WriteStderr("# cleanup sys\n");
5084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        _PyModule_Clear(value);
5094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyDict_SetItemString(modules, "sys", Py_None);
5104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
5114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    value = PyDict_GetItemString(modules, "__builtin__");
5124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (value != NULL && PyModule_Check(value)) {
5134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (Py_VerboseFlag)
5144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PySys_WriteStderr("# cleanup __builtin__\n");
5154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        _PyModule_Clear(value);
5164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyDict_SetItemString(modules, "__builtin__", Py_None);
5174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
5184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* Finally, clear and delete the modules directory */
5204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyDict_Clear(modules);
5214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    interp->modules = NULL;
5224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_DECREF(modules);
5234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_CLEAR(interp->modules_reloading);
5244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
5254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* Helper for pythonrun.c -- return magic number */
5284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmlong
5304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyImport_GetMagicNumber(void)
5314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
5324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return pyc_magic;
5334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
5344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* Magic for extension modules (built-in as well as dynamically
5374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   loaded).  To prevent initializing an extension module more than
5384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   once, we keep a static dictionary 'extensions' keyed by module name
5394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   (for built-in modules) or by filename (for dynamically loaded
5404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   modules), containing these modules.  A copy of the module's
5414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   dictionary is stored by calling _PyImport_FixupExtension()
5424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   immediately after the module initialization function succeeds.  A
5434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   copy can be retrieved from there by calling
5444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   _PyImport_FindExtension(). */
5454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyObject *
5474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm_PyImport_FixupExtension(char *name, char *filename)
5484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
5494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *modules, *mod, *dict, *copy;
5504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (extensions == NULL) {
5514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        extensions = PyDict_New();
5524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (extensions == NULL)
5534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return NULL;
5544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
5554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    modules = PyImport_GetModuleDict();
5564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    mod = PyDict_GetItemString(modules, name);
5574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (mod == NULL || !PyModule_Check(mod)) {
5584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyErr_Format(PyExc_SystemError,
5594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm          "_PyImport_FixupExtension: module %.200s not loaded", name);
5604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
5614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
5624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    dict = PyModule_GetDict(mod);
5634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (dict == NULL)
5644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
5654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    copy = PyDict_Copy(dict);
5664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (copy == NULL)
5674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
5684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyDict_SetItemString(extensions, filename, copy);
5694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_DECREF(copy);
5704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return copy;
5714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
5724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyObject *
5744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm_PyImport_FindExtension(char *name, char *filename)
5754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
5764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *dict, *mod, *mdict;
5774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (extensions == NULL)
5784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
5794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    dict = PyDict_GetItemString(extensions, filename);
5804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (dict == NULL)
5814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
5824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    mod = PyImport_AddModule(name);
5834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (mod == NULL)
5844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
5854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    mdict = PyModule_GetDict(mod);
5864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (mdict == NULL)
5874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
5884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (PyDict_Update(mdict, dict))
5894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
5904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (Py_VerboseFlag)
5914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PySys_WriteStderr("import %s # previously loaded (%s)\n",
5924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            name, filename);
5934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return mod;
5944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
5954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
5974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* Get the module object corresponding to a module name.
5984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   First check the modules dictionary if there's one there,
5994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   if not, create a new one and insert it in the modules dictionary.
6004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   Because the former action is most common, THIS DOES NOT RETURN A
6014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   'NEW' REFERENCE! */
6024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
6034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyObject *
6044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyImport_AddModule(const char *name)
6054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
6064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *modules = PyImport_GetModuleDict();
6074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *m;
6084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
6094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if ((m = PyDict_GetItemString(modules, name)) != NULL &&
6104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyModule_Check(m))
6114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return m;
6124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    m = PyModule_New(name);
6134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (m == NULL)
6144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
6154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (PyDict_SetItemString(modules, name, m) != 0) {
6164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        Py_DECREF(m);
6174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
6184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
6194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_DECREF(m); /* Yes, it still exists, in modules! */
6204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
6214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return m;
6224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
6234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
6244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* Remove name from sys.modules, if it's there. */
6254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic void
6264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmremove_module(const char *name)
6274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
6284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *modules = PyImport_GetModuleDict();
6294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (PyDict_GetItemString(modules, name) == NULL)
6304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return;
6314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (PyDict_DelItemString(modules, name) < 0)
6324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        Py_FatalError("import:  deleting existing key in"
6334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                      "sys.modules failed");
6344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
6354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
6364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* Execute a code object in a module and return the module object
6374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * WITH INCREMENTED REFERENCE COUNT.  If an error occurs, name is
6384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * removed from sys.modules, to avoid leaving damaged module objects
6394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * in sys.modules.  The caller may wish to restore the original
6404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * module object (if any) in this case; PyImport_ReloadModule is an
6414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * example.
6424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm */
6434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyObject *
6444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyImport_ExecCodeModule(char *name, PyObject *co)
6454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
6464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return PyImport_ExecCodeModuleEx(name, co, (char *)NULL);
6474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
6484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
6494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyObject *
6504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyImport_ExecCodeModuleEx(char *name, PyObject *co, char *pathname)
6514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
6524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *modules = PyImport_GetModuleDict();
6534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *m, *d, *v;
6544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
6554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    m = PyImport_AddModule(name);
6564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (m == NULL)
6574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
6584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* If the module is being reloaded, we get the old module back
6594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       and re-use its dict to exec the new code. */
6604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    d = PyModule_GetDict(m);
6614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (PyDict_GetItemString(d, "__builtins__") == NULL) {
6624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (PyDict_SetItemString(d, "__builtins__",
6634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                 PyEval_GetBuiltins()) != 0)
6644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            goto error;
6654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
6664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* Remember the filename as the __file__ attribute */
6674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    v = NULL;
6684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (pathname != NULL) {
6694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        v = PyString_FromString(pathname);
6704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (v == NULL)
6714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PyErr_Clear();
6724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
6734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (v == NULL) {
6744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        v = ((PyCodeObject *)co)->co_filename;
6754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        Py_INCREF(v);
6764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
6774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (PyDict_SetItemString(d, "__file__", v) != 0)
6784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyErr_Clear(); /* Not important enough to report */
6794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_DECREF(v);
6804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
6814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    v = PyEval_EvalCode((PyCodeObject *)co, d, d);
6824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (v == NULL)
6834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        goto error;
6844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_DECREF(v);
6854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
6864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if ((m = PyDict_GetItemString(modules, name)) == NULL) {
6874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyErr_Format(PyExc_ImportError,
6884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                     "Loaded module %.200s not found in sys.modules",
6894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                     name);
6904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
6914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
6924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
6934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_INCREF(m);
6944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
6954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return m;
6964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
6974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm  error:
6984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    remove_module(name);
6994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return NULL;
7004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
7014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
7024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
7034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* Given a pathname for a Python source file, fill a buffer with the
7044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   pathname for the corresponding compiled file.  Return the pathname
7054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   for the compiled file, or NULL if there's no space in the buffer.
7064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   Doesn't set an exception. */
7074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
7084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic char *
7094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmmake_compiled_pathname(char *pathname, char *buf, size_t buflen)
7104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
7114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    size_t len = strlen(pathname);
7124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (len+2 > buflen)
7134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
7144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
7154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef MS_WINDOWS
7164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* Treat .pyw as if it were .py.  The case of ".pyw" must match
7174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       that used in _PyImport_StandardFiletab. */
7184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (len >= 4 && strcmp(&pathname[len-4], ".pyw") == 0)
7194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        --len;          /* pretend 'w' isn't there */
7204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif
7214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    memcpy(buf, pathname, len);
7224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    buf[len] = Py_OptimizeFlag ? 'o' : 'c';
7234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    buf[len+1] = '\0';
7244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
7254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return buf;
7264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
7274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
7284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
7294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* Given a pathname for a Python source file, its time of last
7304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   modification, and a pathname for a compiled file, check whether the
7314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   compiled file represents the same version of the source.  If so,
7324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   return a FILE pointer for the compiled file, positioned just after
7334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   the header; if not, return NULL.
7344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   Doesn't set an exception. */
7354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
7364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic FILE *
7374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmcheck_compiled_module(char *pathname, time_t mtime, char *cpathname)
7384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
7394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    FILE *fp;
7404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    long magic;
7414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    long pyc_mtime;
7424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
7434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    fp = fopen(cpathname, "rb");
7444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (fp == NULL)
7454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
7464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    magic = PyMarshal_ReadLongFromFile(fp);
7474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (magic != pyc_magic) {
7484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (Py_VerboseFlag)
7494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PySys_WriteStderr("# %s has bad magic\n", cpathname);
7504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        fclose(fp);
7514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
7524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
7534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    pyc_mtime = PyMarshal_ReadLongFromFile(fp);
7544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (pyc_mtime != mtime) {
7554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (Py_VerboseFlag)
7564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PySys_WriteStderr("# %s has bad mtime\n", cpathname);
7574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        fclose(fp);
7584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
7594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
7604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (Py_VerboseFlag)
7614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PySys_WriteStderr("# %s matches %s\n", cpathname, pathname);
7624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return fp;
7634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
7644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
7654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
7664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* Read a code object from a file and check it for validity */
7674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
7684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyCodeObject *
7694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmread_compiled_module(char *cpathname, FILE *fp)
7704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
7714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *co;
7724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
7734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    co = PyMarshal_ReadLastObjectFromFile(fp);
7744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (co == NULL)
7754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
7764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (!PyCode_Check(co)) {
7774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyErr_Format(PyExc_ImportError,
7784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                     "Non-code object in %.200s", cpathname);
7794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        Py_DECREF(co);
7804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
7814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
7824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return (PyCodeObject *)co;
7834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
7844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
7854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
7864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* Load a module from a compiled file, execute it, and return its
7874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   module object WITH INCREMENTED REFERENCE COUNT */
7884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
7894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject *
7904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmload_compiled_module(char *name, char *cpathname, FILE *fp)
7914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
7924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    long magic;
7934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyCodeObject *co;
7944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *m;
7954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
7964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    magic = PyMarshal_ReadLongFromFile(fp);
7974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (magic != pyc_magic) {
7984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyErr_Format(PyExc_ImportError,
7994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                     "Bad magic number in %.200s", cpathname);
8004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
8014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
8024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    (void) PyMarshal_ReadLongFromFile(fp);
8034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    co = read_compiled_module(cpathname, fp);
8044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (co == NULL)
8054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
8064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (Py_VerboseFlag)
8074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PySys_WriteStderr("import %s # precompiled from %s\n",
8084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            name, cpathname);
8094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    m = PyImport_ExecCodeModuleEx(name, (PyObject *)co, cpathname);
8104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_DECREF(co);
8114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
8124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return m;
8134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
8144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
8154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* Parse a source file and return the corresponding code object */
8164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
8174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyCodeObject *
8184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmparse_source_module(const char *pathname, FILE *fp)
8194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
8204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyCodeObject *co = NULL;
8214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    mod_ty mod;
8224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyCompilerFlags flags;
8234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyArena *arena = PyArena_New();
8244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (arena == NULL)
8254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
8264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
8274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    flags.cf_flags = 0;
8284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
8294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    mod = PyParser_ASTFromFile(fp, pathname, Py_file_input, 0, 0, &flags,
8304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                               NULL, arena);
8314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (mod) {
8324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        co = PyAST_Compile(mod, pathname, NULL, arena);
8334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
8344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyArena_Free(arena);
8354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return co;
8364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
8374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
8384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
8394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* Helper to open a bytecode file for writing in exclusive mode */
8404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
8414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic FILE *
8424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmopen_exclusive(char *filename, mode_t mode)
8434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
8444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#if defined(O_EXCL)&&defined(O_CREAT)&&defined(O_WRONLY)&&defined(O_TRUNC)
8454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* Use O_EXCL to avoid a race condition when another process tries to
8464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       write the same file.  When that happens, our open() call fails,
8474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       which is just fine (since it's only a cache).
8484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       XXX If the file exists and is writable but the directory is not
8494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       writable, the file will never be written.  Oh well.
8504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    */
8514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    int fd;
8524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    (void) unlink(filename);
8534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    fd = open(filename, O_EXCL|O_CREAT|O_WRONLY|O_TRUNC
8544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef O_BINARY
8554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                            |O_BINARY   /* necessary for Windows */
8564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif
8574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef __VMS
8584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            , mode, "ctxt=bin", "shr=nil"
8594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#else
8604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            , mode
8614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif
8624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm          );
8634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (fd < 0)
8644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
8654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return fdopen(fd, "wb");
8664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#else
8674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* Best we can do -- on Windows this can't happen anyway */
8684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return fopen(filename, "wb");
8694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif
8704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
8714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
8724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
8734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* Write a compiled module to a file, placing the time of last
8744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   modification of its source into the header.
8754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   Errors are ignored, if a write error occurs an attempt is made to
8764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   remove the file. */
8774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
8784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic void
8794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmwrite_compiled_module(PyCodeObject *co, char *cpathname, struct stat *srcstat)
8804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
8814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    FILE *fp;
8824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    time_t mtime = srcstat->st_mtime;
8834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef MS_WINDOWS   /* since Windows uses different permissions  */
8844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    mode_t mode = srcstat->st_mode & ~S_IEXEC;
8854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#else
8864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    mode_t mode = srcstat->st_mode & ~S_IXUSR & ~S_IXGRP & ~S_IXOTH;
8874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif
8884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
8894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    fp = open_exclusive(cpathname, mode);
8904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (fp == NULL) {
8914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (Py_VerboseFlag)
8924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PySys_WriteStderr(
8934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                "# can't create %s\n", cpathname);
8944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return;
8954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
8964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyMarshal_WriteLongToFile(pyc_magic, fp, Py_MARSHAL_VERSION);
8974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* First write a 0 for mtime */
8984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyMarshal_WriteLongToFile(0L, fp, Py_MARSHAL_VERSION);
8994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyMarshal_WriteObjectToFile((PyObject *)co, fp, Py_MARSHAL_VERSION);
9004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (fflush(fp) != 0 || ferror(fp)) {
9014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (Py_VerboseFlag)
9024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PySys_WriteStderr("# can't write %s\n", cpathname);
9034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        /* Don't keep partial file */
9044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        fclose(fp);
9054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        (void) unlink(cpathname);
9064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return;
9074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
9084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* Now write the true mtime */
9094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    fseek(fp, 4L, 0);
9104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    assert(mtime < LONG_MAX);
9114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyMarshal_WriteLongToFile((long)mtime, fp, Py_MARSHAL_VERSION);
9124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    fflush(fp);
9134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    fclose(fp);
9144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (Py_VerboseFlag)
9154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PySys_WriteStderr("# wrote %s\n", cpathname);
9164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
9174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
9184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic void
9194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmupdate_code_filenames(PyCodeObject *co, PyObject *oldname, PyObject *newname)
9204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
9214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *constants, *tmp;
9224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_ssize_t i, n;
9234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
9244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (!_PyString_Eq(co->co_filename, oldname))
9254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return;
9264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
9274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    tmp = co->co_filename;
9284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    co->co_filename = newname;
9294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_INCREF(co->co_filename);
9304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_DECREF(tmp);
9314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
9324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    constants = co->co_consts;
9334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    n = PyTuple_GET_SIZE(constants);
9344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    for (i = 0; i < n; i++) {
9354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        tmp = PyTuple_GET_ITEM(constants, i);
9364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (PyCode_Check(tmp))
9374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            update_code_filenames((PyCodeObject *)tmp,
9384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                  oldname, newname);
9394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
9404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
9414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
9424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic int
9434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmupdate_compiled_module(PyCodeObject *co, char *pathname)
9444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
9454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *oldname, *newname;
9464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
9474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (strcmp(PyString_AsString(co->co_filename), pathname) == 0)
9484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return 0;
9494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
9504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    newname = PyString_FromString(pathname);
9514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (newname == NULL)
9524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return -1;
9534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
9544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    oldname = co->co_filename;
9554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_INCREF(oldname);
9564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    update_code_filenames(co, oldname, newname);
9574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_DECREF(oldname);
9584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_DECREF(newname);
9594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return 1;
9604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
9614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
9624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* Load a source module from a given file and return its module
9634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   object WITH INCREMENTED REFERENCE COUNT.  If there's a matching
9644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   byte-compiled file, use that instead. */
9654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
9664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject *
9674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmload_source_module(char *name, char *pathname, FILE *fp)
9684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
9694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    struct stat st;
9704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    FILE *fpc;
9714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    char buf[MAXPATHLEN+1];
9724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    char *cpathname;
9734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyCodeObject *co;
9744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *m;
9754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
9764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (fstat(fileno(fp), &st) != 0) {
9774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyErr_Format(PyExc_RuntimeError,
9784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                     "unable to get file status from '%s'",
9794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                     pathname);
9804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
9814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
9824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#if SIZEOF_TIME_T > 4
9834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* Python's .pyc timestamp handling presumes that the timestamp fits
9844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       in 4 bytes. This will be fine until sometime in the year 2038,
9854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       when a 4-byte signed time_t will overflow.
9864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm     */
9874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (st.st_mtime >> 32) {
9884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyErr_SetString(PyExc_OverflowError,
9894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            "modification time overflows a 4 byte field");
9904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
9914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
9924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif
9934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    cpathname = make_compiled_pathname(pathname, buf,
9944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                       (size_t)MAXPATHLEN + 1);
9954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (cpathname != NULL &&
9964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        (fpc = check_compiled_module(pathname, st.st_mtime, cpathname))) {
9974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        co = read_compiled_module(cpathname, fpc);
9984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        fclose(fpc);
9994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (co == NULL)
10004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return NULL;
10014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (update_compiled_module(co, pathname) < 0)
10024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return NULL;
10034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (Py_VerboseFlag)
10044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PySys_WriteStderr("import %s # precompiled from %s\n",
10054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                name, cpathname);
10064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        pathname = cpathname;
10074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
10084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    else {
10094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        co = parse_source_module(pathname, fp);
10104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (co == NULL)
10114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return NULL;
10124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (Py_VerboseFlag)
10134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PySys_WriteStderr("import %s # from %s\n",
10144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                name, pathname);
10154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (cpathname) {
10164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PyObject *ro = PySys_GetObject("dont_write_bytecode");
10174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (ro == NULL || !PyObject_IsTrue(ro))
10184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                write_compiled_module(co, cpathname, &st);
10194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
10204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
10214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    m = PyImport_ExecCodeModuleEx(name, (PyObject *)co, pathname);
10224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_DECREF(co);
10234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
10244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return m;
10254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
10264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
10274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
10284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* Forward */
10294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject *load_module(char *, FILE *, char *, int, PyObject *);
10304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic struct filedescr *find_module(char *, char *, PyObject *,
10314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                     char *, size_t, FILE **, PyObject **);
10324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic struct _frozen *find_frozen(char *name);
10334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
10344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* Load a package and return its module object WITH INCREMENTED
10354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   REFERENCE COUNT */
10364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
10374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject *
10384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmload_package(char *name, char *pathname)
10394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
10404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *m, *d;
10414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *file = NULL;
10424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *path = NULL;
10434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    int err;
10444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    char buf[MAXPATHLEN+1];
10454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    FILE *fp = NULL;
10464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    struct filedescr *fdp;
10474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
10484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    m = PyImport_AddModule(name);
10494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (m == NULL)
10504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
10514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (Py_VerboseFlag)
10524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PySys_WriteStderr("import %s # directory %s\n",
10534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            name, pathname);
10544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    d = PyModule_GetDict(m);
10554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    file = PyString_FromString(pathname);
10564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (file == NULL)
10574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        goto error;
10584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    path = Py_BuildValue("[O]", file);
10594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (path == NULL)
10604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        goto error;
10614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    err = PyDict_SetItemString(d, "__file__", file);
10624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (err == 0)
10634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        err = PyDict_SetItemString(d, "__path__", path);
10644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (err != 0)
10654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        goto error;
10664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    buf[0] = '\0';
10674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    fdp = find_module(name, "__init__", path, buf, sizeof(buf), &fp, NULL);
10684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (fdp == NULL) {
10694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (PyErr_ExceptionMatches(PyExc_ImportError)) {
10704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PyErr_Clear();
10714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            Py_INCREF(m);
10724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
10734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else
10744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            m = NULL;
10754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        goto cleanup;
10764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
10774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    m = load_module(name, fp, buf, fdp->type, NULL);
10784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (fp != NULL)
10794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        fclose(fp);
10804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    goto cleanup;
10814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
10824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm  error:
10834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    m = NULL;
10844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm  cleanup:
10854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_XDECREF(path);
10864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_XDECREF(file);
10874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return m;
10884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
10894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
10904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
10914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* Helper to test for built-in module */
10924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
10934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic int
10944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmis_builtin(char *name)
10954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
10964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    int i;
10974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    for (i = 0; PyImport_Inittab[i].name != NULL; i++) {
10984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (strcmp(name, PyImport_Inittab[i].name) == 0) {
10994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (PyImport_Inittab[i].initfunc == NULL)
11004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return -1;
11014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            else
11024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return 1;
11034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
11044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
11054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return 0;
11064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
11074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
11084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
11094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* Return an importer object for a sys.path/pkg.__path__ item 'p',
11104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   possibly by fetching it from the path_importer_cache dict. If it
11114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   wasn't yet cached, traverse path_hooks until a hook is found
11124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   that can handle the path item. Return None if no hook could;
11134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   this tells our caller it should fall back to the builtin
11144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   import mechanism. Cache the result in path_importer_cache.
11154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   Returns a borrowed reference. */
11164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
11174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject *
11184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmget_path_importer(PyObject *path_importer_cache, PyObject *path_hooks,
11194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                  PyObject *p)
11204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
11214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *importer;
11224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_ssize_t j, nhooks;
11234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
11244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* These conditions are the caller's responsibility: */
11254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    assert(PyList_Check(path_hooks));
11264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    assert(PyDict_Check(path_importer_cache));
11274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
11284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    nhooks = PyList_Size(path_hooks);
11294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (nhooks < 0)
11304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL; /* Shouldn't happen */
11314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
11324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    importer = PyDict_GetItem(path_importer_cache, p);
11334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (importer != NULL)
11344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return importer;
11354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
11364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* set path_importer_cache[p] to None to avoid recursion */
11374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (PyDict_SetItem(path_importer_cache, p, Py_None) != 0)
11384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
11394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
11404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    for (j = 0; j < nhooks; j++) {
11414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyObject *hook = PyList_GetItem(path_hooks, j);
11424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (hook == NULL)
11434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return NULL;
11444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        importer = PyObject_CallFunctionObjArgs(hook, p, NULL);
11454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (importer != NULL)
11464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            break;
11474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
11484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (!PyErr_ExceptionMatches(PyExc_ImportError)) {
11494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return NULL;
11504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
11514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyErr_Clear();
11524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
11534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (importer == NULL) {
11544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        importer = PyObject_CallFunctionObjArgs(
11554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            (PyObject *)&PyNullImporter_Type, p, NULL
11564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        );
11574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (importer == NULL) {
11584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (PyErr_ExceptionMatches(PyExc_ImportError)) {
11594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                PyErr_Clear();
11604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return Py_None;
11614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
11624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
11634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
11644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (importer != NULL) {
11654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        int err = PyDict_SetItem(path_importer_cache, p, importer);
11664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        Py_DECREF(importer);
11674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (err != 0)
11684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return NULL;
11694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
11704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return importer;
11714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
11724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
11734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyAPI_FUNC(PyObject *)
11744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyImport_GetImporter(PyObject *path) {
11754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *importer=NULL, *path_importer_cache=NULL, *path_hooks=NULL;
11764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
11774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if ((path_importer_cache = PySys_GetObject("path_importer_cache"))) {
11784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if ((path_hooks = PySys_GetObject("path_hooks"))) {
11794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            importer = get_path_importer(path_importer_cache,
11804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                         path_hooks, path);
11814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
11824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
11834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_XINCREF(importer); /* get_path_importer returns a borrowed reference */
11844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return importer;
11854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
11864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
11874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* Search the path (default sys.path) for a module.  Return the
11884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   corresponding filedescr struct, and (via return arguments) the
11894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   pathname and an open file.  Return NULL if the module is not found. */
11904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
11914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef MS_COREDLL
11924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmextern FILE *PyWin_FindRegisteredModule(const char *, struct filedescr **,
11934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                        char *, Py_ssize_t);
11944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif
11954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
11964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic int case_ok(char *, Py_ssize_t, Py_ssize_t, char *);
11974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic int find_init_module(char *); /* Forward */
11984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic struct filedescr importhookdescr = {"", "", IMP_HOOK};
11994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
12004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic struct filedescr *
12014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmfind_module(char *fullname, char *subname, PyObject *path, char *buf,
12024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            size_t buflen, FILE **p_fp, PyObject **p_loader)
12034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
12044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_ssize_t i, npath;
12054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    size_t len, namelen;
12064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    struct filedescr *fdp = NULL;
12074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    char *filemode;
12084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    FILE *fp = NULL;
12094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *path_hooks, *path_importer_cache;
12104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifndef RISCOS
12114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    struct stat statbuf;
12124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif
12134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    static struct filedescr fd_frozen = {"", "", PY_FROZEN};
12144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    static struct filedescr fd_builtin = {"", "", C_BUILTIN};
12154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    static struct filedescr fd_package = {"", "", PKG_DIRECTORY};
12164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    char name[MAXPATHLEN+1];
12174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#if defined(PYOS_OS2)
12184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    size_t saved_len;
12194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    size_t saved_namelen;
12204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    char *saved_buf = NULL;
12214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif
12224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (p_loader != NULL)
12234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        *p_loader = NULL;
12244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
12254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (strlen(subname) > MAXPATHLEN) {
12264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyErr_SetString(PyExc_OverflowError,
12274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        "module name is too long");
12284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
12294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
12304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    strcpy(name, subname);
12314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
12324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* sys.meta_path import hook */
12334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (p_loader != NULL) {
12344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyObject *meta_path;
12354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
12364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        meta_path = PySys_GetObject("meta_path");
12374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (meta_path == NULL || !PyList_Check(meta_path)) {
12384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PyErr_SetString(PyExc_ImportError,
12394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                            "sys.meta_path must be a list of "
12404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                            "import hooks");
12414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return NULL;
12424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
12434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        Py_INCREF(meta_path);  /* zap guard */
12444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        npath = PyList_Size(meta_path);
12454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        for (i = 0; i < npath; i++) {
12464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PyObject *loader;
12474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PyObject *hook = PyList_GetItem(meta_path, i);
12484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            loader = PyObject_CallMethod(hook, "find_module",
12494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                         "sO", fullname,
12504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                         path != NULL ?
12514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                         path : Py_None);
12524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (loader == NULL) {
12534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                Py_DECREF(meta_path);
12544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return NULL;  /* true error */
12554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
12564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (loader != Py_None) {
12574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                /* a loader was found */
12584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                *p_loader = loader;
12594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                Py_DECREF(meta_path);
12604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return &importhookdescr;
12614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
12624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            Py_DECREF(loader);
12634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
12644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        Py_DECREF(meta_path);
12654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
12664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
12674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (path != NULL && PyString_Check(path)) {
12684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        /* The only type of submodule allowed inside a "frozen"
12694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm           package are other frozen modules or packages. */
12704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (PyString_Size(path) + 1 + strlen(name) >= (size_t)buflen) {
12714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PyErr_SetString(PyExc_ImportError,
12724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                            "full frozen module name too long");
12734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return NULL;
12744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
12754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        strcpy(buf, PyString_AsString(path));
12764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        strcat(buf, ".");
12774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        strcat(buf, name);
12784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        strcpy(name, buf);
12794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (find_frozen(name) != NULL) {
12804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            strcpy(buf, name);
12814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return &fd_frozen;
12824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
12834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyErr_Format(PyExc_ImportError,
12844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                     "No frozen submodule named %.200s", name);
12854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
12864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
12874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (path == NULL) {
12884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (is_builtin(name)) {
12894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            strcpy(buf, name);
12904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return &fd_builtin;
12914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
12924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if ((find_frozen(name)) != NULL) {
12934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            strcpy(buf, name);
12944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return &fd_frozen;
12954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
12964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
12974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef MS_COREDLL
12984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        fp = PyWin_FindRegisteredModule(name, &fdp, buf, buflen);
12994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (fp != NULL) {
13004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            *p_fp = fp;
13014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return fdp;
13024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
13034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif
13044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        path = PySys_GetObject("path");
13054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
13064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (path == NULL || !PyList_Check(path)) {
13074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyErr_SetString(PyExc_ImportError,
13084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        "sys.path must be a list of directory names");
13094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
13104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
13114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
13124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    path_hooks = PySys_GetObject("path_hooks");
13134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (path_hooks == NULL || !PyList_Check(path_hooks)) {
13144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyErr_SetString(PyExc_ImportError,
13154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        "sys.path_hooks must be a list of "
13164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        "import hooks");
13174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
13184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
13194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    path_importer_cache = PySys_GetObject("path_importer_cache");
13204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (path_importer_cache == NULL ||
13214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        !PyDict_Check(path_importer_cache)) {
13224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyErr_SetString(PyExc_ImportError,
13234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        "sys.path_importer_cache must be a dict");
13244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
13254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
13264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
13274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    npath = PyList_Size(path);
13284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    namelen = strlen(name);
13294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    for (i = 0; i < npath; i++) {
13304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyObject *copy = NULL;
13314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyObject *v = PyList_GetItem(path, i);
13324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (!v)
13334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return NULL;
13344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef Py_USING_UNICODE
13354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (PyUnicode_Check(v)) {
13364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            copy = PyUnicode_Encode(PyUnicode_AS_UNICODE(v),
13374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                PyUnicode_GET_SIZE(v), Py_FileSystemDefaultEncoding, NULL);
13384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (copy == NULL)
13394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return NULL;
13404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            v = copy;
13414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
13424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else
13434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif
13444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (!PyString_Check(v))
13454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            continue;
13464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        len = PyString_GET_SIZE(v);
13474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (len + 2 + namelen + MAXSUFFIXSIZE >= buflen) {
13484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            Py_XDECREF(copy);
13494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            continue; /* Too long */
13504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
13514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        strcpy(buf, PyString_AS_STRING(v));
13524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (strlen(buf) != len) {
13534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            Py_XDECREF(copy);
13544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            continue; /* v contains '\0' */
13554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
13564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
13574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        /* sys.path_hooks import hook */
13584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (p_loader != NULL) {
13594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PyObject *importer;
13604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
13614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            importer = get_path_importer(path_importer_cache,
13624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                         path_hooks, v);
13634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (importer == NULL) {
13644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                Py_XDECREF(copy);
13654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return NULL;
13664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
13674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            /* Note: importer is a borrowed reference */
13684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (importer != Py_None) {
13694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                PyObject *loader;
13704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                loader = PyObject_CallMethod(importer,
13714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                             "find_module",
13724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                             "s", fullname);
13734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                Py_XDECREF(copy);
13744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                if (loader == NULL)
13754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    return NULL;  /* error */
13764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                if (loader != Py_None) {
13774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    /* a loader was found */
13784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    *p_loader = loader;
13794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    return &importhookdescr;
13804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                }
13814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                Py_DECREF(loader);
13824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                continue;
13834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
13844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
13854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        /* no hook was found, use builtin import */
13864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
13874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (len > 0 && buf[len-1] != SEP
13884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef ALTSEP
13894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            && buf[len-1] != ALTSEP
13904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif
13914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            )
13924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            buf[len++] = SEP;
13934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        strcpy(buf+len, name);
13944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        len += namelen;
13954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
13964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        /* Check for package import (buf holds a directory name,
13974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm           and there's an __init__ module in that directory */
13984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef HAVE_STAT
13994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (stat(buf, &statbuf) == 0 &&         /* it exists */
14004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            S_ISDIR(statbuf.st_mode) &&         /* it's a directory */
14014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            case_ok(buf, len, namelen, name)) { /* case matches */
14024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (find_init_module(buf)) { /* and has __init__.py */
14034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                Py_XDECREF(copy);
14044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return &fd_package;
14054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
14064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            else {
14074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                char warnstr[MAXPATHLEN+80];
14084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                sprintf(warnstr, "Not importing directory "
14094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    "'%.*s': missing __init__.py",
14104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    MAXPATHLEN, buf);
14114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                if (PyErr_Warn(PyExc_ImportWarning,
14124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                               warnstr)) {
14134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    Py_XDECREF(copy);
14144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    return NULL;
14154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                }
14164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
14174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
14184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#else
14194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        /* XXX How are you going to test for directories? */
14204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef RISCOS
14214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (isdir(buf) &&
14224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            case_ok(buf, len, namelen, name)) {
14234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (find_init_module(buf)) {
14244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                Py_XDECREF(copy);
14254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return &fd_package;
14264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
14274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            else {
14284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                char warnstr[MAXPATHLEN+80];
14294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                sprintf(warnstr, "Not importing directory "
14304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    "'%.*s': missing __init__.py",
14314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    MAXPATHLEN, buf);
14324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                if (PyErr_Warn(PyExc_ImportWarning,
14334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                               warnstr)) {
14344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    Py_XDECREF(copy);
14354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    return NULL;
14364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                }
14374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
14384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif
14394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif
14404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#if defined(PYOS_OS2)
14414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        /* take a snapshot of the module spec for restoration
14424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm         * after the 8 character DLL hackery
14434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm         */
14444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        saved_buf = strdup(buf);
14454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        saved_len = len;
14464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        saved_namelen = namelen;
14474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif /* PYOS_OS2 */
14484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        for (fdp = _PyImport_Filetab; fdp->suffix != NULL; fdp++) {
14494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#if defined(PYOS_OS2) && defined(HAVE_DYNAMIC_LOADING)
14504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            /* OS/2 limits DLLs to 8 character names (w/o
14514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm               extension)
14524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm             * so if the name is longer than that and its a
14534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm             * dynamically loaded module we're going to try,
14544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm             * truncate the name before trying
14554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm             */
14564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (strlen(subname) > 8) {
14574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                /* is this an attempt to load a C extension? */
14584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                const struct filedescr *scan;
14594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                scan = _PyImport_DynLoadFiletab;
14604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                while (scan->suffix != NULL) {
14614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    if (!strcmp(scan->suffix, fdp->suffix))
14624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        break;
14634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    else
14644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        scan++;
14654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                }
14664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                if (scan->suffix != NULL) {
14674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    /* yes, so truncate the name */
14684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    namelen = 8;
14694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    len -= strlen(subname) - namelen;
14704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    buf[len] = '\0';
14714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                }
14724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
14734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif /* PYOS_OS2 */
14744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            strcpy(buf+len, fdp->suffix);
14754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (Py_VerboseFlag > 1)
14764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                PySys_WriteStderr("# trying %s\n", buf);
14774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            filemode = fdp->mode;
14784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (filemode[0] == 'U')
14794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                filemode = "r" PY_STDIOTEXTMODE;
14804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            fp = fopen(buf, filemode);
14814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (fp != NULL) {
14824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                if (case_ok(buf, len, namelen, name))
14834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    break;
14844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                else {                   /* continue search */
14854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    fclose(fp);
14864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    fp = NULL;
14874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                }
14884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
14894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#if defined(PYOS_OS2)
14904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            /* restore the saved snapshot */
14914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            strcpy(buf, saved_buf);
14924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            len = saved_len;
14934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            namelen = saved_namelen;
14944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif
14954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
14964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#if defined(PYOS_OS2)
14974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        /* don't need/want the module name snapshot anymore */
14984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (saved_buf)
14994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        {
15004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            free(saved_buf);
15014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            saved_buf = NULL;
15024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
15034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif
15044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        Py_XDECREF(copy);
15054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (fp != NULL)
15064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            break;
15074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
15084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (fp == NULL) {
15094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyErr_Format(PyExc_ImportError,
15104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                     "No module named %.200s", name);
15114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
15124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
15134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    *p_fp = fp;
15144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return fdp;
15154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
15164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
15174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* Helpers for main.c
15184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm *  Find the source file corresponding to a named module
15194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm */
15204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstruct filedescr *
15214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm_PyImport_FindModule(const char *name, PyObject *path, char *buf,
15224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            size_t buflen, FILE **p_fp, PyObject **p_loader)
15234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
15244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return find_module((char *) name, (char *) name, path,
15254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                       buf, buflen, p_fp, p_loader);
15264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
15274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
15284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyAPI_FUNC(int) _PyImport_IsScript(struct filedescr * fd)
15294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
15304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return fd->type == PY_SOURCE || fd->type == PY_COMPILED;
15314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
15324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
15334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* case_ok(char* buf, Py_ssize_t len, Py_ssize_t namelen, char* name)
15344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * The arguments here are tricky, best shown by example:
15354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm *    /a/b/c/d/e/f/g/h/i/j/k/some_long_module_name.py\0
15364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm *    ^                      ^                   ^    ^
15374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm *    |--------------------- buf ---------------------|
15384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm *    |------------------- len ------------------|
15394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm *                           |------ name -------|
15404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm *                           |----- namelen -----|
15414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * buf is the full path, but len only counts up to (& exclusive of) the
15424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * extension.  name is the module name, also exclusive of extension.
15434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm *
15444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * We've already done a successful stat() or fopen() on buf, so know that
15454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * there's some match, possibly case-insensitive.
15464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm *
15474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * case_ok() is to return 1 if there's a case-sensitive match for
15484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * name, else 0.  case_ok() is also to return 1 if envar PYTHONCASEOK
15494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * exists.
15504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm *
15514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * case_ok() is used to implement case-sensitive import semantics even
15524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * on platforms with case-insensitive filesystems.  It's trivial to implement
15534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * for case-sensitive filesystems.  It's pretty much a cross-platform
15544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * nightmare for systems with case-insensitive filesystems.
15554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm */
15564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
15574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* First we may need a pile of platform-specific header files; the sequence
15584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * of #if's here should match the sequence in the body of case_ok().
15594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm */
15604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#if defined(MS_WINDOWS)
15614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#include <windows.h>
15624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
15634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#elif defined(DJGPP)
15644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#include <dir.h>
15654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
15664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#elif (defined(__MACH__) && defined(__APPLE__) || defined(__CYGWIN__)) && defined(HAVE_DIRENT_H)
15674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#include <sys/types.h>
15684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#include <dirent.h>
15694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
15704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#elif defined(PYOS_OS2)
15714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#define INCL_DOS
15724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#define INCL_DOSERRORS
15734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#define INCL_NOPMAPI
15744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#include <os2.h>
15754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
15764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#elif defined(RISCOS)
15774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#include "oslib/osfscontrol.h"
15784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif
15794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
15804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic int
15814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmcase_ok(char *buf, Py_ssize_t len, Py_ssize_t namelen, char *name)
15824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
15834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* Pick a platform-specific implementation; the sequence of #if's here should
15844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * match the sequence just above.
15854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm */
15864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
15874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* MS_WINDOWS */
15884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#if defined(MS_WINDOWS)
15894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    WIN32_FIND_DATA data;
15904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    HANDLE h;
15914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
15924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (Py_GETENV("PYTHONCASEOK") != NULL)
15934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return 1;
15944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
15954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    h = FindFirstFile(buf, &data);
15964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (h == INVALID_HANDLE_VALUE) {
15974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyErr_Format(PyExc_NameError,
15984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm          "Can't find file for module %.100s\n(filename %.300s)",
15994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm          name, buf);
16004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return 0;
16014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
16024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    FindClose(h);
16034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return strncmp(data.cFileName, name, namelen) == 0;
16044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
16054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* DJGPP */
16064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#elif defined(DJGPP)
16074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    struct ffblk ffblk;
16084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    int done;
16094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
16104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (Py_GETENV("PYTHONCASEOK") != NULL)
16114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return 1;
16124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
16134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    done = findfirst(buf, &ffblk, FA_ARCH|FA_RDONLY|FA_HIDDEN|FA_DIREC);
16144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (done) {
16154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyErr_Format(PyExc_NameError,
16164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm          "Can't find file for module %.100s\n(filename %.300s)",
16174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm          name, buf);
16184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return 0;
16194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
16204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return strncmp(ffblk.ff_name, name, namelen) == 0;
16214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
16224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* new-fangled macintosh (macosx) or Cygwin */
16234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#elif (defined(__MACH__) && defined(__APPLE__) || defined(__CYGWIN__)) && defined(HAVE_DIRENT_H)
16244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    DIR *dirp;
16254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    struct dirent *dp;
16264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    char dirname[MAXPATHLEN + 1];
16274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    const int dirlen = len - namelen - 1; /* don't want trailing SEP */
16284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
16294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (Py_GETENV("PYTHONCASEOK") != NULL)
16304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return 1;
16314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
16324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* Copy the dir component into dirname; substitute "." if empty */
16334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (dirlen <= 0) {
16344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        dirname[0] = '.';
16354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        dirname[1] = '\0';
16364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
16374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    else {
16384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        assert(dirlen <= MAXPATHLEN);
16394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        memcpy(dirname, buf, dirlen);
16404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        dirname[dirlen] = '\0';
16414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
16424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* Open the directory and search the entries for an exact match. */
16434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    dirp = opendir(dirname);
16444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (dirp) {
16454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        char *nameWithExt = buf + len - namelen;
16464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        while ((dp = readdir(dirp)) != NULL) {
16474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            const int thislen =
16484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef _DIRENT_HAVE_D_NAMELEN
16494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                    dp->d_namlen;
16504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#else
16514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                    strlen(dp->d_name);
16524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif
16534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (thislen >= namelen &&
16544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                strcmp(dp->d_name, nameWithExt) == 0) {
16554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                (void)closedir(dirp);
16564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return 1; /* Found */
16574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
16584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
16594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        (void)closedir(dirp);
16604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
16614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return 0 ; /* Not found */
16624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
16634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* RISC OS */
16644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#elif defined(RISCOS)
16654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    char canon[MAXPATHLEN+1]; /* buffer for the canonical form of the path */
16664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    char buf2[MAXPATHLEN+2];
16674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    char *nameWithExt = buf+len-namelen;
16684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    int canonlen;
16694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    os_error *e;
16704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
16714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (Py_GETENV("PYTHONCASEOK") != NULL)
16724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return 1;
16734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
16744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* workaround:
16754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       append wildcard, otherwise case of filename wouldn't be touched */
16764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    strcpy(buf2, buf);
16774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    strcat(buf2, "*");
16784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
16794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    e = xosfscontrol_canonicalise_path(buf2,canon,0,0,MAXPATHLEN+1,&canonlen);
16804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    canonlen = MAXPATHLEN+1-canonlen;
16814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (e || canonlen<=0 || canonlen>(MAXPATHLEN+1) )
16824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return 0;
16834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (strcmp(nameWithExt, canon+canonlen-strlen(nameWithExt))==0)
16844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return 1; /* match */
16854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
16864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return 0;
16874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
16884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* OS/2 */
16894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#elif defined(PYOS_OS2)
16904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    HDIR hdir = 1;
16914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    ULONG srchcnt = 1;
16924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    FILEFINDBUF3 ffbuf;
16934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    APIRET rc;
16944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
16954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (Py_GETENV("PYTHONCASEOK") != NULL)
16964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return 1;
16974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
16984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    rc = DosFindFirst(buf,
16994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                      &hdir,
17004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                      FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
17014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                      &ffbuf, sizeof(ffbuf),
17024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                      &srchcnt,
17034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                      FIL_STANDARD);
17044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (rc != NO_ERROR)
17054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return 0;
17064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return strncmp(ffbuf.achName, name, namelen) == 0;
17074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
17084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* assuming it's a case-sensitive filesystem, so there's nothing to do! */
17094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#else
17104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return 1;
17114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
17124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif
17134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
17144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
17154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
17164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef HAVE_STAT
17174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* Helper to look for __init__.py or __init__.py[co] in potential package */
17184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic int
17194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmfind_init_module(char *buf)
17204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
17214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    const size_t save_len = strlen(buf);
17224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    size_t i = save_len;
17234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    char *pname;  /* pointer to start of __init__ */
17244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    struct stat statbuf;
17254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
17264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/*      For calling case_ok(buf, len, namelen, name):
17274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm *      /a/b/c/d/e/f/g/h/i/j/k/some_long_module_name.py\0
17284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm *      ^                      ^                   ^    ^
17294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm *      |--------------------- buf ---------------------|
17304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm *      |------------------- len ------------------|
17314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm *                             |------ name -------|
17324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm *                             |----- namelen -----|
17334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm */
17344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (save_len + 13 >= MAXPATHLEN)
17354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return 0;
17364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    buf[i++] = SEP;
17374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    pname = buf + i;
17384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    strcpy(pname, "__init__.py");
17394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (stat(buf, &statbuf) == 0) {
17404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (case_ok(buf,
17414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    save_len + 9,               /* len("/__init__") */
17424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                8,                              /* len("__init__") */
17434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                pname)) {
17444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            buf[save_len] = '\0';
17454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return 1;
17464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
17474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
17484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    i += strlen(pname);
17494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    strcpy(buf+i, Py_OptimizeFlag ? "o" : "c");
17504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (stat(buf, &statbuf) == 0) {
17514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (case_ok(buf,
17524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    save_len + 9,               /* len("/__init__") */
17534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                8,                              /* len("__init__") */
17544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                pname)) {
17554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            buf[save_len] = '\0';
17564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return 1;
17574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
17584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
17594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    buf[save_len] = '\0';
17604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return 0;
17614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
17624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
17634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#else
17644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
17654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef RISCOS
17664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic int
17674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmfind_init_module(buf)
17684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    char *buf;
17694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
17704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    int save_len = strlen(buf);
17714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    int i = save_len;
17724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
17734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (save_len + 13 >= MAXPATHLEN)
17744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return 0;
17754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    buf[i++] = SEP;
17764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    strcpy(buf+i, "__init__/py");
17774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (isfile(buf)) {
17784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        buf[save_len] = '\0';
17794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return 1;
17804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
17814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
17824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (Py_OptimizeFlag)
17834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        strcpy(buf+i, "o");
17844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    else
17854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        strcpy(buf+i, "c");
17864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (isfile(buf)) {
17874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        buf[save_len] = '\0';
17884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return 1;
17894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
17904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    buf[save_len] = '\0';
17914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return 0;
17924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
17934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif /*RISCOS*/
17944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
17954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif /* HAVE_STAT */
17964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
17974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
17984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic int init_builtin(char *); /* Forward */
17994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
18004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* Load an external module using the default search path and return
18014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   its module object WITH INCREMENTED REFERENCE COUNT */
18024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
18034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject *
18044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmload_module(char *name, FILE *fp, char *pathname, int type, PyObject *loader)
18054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
18064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *modules;
18074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *m;
18084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    int err;
18094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
18104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* First check that there's an open file (if we need one)  */
18114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    switch (type) {
18124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    case PY_SOURCE:
18134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    case PY_COMPILED:
18144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (fp == NULL) {
18154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PyErr_Format(PyExc_ValueError,
18164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm               "file object required for import (type code %d)",
18174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                         type);
18184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return NULL;
18194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
18204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
18214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
18224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    switch (type) {
18234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
18244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    case PY_SOURCE:
18254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        m = load_source_module(name, pathname, fp);
18264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        break;
18274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
18284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    case PY_COMPILED:
18294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        m = load_compiled_module(name, pathname, fp);
18304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        break;
18314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
18324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef HAVE_DYNAMIC_LOADING
18334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    case C_EXTENSION:
18344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        m = _PyImport_LoadDynamicModule(name, pathname, fp);
18354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        break;
18364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif
18374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
18384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    case PKG_DIRECTORY:
18394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        m = load_package(name, pathname);
18404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        break;
18414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
18424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    case C_BUILTIN:
18434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    case PY_FROZEN:
18444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (pathname != NULL && pathname[0] != '\0')
18454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            name = pathname;
18464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (type == C_BUILTIN)
18474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            err = init_builtin(name);
18484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else
18494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            err = PyImport_ImportFrozenModule(name);
18504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (err < 0)
18514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return NULL;
18524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (err == 0) {
18534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PyErr_Format(PyExc_ImportError,
18544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                         "Purported %s module %.200s not found",
18554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                         type == C_BUILTIN ?
18564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                    "builtin" : "frozen",
18574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                         name);
18584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return NULL;
18594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
18604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        modules = PyImport_GetModuleDict();
18614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        m = PyDict_GetItemString(modules, name);
18624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (m == NULL) {
18634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PyErr_Format(
18644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                PyExc_ImportError,
18654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                "%s module %.200s not properly initialized",
18664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                type == C_BUILTIN ?
18674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    "builtin" : "frozen",
18684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                name);
18694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return NULL;
18704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
18714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        Py_INCREF(m);
18724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        break;
18734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
18744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    case IMP_HOOK: {
18754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (loader == NULL) {
18764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PyErr_SetString(PyExc_ImportError,
18774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                            "import hook without loader");
18784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return NULL;
18794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
18804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        m = PyObject_CallMethod(loader, "load_module", "s", name);
18814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        break;
18824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
18834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
18844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    default:
18854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyErr_Format(PyExc_ImportError,
18864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                     "Don't know how to import %.200s (type code %d)",
18874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                      name, type);
18884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        m = NULL;
18894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
18904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
18914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
18924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return m;
18934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
18944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
18954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
18964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* Initialize a built-in module.
18974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   Return 1 for success, 0 if the module is not found, and -1 with
18984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   an exception set if the initialization failed. */
18994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
19004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic int
19014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylminit_builtin(char *name)
19024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
19034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    struct _inittab *p;
19044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
19054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (_PyImport_FindExtension(name, name) != NULL)
19064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return 1;
19074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
19084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    for (p = PyImport_Inittab; p->name != NULL; p++) {
19094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (strcmp(name, p->name) == 0) {
19104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (p->initfunc == NULL) {
19114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                PyErr_Format(PyExc_ImportError,
19124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    "Cannot re-init internal module %.200s",
19134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    name);
19144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return -1;
19154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
19164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (Py_VerboseFlag)
19174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                PySys_WriteStderr("import %s # builtin\n", name);
19184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            (*p->initfunc)();
19194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (PyErr_Occurred())
19204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return -1;
19214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (_PyImport_FixupExtension(name, name) == NULL)
19224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return -1;
19234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return 1;
19244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
19254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
19264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return 0;
19274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
19284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
19294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
19304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* Frozen modules */
19314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
19324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic struct _frozen *
19334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmfind_frozen(char *name)
19344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
19354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    struct _frozen *p;
19364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
19374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    for (p = PyImport_FrozenModules; ; p++) {
19384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (p->name == NULL)
19394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return NULL;
19404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (strcmp(p->name, name) == 0)
19414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            break;
19424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
19434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return p;
19444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
19454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
19464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject *
19474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmget_frozen_object(char *name)
19484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
19494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    struct _frozen *p = find_frozen(name);
19504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    int size;
19514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
19524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (p == NULL) {
19534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyErr_Format(PyExc_ImportError,
19544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                     "No such frozen object named %.200s",
19554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                     name);
19564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
19574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
19584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (p->code == NULL) {
19594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyErr_Format(PyExc_ImportError,
19604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                     "Excluded frozen object named %.200s",
19614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                     name);
19624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
19634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
19644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    size = p->size;
19654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (size < 0)
19664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        size = -size;
19674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return PyMarshal_ReadObjectFromString((char *)p->code, size);
19684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
19694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
19704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* Initialize a frozen module.
19714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   Return 1 for succes, 0 if the module is not found, and -1 with
19724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   an exception set if the initialization failed.
19734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   This function is also used from frozenmain.c */
19744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
19754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmint
19764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyImport_ImportFrozenModule(char *name)
19774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
19784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    struct _frozen *p = find_frozen(name);
19794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *co;
19804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *m;
19814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    int ispackage;
19824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    int size;
19834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
19844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (p == NULL)
19854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return 0;
19864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (p->code == NULL) {
19874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyErr_Format(PyExc_ImportError,
19884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                     "Excluded frozen object named %.200s",
19894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                     name);
19904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return -1;
19914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
19924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    size = p->size;
19934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    ispackage = (size < 0);
19944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (ispackage)
19954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        size = -size;
19964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (Py_VerboseFlag)
19974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PySys_WriteStderr("import %s # frozen%s\n",
19984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            name, ispackage ? " package" : "");
19994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    co = PyMarshal_ReadObjectFromString((char *)p->code, size);
20004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (co == NULL)
20014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return -1;
20024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (!PyCode_Check(co)) {
20034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyErr_Format(PyExc_TypeError,
20044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                     "frozen object %.200s is not a code object",
20054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                     name);
20064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        goto err_return;
20074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
20084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (ispackage) {
20094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        /* Set __path__ to the package name */
20104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyObject *d, *s;
20114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        int err;
20124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        m = PyImport_AddModule(name);
20134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (m == NULL)
20144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            goto err_return;
20154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        d = PyModule_GetDict(m);
20164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        s = PyString_InternFromString(name);
20174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (s == NULL)
20184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            goto err_return;
20194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        err = PyDict_SetItemString(d, "__path__", s);
20204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        Py_DECREF(s);
20214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (err != 0)
20224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            goto err_return;
20234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
20244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    m = PyImport_ExecCodeModuleEx(name, co, "<frozen>");
20254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (m == NULL)
20264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        goto err_return;
20274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_DECREF(co);
20284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_DECREF(m);
20294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return 1;
20304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmerr_return:
20314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_DECREF(co);
20324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return -1;
20334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
20344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
20354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
20364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* Import a module, either built-in, frozen, or external, and return
20374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   its module object WITH INCREMENTED REFERENCE COUNT */
20384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
20394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyObject *
20404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyImport_ImportModule(const char *name)
20414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
20424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *pname;
20434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *result;
20444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
20454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    pname = PyString_FromString(name);
20464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (pname == NULL)
20474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
20484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    result = PyImport_Import(pname);
20494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_DECREF(pname);
20504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return result;
20514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
20524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
20534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* Import a module without blocking
20544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm *
20554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * At first it tries to fetch the module from sys.modules. If the module was
20564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * never loaded before it loads it with PyImport_ImportModule() unless another
20574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * thread holds the import lock. In the latter case the function raises an
20584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * ImportError instead of blocking.
20594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm *
20604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm * Returns the module object with incremented ref count.
20614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm */
20624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyObject *
20634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyImport_ImportModuleNoBlock(const char *name)
20644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
20654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *result;
20664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *modules;
20674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef WITH_THREAD
20684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    long me;
20694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif
20704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
20714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* Try to get the module from sys.modules[name] */
20724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    modules = PyImport_GetModuleDict();
20734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (modules == NULL)
20744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
20754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
20764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    result = PyDict_GetItemString(modules, name);
20774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (result != NULL) {
20784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        Py_INCREF(result);
20794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return result;
20804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
20814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    else {
20824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyErr_Clear();
20834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
20844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef WITH_THREAD
20854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* check the import lock
20864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm     * me might be -1 but I ignore the error here, the lock function
20874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm     * takes care of the problem */
20884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    me = PyThread_get_thread_ident();
20894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (import_lock_thread == -1 || import_lock_thread == me) {
20904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        /* no thread or me is holding the lock */
20914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return PyImport_ImportModule(name);
20924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
20934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    else {
20944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyErr_Format(PyExc_ImportError,
20954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                     "Failed to import %.200s because the import lock"
20964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                     "is held by another thread.",
20974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                     name);
20984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
20994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
21004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#else
21014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return PyImport_ImportModule(name);
21024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif
21034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
21044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
21054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* Forward declarations for helper routines */
21064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject *get_parent(PyObject *globals, char *buf,
21074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                            Py_ssize_t *p_buflen, int level);
21084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject *load_next(PyObject *mod, PyObject *altmod,
21094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                           char **p_name, char *buf, Py_ssize_t *p_buflen);
21104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic int mark_miss(char *name);
21114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic int ensure_fromlist(PyObject *mod, PyObject *fromlist,
21124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                           char *buf, Py_ssize_t buflen, int recursive);
21134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject * import_submodule(PyObject *mod, char *name, char *fullname);
21144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
21154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* The Magnum Opus of dotted-name import :-) */
21164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
21174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject *
21184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport_module_level(char *name, PyObject *globals, PyObject *locals,
21194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    PyObject *fromlist, int level)
21204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
21214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    char buf[MAXPATHLEN+1];
21224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_ssize_t buflen = 0;
21234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *parent, *head, *next, *tail;
21244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
21254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (strchr(name, '/') != NULL
21264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef MS_WINDOWS
21274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        || strchr(name, '\\') != NULL
21284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif
21294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        ) {
21304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyErr_SetString(PyExc_ImportError,
21314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        "Import by filename is not supported.");
21324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
21334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
21344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
21354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    parent = get_parent(globals, buf, &buflen, level);
21364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (parent == NULL)
21374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
21384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
21394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    head = load_next(parent, level < 0 ? Py_None : parent, &name, buf,
21404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        &buflen);
21414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (head == NULL)
21424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
21434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
21444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    tail = head;
21454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_INCREF(tail);
21464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    while (name) {
21474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        next = load_next(tail, tail, &name, buf, &buflen);
21484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        Py_DECREF(tail);
21494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (next == NULL) {
21504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            Py_DECREF(head);
21514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return NULL;
21524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
21534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        tail = next;
21544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
21554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (tail == Py_None) {
21564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        /* If tail is Py_None, both get_parent and load_next found
21574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm           an empty module name: someone called __import__("") or
21584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm           doctored faulty bytecode */
21594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        Py_DECREF(tail);
21604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        Py_DECREF(head);
21614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyErr_SetString(PyExc_ValueError,
21624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        "Empty module name");
21634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
21644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
21654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
21664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (fromlist != NULL) {
21674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (fromlist == Py_None || !PyObject_IsTrue(fromlist))
21684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            fromlist = NULL;
21694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
21704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
21714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (fromlist == NULL) {
21724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        Py_DECREF(tail);
21734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return head;
21744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
21754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
21764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_DECREF(head);
21774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (!ensure_fromlist(tail, fromlist, buf, buflen, 0)) {
21784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        Py_DECREF(tail);
21794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
21804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
21814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
21824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return tail;
21834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
21844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
21854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyObject *
21864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyImport_ImportModuleLevel(char *name, PyObject *globals, PyObject *locals,
21874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                         PyObject *fromlist, int level)
21884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
21894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *result;
21904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    _PyImport_AcquireLock();
21914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    result = import_module_level(name, globals, locals, fromlist, level);
21924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (_PyImport_ReleaseLock() < 0) {
21934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        Py_XDECREF(result);
21944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyErr_SetString(PyExc_RuntimeError,
21954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        "not holding the import lock");
21964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
21974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
21984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return result;
21994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
22004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
22014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* Return the package that an import is being performed in.  If globals comes
22024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   from the module foo.bar.bat (not itself a package), this returns the
22034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   sys.modules entry for foo.bar.  If globals is from a package's __init__.py,
22044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   the package's entry in sys.modules is returned, as a borrowed reference.
22054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
22064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   The *name* of the returned package is returned in buf, with the length of
22074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   the name in *p_buflen.
22084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
22094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   If globals doesn't come from a package or a module in a package, or a
22104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   corresponding entry is not found in sys.modules, Py_None is returned.
22114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm*/
22124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject *
22134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmget_parent(PyObject *globals, char *buf, Py_ssize_t *p_buflen, int level)
22144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
22154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    static PyObject *namestr = NULL;
22164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    static PyObject *pathstr = NULL;
22174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    static PyObject *pkgstr = NULL;
22184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *pkgname, *modname, *modpath, *modules, *parent;
22194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    int orig_level = level;
22204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
22214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (globals == NULL || !PyDict_Check(globals) || !level)
22224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return Py_None;
22234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
22244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (namestr == NULL) {
22254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        namestr = PyString_InternFromString("__name__");
22264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (namestr == NULL)
22274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return NULL;
22284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
22294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (pathstr == NULL) {
22304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        pathstr = PyString_InternFromString("__path__");
22314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (pathstr == NULL)
22324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return NULL;
22334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
22344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (pkgstr == NULL) {
22354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        pkgstr = PyString_InternFromString("__package__");
22364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (pkgstr == NULL)
22374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return NULL;
22384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
22394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
22404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    *buf = '\0';
22414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    *p_buflen = 0;
22424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    pkgname = PyDict_GetItem(globals, pkgstr);
22434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
22444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if ((pkgname != NULL) && (pkgname != Py_None)) {
22454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        /* __package__ is set, so use it */
22464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        Py_ssize_t len;
22474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (!PyString_Check(pkgname)) {
22484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PyErr_SetString(PyExc_ValueError,
22494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                            "__package__ set to non-string");
22504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return NULL;
22514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
22524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        len = PyString_GET_SIZE(pkgname);
22534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (len == 0) {
22544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (level > 0) {
22554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                PyErr_SetString(PyExc_ValueError,
22564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    "Attempted relative import in non-package");
22574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return NULL;
22584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
22594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return Py_None;
22604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
22614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (len > MAXPATHLEN) {
22624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PyErr_SetString(PyExc_ValueError,
22634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                            "Package name too long");
22644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return NULL;
22654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
22664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        strcpy(buf, PyString_AS_STRING(pkgname));
22674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    } else {
22684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        /* __package__ not set, so figure it out and set it */
22694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        modname = PyDict_GetItem(globals, namestr);
22704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (modname == NULL || !PyString_Check(modname))
22714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return Py_None;
22724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
22734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        modpath = PyDict_GetItem(globals, pathstr);
22744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (modpath != NULL) {
22754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            /* __path__ is set, so modname is already the package name */
22764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            Py_ssize_t len = PyString_GET_SIZE(modname);
22774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            int error;
22784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (len > MAXPATHLEN) {
22794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                PyErr_SetString(PyExc_ValueError,
22804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                "Module name too long");
22814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return NULL;
22824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
22834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            strcpy(buf, PyString_AS_STRING(modname));
22844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            error = PyDict_SetItem(globals, pkgstr, modname);
22854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (error) {
22864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                PyErr_SetString(PyExc_ValueError,
22874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                "Could not set __package__");
22884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return NULL;
22894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
22904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        } else {
22914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            /* Normal module, so work out the package name if any */
22924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            char *start = PyString_AS_STRING(modname);
22934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            char *lastdot = strrchr(start, '.');
22944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            size_t len;
22954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            int error;
22964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (lastdot == NULL && level > 0) {
22974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                PyErr_SetString(PyExc_ValueError,
22984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    "Attempted relative import in non-package");
22994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return NULL;
23004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
23014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (lastdot == NULL) {
23024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                error = PyDict_SetItem(globals, pkgstr, Py_None);
23034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                if (error) {
23044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    PyErr_SetString(PyExc_ValueError,
23054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        "Could not set __package__");
23064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    return NULL;
23074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                }
23084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return Py_None;
23094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
23104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            len = lastdot - start;
23114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (len >= MAXPATHLEN) {
23124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                PyErr_SetString(PyExc_ValueError,
23134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                "Module name too long");
23144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return NULL;
23154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
23164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            strncpy(buf, start, len);
23174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            buf[len] = '\0';
23184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            pkgname = PyString_FromString(buf);
23194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (pkgname == NULL) {
23204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return NULL;
23214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
23224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            error = PyDict_SetItem(globals, pkgstr, pkgname);
23234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            Py_DECREF(pkgname);
23244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (error) {
23254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                PyErr_SetString(PyExc_ValueError,
23264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                "Could not set __package__");
23274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return NULL;
23284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
23294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
23304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
23314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    while (--level > 0) {
23324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        char *dot = strrchr(buf, '.');
23334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (dot == NULL) {
23344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PyErr_SetString(PyExc_ValueError,
23354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                "Attempted relative import beyond "
23364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                "toplevel package");
23374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return NULL;
23384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
23394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        *dot = '\0';
23404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
23414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    *p_buflen = strlen(buf);
23424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
23434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    modules = PyImport_GetModuleDict();
23444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    parent = PyDict_GetItemString(modules, buf);
23454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (parent == NULL) {
23464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (orig_level < 1) {
23474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PyObject *err_msg = PyString_FromFormat(
23484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                "Parent module '%.200s' not found "
23494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                "while handling absolute import", buf);
23504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (err_msg == NULL) {
23514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return NULL;
23524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
23534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (!PyErr_WarnEx(PyExc_RuntimeWarning,
23544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                            PyString_AsString(err_msg), 1)) {
23554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                *buf = '\0';
23564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                *p_buflen = 0;
23574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                parent = Py_None;
23584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
23594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            Py_DECREF(err_msg);
23604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        } else {
23614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PyErr_Format(PyExc_SystemError,
23624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                "Parent module '%.200s' not loaded, "
23634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                "cannot perform relative import", buf);
23644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
23654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
23664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return parent;
23674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* We expect, but can't guarantee, if parent != None, that:
23684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       - parent.__name__ == buf
23694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       - parent.__dict__ is globals
23704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       If this is violated...  Who cares? */
23714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
23724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
23734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* altmod is either None or same as mod */
23744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject *
23754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmload_next(PyObject *mod, PyObject *altmod, char **p_name, char *buf,
23764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm          Py_ssize_t *p_buflen)
23774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
23784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    char *name = *p_name;
23794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    char *dot = strchr(name, '.');
23804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    size_t len;
23814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    char *p;
23824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *result;
23834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
23844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (strlen(name) == 0) {
23854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        /* completely empty module name should only happen in
23864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm           'from . import' (or '__import__("")')*/
23874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        Py_INCREF(mod);
23884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        *p_name = NULL;
23894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return mod;
23904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
23914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
23924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (dot == NULL) {
23934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        *p_name = NULL;
23944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        len = strlen(name);
23954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
23964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    else {
23974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        *p_name = dot+1;
23984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        len = dot-name;
23994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
24004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (len == 0) {
24014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyErr_SetString(PyExc_ValueError,
24024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        "Empty module name");
24034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
24044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
24054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
24064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    p = buf + *p_buflen;
24074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (p != buf)
24084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        *p++ = '.';
24094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (p+len-buf >= MAXPATHLEN) {
24104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyErr_SetString(PyExc_ValueError,
24114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        "Module name too long");
24124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
24134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
24144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    strncpy(p, name, len);
24154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    p[len] = '\0';
24164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    *p_buflen = p+len-buf;
24174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
24184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    result = import_submodule(mod, p, buf);
24194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (result == Py_None && altmod != mod) {
24204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        Py_DECREF(result);
24214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        /* Here, altmod must be None and mod must not be None */
24224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        result = import_submodule(altmod, p, p);
24234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (result != NULL && result != Py_None) {
24244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (mark_miss(buf) != 0) {
24254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                Py_DECREF(result);
24264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return NULL;
24274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
24284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            strncpy(buf, name, len);
24294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            buf[len] = '\0';
24304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            *p_buflen = len;
24314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
24324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
24334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (result == NULL)
24344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
24354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
24364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (result == Py_None) {
24374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        Py_DECREF(result);
24384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyErr_Format(PyExc_ImportError,
24394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                     "No module named %.200s", name);
24404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
24414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
24424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
24434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return result;
24444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
24454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
24464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic int
24474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmmark_miss(char *name)
24484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
24494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *modules = PyImport_GetModuleDict();
24504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return PyDict_SetItemString(modules, name, Py_None);
24514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
24524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
24534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic int
24544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmensure_fromlist(PyObject *mod, PyObject *fromlist, char *buf, Py_ssize_t buflen,
24554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                int recursive)
24564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
24574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    int i;
24584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
24594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (!PyObject_HasAttrString(mod, "__path__"))
24604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return 1;
24614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
24624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    for (i = 0; ; i++) {
24634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyObject *item = PySequence_GetItem(fromlist, i);
24644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        int hasit;
24654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (item == NULL) {
24664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (PyErr_ExceptionMatches(PyExc_IndexError)) {
24674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                PyErr_Clear();
24684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return 1;
24694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
24704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return 0;
24714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
24724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (!PyString_Check(item)) {
24734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PyErr_SetString(PyExc_TypeError,
24744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                            "Item in ``from list'' not a string");
24754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            Py_DECREF(item);
24764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return 0;
24774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
24784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (PyString_AS_STRING(item)[0] == '*') {
24794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PyObject *all;
24804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            Py_DECREF(item);
24814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            /* See if the package defines __all__ */
24824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (recursive)
24834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                continue; /* Avoid endless recursion */
24844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            all = PyObject_GetAttrString(mod, "__all__");
24854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (all == NULL)
24864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                PyErr_Clear();
24874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            else {
24884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                int ret = ensure_fromlist(mod, all, buf, buflen, 1);
24894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                Py_DECREF(all);
24904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                if (!ret)
24914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                    return 0;
24924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
24934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            continue;
24944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
24954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        hasit = PyObject_HasAttr(mod, item);
24964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (!hasit) {
24974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            char *subname = PyString_AS_STRING(item);
24984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PyObject *submod;
24994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            char *p;
25004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (buflen + strlen(subname) >= MAXPATHLEN) {
25014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                PyErr_SetString(PyExc_ValueError,
25024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                "Module name too long");
25034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                Py_DECREF(item);
25044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return 0;
25054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
25064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            p = buf + buflen;
25074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            *p++ = '.';
25084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            strcpy(p, subname);
25094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            submod = import_submodule(mod, subname, buf);
25104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            Py_XDECREF(submod);
25114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (submod == NULL) {
25124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                Py_DECREF(item);
25134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return 0;
25144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
25154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
25164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        Py_DECREF(item);
25174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
25184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
25194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* NOTREACHED */
25204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
25214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
25224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic int
25234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmadd_submodule(PyObject *mod, PyObject *submod, char *fullname, char *subname,
25244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm              PyObject *modules)
25254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
25264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (mod == Py_None)
25274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return 1;
25284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* Irrespective of the success of this load, make a
25294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       reference to it in the parent package module.  A copy gets
25304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       saved in the modules dictionary under the full name, so get a
25314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       reference from there, if need be.  (The exception is when the
25324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       load failed with a SyntaxError -- then there's no trace in
25334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       sys.modules.  In that case, of course, do nothing extra.) */
25344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (submod == NULL) {
25354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        submod = PyDict_GetItemString(modules, fullname);
25364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (submod == NULL)
25374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return 1;
25384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
25394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (PyModule_Check(mod)) {
25404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        /* We can't use setattr here since it can give a
25414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm         * spurious warning if the submodule name shadows a
25424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm         * builtin name */
25434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyObject *dict = PyModule_GetDict(mod);
25444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (!dict)
25454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return 0;
25464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (PyDict_SetItemString(dict, subname, submod) < 0)
25474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return 0;
25484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
25494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    else {
25504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (PyObject_SetAttrString(mod, subname, submod) < 0)
25514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return 0;
25524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
25534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return 1;
25544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
25554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
25564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject *
25574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimport_submodule(PyObject *mod, char *subname, char *fullname)
25584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
25594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *modules = PyImport_GetModuleDict();
25604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *m = NULL;
25614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
25624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* Require:
25634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       if mod == None: subname == fullname
25644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm       else: mod.__name__ + "." + subname == fullname
25654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    */
25664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
25674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if ((m = PyDict_GetItemString(modules, fullname)) != NULL) {
25684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        Py_INCREF(m);
25694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
25704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    else {
25714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyObject *path, *loader = NULL;
25724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        char buf[MAXPATHLEN+1];
25734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        struct filedescr *fdp;
25744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        FILE *fp = NULL;
25754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
25764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (mod == Py_None)
25774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            path = NULL;
25784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        else {
25794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            path = PyObject_GetAttrString(mod, "__path__");
25804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (path == NULL) {
25814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                PyErr_Clear();
25824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                Py_INCREF(Py_None);
25834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return Py_None;
25844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
25854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
25864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
25874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        buf[0] = '\0';
25884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        fdp = find_module(fullname, subname, path, buf, MAXPATHLEN+1,
25894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                          &fp, &loader);
25904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        Py_XDECREF(path);
25914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (fdp == NULL) {
25924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (!PyErr_ExceptionMatches(PyExc_ImportError))
25934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return NULL;
25944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PyErr_Clear();
25954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            Py_INCREF(Py_None);
25964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return Py_None;
25974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
25984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        m = load_module(fullname, fp, buf, fdp->type, loader);
25994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        Py_XDECREF(loader);
26004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (fp)
26014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            fclose(fp);
26024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (!add_submodule(mod, m, fullname, subname, modules)) {
26034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            Py_XDECREF(m);
26044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            m = NULL;
26054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
26064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
26074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
26084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return m;
26094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
26104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
26114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
26124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* Re-import a module of any kind and return its module object, WITH
26134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   INCREMENTED REFERENCE COUNT */
26144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
26154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyObject *
26164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyImport_ReloadModule(PyObject *m)
26174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
26184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyInterpreterState *interp = PyThreadState_Get()->interp;
26194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *modules_reloading = interp->modules_reloading;
26204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *modules = PyImport_GetModuleDict();
26214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *path = NULL, *loader = NULL, *existing_m = NULL;
26224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    char *name, *subname;
26234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    char buf[MAXPATHLEN+1];
26244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    struct filedescr *fdp;
26254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    FILE *fp = NULL;
26264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *newm;
26274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
26284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (modules_reloading == NULL) {
26294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        Py_FatalError("PyImport_ReloadModule: "
26304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                      "no modules_reloading dictionary!");
26314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
26324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
26334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
26344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (m == NULL || !PyModule_Check(m)) {
26354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyErr_SetString(PyExc_TypeError,
26364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                        "reload() argument must be module");
26374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
26384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
26394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    name = PyModule_GetName(m);
26404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (name == NULL)
26414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
26424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (m != PyDict_GetItemString(modules, name)) {
26434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyErr_Format(PyExc_ImportError,
26444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                     "reload(): module %.200s not in sys.modules",
26454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                     name);
26464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
26474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
26484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    existing_m = PyDict_GetItemString(modules_reloading, name);
26494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (existing_m != NULL) {
26504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        /* Due to a recursive reload, this module is already
26514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm           being reloaded. */
26524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        Py_INCREF(existing_m);
26534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return existing_m;
26544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
26554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (PyDict_SetItemString(modules_reloading, name, m) < 0)
26564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
26574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
26584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    subname = strrchr(name, '.');
26594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (subname == NULL)
26604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        subname = name;
26614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    else {
26624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyObject *parentname, *parent;
26634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        parentname = PyString_FromStringAndSize(name, (subname-name));
26644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (parentname == NULL) {
26654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            imp_modules_reloading_clear();
26664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return NULL;
26674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
26684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        parent = PyDict_GetItem(modules, parentname);
26694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (parent == NULL) {
26704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PyErr_Format(PyExc_ImportError,
26714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                "reload(): parent %.200s not in sys.modules",
26724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                PyString_AS_STRING(parentname));
26734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            Py_DECREF(parentname);
26744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            imp_modules_reloading_clear();
26754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return NULL;
26764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
26774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        Py_DECREF(parentname);
26784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        subname++;
26794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        path = PyObject_GetAttrString(parent, "__path__");
26804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (path == NULL)
26814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PyErr_Clear();
26824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
26834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    buf[0] = '\0';
26844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    fdp = find_module(name, subname, path, buf, MAXPATHLEN+1, &fp, &loader);
26854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_XDECREF(path);
26864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
26874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (fdp == NULL) {
26884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        Py_XDECREF(loader);
26894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        imp_modules_reloading_clear();
26904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
26914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
26924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
26934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    newm = load_module(name, fp, buf, fdp->type, loader);
26944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_XDECREF(loader);
26954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
26964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (fp)
26974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        fclose(fp);
26984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (newm == NULL) {
26994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        /* load_module probably removed name from modules because of
27004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm         * the error.  Put back the original module object.  We're
27014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm         * going to return NULL in this case regardless of whether
27024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm         * replacing name succeeds, so the return value is ignored.
27034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm         */
27044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyDict_SetItemString(modules, name, m);
27054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
27064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    imp_modules_reloading_clear();
27074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return newm;
27084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
27094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
27104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
27114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* Higher-level import emulator which emulates the "import" statement
27124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   more accurately -- it invokes the __import__() function from the
27134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   builtins of the current globals.  This means that the import is
27144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   done using whatever import hooks are installed in the current
27154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   environment, e.g. by "rexec".
27164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   A dummy list ["__doc__"] is passed as the 4th argument so that
27174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   e.g. PyImport_Import(PyString_FromString("win32com.client.gencache"))
27184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   will return <module "gencache"> instead of <module "win32com">. */
27194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
27204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyObject *
27214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyImport_Import(PyObject *module_name)
27224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
27234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    static PyObject *silly_list = NULL;
27244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    static PyObject *builtins_str = NULL;
27254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    static PyObject *import_str = NULL;
27264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *globals = NULL;
27274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *import = NULL;
27284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *builtins = NULL;
27294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *r = NULL;
27304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
27314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* Initialize constant string objects */
27324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (silly_list == NULL) {
27334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        import_str = PyString_InternFromString("__import__");
27344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (import_str == NULL)
27354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return NULL;
27364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        builtins_str = PyString_InternFromString("__builtins__");
27374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (builtins_str == NULL)
27384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return NULL;
27394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        silly_list = Py_BuildValue("[s]", "__doc__");
27404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (silly_list == NULL)
27414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return NULL;
27424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
27434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
27444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* Get the builtins from current globals */
27454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    globals = PyEval_GetGlobals();
27464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (globals != NULL) {
27474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        Py_INCREF(globals);
27484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        builtins = PyObject_GetItem(globals, builtins_str);
27494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (builtins == NULL)
27504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            goto err;
27514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
27524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    else {
27534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        /* No globals -- use standard builtins, and fake globals */
27544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        builtins = PyImport_ImportModuleLevel("__builtin__",
27554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                              NULL, NULL, NULL, 0);
27564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (builtins == NULL)
27574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return NULL;
27584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        globals = Py_BuildValue("{OO}", builtins_str, builtins);
27594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (globals == NULL)
27604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            goto err;
27614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
27624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
27634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* Get the __import__ function from the builtins */
27644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (PyDict_Check(builtins)) {
27654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        import = PyObject_GetItem(builtins, import_str);
27664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (import == NULL)
27674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PyErr_SetObject(PyExc_KeyError, import_str);
27684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
27694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    else
27704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        import = PyObject_GetAttr(builtins, import_str);
27714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (import == NULL)
27724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        goto err;
27734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
27744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* Call the __import__ function with the proper argument list
27754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm     * Always use absolute import here. */
27764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    r = PyObject_CallFunction(import, "OOOOi", module_name, globals,
27774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                              globals, silly_list, 0, NULL);
27784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
27794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm  err:
27804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_XDECREF(globals);
27814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_XDECREF(builtins);
27824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_XDECREF(import);
27834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
27844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return r;
27854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
27864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
27874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
27884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* Module 'imp' provides Python access to the primitives used for
27894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   importing modules.
27904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm*/
27914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
27924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject *
27934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimp_get_magic(PyObject *self, PyObject *noargs)
27944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
27954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    char buf[4];
27964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
27974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    buf[0] = (char) ((pyc_magic >>  0) & 0xff);
27984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    buf[1] = (char) ((pyc_magic >>  8) & 0xff);
27994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    buf[2] = (char) ((pyc_magic >> 16) & 0xff);
28004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    buf[3] = (char) ((pyc_magic >> 24) & 0xff);
28014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
28024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return PyString_FromStringAndSize(buf, 4);
28034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
28044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
28054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject *
28064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimp_get_suffixes(PyObject *self, PyObject *noargs)
28074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
28084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *list;
28094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    struct filedescr *fdp;
28104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
28114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    list = PyList_New(0);
28124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (list == NULL)
28134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
28144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    for (fdp = _PyImport_Filetab; fdp->suffix != NULL; fdp++) {
28154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyObject *item = Py_BuildValue("ssi",
28164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                               fdp->suffix, fdp->mode, fdp->type);
28174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (item == NULL) {
28184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            Py_DECREF(list);
28194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return NULL;
28204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
28214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (PyList_Append(list, item) < 0) {
28224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            Py_DECREF(list);
28234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            Py_DECREF(item);
28244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return NULL;
28254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
28264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        Py_DECREF(item);
28274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
28284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return list;
28294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
28304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
28314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject *
28324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmcall_find_module(char *name, PyObject *path)
28334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
28344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    extern int fclose(FILE *);
28354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *fob, *ret;
28364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    struct filedescr *fdp;
28374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    char pathname[MAXPATHLEN+1];
28384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    FILE *fp = NULL;
28394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
28404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    pathname[0] = '\0';
28414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (path == Py_None)
28424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        path = NULL;
28434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    fdp = find_module(NULL, name, path, pathname, MAXPATHLEN+1, &fp, NULL);
28444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (fdp == NULL)
28454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
28464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (fp != NULL) {
28474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        fob = PyFile_FromFile(fp, pathname, fdp->mode, fclose);
28484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (fob == NULL) {
28494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            fclose(fp);
28504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return NULL;
28514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
28524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
28534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    else {
28544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        fob = Py_None;
28554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        Py_INCREF(fob);
28564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
28574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    ret = Py_BuildValue("Os(ssi)",
28584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                  fob, pathname, fdp->suffix, fdp->mode, fdp->type);
28594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_DECREF(fob);
28604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return ret;
28614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
28624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
28634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject *
28644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimp_find_module(PyObject *self, PyObject *args)
28654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
28664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    char *name;
28674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *path = NULL;
28684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (!PyArg_ParseTuple(args, "s|O:find_module", &name, &path))
28694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
28704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return call_find_module(name, path);
28714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
28724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
28734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject *
28744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimp_init_builtin(PyObject *self, PyObject *args)
28754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
28764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    char *name;
28774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    int ret;
28784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *m;
28794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (!PyArg_ParseTuple(args, "s:init_builtin", &name))
28804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
28814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    ret = init_builtin(name);
28824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (ret < 0)
28834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
28844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (ret == 0) {
28854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        Py_INCREF(Py_None);
28864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return Py_None;
28874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
28884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    m = PyImport_AddModule(name);
28894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_XINCREF(m);
28904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return m;
28914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
28924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
28934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject *
28944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimp_init_frozen(PyObject *self, PyObject *args)
28954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
28964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    char *name;
28974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    int ret;
28984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *m;
28994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (!PyArg_ParseTuple(args, "s:init_frozen", &name))
29004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
29014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    ret = PyImport_ImportFrozenModule(name);
29024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (ret < 0)
29034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
29044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (ret == 0) {
29054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        Py_INCREF(Py_None);
29064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return Py_None;
29074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
29084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    m = PyImport_AddModule(name);
29094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_XINCREF(m);
29104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return m;
29114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
29124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
29134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject *
29144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimp_get_frozen_object(PyObject *self, PyObject *args)
29154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
29164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    char *name;
29174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
29184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (!PyArg_ParseTuple(args, "s:get_frozen_object", &name))
29194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
29204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return get_frozen_object(name);
29214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
29224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
29234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject *
29244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimp_is_builtin(PyObject *self, PyObject *args)
29254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
29264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    char *name;
29274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (!PyArg_ParseTuple(args, "s:is_builtin", &name))
29284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
29294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return PyInt_FromLong(is_builtin(name));
29304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
29314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
29324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject *
29334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimp_is_frozen(PyObject *self, PyObject *args)
29344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
29354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    char *name;
29364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    struct _frozen *p;
29374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (!PyArg_ParseTuple(args, "s:is_frozen", &name))
29384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
29394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    p = find_frozen(name);
29404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return PyBool_FromLong((long) (p == NULL ? 0 : p->size));
29414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
29424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
29434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic FILE *
29444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmget_file(char *pathname, PyObject *fob, char *mode)
29454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
29464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    FILE *fp;
29474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (fob == NULL) {
29484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (mode[0] == 'U')
29494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            mode = "r" PY_STDIOTEXTMODE;
29504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        fp = fopen(pathname, mode);
29514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (fp == NULL)
29524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PyErr_SetFromErrno(PyExc_IOError);
29534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
29544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    else {
29554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        fp = PyFile_AsFile(fob);
29564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (fp == NULL)
29574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PyErr_SetString(PyExc_ValueError,
29584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                            "bad/closed file object");
29594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
29604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return fp;
29614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
29624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
29634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject *
29644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimp_load_compiled(PyObject *self, PyObject *args)
29654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
29664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    char *name;
29674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    char *pathname;
29684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *fob = NULL;
29694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *m;
29704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    FILE *fp;
29714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (!PyArg_ParseTuple(args, "ss|O!:load_compiled", &name, &pathname,
29724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                          &PyFile_Type, &fob))
29734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
29744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    fp = get_file(pathname, fob, "rb");
29754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (fp == NULL)
29764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
29774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    m = load_compiled_module(name, pathname, fp);
29784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (fob == NULL)
29794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        fclose(fp);
29804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return m;
29814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
29824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
29834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef HAVE_DYNAMIC_LOADING
29844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
29854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject *
29864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimp_load_dynamic(PyObject *self, PyObject *args)
29874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
29884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    char *name;
29894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    char *pathname;
29904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *fob = NULL;
29914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *m;
29924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    FILE *fp = NULL;
29934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (!PyArg_ParseTuple(args, "ss|O!:load_dynamic", &name, &pathname,
29944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                          &PyFile_Type, &fob))
29954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
29964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (fob) {
29974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        fp = get_file(pathname, fob, "r");
29984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (fp == NULL)
29994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return NULL;
30004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
30014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    m = _PyImport_LoadDynamicModule(name, pathname, fp);
30024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return m;
30034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
30044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
30054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif /* HAVE_DYNAMIC_LOADING */
30064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
30074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject *
30084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimp_load_source(PyObject *self, PyObject *args)
30094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
30104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    char *name;
30114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    char *pathname;
30124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *fob = NULL;
30134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *m;
30144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    FILE *fp;
30154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (!PyArg_ParseTuple(args, "ss|O!:load_source", &name, &pathname,
30164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                          &PyFile_Type, &fob))
30174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
30184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    fp = get_file(pathname, fob, "r");
30194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (fp == NULL)
30204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
30214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    m = load_source_module(name, pathname, fp);
30224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (fob == NULL)
30234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        fclose(fp);
30244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return m;
30254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
30264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
30274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject *
30284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimp_load_module(PyObject *self, PyObject *args)
30294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
30304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    char *name;
30314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *fob;
30324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    char *pathname;
30334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    char *suffix; /* Unused */
30344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    char *mode;
30354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    int type;
30364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    FILE *fp;
30374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
30384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (!PyArg_ParseTuple(args, "sOs(ssi):load_module",
30394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                          &name, &fob, &pathname,
30404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                          &suffix, &mode, &type))
30414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
30424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (*mode) {
30434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        /* Mode must start with 'r' or 'U' and must not contain '+'.
30444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm           Implicit in this test is the assumption that the mode
30454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm           may contain other modifiers like 'b' or 't'. */
30464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
30474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (!(*mode == 'r' || *mode == 'U') || strchr(mode, '+')) {
30484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PyErr_Format(PyExc_ValueError,
30494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                         "invalid file open mode %.200s", mode);
30504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return NULL;
30514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
30524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
30534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (fob == Py_None)
30544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        fp = NULL;
30554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    else {
30564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (!PyFile_Check(fob)) {
30574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            PyErr_SetString(PyExc_ValueError,
30584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                "load_module arg#2 should be a file or None");
30594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return NULL;
30604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
30614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        fp = get_file(pathname, fob, mode);
30624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (fp == NULL)
30634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            return NULL;
30644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
30654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return load_module(name, fp, pathname, type, NULL);
30664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
30674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
30684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject *
30694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimp_load_package(PyObject *self, PyObject *args)
30704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
30714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    char *name;
30724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    char *pathname;
30734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (!PyArg_ParseTuple(args, "ss:load_package", &name, &pathname))
30744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
30754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return load_package(name, pathname);
30764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
30774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
30784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject *
30794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimp_new_module(PyObject *self, PyObject *args)
30804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
30814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    char *name;
30824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (!PyArg_ParseTuple(args, "s:new_module", &name))
30834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return NULL;
30844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return PyModule_New(name);
30854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
30864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
30874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject *
30884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmimp_reload(PyObject *self, PyObject *v)
30894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
30904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return PyImport_ReloadModule(v);
30914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
30924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
30934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
30944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* Doc strings */
30954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
30964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyDoc_STRVAR(doc_imp,
30974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"This module provides the components needed to build your own\n\
30984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm__import__ function.  Undocumented functions are obsolete.");
30994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
31004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyDoc_STRVAR(doc_reload,
31014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"reload(module) -> module\n\
31024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm\n\
31034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmReload the module.  The module must have been successfully imported before.");
31044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
31054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyDoc_STRVAR(doc_find_module,
31064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"find_module(name, [path]) -> (file, filename, (suffix, mode, type))\n\
31074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmSearch for a module.  If path is omitted or None, search for a\n\
31084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmbuilt-in, frozen or special module and continue search in sys.path.\n\
31094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmThe module name cannot contain '.'; to search for a submodule of a\n\
31104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmpackage, pass the submodule name and the package's __path__.");
31114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
31124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyDoc_STRVAR(doc_load_module,
31134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"load_module(name, file, filename, (suffix, mode, type)) -> module\n\
31144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmLoad a module, given information returned by find_module().\n\
31154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmThe module name must include the full package name, if any.");
31164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
31174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyDoc_STRVAR(doc_get_magic,
31184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"get_magic() -> string\n\
31194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmReturn the magic number for .pyc or .pyo files.");
31204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
31214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyDoc_STRVAR(doc_get_suffixes,
31224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"get_suffixes() -> [(suffix, mode, type), ...]\n\
31234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmReturn a list of (suffix, mode, type) tuples describing the files\n\
31244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmthat find_module() looks for.");
31254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
31264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyDoc_STRVAR(doc_new_module,
31274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"new_module(name) -> module\n\
31284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmCreate a new module.  Do not enter it in sys.modules.\n\
31294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmThe module name must include the full package name, if any.");
31304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
31314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyDoc_STRVAR(doc_lock_held,
31324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"lock_held() -> boolean\n\
31334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmReturn True if the import lock is currently held, else False.\n\
31344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmOn platforms without threads, return False.");
31354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
31364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyDoc_STRVAR(doc_acquire_lock,
31374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"acquire_lock() -> None\n\
31384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmAcquires the interpreter's import lock for the current thread.\n\
31394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmThis lock should be used by import hooks to ensure thread-safety\n\
31404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmwhen importing modules.\n\
31414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmOn platforms without threads, this function does nothing.");
31424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
31434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyDoc_STRVAR(doc_release_lock,
31444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm"release_lock() -> None\n\
31454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmRelease the interpreter's import lock.\n\
31464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmOn platforms without threads, this function does nothing.");
31474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
31484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyMethodDef imp_methods[] = {
31494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    {"reload",           imp_reload,       METH_O,       doc_reload},
31504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    {"find_module",      imp_find_module,  METH_VARARGS, doc_find_module},
31514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    {"get_magic",        imp_get_magic,    METH_NOARGS,  doc_get_magic},
31524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    {"get_suffixes", imp_get_suffixes, METH_NOARGS,  doc_get_suffixes},
31534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    {"load_module",      imp_load_module,  METH_VARARGS, doc_load_module},
31544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    {"new_module",       imp_new_module,   METH_VARARGS, doc_new_module},
31554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    {"lock_held",        imp_lock_held,    METH_NOARGS,  doc_lock_held},
31564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    {"acquire_lock", imp_acquire_lock, METH_NOARGS,  doc_acquire_lock},
31574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    {"release_lock", imp_release_lock, METH_NOARGS,  doc_release_lock},
31584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* The rest are obsolete */
31594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    {"get_frozen_object",       imp_get_frozen_object,  METH_VARARGS},
31604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    {"init_builtin",            imp_init_builtin,       METH_VARARGS},
31614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    {"init_frozen",             imp_init_frozen,        METH_VARARGS},
31624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    {"is_builtin",              imp_is_builtin,         METH_VARARGS},
31634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    {"is_frozen",               imp_is_frozen,          METH_VARARGS},
31644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    {"load_compiled",           imp_load_compiled,      METH_VARARGS},
31654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef HAVE_DYNAMIC_LOADING
31664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    {"load_dynamic",            imp_load_dynamic,       METH_VARARGS},
31674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif
31684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    {"load_package",            imp_load_package,       METH_VARARGS},
31694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    {"load_source",             imp_load_source,        METH_VARARGS},
31704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    {NULL,                      NULL}           /* sentinel */
31714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm};
31724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
31734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic int
31744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmsetint(PyObject *d, char *name, int value)
31754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
31764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *v;
31774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    int err;
31784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
31794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    v = PyInt_FromLong((long)value);
31804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    err = PyDict_SetItemString(d, name, v);
31814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_XDECREF(v);
31824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return err;
31834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
31844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
31854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmtypedef struct {
31864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject_HEAD
31874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm} NullImporter;
31884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
31894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic int
31904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmNullImporter_init(NullImporter *self, PyObject *args, PyObject *kwds)
31914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
31924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    char *path;
31934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_ssize_t pathlen;
31944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
31954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (!_PyArg_NoKeywords("NullImporter()", kwds))
31964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return -1;
31974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
31984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (!PyArg_ParseTuple(args, "s:NullImporter",
31994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                          &path))
32004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return -1;
32014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
32024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    pathlen = strlen(path);
32034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (pathlen == 0) {
32044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        PyErr_SetString(PyExc_ImportError, "empty pathname");
32054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return -1;
32064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    } else {
32074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifndef RISCOS
32084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifndef MS_WINDOWS
32094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        struct stat statbuf;
32104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        int rv;
32114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
32124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        rv = stat(path, &statbuf);
32134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (rv == 0) {
32144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            /* it exists */
32154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (S_ISDIR(statbuf.st_mode)) {
32164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                /* it's a directory */
32174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                PyErr_SetString(PyExc_ImportError,
32184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                "existing directory");
32194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return -1;
32204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
32214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
32224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#else /* MS_WINDOWS */
32234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        DWORD rv;
32244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        /* see issue1293 and issue3677:
32254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm         * stat() on Windows doesn't recognise paths like
32264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm         * "e:\\shared\\" and "\\\\whiterab-c2znlh\\shared" as dirs.
32274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm         */
32284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        rv = GetFileAttributesA(path);
32294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (rv != INVALID_FILE_ATTRIBUTES) {
32304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            /* it exists */
32314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (rv & FILE_ATTRIBUTE_DIRECTORY) {
32324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                /* it's a directory */
32334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                PyErr_SetString(PyExc_ImportError,
32344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                "existing directory");
32354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return -1;
32364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
32374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
32384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif
32394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#else /* RISCOS */
32404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        if (object_exists(path)) {
32414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            /* it exists */
32424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            if (isdir(path)) {
32434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                /* it's a directory */
32444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                PyErr_SetString(PyExc_ImportError,
32454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                                "existing directory");
32464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                return -1;
32474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm            }
32484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        }
32494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif
32504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    }
32514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return 0;
32524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
32534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
32544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyObject *
32554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmNullImporter_find_module(NullImporter *self, PyObject *args)
32564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
32574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_RETURN_NONE;
32584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
32594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
32604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmstatic PyMethodDef NullImporter_methods[] = {
32614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    {"find_module", (PyCFunction)NullImporter_find_module, METH_VARARGS,
32624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm     "Always return None"
32634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    },
32644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    {NULL}  /* Sentinel */
32654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm};
32664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
32674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
32684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyTypeObject PyNullImporter_Type = {
32694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyVarObject_HEAD_INIT(NULL, 0)
32704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    "imp.NullImporter",        /*tp_name*/
32714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    sizeof(NullImporter),      /*tp_basicsize*/
32724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0,                         /*tp_itemsize*/
32734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0,                         /*tp_dealloc*/
32744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0,                         /*tp_print*/
32754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0,                         /*tp_getattr*/
32764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0,                         /*tp_setattr*/
32774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0,                         /*tp_compare*/
32784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0,                         /*tp_repr*/
32794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0,                         /*tp_as_number*/
32804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0,                         /*tp_as_sequence*/
32814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0,                         /*tp_as_mapping*/
32824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0,                         /*tp_hash */
32834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0,                         /*tp_call*/
32844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0,                         /*tp_str*/
32854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0,                         /*tp_getattro*/
32864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0,                         /*tp_setattro*/
32874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0,                         /*tp_as_buffer*/
32884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_TPFLAGS_DEFAULT,        /*tp_flags*/
32894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    "Null importer object",    /* tp_doc */
32904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0,                             /* tp_traverse */
32914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0,                             /* tp_clear */
32924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0,                             /* tp_richcompare */
32934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0,                             /* tp_weaklistoffset */
32944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0,                             /* tp_iter */
32954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0,                             /* tp_iternext */
32964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    NullImporter_methods,      /* tp_methods */
32974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0,                         /* tp_members */
32984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0,                         /* tp_getset */
32994710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0,                         /* tp_base */
33004710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0,                         /* tp_dict */
33014710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0,                         /* tp_descr_get */
33024710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0,                         /* tp_descr_set */
33034710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0,                         /* tp_dictoffset */
33044710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    (initproc)NullImporter_init,      /* tp_init */
33054710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    0,                         /* tp_alloc */
33064710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyType_GenericNew          /* tp_new */
33074710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm};
33084710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
33094710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
33104710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyMODINIT_FUNC
33114710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylminitimp(void)
33124710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
33134710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyObject *m, *d;
33144710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
33154710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (PyType_Ready(&PyNullImporter_Type) < 0)
33164710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        goto failure;
33174710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
33184710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    m = Py_InitModule4("imp", imp_methods, doc_imp,
33194710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm                       NULL, PYTHON_API_VERSION);
33204710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (m == NULL)
33214710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        goto failure;
33224710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    d = PyModule_GetDict(m);
33234710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (d == NULL)
33244710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        goto failure;
33254710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
33264710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (setint(d, "SEARCH_ERROR", SEARCH_ERROR) < 0) goto failure;
33274710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (setint(d, "PY_SOURCE", PY_SOURCE) < 0) goto failure;
33284710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (setint(d, "PY_COMPILED", PY_COMPILED) < 0) goto failure;
33294710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (setint(d, "C_EXTENSION", C_EXTENSION) < 0) goto failure;
33304710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (setint(d, "PY_RESOURCE", PY_RESOURCE) < 0) goto failure;
33314710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (setint(d, "PKG_DIRECTORY", PKG_DIRECTORY) < 0) goto failure;
33324710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (setint(d, "C_BUILTIN", C_BUILTIN) < 0) goto failure;
33334710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (setint(d, "PY_FROZEN", PY_FROZEN) < 0) goto failure;
33344710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (setint(d, "PY_CODERESOURCE", PY_CODERESOURCE) < 0) goto failure;
33354710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (setint(d, "IMP_HOOK", IMP_HOOK) < 0) goto failure;
33364710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
33374710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    Py_INCREF(&PyNullImporter_Type);
33384710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyModule_AddObject(m, "NullImporter", (PyObject *)&PyNullImporter_Type);
33394710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm  failure:
33404710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    ;
33414710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
33424710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
33434710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
33444710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* API for embedding applications that want to add their own entries
33454710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   to the table of built-in modules.  This should normally be called
33464710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   *before* Py_Initialize().  When the table resize fails, -1 is
33474710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   returned and the existing table is unchanged.
33484710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
33494710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm   After a similar function by Just van Rossum. */
33504710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
33514710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmint
33524710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyImport_ExtendInittab(struct _inittab *newtab)
33534710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
33544710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    static struct _inittab *our_copy = NULL;
33554710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    struct _inittab *p;
33564710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    int i, n;
33574710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
33584710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* Count the number of entries in both tables */
33594710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    for (n = 0; newtab[n].name != NULL; n++)
33604710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        ;
33614710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (n == 0)
33624710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return 0; /* Nothing to do */
33634710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    for (i = 0; PyImport_Inittab[i].name != NULL; i++)
33644710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        ;
33654710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
33664710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* Allocate new memory for the combined table */
33674710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    p = our_copy;
33684710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyMem_RESIZE(p, struct _inittab, i+n+1);
33694710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (p == NULL)
33704710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        return -1;
33714710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
33724710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    /* Copy the tables into the new memory */
33734710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    if (our_copy != PyImport_Inittab)
33744710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm        memcpy(p, PyImport_Inittab, (i+1) * sizeof(struct _inittab));
33754710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    PyImport_Inittab = our_copy = p;
33764710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    memcpy(p+i, newtab, (n+1) * sizeof(struct _inittab));
33774710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
33784710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return 0;
33794710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
33804710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
33814710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm/* Shorthand to add a single entry given a name and a function */
33824710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
33834710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmint
33844710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylmPyImport_AppendInittab(const char *name, void (*initfunc)(void))
33854710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm{
33864710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    struct _inittab newtab[2];
33874710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
33884710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    memset(newtab, '\0', sizeof newtab);
33894710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
33904710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    newtab[0].name = (char *)name;
33914710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    newtab[0].initfunc = initfunc;
33924710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
33934710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm    return PyImport_ExtendInittab(newtab);
33944710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
33954710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm
33964710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#ifdef __cplusplus
33974710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm}
33984710c53dcad1ebf3755f3efb9e80ac24bd72a9b2darylm#endif
3399