view Python/import.c @ 66:46cb14aec10a legacy-trunk

Reformulated err_badarg error message.
author Guido van Rossum <guido@python.org>
date Fri, 09 Nov 1990 15:05:53 +0000
parents f28ac7f621c7
children bc244df20251
line wrap: on
line source

/* 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;
}

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;
}