symbian-qemu-0.9.1-12/python-2.6.1/Modules/zipimport.c
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 #include "Python.h"
       
     2 #include "structmember.h"
       
     3 #include "osdefs.h"
       
     4 #include "marshal.h"
       
     5 #include <time.h>
       
     6 
       
     7 
       
     8 #define IS_SOURCE   0x0
       
     9 #define IS_BYTECODE 0x1
       
    10 #define IS_PACKAGE  0x2
       
    11 
       
    12 struct st_zip_searchorder {
       
    13 	char suffix[14];
       
    14 	int type;
       
    15 };
       
    16 
       
    17 /* zip_searchorder defines how we search for a module in the Zip
       
    18    archive: we first search for a package __init__, then for
       
    19    non-package .pyc, .pyo and .py entries. The .pyc and .pyo entries
       
    20    are swapped by initzipimport() if we run in optimized mode. Also,
       
    21    '/' is replaced by SEP there. */
       
    22 static struct st_zip_searchorder zip_searchorder[] = {
       
    23 	{"/__init__.pyc", IS_PACKAGE | IS_BYTECODE},
       
    24 	{"/__init__.pyo", IS_PACKAGE | IS_BYTECODE},
       
    25 	{"/__init__.py", IS_PACKAGE | IS_SOURCE},
       
    26 	{".pyc", IS_BYTECODE},
       
    27 	{".pyo", IS_BYTECODE},
       
    28 	{".py", IS_SOURCE},
       
    29 	{"", 0}
       
    30 };
       
    31 
       
    32 /* zipimporter object definition and support */
       
    33 
       
    34 typedef struct _zipimporter ZipImporter;
       
    35 
       
    36 struct _zipimporter {
       
    37 	PyObject_HEAD
       
    38 	PyObject *archive;  /* pathname of the Zip archive */
       
    39 	PyObject *prefix;   /* file prefix: "a/sub/directory/" */
       
    40 	PyObject *files;    /* dict with file info {path: toc_entry} */
       
    41 };
       
    42 
       
    43 static PyObject *ZipImportError;
       
    44 static PyObject *zip_directory_cache = NULL;
       
    45 
       
    46 /* forward decls */
       
    47 static PyObject *read_directory(char *archive);
       
    48 static PyObject *get_data(char *archive, PyObject *toc_entry);
       
    49 static PyObject *get_module_code(ZipImporter *self, char *fullname,
       
    50 				 int *p_ispackage, char **p_modpath);
       
    51 
       
    52 
       
    53 #define ZipImporter_Check(op) PyObject_TypeCheck(op, &ZipImporter_Type)
       
    54 
       
    55 
       
    56 /* zipimporter.__init__
       
    57    Split the "subdirectory" from the Zip archive path, lookup a matching
       
    58    entry in sys.path_importer_cache, fetch the file directory from there
       
    59    if found, or else read it from the archive. */
       
    60 static int
       
    61 zipimporter_init(ZipImporter *self, PyObject *args, PyObject *kwds)
       
    62 {
       
    63 	char *path, *p, *prefix, buf[MAXPATHLEN+2];
       
    64 	size_t len;
       
    65 
       
    66 	if (!_PyArg_NoKeywords("zipimporter()", kwds))
       
    67 		return -1;
       
    68 
       
    69 	if (!PyArg_ParseTuple(args, "s:zipimporter",
       
    70 			      &path))
       
    71 		return -1;
       
    72 
       
    73 	len = strlen(path);
       
    74 	if (len == 0) {
       
    75 		PyErr_SetString(ZipImportError, "archive path is empty");
       
    76 		return -1;
       
    77 	}
       
    78 	if (len >= MAXPATHLEN) {
       
    79 		PyErr_SetString(ZipImportError,
       
    80 				"archive path too long");
       
    81 		return -1;
       
    82 	}
       
    83 	strcpy(buf, path);
       
    84 
       
    85 #ifdef ALTSEP
       
    86 	for (p = buf; *p; p++) {
       
    87 		if (*p == ALTSEP)
       
    88 			*p = SEP;
       
    89 	}
       
    90 #endif
       
    91 
       
    92 	path = NULL;
       
    93 	prefix = NULL;
       
    94 	for (;;) {
       
    95 #ifndef RISCOS
       
    96 		struct stat statbuf;
       
    97 		int rv;
       
    98 
       
    99 		rv = stat(buf, &statbuf);
       
   100 		if (rv == 0) {
       
   101 			/* it exists */
       
   102 			if (S_ISREG(statbuf.st_mode))
       
   103 				/* it's a file */
       
   104 				path = buf;
       
   105 			break;
       
   106 		}
       
   107 #else
       
   108 		if (object_exists(buf)) {
       
   109 			/* it exists */
       
   110 			if (isfile(buf))
       
   111 				/* it's a file */
       
   112 				path = buf;
       
   113 			break;
       
   114 		}
       
   115 #endif
       
   116 		/* back up one path element */
       
   117 		p = strrchr(buf, SEP);
       
   118 		if (prefix != NULL)
       
   119 			*prefix = SEP;
       
   120 		if (p == NULL)
       
   121 			break;
       
   122 		*p = '\0';
       
   123 		prefix = p;
       
   124 	}
       
   125 	if (path != NULL) {
       
   126 		PyObject *files;
       
   127 		files = PyDict_GetItemString(zip_directory_cache, path);
       
   128 		if (files == NULL) {
       
   129 			files = read_directory(buf);
       
   130 			if (files == NULL)
       
   131 				return -1;
       
   132 			if (PyDict_SetItemString(zip_directory_cache, path,
       
   133 						 files) != 0)
       
   134 				return -1;
       
   135 		}
       
   136 		else
       
   137 			Py_INCREF(files);
       
   138 		self->files = files;
       
   139 	}
       
   140 	else {
       
   141 		PyErr_SetString(ZipImportError, "not a Zip file");
       
   142 		return -1;
       
   143 	}
       
   144 
       
   145 	if (prefix == NULL)
       
   146 		prefix = "";
       
   147 	else {
       
   148 		prefix++;
       
   149 		len = strlen(prefix);
       
   150 		if (prefix[len-1] != SEP) {
       
   151 			/* add trailing SEP */
       
   152 			prefix[len] = SEP;
       
   153 			prefix[len + 1] = '\0';
       
   154 		}
       
   155 	}
       
   156 
       
   157 	self->archive = PyString_FromString(buf);
       
   158 	if (self->archive == NULL)
       
   159 		return -1;
       
   160 
       
   161 	self->prefix = PyString_FromString(prefix);
       
   162 	if (self->prefix == NULL)
       
   163 		return -1;
       
   164 
       
   165 	return 0;
       
   166 }
       
   167 
       
   168 /* GC support. */
       
   169 static int
       
   170 zipimporter_traverse(PyObject *obj, visitproc visit, void *arg)
       
   171 {
       
   172 	ZipImporter *self = (ZipImporter *)obj;
       
   173 	Py_VISIT(self->files);
       
   174 	return 0;
       
   175 }
       
   176 
       
   177 static void
       
   178 zipimporter_dealloc(ZipImporter *self)
       
   179 {
       
   180 	PyObject_GC_UnTrack(self);
       
   181 	Py_XDECREF(self->archive);
       
   182 	Py_XDECREF(self->prefix);
       
   183 	Py_XDECREF(self->files);
       
   184 	Py_TYPE(self)->tp_free((PyObject *)self);
       
   185 }
       
   186 
       
   187 static PyObject *
       
   188 zipimporter_repr(ZipImporter *self)
       
   189 {
       
   190 	char buf[500];
       
   191 	char *archive = "???";
       
   192 	char *prefix = "";
       
   193 
       
   194 	if (self->archive != NULL && PyString_Check(self->archive))
       
   195 		archive = PyString_AsString(self->archive);
       
   196 	if (self->prefix != NULL && PyString_Check(self->prefix))
       
   197 		prefix = PyString_AsString(self->prefix);
       
   198 	if (prefix != NULL && *prefix)
       
   199 		PyOS_snprintf(buf, sizeof(buf),
       
   200 			      "<zipimporter object \"%.300s%c%.150s\">",
       
   201 			      archive, SEP, prefix);
       
   202 	else
       
   203 		PyOS_snprintf(buf, sizeof(buf),
       
   204 			      "<zipimporter object \"%.300s\">",
       
   205 			      archive);
       
   206 	return PyString_FromString(buf);
       
   207 }
       
   208 
       
   209 /* return fullname.split(".")[-1] */
       
   210 static char *
       
   211 get_subname(char *fullname)
       
   212 {
       
   213 	char *subname = strrchr(fullname, '.');
       
   214 	if (subname == NULL)
       
   215 		subname = fullname;
       
   216 	else
       
   217 		subname++;
       
   218 	return subname;
       
   219 }
       
   220 
       
   221 /* Given a (sub)modulename, write the potential file path in the
       
   222    archive (without extension) to the path buffer. Return the
       
   223    length of the resulting string. */
       
   224 static int
       
   225 make_filename(char *prefix, char *name, char *path)
       
   226 {
       
   227 	size_t len;
       
   228 	char *p;
       
   229 
       
   230 	len = strlen(prefix);
       
   231 
       
   232 	/* self.prefix + name [+ SEP + "__init__"] + ".py[co]" */
       
   233 	if (len + strlen(name) + 13 >= MAXPATHLEN) {
       
   234 		PyErr_SetString(ZipImportError, "path too long");
       
   235 		return -1;
       
   236 	}
       
   237 
       
   238 	strcpy(path, prefix);
       
   239 	strcpy(path + len, name);
       
   240 	for (p = path + len; *p; p++) {
       
   241 		if (*p == '.')
       
   242 			*p = SEP;
       
   243 	}
       
   244 	len += strlen(name);
       
   245 	assert(len < INT_MAX);
       
   246 	return (int)len;
       
   247 }
       
   248 
       
   249 enum zi_module_info {
       
   250 	MI_ERROR,
       
   251 	MI_NOT_FOUND,
       
   252 	MI_MODULE,
       
   253 	MI_PACKAGE
       
   254 };
       
   255 
       
   256 /* Return some information about a module. */
       
   257 static enum zi_module_info
       
   258 get_module_info(ZipImporter *self, char *fullname)
       
   259 {
       
   260 	char *subname, path[MAXPATHLEN + 1];
       
   261 	int len;
       
   262 	struct st_zip_searchorder *zso;
       
   263 
       
   264 	subname = get_subname(fullname);
       
   265 
       
   266 	len = make_filename(PyString_AsString(self->prefix), subname, path);
       
   267 	if (len < 0)
       
   268 		return MI_ERROR;
       
   269 
       
   270 	for (zso = zip_searchorder; *zso->suffix; zso++) {
       
   271 		strcpy(path + len, zso->suffix);
       
   272 		if (PyDict_GetItemString(self->files, path) != NULL) {
       
   273 			if (zso->type & IS_PACKAGE)
       
   274 				return MI_PACKAGE;
       
   275 			else
       
   276 				return MI_MODULE;
       
   277 		}
       
   278 	}
       
   279 	return MI_NOT_FOUND;
       
   280 }
       
   281 
       
   282 /* Check whether we can satisfy the import of the module named by
       
   283    'fullname'. Return self if we can, None if we can't. */
       
   284 static PyObject *
       
   285 zipimporter_find_module(PyObject *obj, PyObject *args)
       
   286 {
       
   287 	ZipImporter *self = (ZipImporter *)obj;
       
   288 	PyObject *path = NULL;
       
   289 	char *fullname;
       
   290 	enum zi_module_info mi;
       
   291 
       
   292 	if (!PyArg_ParseTuple(args, "s|O:zipimporter.find_module",
       
   293 			      &fullname, &path))
       
   294 		return NULL;
       
   295 
       
   296 	mi = get_module_info(self, fullname);
       
   297 	if (mi == MI_ERROR)
       
   298 		return NULL;
       
   299 	if (mi == MI_NOT_FOUND) {
       
   300 		Py_INCREF(Py_None);
       
   301 		return Py_None;
       
   302 	}
       
   303 	Py_INCREF(self);
       
   304 	return (PyObject *)self;
       
   305 }
       
   306 
       
   307 /* Load and return the module named by 'fullname'. */
       
   308 static PyObject *
       
   309 zipimporter_load_module(PyObject *obj, PyObject *args)
       
   310 {
       
   311 	ZipImporter *self = (ZipImporter *)obj;
       
   312 	PyObject *code, *mod, *dict;
       
   313 	char *fullname, *modpath;
       
   314 	int ispackage;
       
   315 
       
   316 	if (!PyArg_ParseTuple(args, "s:zipimporter.load_module",
       
   317 			      &fullname))
       
   318 		return NULL;
       
   319 
       
   320 	code = get_module_code(self, fullname, &ispackage, &modpath);
       
   321 	if (code == NULL)
       
   322 		return NULL;
       
   323 
       
   324 	mod = PyImport_AddModule(fullname);
       
   325 	if (mod == NULL) {
       
   326 		Py_DECREF(code);
       
   327 		return NULL;
       
   328 	}
       
   329 	dict = PyModule_GetDict(mod);
       
   330 
       
   331 	/* mod.__loader__ = self */
       
   332 	if (PyDict_SetItemString(dict, "__loader__", (PyObject *)self) != 0)
       
   333 		goto error;
       
   334 
       
   335 	if (ispackage) {
       
   336 		/* add __path__ to the module *before* the code gets
       
   337 		   executed */
       
   338 		PyObject *pkgpath, *fullpath;
       
   339 		char *prefix = PyString_AsString(self->prefix);
       
   340 		char *subname = get_subname(fullname);
       
   341 		int err;
       
   342 
       
   343 		fullpath = PyString_FromFormat("%s%c%s%s",
       
   344 					PyString_AsString(self->archive),
       
   345 					SEP,
       
   346 					*prefix ? prefix : "",
       
   347 					subname);
       
   348 		if (fullpath == NULL)
       
   349 			goto error;
       
   350 
       
   351 		pkgpath = Py_BuildValue("[O]", fullpath);
       
   352 		Py_DECREF(fullpath);
       
   353 		if (pkgpath == NULL)
       
   354 			goto error;
       
   355 		err = PyDict_SetItemString(dict, "__path__", pkgpath);
       
   356 		Py_DECREF(pkgpath);
       
   357 		if (err != 0)
       
   358 			goto error;
       
   359 	}
       
   360 	mod = PyImport_ExecCodeModuleEx(fullname, code, modpath);
       
   361 	Py_DECREF(code);
       
   362 	if (Py_VerboseFlag)
       
   363 		PySys_WriteStderr("import %s # loaded from Zip %s\n",
       
   364 				  fullname, modpath);
       
   365 	return mod;
       
   366 error:
       
   367 	Py_DECREF(code);
       
   368 	Py_DECREF(mod);
       
   369 	return NULL;
       
   370 }
       
   371 
       
   372 /* Return a bool signifying whether the module is a package or not. */
       
   373 static PyObject *
       
   374 zipimporter_is_package(PyObject *obj, PyObject *args)
       
   375 {
       
   376 	ZipImporter *self = (ZipImporter *)obj;
       
   377 	char *fullname;
       
   378 	enum zi_module_info mi;
       
   379 
       
   380 	if (!PyArg_ParseTuple(args, "s:zipimporter.is_package",
       
   381 			      &fullname))
       
   382 		return NULL;
       
   383 
       
   384 	mi = get_module_info(self, fullname);
       
   385 	if (mi == MI_ERROR)
       
   386 		return NULL;
       
   387 	if (mi == MI_NOT_FOUND) {
       
   388 		PyErr_Format(ZipImportError, "can't find module '%.200s'",
       
   389 			     fullname);
       
   390 		return NULL;
       
   391 	}
       
   392 	return PyBool_FromLong(mi == MI_PACKAGE);
       
   393 }
       
   394 
       
   395 static PyObject *
       
   396 zipimporter_get_data(PyObject *obj, PyObject *args)
       
   397 {
       
   398 	ZipImporter *self = (ZipImporter *)obj;
       
   399 	char *path;
       
   400 #ifdef ALTSEP
       
   401 	char *p, buf[MAXPATHLEN + 1];
       
   402 #endif
       
   403 	PyObject *toc_entry;
       
   404 	Py_ssize_t len;
       
   405 
       
   406 	if (!PyArg_ParseTuple(args, "s:zipimporter.get_data", &path))
       
   407 		return NULL;
       
   408 
       
   409 #ifdef ALTSEP
       
   410 	if (strlen(path) >= MAXPATHLEN) {
       
   411 		PyErr_SetString(ZipImportError, "path too long");
       
   412 		return NULL;
       
   413 	}
       
   414 	strcpy(buf, path);
       
   415 	for (p = buf; *p; p++) {
       
   416 		if (*p == ALTSEP)
       
   417 			*p = SEP;
       
   418 	}
       
   419 	path = buf;
       
   420 #endif
       
   421 	len = PyString_Size(self->archive);
       
   422 	if ((size_t)len < strlen(path) &&
       
   423 	    strncmp(path, PyString_AsString(self->archive), len) == 0 &&
       
   424 	    path[len] == SEP) {
       
   425 		path = path + len + 1;
       
   426 	}
       
   427 
       
   428 	toc_entry = PyDict_GetItemString(self->files, path);
       
   429 	if (toc_entry == NULL) {
       
   430 		PyErr_SetFromErrnoWithFilename(PyExc_IOError, path);
       
   431 		return NULL;
       
   432 	}
       
   433 	return get_data(PyString_AsString(self->archive), toc_entry);
       
   434 }
       
   435 
       
   436 static PyObject *
       
   437 zipimporter_get_code(PyObject *obj, PyObject *args)
       
   438 {
       
   439 	ZipImporter *self = (ZipImporter *)obj;
       
   440 	char *fullname;
       
   441 
       
   442 	if (!PyArg_ParseTuple(args, "s:zipimporter.get_code", &fullname))
       
   443 		return NULL;
       
   444 
       
   445 	return get_module_code(self, fullname, NULL, NULL);
       
   446 }
       
   447 
       
   448 static PyObject *
       
   449 zipimporter_get_source(PyObject *obj, PyObject *args)
       
   450 {
       
   451 	ZipImporter *self = (ZipImporter *)obj;
       
   452 	PyObject *toc_entry;
       
   453 	char *fullname, *subname, path[MAXPATHLEN+1];
       
   454 	int len;
       
   455 	enum zi_module_info mi;
       
   456 
       
   457 	if (!PyArg_ParseTuple(args, "s:zipimporter.get_source", &fullname))
       
   458 		return NULL;
       
   459 
       
   460 	mi = get_module_info(self, fullname);
       
   461 	if (mi == MI_ERROR)
       
   462 		return NULL;
       
   463 	if (mi == MI_NOT_FOUND) {
       
   464 		PyErr_Format(ZipImportError, "can't find module '%.200s'",
       
   465 			     fullname);
       
   466 		return NULL;
       
   467 	}
       
   468 	subname = get_subname(fullname);
       
   469 
       
   470 	len = make_filename(PyString_AsString(self->prefix), subname, path);
       
   471 	if (len < 0)
       
   472 		return NULL;
       
   473 
       
   474 	if (mi == MI_PACKAGE) {
       
   475 		path[len] = SEP;
       
   476 		strcpy(path + len + 1, "__init__.py");
       
   477 	}
       
   478 	else
       
   479 		strcpy(path + len, ".py");
       
   480 
       
   481 	toc_entry = PyDict_GetItemString(self->files, path);
       
   482 	if (toc_entry != NULL)
       
   483 		return get_data(PyString_AsString(self->archive), toc_entry);
       
   484 
       
   485 	/* we have the module, but no source */
       
   486 	Py_INCREF(Py_None);
       
   487 	return Py_None;
       
   488 }
       
   489 
       
   490 PyDoc_STRVAR(doc_find_module,
       
   491 "find_module(fullname, path=None) -> self or None.\n\
       
   492 \n\
       
   493 Search for a module specified by 'fullname'. 'fullname' must be the\n\
       
   494 fully qualified (dotted) module name. It returns the zipimporter\n\
       
   495 instance itself if the module was found, or None if it wasn't.\n\
       
   496 The optional 'path' argument is ignored -- it's there for compatibility\n\
       
   497 with the importer protocol.");
       
   498 
       
   499 PyDoc_STRVAR(doc_load_module,
       
   500 "load_module(fullname) -> module.\n\
       
   501 \n\
       
   502 Load the module specified by 'fullname'. 'fullname' must be the\n\
       
   503 fully qualified (dotted) module name. It returns the imported\n\
       
   504 module, or raises ZipImportError if it wasn't found.");
       
   505 
       
   506 PyDoc_STRVAR(doc_get_data,
       
   507 "get_data(pathname) -> string with file data.\n\
       
   508 \n\
       
   509 Return the data associated with 'pathname'. Raise IOError if\n\
       
   510 the file wasn't found.");
       
   511 
       
   512 PyDoc_STRVAR(doc_is_package,
       
   513 "is_package(fullname) -> bool.\n\
       
   514 \n\
       
   515 Return True if the module specified by fullname is a package.\n\
       
   516 Raise ZipImportError is the module couldn't be found.");
       
   517 
       
   518 PyDoc_STRVAR(doc_get_code,
       
   519 "get_code(fullname) -> code object.\n\
       
   520 \n\
       
   521 Return the code object for the specified module. Raise ZipImportError\n\
       
   522 is the module couldn't be found.");
       
   523 
       
   524 PyDoc_STRVAR(doc_get_source,
       
   525 "get_source(fullname) -> source string.\n\
       
   526 \n\
       
   527 Return the source code for the specified module. Raise ZipImportError\n\
       
   528 is the module couldn't be found, return None if the archive does\n\
       
   529 contain the module, but has no source for it.");
       
   530 
       
   531 static PyMethodDef zipimporter_methods[] = {
       
   532 	{"find_module", zipimporter_find_module, METH_VARARGS,
       
   533 	 doc_find_module},
       
   534 	{"load_module", zipimporter_load_module, METH_VARARGS,
       
   535 	 doc_load_module},
       
   536 	{"get_data", zipimporter_get_data, METH_VARARGS,
       
   537 	 doc_get_data},
       
   538 	{"get_code", zipimporter_get_code, METH_VARARGS,
       
   539 	 doc_get_code},
       
   540 	{"get_source", zipimporter_get_source, METH_VARARGS,
       
   541 	 doc_get_source},
       
   542 	{"is_package", zipimporter_is_package, METH_VARARGS,
       
   543 	 doc_is_package},
       
   544 	{NULL,		NULL}	/* sentinel */
       
   545 };
       
   546 
       
   547 static PyMemberDef zipimporter_members[] = {
       
   548 	{"archive",  T_OBJECT, offsetof(ZipImporter, archive),  READONLY},
       
   549 	{"prefix",   T_OBJECT, offsetof(ZipImporter, prefix),   READONLY},
       
   550 	{"_files",   T_OBJECT, offsetof(ZipImporter, files),    READONLY},
       
   551 	{NULL}
       
   552 };
       
   553 
       
   554 PyDoc_STRVAR(zipimporter_doc,
       
   555 "zipimporter(archivepath) -> zipimporter object\n\
       
   556 \n\
       
   557 Create a new zipimporter instance. 'archivepath' must be a path to\n\
       
   558 a zipfile, or to a specific path inside a zipfile. For example, it can be\n\
       
   559 '/tmp/myimport.zip', or '/tmp/myimport.zip/mydirectory', if mydirectory is a\n\
       
   560 valid directory inside the archive.\n\
       
   561 \n\
       
   562 'ZipImportError is raised if 'archivepath' doesn't point to a valid Zip\n\
       
   563 archive.\n\
       
   564 \n\
       
   565 The 'archive' attribute of zipimporter objects contains the name of the\n\
       
   566 zipfile targeted.");
       
   567 
       
   568 #define DEFERRED_ADDRESS(ADDR) 0
       
   569 
       
   570 static PyTypeObject ZipImporter_Type = {
       
   571 	PyVarObject_HEAD_INIT(DEFERRED_ADDRESS(&PyType_Type), 0)
       
   572 	"zipimport.zipimporter",
       
   573 	sizeof(ZipImporter),
       
   574 	0,					/* tp_itemsize */
       
   575 	(destructor)zipimporter_dealloc,	/* tp_dealloc */
       
   576 	0,					/* tp_print */
       
   577 	0,					/* tp_getattr */
       
   578 	0,					/* tp_setattr */
       
   579 	0,					/* tp_compare */
       
   580 	(reprfunc)zipimporter_repr,		/* tp_repr */
       
   581 	0,					/* tp_as_number */
       
   582 	0,					/* tp_as_sequence */
       
   583 	0,					/* tp_as_mapping */
       
   584 	0,					/* tp_hash */
       
   585 	0,					/* tp_call */
       
   586 	0,					/* tp_str */
       
   587 	PyObject_GenericGetAttr,		/* tp_getattro */
       
   588 	0,					/* tp_setattro */
       
   589 	0,					/* tp_as_buffer */
       
   590 	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |
       
   591 		Py_TPFLAGS_HAVE_GC,		/* tp_flags */
       
   592 	zipimporter_doc,			/* tp_doc */
       
   593 	zipimporter_traverse,			/* tp_traverse */
       
   594 	0,					/* tp_clear */
       
   595 	0,					/* tp_richcompare */
       
   596 	0,					/* tp_weaklistoffset */
       
   597 	0,					/* tp_iter */
       
   598 	0,					/* tp_iternext */
       
   599 	zipimporter_methods,			/* tp_methods */
       
   600 	zipimporter_members,			/* tp_members */
       
   601 	0,					/* tp_getset */
       
   602 	0,					/* tp_base */
       
   603 	0,					/* tp_dict */
       
   604 	0,					/* tp_descr_get */
       
   605 	0,					/* tp_descr_set */
       
   606 	0,					/* tp_dictoffset */
       
   607 	(initproc)zipimporter_init,		/* tp_init */
       
   608 	PyType_GenericAlloc,			/* tp_alloc */
       
   609 	PyType_GenericNew,			/* tp_new */
       
   610 	PyObject_GC_Del,			/* tp_free */
       
   611 };
       
   612 
       
   613 
       
   614 /* implementation */
       
   615 
       
   616 /* Given a buffer, return the long that is represented by the first
       
   617    4 bytes, encoded as little endian. This partially reimplements
       
   618    marshal.c:r_long() */
       
   619 static long
       
   620 get_long(unsigned char *buf) {
       
   621 	long x;
       
   622 	x =  buf[0];
       
   623 	x |= (long)buf[1] <<  8;
       
   624 	x |= (long)buf[2] << 16;
       
   625 	x |= (long)buf[3] << 24;
       
   626 #if SIZEOF_LONG > 4
       
   627 	/* Sign extension for 64-bit machines */
       
   628 	x |= -(x & 0x80000000L);
       
   629 #endif
       
   630 	return x;
       
   631 }
       
   632 
       
   633 /*
       
   634    read_directory(archive) -> files dict (new reference)
       
   635 
       
   636    Given a path to a Zip archive, build a dict, mapping file names
       
   637    (local to the archive, using SEP as a separator) to toc entries.
       
   638 
       
   639    A toc_entry is a tuple:
       
   640 
       
   641        (__file__,      # value to use for __file__, available for all files
       
   642         compress,      # compression kind; 0 for uncompressed
       
   643         data_size,     # size of compressed data on disk
       
   644         file_size,     # size of decompressed data
       
   645         file_offset,   # offset of file header from start of archive
       
   646         time,          # mod time of file (in dos format)
       
   647         date,          # mod data of file (in dos format)
       
   648         crc,           # crc checksum of the data
       
   649        )
       
   650 
       
   651    Directories can be recognized by the trailing SEP in the name,
       
   652    data_size and file_offset are 0.
       
   653 */
       
   654 static PyObject *
       
   655 read_directory(char *archive)
       
   656 {
       
   657 	PyObject *files = NULL;
       
   658 	FILE *fp;
       
   659 	long compress, crc, data_size, file_size, file_offset, date, time;
       
   660 	long header_offset, name_size, header_size, header_position;
       
   661 	long i, l, count;
       
   662 	size_t length;
       
   663 	char path[MAXPATHLEN + 5];
       
   664 	char name[MAXPATHLEN + 5];
       
   665 	char *p, endof_central_dir[22];
       
   666 	long arc_offset; /* offset from beginning of file to start of zip-archive */
       
   667 
       
   668 	if (strlen(archive) > MAXPATHLEN) {
       
   669 		PyErr_SetString(PyExc_OverflowError,
       
   670 				"Zip path name is too long");
       
   671 		return NULL;
       
   672 	}
       
   673 	strcpy(path, archive);
       
   674 
       
   675 	fp = fopen(archive, "rb");
       
   676 	if (fp == NULL) {
       
   677 		PyErr_Format(ZipImportError, "can't open Zip file: "
       
   678 			     "'%.200s'", archive);
       
   679 		return NULL;
       
   680 	}
       
   681 	fseek(fp, -22, SEEK_END);
       
   682 	header_position = ftell(fp);
       
   683 	if (fread(endof_central_dir, 1, 22, fp) != 22) {
       
   684 		fclose(fp);
       
   685 		PyErr_Format(ZipImportError, "can't read Zip file: "
       
   686 			     "'%.200s'", archive);
       
   687 		return NULL;
       
   688 	}
       
   689 	if (get_long((unsigned char *)endof_central_dir) != 0x06054B50) {
       
   690 		/* Bad: End of Central Dir signature */
       
   691 		fclose(fp);
       
   692 		PyErr_Format(ZipImportError, "not a Zip file: "
       
   693 			     "'%.200s'", archive);
       
   694 		return NULL;
       
   695 	}
       
   696 
       
   697 	header_size = get_long((unsigned char *)endof_central_dir + 12);
       
   698 	header_offset = get_long((unsigned char *)endof_central_dir + 16);
       
   699 	arc_offset = header_position - header_offset - header_size;
       
   700 	header_offset += arc_offset;
       
   701 
       
   702 	files = PyDict_New();
       
   703 	if (files == NULL)
       
   704 		goto error;
       
   705 
       
   706 	length = (long)strlen(path);
       
   707 	path[length] = SEP;
       
   708 
       
   709 	/* Start of Central Directory */
       
   710 	count = 0;
       
   711 	for (;;) {
       
   712 		PyObject *t;
       
   713 		int err;
       
   714 
       
   715 		fseek(fp, header_offset, 0);  /* Start of file header */
       
   716 		l = PyMarshal_ReadLongFromFile(fp);
       
   717 		if (l != 0x02014B50)
       
   718 			break;	/* Bad: Central Dir File Header */
       
   719 		fseek(fp, header_offset + 10, 0);
       
   720 		compress = PyMarshal_ReadShortFromFile(fp);
       
   721 		time = PyMarshal_ReadShortFromFile(fp);
       
   722 		date = PyMarshal_ReadShortFromFile(fp);
       
   723 		crc = PyMarshal_ReadLongFromFile(fp);
       
   724 		data_size = PyMarshal_ReadLongFromFile(fp);
       
   725 		file_size = PyMarshal_ReadLongFromFile(fp);
       
   726 		name_size = PyMarshal_ReadShortFromFile(fp);
       
   727 		header_size = 46 + name_size +
       
   728 		   PyMarshal_ReadShortFromFile(fp) +
       
   729 		   PyMarshal_ReadShortFromFile(fp);
       
   730 		fseek(fp, header_offset + 42, 0);
       
   731 		file_offset = PyMarshal_ReadLongFromFile(fp) + arc_offset;
       
   732 		if (name_size > MAXPATHLEN)
       
   733 			name_size = MAXPATHLEN;
       
   734 
       
   735 		p = name;
       
   736 		for (i = 0; i < name_size; i++) {
       
   737 			*p = (char)getc(fp);
       
   738 			if (*p == '/')
       
   739 				*p = SEP;
       
   740 			p++;
       
   741 		}
       
   742 		*p = 0;	/* Add terminating null byte */
       
   743 		header_offset += header_size;
       
   744 
       
   745 		strncpy(path + length + 1, name, MAXPATHLEN - length - 1);
       
   746 
       
   747 		t = Py_BuildValue("siiiiiii", path, compress, data_size,
       
   748 				  file_size, file_offset, time, date, crc);
       
   749 		if (t == NULL)
       
   750 			goto error;
       
   751 		err = PyDict_SetItemString(files, name, t);
       
   752 		Py_DECREF(t);
       
   753 		if (err != 0)
       
   754 			goto error;
       
   755 		count++;
       
   756 	}
       
   757 	fclose(fp);
       
   758 	if (Py_VerboseFlag)
       
   759 		PySys_WriteStderr("# zipimport: found %ld names in %s\n",
       
   760 			count, archive);
       
   761 	return files;
       
   762 error:
       
   763 	fclose(fp);
       
   764 	Py_XDECREF(files);
       
   765 	return NULL;
       
   766 }
       
   767 
       
   768 /* Return the zlib.decompress function object, or NULL if zlib couldn't
       
   769    be imported. The function is cached when found, so subsequent calls
       
   770    don't import zlib again. Returns a *borrowed* reference.
       
   771    XXX This makes zlib.decompress immortal. */
       
   772 static PyObject *
       
   773 get_decompress_func(void)
       
   774 {
       
   775 	static PyObject *decompress = NULL;
       
   776 
       
   777 	if (decompress == NULL) {
       
   778 		PyObject *zlib;
       
   779 		static int importing_zlib = 0;
       
   780 
       
   781 		if (importing_zlib != 0)
       
   782 			/* Someone has a zlib.py[co] in their Zip file;
       
   783 			   let's avoid a stack overflow. */
       
   784 			return NULL;
       
   785 		importing_zlib = 1;
       
   786 		zlib = PyImport_ImportModuleNoBlock("zlib");
       
   787 		importing_zlib = 0;
       
   788 		if (zlib != NULL) {
       
   789 			decompress = PyObject_GetAttrString(zlib,
       
   790 							    "decompress");
       
   791 			Py_DECREF(zlib);
       
   792 		}
       
   793 		else
       
   794 			PyErr_Clear();
       
   795 		if (Py_VerboseFlag)
       
   796 			PySys_WriteStderr("# zipimport: zlib %s\n",
       
   797 				zlib != NULL ? "available": "UNAVAILABLE");
       
   798 	}
       
   799 	return decompress;
       
   800 }
       
   801 
       
   802 /* Given a path to a Zip file and a toc_entry, return the (uncompressed)
       
   803    data as a new reference. */
       
   804 static PyObject *
       
   805 get_data(char *archive, PyObject *toc_entry)
       
   806 {
       
   807 	PyObject *raw_data, *data = NULL, *decompress;
       
   808 	char *buf;
       
   809 	FILE *fp;
       
   810 	int err;
       
   811 	Py_ssize_t bytes_read = 0;
       
   812 	long l;
       
   813 	char *datapath;
       
   814 	long compress, data_size, file_size, file_offset;
       
   815 	long time, date, crc;
       
   816 
       
   817 	if (!PyArg_ParseTuple(toc_entry, "slllllll", &datapath, &compress,
       
   818 			      &data_size, &file_size, &file_offset, &time,
       
   819 			      &date, &crc)) {
       
   820 		return NULL;
       
   821 	}
       
   822 
       
   823 	fp = fopen(archive, "rb");
       
   824 	if (!fp) {
       
   825 		PyErr_Format(PyExc_IOError,
       
   826 		   "zipimport: can not open file %s", archive);
       
   827 		return NULL;
       
   828 	}
       
   829 
       
   830 	/* Check to make sure the local file header is correct */
       
   831 	fseek(fp, file_offset, 0);
       
   832 	l = PyMarshal_ReadLongFromFile(fp);
       
   833 	if (l != 0x04034B50) {
       
   834 		/* Bad: Local File Header */
       
   835 		PyErr_Format(ZipImportError,
       
   836 			     "bad local file header in %s",
       
   837 			     archive);
       
   838 		fclose(fp);
       
   839 		return NULL;
       
   840 	}
       
   841 	fseek(fp, file_offset + 26, 0);
       
   842 	l = 30 + PyMarshal_ReadShortFromFile(fp) +
       
   843 	    PyMarshal_ReadShortFromFile(fp);	/* local header size */
       
   844 	file_offset += l;	/* Start of file data */
       
   845 
       
   846 	raw_data = PyString_FromStringAndSize((char *)NULL, compress == 0 ?
       
   847 					      data_size : data_size + 1);
       
   848 	if (raw_data == NULL) {
       
   849 		fclose(fp);
       
   850 		return NULL;
       
   851 	}
       
   852 	buf = PyString_AsString(raw_data);
       
   853 
       
   854 	err = fseek(fp, file_offset, 0);
       
   855 	if (err == 0)
       
   856 		bytes_read = fread(buf, 1, data_size, fp);
       
   857 	fclose(fp);
       
   858 	if (err || bytes_read != data_size) {
       
   859 		PyErr_SetString(PyExc_IOError,
       
   860 				"zipimport: can't read data");
       
   861 		Py_DECREF(raw_data);
       
   862 		return NULL;
       
   863 	}
       
   864 
       
   865 	if (compress != 0) {
       
   866 		buf[data_size] = 'Z';  /* saw this in zipfile.py */
       
   867 		data_size++;
       
   868 	}
       
   869 	buf[data_size] = '\0';
       
   870 
       
   871 	if (compress == 0)  /* data is not compressed */
       
   872 		return raw_data;
       
   873 
       
   874 	/* Decompress with zlib */
       
   875 	decompress = get_decompress_func();
       
   876 	if (decompress == NULL) {
       
   877 		PyErr_SetString(ZipImportError,
       
   878 				"can't decompress data; "
       
   879 				"zlib not available");
       
   880 		goto error;
       
   881 	}
       
   882 	data = PyObject_CallFunction(decompress, "Oi", raw_data, -15);
       
   883 error:
       
   884 	Py_DECREF(raw_data);
       
   885 	return data;
       
   886 }
       
   887 
       
   888 /* Lenient date/time comparison function. The precision of the mtime
       
   889    in the archive is lower than the mtime stored in a .pyc: we
       
   890    must allow a difference of at most one second. */
       
   891 static int
       
   892 eq_mtime(time_t t1, time_t t2)
       
   893 {
       
   894 	time_t d = t1 - t2;
       
   895 	if (d < 0)
       
   896 		d = -d;
       
   897 	/* dostime only stores even seconds, so be lenient */
       
   898 	return d <= 1;
       
   899 }
       
   900 
       
   901 /* Given the contents of a .py[co] file in a buffer, unmarshal the data
       
   902    and return the code object. Return None if it the magic word doesn't
       
   903    match (we do this instead of raising an exception as we fall back
       
   904    to .py if available and we don't want to mask other errors).
       
   905    Returns a new reference. */
       
   906 static PyObject *
       
   907 unmarshal_code(char *pathname, PyObject *data, time_t mtime)
       
   908 {
       
   909 	PyObject *code;
       
   910 	char *buf = PyString_AsString(data);
       
   911 	Py_ssize_t size = PyString_Size(data);
       
   912 
       
   913 	if (size <= 9) {
       
   914 		PyErr_SetString(ZipImportError,
       
   915 				"bad pyc data");
       
   916 		return NULL;
       
   917 	}
       
   918 
       
   919 	if (get_long((unsigned char *)buf) != PyImport_GetMagicNumber()) {
       
   920 		if (Py_VerboseFlag)
       
   921 			PySys_WriteStderr("# %s has bad magic\n",
       
   922 					  pathname);
       
   923 		Py_INCREF(Py_None);
       
   924 		return Py_None;  /* signal caller to try alternative */
       
   925 	}
       
   926 
       
   927 	if (mtime != 0 && !eq_mtime(get_long((unsigned char *)buf + 4),
       
   928 				    mtime)) {
       
   929 		if (Py_VerboseFlag)
       
   930 			PySys_WriteStderr("# %s has bad mtime\n",
       
   931 					  pathname);
       
   932 		Py_INCREF(Py_None);
       
   933 		return Py_None;  /* signal caller to try alternative */
       
   934 	}
       
   935 
       
   936 	code = PyMarshal_ReadObjectFromString(buf + 8, size - 8);
       
   937 	if (code == NULL)
       
   938 		return NULL;
       
   939 	if (!PyCode_Check(code)) {
       
   940 		Py_DECREF(code);
       
   941 		PyErr_Format(PyExc_TypeError,
       
   942 		     "compiled module %.200s is not a code object",
       
   943 		     pathname);
       
   944 		return NULL;
       
   945 	}
       
   946 	return code;
       
   947 }
       
   948 
       
   949 /* Replace any occurances of "\r\n?" in the input string with "\n".
       
   950    This converts DOS and Mac line endings to Unix line endings.
       
   951    Also append a trailing "\n" to be compatible with
       
   952    PyParser_SimpleParseFile(). Returns a new reference. */
       
   953 static PyObject *
       
   954 normalize_line_endings(PyObject *source)
       
   955 {
       
   956 	char *buf, *q, *p = PyString_AsString(source);
       
   957 	PyObject *fixed_source;
       
   958 
       
   959 	if (!p)
       
   960 		return NULL;
       
   961 
       
   962 	/* one char extra for trailing \n and one for terminating \0 */
       
   963 	buf = (char *)PyMem_Malloc(PyString_Size(source) + 2);
       
   964 	if (buf == NULL) {
       
   965 		PyErr_SetString(PyExc_MemoryError,
       
   966 				"zipimport: no memory to allocate "
       
   967 				"source buffer");
       
   968 		return NULL;
       
   969 	}
       
   970 	/* replace "\r\n?" by "\n" */
       
   971 	for (q = buf; *p != '\0'; p++) {
       
   972 		if (*p == '\r') {
       
   973 			*q++ = '\n';
       
   974 			if (*(p + 1) == '\n')
       
   975 				p++;
       
   976 		}
       
   977 		else
       
   978 			*q++ = *p;
       
   979 	}
       
   980 	*q++ = '\n';  /* add trailing \n */
       
   981 	*q = '\0';
       
   982 	fixed_source = PyString_FromString(buf);
       
   983 	PyMem_Free(buf);
       
   984 	return fixed_source;
       
   985 }
       
   986 
       
   987 /* Given a string buffer containing Python source code, compile it
       
   988    return and return a code object as a new reference. */
       
   989 static PyObject *
       
   990 compile_source(char *pathname, PyObject *source)
       
   991 {
       
   992 	PyObject *code, *fixed_source;
       
   993 
       
   994 	fixed_source = normalize_line_endings(source);
       
   995 	if (fixed_source == NULL)
       
   996 		return NULL;
       
   997 
       
   998 	code = Py_CompileString(PyString_AsString(fixed_source), pathname,
       
   999 				Py_file_input);
       
  1000 	Py_DECREF(fixed_source);
       
  1001 	return code;
       
  1002 }
       
  1003 
       
  1004 /* Convert the date/time values found in the Zip archive to a value
       
  1005    that's compatible with the time stamp stored in .pyc files. */
       
  1006 static time_t
       
  1007 parse_dostime(int dostime, int dosdate)
       
  1008 {
       
  1009 	struct tm stm;
       
  1010 
       
  1011 	memset((void *) &stm, '\0', sizeof(stm));
       
  1012 
       
  1013 	stm.tm_sec   =  (dostime        & 0x1f) * 2;
       
  1014 	stm.tm_min   =  (dostime >> 5)  & 0x3f;
       
  1015 	stm.tm_hour  =  (dostime >> 11) & 0x1f;
       
  1016 	stm.tm_mday  =   dosdate        & 0x1f;
       
  1017 	stm.tm_mon   = ((dosdate >> 5)  & 0x0f) - 1;
       
  1018 	stm.tm_year  = ((dosdate >> 9)  & 0x7f) + 80;
       
  1019 	stm.tm_isdst =   -1; /* wday/yday is ignored */
       
  1020 
       
  1021 	return mktime(&stm);
       
  1022 }
       
  1023 
       
  1024 /* Given a path to a .pyc or .pyo file in the archive, return the
       
  1025    modifictaion time of the matching .py file, or 0 if no source
       
  1026    is available. */
       
  1027 static time_t
       
  1028 get_mtime_of_source(ZipImporter *self, char *path)
       
  1029 {
       
  1030 	PyObject *toc_entry;
       
  1031 	time_t mtime = 0;
       
  1032 	Py_ssize_t lastchar = strlen(path) - 1;
       
  1033 	char savechar = path[lastchar];
       
  1034 	path[lastchar] = '\0';  /* strip 'c' or 'o' from *.py[co] */
       
  1035 	toc_entry = PyDict_GetItemString(self->files, path);
       
  1036 	if (toc_entry != NULL && PyTuple_Check(toc_entry) &&
       
  1037 	    PyTuple_Size(toc_entry) == 8) {
       
  1038 		/* fetch the time stamp of the .py file for comparison
       
  1039 		   with an embedded pyc time stamp */
       
  1040 		int time, date;
       
  1041 		time = PyInt_AsLong(PyTuple_GetItem(toc_entry, 5));
       
  1042 		date = PyInt_AsLong(PyTuple_GetItem(toc_entry, 6));
       
  1043 		mtime = parse_dostime(time, date);
       
  1044 	}
       
  1045 	path[lastchar] = savechar;
       
  1046 	return mtime;
       
  1047 }
       
  1048 
       
  1049 /* Return the code object for the module named by 'fullname' from the
       
  1050    Zip archive as a new reference. */
       
  1051 static PyObject *
       
  1052 get_code_from_data(ZipImporter *self, int ispackage, int isbytecode,
       
  1053 		   time_t mtime, PyObject *toc_entry)
       
  1054 {
       
  1055 	PyObject *data, *code;
       
  1056 	char *modpath;
       
  1057 	char *archive = PyString_AsString(self->archive);
       
  1058 
       
  1059 	if (archive == NULL)
       
  1060 		return NULL;
       
  1061 
       
  1062 	data = get_data(archive, toc_entry);
       
  1063 	if (data == NULL)
       
  1064 		return NULL;
       
  1065 
       
  1066 	modpath = PyString_AsString(PyTuple_GetItem(toc_entry, 0));
       
  1067 
       
  1068 	if (isbytecode) {
       
  1069 		code = unmarshal_code(modpath, data, mtime);
       
  1070 	}
       
  1071 	else {
       
  1072 		code = compile_source(modpath, data);
       
  1073 	}
       
  1074 	Py_DECREF(data);
       
  1075 	return code;
       
  1076 }
       
  1077 
       
  1078 /* Get the code object assoiciated with the module specified by
       
  1079    'fullname'. */
       
  1080 static PyObject *
       
  1081 get_module_code(ZipImporter *self, char *fullname,
       
  1082 		int *p_ispackage, char **p_modpath)
       
  1083 {
       
  1084 	PyObject *toc_entry;
       
  1085 	char *subname, path[MAXPATHLEN + 1];
       
  1086 	int len;
       
  1087 	struct st_zip_searchorder *zso;
       
  1088 
       
  1089 	subname = get_subname(fullname);
       
  1090 
       
  1091 	len = make_filename(PyString_AsString(self->prefix), subname, path);
       
  1092 	if (len < 0)
       
  1093 		return NULL;
       
  1094 
       
  1095 	for (zso = zip_searchorder; *zso->suffix; zso++) {
       
  1096 		PyObject *code = NULL;
       
  1097 
       
  1098 		strcpy(path + len, zso->suffix);
       
  1099 		if (Py_VerboseFlag > 1)
       
  1100 			PySys_WriteStderr("# trying %s%c%s\n",
       
  1101 					  PyString_AsString(self->archive),
       
  1102 					  SEP, path);
       
  1103 		toc_entry = PyDict_GetItemString(self->files, path);
       
  1104 		if (toc_entry != NULL) {
       
  1105 			time_t mtime = 0;
       
  1106 			int ispackage = zso->type & IS_PACKAGE;
       
  1107 			int isbytecode = zso->type & IS_BYTECODE;
       
  1108 
       
  1109 			if (isbytecode)
       
  1110 				mtime = get_mtime_of_source(self, path);
       
  1111 			if (p_ispackage != NULL)
       
  1112 				*p_ispackage = ispackage;
       
  1113 			code = get_code_from_data(self, ispackage,
       
  1114 						  isbytecode, mtime,
       
  1115 						  toc_entry);
       
  1116 			if (code == Py_None) {
       
  1117 				/* bad magic number or non-matching mtime
       
  1118 				   in byte code, try next */
       
  1119 				Py_DECREF(code);
       
  1120 				continue;
       
  1121 			}
       
  1122 			if (code != NULL && p_modpath != NULL)
       
  1123 				*p_modpath = PyString_AsString(
       
  1124 					PyTuple_GetItem(toc_entry, 0));
       
  1125 			return code;
       
  1126 		}
       
  1127 	}
       
  1128 	PyErr_Format(ZipImportError, "can't find module '%.200s'", fullname);
       
  1129 	return NULL;
       
  1130 }
       
  1131 
       
  1132 
       
  1133 /* Module init */
       
  1134 
       
  1135 PyDoc_STRVAR(zipimport_doc,
       
  1136 "zipimport provides support for importing Python modules from Zip archives.\n\
       
  1137 \n\
       
  1138 This module exports three objects:\n\
       
  1139 - zipimporter: a class; its constructor takes a path to a Zip archive.\n\
       
  1140 - ZipImportError: exception raised by zipimporter objects. It's a\n\
       
  1141   subclass of ImportError, so it can be caught as ImportError, too.\n\
       
  1142 - _zip_directory_cache: a dict, mapping archive paths to zip directory\n\
       
  1143   info dicts, as used in zipimporter._files.\n\
       
  1144 \n\
       
  1145 It is usually not needed to use the zipimport module explicitly; it is\n\
       
  1146 used by the builtin import mechanism for sys.path items that are paths\n\
       
  1147 to Zip archives.");
       
  1148 
       
  1149 PyMODINIT_FUNC
       
  1150 initzipimport(void)
       
  1151 {
       
  1152 	PyObject *mod;
       
  1153 
       
  1154 	if (PyType_Ready(&ZipImporter_Type) < 0)
       
  1155 		return;
       
  1156 
       
  1157 	/* Correct directory separator */
       
  1158 	zip_searchorder[0].suffix[0] = SEP;
       
  1159 	zip_searchorder[1].suffix[0] = SEP;
       
  1160 	zip_searchorder[2].suffix[0] = SEP;
       
  1161 	if (Py_OptimizeFlag) {
       
  1162 		/* Reverse *.pyc and *.pyo */
       
  1163 		struct st_zip_searchorder tmp;
       
  1164 		tmp = zip_searchorder[0];
       
  1165 		zip_searchorder[0] = zip_searchorder[1];
       
  1166 		zip_searchorder[1] = tmp;
       
  1167 		tmp = zip_searchorder[3];
       
  1168 		zip_searchorder[3] = zip_searchorder[4];
       
  1169 		zip_searchorder[4] = tmp;
       
  1170 	}
       
  1171 
       
  1172 	mod = Py_InitModule4("zipimport", NULL, zipimport_doc,
       
  1173 			     NULL, PYTHON_API_VERSION);
       
  1174 	if (mod == NULL)
       
  1175 		return;
       
  1176 
       
  1177 	ZipImportError = PyErr_NewException("zipimport.ZipImportError",
       
  1178 					    PyExc_ImportError, NULL);
       
  1179 	if (ZipImportError == NULL)
       
  1180 		return;
       
  1181 
       
  1182 	Py_INCREF(ZipImportError);
       
  1183 	if (PyModule_AddObject(mod, "ZipImportError",
       
  1184 			       ZipImportError) < 0)
       
  1185 		return;
       
  1186 
       
  1187 	Py_INCREF(&ZipImporter_Type);
       
  1188 	if (PyModule_AddObject(mod, "zipimporter",
       
  1189 			       (PyObject *)&ZipImporter_Type) < 0)
       
  1190 		return;
       
  1191 
       
  1192 	zip_directory_cache = PyDict_New();
       
  1193 	if (zip_directory_cache == NULL)
       
  1194 		return;
       
  1195 	Py_INCREF(zip_directory_cache);
       
  1196 	if (PyModule_AddObject(mod, "_zip_directory_cache",
       
  1197 			       zip_directory_cache) < 0)
       
  1198 		return;
       
  1199 }