diff options
author | Guido van Rossum <guido@python.org> | 1990-10-14 12:07:46 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 1990-10-14 12:07:46 (GMT) |
commit | 85a5fbbdfea617f6cc8fae82c9e8c2b5c424436d (patch) | |
tree | a1bf57db1c75e2a7029c8f2fad5f8dba4b9ba25c /Python/import.c | |
parent | c636014c430620325f8d213e9ba10d925991b8d7 (diff) | |
download | cpython-85a5fbbdfea617f6cc8fae82c9e8c2b5c424436d.zip cpython-85a5fbbdfea617f6cc8fae82c9e8c2b5c424436d.tar.gz cpython-85a5fbbdfea617f6cc8fae82c9e8c2b5c424436d.tar.bz2 |
Initial revision
Diffstat (limited to 'Python/import.c')
-rw-r--r-- | Python/import.c | 252 |
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; +} |