summaryrefslogtreecommitdiffstats
path: root/Python/import.c
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>1990-10-14 12:07:46 (GMT)
committerGuido van Rossum <guido@python.org>1990-10-14 12:07:46 (GMT)
commit85a5fbbdfea617f6cc8fae82c9e8c2b5c424436d (patch)
treea1bf57db1c75e2a7029c8f2fad5f8dba4b9ba25c /Python/import.c
parentc636014c430620325f8d213e9ba10d925991b8d7 (diff)
downloadcpython-85a5fbbdfea617f6cc8fae82c9e8c2b5c424436d.zip
cpython-85a5fbbdfea617f6cc8fae82c9e8c2b5c424436d.tar.gz
cpython-85a5fbbdfea617f6cc8fae82c9e8c2b5c424436d.tar.bz2
Initial revision
Diffstat (limited to 'Python/import.c')
-rw-r--r--Python/import.c252
1 files changed, 252 insertions, 0 deletions
diff --git a/Python/import.c b/Python/import.c
new file mode 100644
index 0000000..8e94170
--- /dev/null
+++ b/Python/import.c
@@ -0,0 +1,252 @@
+/* Module definition and import implementation */
+
+#include <stdio.h>
+#include "string.h"
+
+#include "PROTO.h"
+#include "object.h"
+#include "stringobject.h"
+#include "listobject.h"
+#include "dictobject.h"
+#include "moduleobject.h"
+#include "node.h"
+#include "context.h"
+#include "token.h"
+#include "graminit.h"
+#include "run.h"
+#include "support.h"
+#include "import.h"
+#include "errcode.h"
+#include "sysmodule.h"
+
+/* Define pathname separator and delimiter in $PYTHONPATH */
+
+#ifdef THINK_C
+#define SEP ':'
+#define DELIM ' '
+#endif
+
+#ifndef SEP
+#define SEP '/'
+#endif
+
+#ifndef DELIM
+#define DELIM ':'
+#endif
+
+void
+initimport()
+{
+ object *v;
+ if ((v = newdictobject()) == NULL)
+ fatal("no mem for module table");
+ if (sysset("modules", v) != 0)
+ fatal("can't assign sys.modules");
+}
+
+object *
+new_module(name)
+ char *name;
+{
+ object *m;
+ object *mtab;
+ mtab = sysget("modules");
+ if (mtab == NULL || !is_dictobject(mtab)) {
+ errno = EBADF;
+ return NULL;
+ }
+ m = newmoduleobject(name);
+ if (m == NULL)
+ return NULL;
+ if (dictinsert(mtab, name, m) != 0) {
+ DECREF(m);
+ return NULL;
+ }
+ return m;
+}
+
+void
+define_module(ctx, name)
+ context *ctx;
+ char *name;
+{
+ object *m, *d;
+ m = new_module(name);
+ if (m == NULL) {
+ puterrno(ctx);
+ return;
+ }
+ d = getmoduledict(m);
+ INCREF(d);
+ DECREF(ctx->ctx_locals);
+ ctx->ctx_locals = d;
+ INCREF(d);
+ DECREF(ctx->ctx_globals);
+ ctx->ctx_globals = d;
+ DECREF(m);
+}
+
+object *
+parsepath(path, delim)
+ char *path;
+ int delim;
+{
+ int i, n;
+ char *p;
+ object *v, *w;
+
+ n = 1;
+ p = path;
+ while ((p = strchr(p, delim)) != NULL) {
+ n++;
+ p++;
+ }
+ v = newlistobject(n);
+ if (v == NULL)
+ return NULL;
+ for (i = 0; ; i++) {
+ p = strchr(path, delim);
+ if (p == NULL)
+ p = strchr(path, '\0'); /* End of string */
+ w = newsizedstringobject(path, (int) (p - path));
+ if (w == NULL) {
+ DECREF(v);
+ return NULL;
+ }
+ setlistitem(v, i, w);
+ if (*p == '\0')
+ break;
+ path = p+1;
+ }
+ return v;
+}
+
+void
+setpythonpath(path)
+ char *path;
+{
+ object *v;
+ if ((v = parsepath(path, DELIM)) != NULL) {
+ if (sysset("path", v) != 0)
+ fatal("can't assign sys.path");
+ DECREF(v);
+ }
+}
+
+static FILE *
+open_module(name, suffix)
+ char *name;
+ char *suffix;
+{
+ object *path;
+ char namebuf[256];
+ FILE *fp;
+
+ path = sysget("path");
+ if (path == NULL || !is_listobject(path)) {
+ strcpy(namebuf, name);
+ strcat(namebuf, suffix);
+ fp = fopen(namebuf, "r");
+ }
+ else {
+ int npath = getlistsize(path);
+ int i;
+ fp = NULL;
+ for (i = 0; i < npath; i++) {
+ object *v = getlistitem(path, i);
+ int len;
+ if (!is_stringobject(v))
+ continue;
+ strcpy(namebuf, getstringvalue(v));
+ len = getstringsize(v);
+ if (len > 0 && namebuf[len-1] != SEP)
+ namebuf[len++] = SEP;
+ strcpy(namebuf+len, name); /* XXX check for overflow */
+ strcat(namebuf, suffix); /* XXX ditto */
+ fp = fopen(namebuf, "r");
+ if (fp != NULL)
+ break;
+ }
+ }
+ return fp;
+}
+
+static object *
+load_module(ctx, name)
+ context *ctx;
+ char *name;
+{
+ object *m;
+ char **p;
+ FILE *fp;
+ node *n, *mh;
+ int err;
+ object *mtab;
+ object *save_locals, *save_globals;
+
+ mtab = sysget("modules");
+ if (mtab == NULL || !is_dictobject(mtab)) {
+ errno = EBADF;
+ return NULL;
+ }
+ fp = open_module(name, ".py");
+ if (fp == NULL) {
+ /* XXX Compatibility hack */
+ fprintf(stderr,
+ "Can't find '%s.py' in sys.path, trying '%s'\n",
+ name, name);
+ fp = open_module(name, "");
+ }
+ if (fp == NULL) {
+ name_error(ctx, name);
+ return NULL;
+ }
+#ifdef DEBUG
+ fprintf(stderr, "Reading module %s from file '%s'\n", name, namebuf);
+#endif
+ err = parseinput(fp, file_input, &n);
+ fclose(fp);
+ if (err != E_DONE) {
+ input_error(ctx, err);
+ return NULL;
+ }
+ save_locals = ctx->ctx_locals;
+ INCREF(save_locals);
+ save_globals = ctx->ctx_globals;
+ INCREF(save_globals);
+ define_module(ctx, name);
+ exec_node(ctx, n);
+ DECREF(ctx->ctx_locals);
+ ctx->ctx_locals = save_locals;
+ DECREF(ctx->ctx_globals);
+ ctx->ctx_globals = save_globals;
+ /* XXX need to free the tree n here; except referenced defs */
+ if (ctx->ctx_exception) {
+ dictremove(mtab, name); /* Undefine the module */
+ return NULL;
+ }
+ m = dictlookup(mtab, name);
+ if (m == NULL) {
+ error(ctx, "module not defined after loading");
+ return NULL;
+ }
+ return m;
+}
+
+object *
+import_module(ctx, name)
+ context *ctx;
+ char *name;
+{
+ object *m;
+ object *mtab;
+ mtab = sysget("modules");
+ if (mtab == NULL || !is_dictobject(mtab)) {
+ error(ctx, "bad sys.modules");
+ return NULL;
+ }
+ if ((m = dictlookup(mtab, name)) == NULL) {
+ m = load_module(ctx, name);
+ }
+ return m;
+}