mirror of
				https://github.com/python/cpython.git
				synced 2025-11-04 07:31:38 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			297 lines
		
	
	
	
		
			5.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			297 lines
		
	
	
	
		
			5.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/* 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;
 | 
						|
}
 |