/* Module definition and import implementation */ #include #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"); DECREF(v); } 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; } static void use_module(ctx, d) context *ctx; object *d; { INCREF(d); DECREF(ctx->ctx_locals); ctx->ctx_locals = d; INCREF(d); DECREF(ctx->ctx_globals); ctx->ctx_globals = d; } static void define_module(ctx, name) context *ctx; char *name; { object *m; m = new_module(name); if (m == NULL) { puterrno(ctx); return; } use_module(ctx, getmoduledict(m)); DECREF(m); } static 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; 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) { name_error(ctx, name); return NULL; } 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; } object * reload_module(ctx, m) context *ctx; object *m; { char *name; FILE *fp; node *n; int err; object *d; object *save_locals, *save_globals; if (m == NULL || !is_moduleobject(m)) { type_error(ctx, "reload() argument must be module"); return NULL; } /* XXX Ought to check for builtin module */ name = getmodulename(m); fp = open_module(name, ".py"); if (fp == NULL) { error(ctx, "reload() cannot find module source file"); return NULL; } err = parseinput(fp, file_input, &n); fclose(fp); if (err != E_DONE) { input_error(ctx, err); return NULL; } d = newdictobject(); if (d == NULL) return NULL; setmoduledict(m, d); save_locals = ctx->ctx_locals; INCREF(save_locals); save_globals = ctx->ctx_globals; INCREF(save_globals); use_module(ctx, d); exec_node(ctx, n); DECREF(ctx->ctx_locals); ctx->ctx_locals = save_locals; DECREF(ctx->ctx_globals); ctx->ctx_globals = save_globals; if (ctx->ctx_exception) return NULL; INCREF(None); return None; }