mirror of https://github.com/python/cpython
Lots of changes, most minor (fatal() instead of abort(), use of
err_fetch/err_restore and so on). But... NOTE: import.c has been rewritten and all the DL stuff is now in the new file importdl.c.
This commit is contained in:
parent
824de25fe2
commit
1ae940a587
|
@ -35,7 +35,7 @@ OBJS= \
|
|||
errors.o \
|
||||
frozenmain.o \
|
||||
getargs.o getmtime.o graminit.o \
|
||||
import.o \
|
||||
import.o importdl.o \
|
||||
marshal.o modsupport.o mystrtoul.o \
|
||||
pythonmain.o pythonrun.o \
|
||||
sigcheck.o structmember.o sysmodule.o \
|
||||
|
@ -66,8 +66,8 @@ Makefile: $(srcdir)/Makefile.in ../config.status
|
|||
(cd ..; CONFIG_FILES=Python/Makefile CONFIG_HEADERS= \
|
||||
$(SHELL) config.status)
|
||||
|
||||
import.o: import.c
|
||||
$(CC) $(CFLAGS) -I$(DLINCLDIR) -c $(srcdir)/import.c
|
||||
importdl.o: importdl.c
|
||||
$(CC) $(CFLAGS) -I$(DLINCLDIR) -c $(srcdir)/importdl.c
|
||||
|
||||
depend:
|
||||
$(MKDEP) $(CFLAGS) `echo $(OBJS) | tr ' ' '\012' | \
|
||||
|
@ -88,6 +88,7 @@ getcwd.o: getcwd.c
|
|||
getmtime.o: getmtime.c
|
||||
graminit.o: graminit.c
|
||||
import.o: import.c
|
||||
importdl.o: importdl.c
|
||||
marshal.o: marshal.c
|
||||
memmove.o: memmove.c
|
||||
modsupport.o: modsupport.c
|
||||
|
|
|
@ -40,15 +40,35 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
/* Forward */
|
||||
static object *filterstring PROTO((object *, object *));
|
||||
static object *filtertuple PROTO((object *, object *));
|
||||
static object *exec_eval PROTO((object *v, int start));
|
||||
|
||||
static object *
|
||||
builtin_abs(self, v)
|
||||
builtin___import__(self, args)
|
||||
object *self;
|
||||
object *v;
|
||||
object *args;
|
||||
{
|
||||
char *name;
|
||||
object *m;
|
||||
|
||||
if (!newgetargs(args, "s:__import__", &name))
|
||||
return NULL;
|
||||
m = import_module(name);
|
||||
XINCREF(m);
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
static object *
|
||||
builtin_abs(self, args)
|
||||
object *self;
|
||||
object *args;
|
||||
{
|
||||
object *v;
|
||||
number_methods *nm;
|
||||
if (v == NULL || (nm = v->ob_type->tp_as_number) == NULL) {
|
||||
|
||||
if (!newgetargs(args, "O:abs", &v))
|
||||
return NULL;
|
||||
if ((nm = v->ob_type->tp_as_number) == NULL) {
|
||||
err_setstr(TypeError, "abs() requires numeric argument");
|
||||
return NULL;
|
||||
}
|
||||
|
@ -61,7 +81,8 @@ builtin_apply(self, args)
|
|||
object *args;
|
||||
{
|
||||
object *func, *arglist;
|
||||
if (!getargs(args, "(OO)", &func, &arglist))
|
||||
|
||||
if (!newgetargs(args, "OO:apply", &func, &arglist))
|
||||
return NULL;
|
||||
if (!is_tupleobject(arglist)) {
|
||||
err_setstr(TypeError, "apply() 2nd argument must be tuple");
|
||||
|
@ -101,12 +122,11 @@ builtin_callable(self, args)
|
|||
object *self;
|
||||
object *args;
|
||||
{
|
||||
if (args == NULL) {
|
||||
err_setstr(TypeError,
|
||||
"callable requires exactly one argument");
|
||||
object *v;
|
||||
|
||||
if (!newgetargs(args, "O:callable", &v))
|
||||
return NULL;
|
||||
}
|
||||
return newintobject((long)callable(args));
|
||||
return newintobject((long)callable(v));
|
||||
}
|
||||
|
||||
static object *
|
||||
|
@ -119,7 +139,7 @@ builtin_filter(self, args)
|
|||
int len;
|
||||
register int i, j;
|
||||
|
||||
if (!getargs(args, "(OO)", &func, &seq))
|
||||
if (!newgetargs(args, "OO:filter", &func, &seq))
|
||||
return NULL;
|
||||
|
||||
if (is_stringobject(seq)) {
|
||||
|
@ -212,7 +232,8 @@ builtin_chr(self, args)
|
|||
{
|
||||
long x;
|
||||
char s[1];
|
||||
if (!getargs(args, "l", &x))
|
||||
|
||||
if (!newgetargs(args, "l:chr", &x))
|
||||
return NULL;
|
||||
if (x < 0 || x >= 256) {
|
||||
err_setstr(ValueError, "chr() arg not in range(256)");
|
||||
|
@ -228,7 +249,8 @@ builtin_cmp(self, args)
|
|||
object *args;
|
||||
{
|
||||
object *a, *b;
|
||||
if (!getargs(args, "(OO)", &a, &b))
|
||||
|
||||
if (!newgetargs(args, "OO:cmp", &a, &b))
|
||||
return NULL;
|
||||
return newintobject((long)cmpobject(a, b));
|
||||
}
|
||||
|
@ -241,7 +263,7 @@ builtin_coerce(self, args)
|
|||
object *v, *w;
|
||||
object *res;
|
||||
|
||||
if (!getargs(args, "(OO)", &v, &w))
|
||||
if (!newgetargs(args, "OO:coerce", &v, &w))
|
||||
return NULL;
|
||||
if (is_instanceobject(v) || is_instanceobject(w))
|
||||
return instancebinop(v, w, "__coerce__", "__rcoerce__");
|
||||
|
@ -262,7 +284,8 @@ builtin_compile(self, args)
|
|||
char *filename;
|
||||
char *startstr;
|
||||
int start;
|
||||
if (!getargs(args, "(sss)", &str, &filename, &startstr))
|
||||
|
||||
if (!newgetargs(args, "sss:compile", &str, &filename, &startstr))
|
||||
return NULL;
|
||||
if (strcmp(startstr, "exec") == 0)
|
||||
start = file_input;
|
||||
|
@ -277,11 +300,15 @@ builtin_compile(self, args)
|
|||
}
|
||||
|
||||
static object *
|
||||
builtin_dir(self, v)
|
||||
builtin_dir(self, args)
|
||||
object *self;
|
||||
object *v;
|
||||
object *args;
|
||||
{
|
||||
object *v = NULL;
|
||||
object *d;
|
||||
|
||||
if (!newgetargs(args, "|O:dir", &v))
|
||||
return NULL;
|
||||
if (v == NULL) {
|
||||
d = getlocals();
|
||||
INCREF(d);
|
||||
|
@ -314,13 +341,15 @@ builtin_divmod(self, args)
|
|||
object *args;
|
||||
{
|
||||
object *v, *w, *x;
|
||||
if (!getargs(args, "(OO)", &v, &w))
|
||||
|
||||
if (!newgetargs(args, "OO:divmod", &v, &w))
|
||||
return NULL;
|
||||
if (is_instanceobject(v) || is_instanceobject(w))
|
||||
return instancebinop(v, w, "__divmod__", "__rdivmod__");
|
||||
if (v->ob_type->tp_as_number == NULL ||
|
||||
w->ob_type->tp_as_number == NULL) {
|
||||
err_setstr(TypeError, "divmod() requires numeric or class instance arguments");
|
||||
err_setstr(TypeError,
|
||||
"divmod() requires numeric or class instance arguments");
|
||||
return NULL;
|
||||
}
|
||||
if (coerce(&v, &w) != 0)
|
||||
|
@ -332,110 +361,80 @@ builtin_divmod(self, args)
|
|||
}
|
||||
|
||||
static object *
|
||||
exec_eval(v, start)
|
||||
object *v;
|
||||
int start;
|
||||
builtin_eval(self, args)
|
||||
object *self;
|
||||
object *args;
|
||||
{
|
||||
object *str = NULL, *globals = NULL, *locals = NULL;
|
||||
char *s;
|
||||
int n;
|
||||
/* XXX This is a bit of a mess. Should make it varargs */
|
||||
if (v != NULL) {
|
||||
if (is_tupleobject(v) &&
|
||||
((n = gettuplesize(v)) == 2 || n == 3)) {
|
||||
str = gettupleitem(v, 0);
|
||||
globals = gettupleitem(v, 1);
|
||||
if (n == 3)
|
||||
locals = gettupleitem(v, 2);
|
||||
}
|
||||
else
|
||||
str = v;
|
||||
}
|
||||
if (str == NULL || (!is_stringobject(str) && !is_codeobject(str)) ||
|
||||
globals != NULL && !is_dictobject(globals) ||
|
||||
locals != NULL && !is_dictobject(locals)) {
|
||||
err_setstr(TypeError,
|
||||
"eval arguments must be (string|code)[,dict[,dict]]");
|
||||
return NULL;
|
||||
}
|
||||
object *cmd;
|
||||
object *globals = NULL, *locals = NULL;
|
||||
char *str;
|
||||
|
||||
if (is_codeobject(str))
|
||||
return eval_code((codeobject *) str, globals, locals,
|
||||
if (!newgetargs(args, "O|O!O!:eval",
|
||||
&cmd,
|
||||
&Mappingtype, &globals,
|
||||
&Mappingtype, &locals))
|
||||
return NULL;
|
||||
if (is_codeobject(cmd))
|
||||
return eval_code((codeobject *) cmd, globals, locals,
|
||||
(object *)NULL, (object *)NULL);
|
||||
s = getstringvalue(str);
|
||||
if (strlen(s) != getstringsize(str)) {
|
||||
err_setstr(ValueError, "embedded '\\0' in string arg");
|
||||
if (!is_stringobject(cmd)) {
|
||||
err_setstr(TypeError,
|
||||
"eval() argument 1 must be string or code object");
|
||||
return NULL;
|
||||
}
|
||||
if (start == eval_input) {
|
||||
while (*s == ' ' || *s == '\t')
|
||||
s++;
|
||||
str = getstringvalue(cmd);
|
||||
if (strlen(str) != getstringsize(cmd)) {
|
||||
err_setstr(ValueError,
|
||||
"embedded '\\0' in string arg");
|
||||
return NULL;
|
||||
}
|
||||
return run_string(s, start, globals, locals);
|
||||
while (*str == ' ' || *str == '\t')
|
||||
str++;
|
||||
return run_string(str, eval_input, globals, locals);
|
||||
}
|
||||
|
||||
static object *
|
||||
builtin_eval(self, v)
|
||||
builtin_execfile(self, args)
|
||||
object *self;
|
||||
object *v;
|
||||
object *args;
|
||||
{
|
||||
return exec_eval(v, eval_input);
|
||||
}
|
||||
|
||||
static object *
|
||||
builtin_execfile(self, v)
|
||||
object *self;
|
||||
object *v;
|
||||
{
|
||||
object *str = NULL, *globals = NULL, *locals = NULL, *w;
|
||||
char *filename;
|
||||
object *globals = NULL, *locals = NULL;
|
||||
object *res;
|
||||
FILE* fp;
|
||||
char *s;
|
||||
int n;
|
||||
if (v != NULL) {
|
||||
if (is_stringobject(v))
|
||||
str = v;
|
||||
else if (is_tupleobject(v) &&
|
||||
((n = gettuplesize(v)) == 2 || n == 3)) {
|
||||
str = gettupleitem(v, 0);
|
||||
globals = gettupleitem(v, 1);
|
||||
if (n == 3)
|
||||
locals = gettupleitem(v, 2);
|
||||
}
|
||||
}
|
||||
if (str == NULL || !is_stringobject(str) ||
|
||||
globals != NULL && !is_dictobject(globals) ||
|
||||
locals != NULL && !is_dictobject(locals)) {
|
||||
err_setstr(TypeError,
|
||||
"execfile arguments must be filename[,dict[,dict]]");
|
||||
|
||||
if (!newgetargs(args, "s|O!O!:execfile",
|
||||
&filename,
|
||||
&Mappingtype, &globals,
|
||||
&Mappingtype, &locals))
|
||||
return NULL;
|
||||
}
|
||||
s = getstringvalue(str);
|
||||
if (strlen(s) != getstringsize(str)) {
|
||||
err_setstr(ValueError, "embedded '\\0' in string arg");
|
||||
return NULL;
|
||||
}
|
||||
BGN_SAVE
|
||||
fp = fopen(s, "r");
|
||||
fp = fopen(filename, "r");
|
||||
END_SAVE
|
||||
if (fp == NULL) {
|
||||
err_setstr(IOError, "execfile cannot open the file argument");
|
||||
err_errno(IOError);
|
||||
return NULL;
|
||||
}
|
||||
w = run_file(fp, getstringvalue(str), file_input, globals, locals);
|
||||
res = run_file(fp, filename, file_input, globals, locals);
|
||||
BGN_SAVE
|
||||
fclose(fp);
|
||||
END_SAVE
|
||||
return w;
|
||||
return res;
|
||||
}
|
||||
|
||||
static object *
|
||||
builtin_float(self, v)
|
||||
builtin_float(self, args)
|
||||
object *self;
|
||||
object *v;
|
||||
object *args;
|
||||
{
|
||||
object *v;
|
||||
number_methods *nb;
|
||||
|
||||
if (v == NULL || (nb = v->ob_type->tp_as_number) == NULL ||
|
||||
|
||||
if (!newgetargs(args, "O:float", &v))
|
||||
return NULL;
|
||||
if ((nb = v->ob_type->tp_as_number) == NULL ||
|
||||
nb->nb_float == NULL) {
|
||||
err_setstr(TypeError,
|
||||
"float() argument can't be converted to float");
|
||||
|
@ -451,7 +450,8 @@ builtin_getattr(self, args)
|
|||
{
|
||||
object *v;
|
||||
object *name;
|
||||
if (!getargs(args, "(OS)", &v, &name))
|
||||
|
||||
if (!newgetargs(args, "OS:getattr", &v, &name))
|
||||
return NULL;
|
||||
return getattro(v, name);
|
||||
}
|
||||
|
@ -463,7 +463,8 @@ builtin_hasattr(self, args)
|
|||
{
|
||||
object *v;
|
||||
object *name;
|
||||
if (!getargs(args, "(OS)", &v, &name))
|
||||
|
||||
if (!newgetargs(args, "OS:hasattr", &v, &name))
|
||||
return NULL;
|
||||
v = getattro(v, name);
|
||||
if (v == NULL) {
|
||||
|
@ -480,7 +481,8 @@ builtin_id(self, args)
|
|||
object *args;
|
||||
{
|
||||
object *v;
|
||||
if (!getargs(args, "O", &v))
|
||||
|
||||
if (!newgetargs(args, "O:id", &v))
|
||||
return NULL;
|
||||
return newintobject((long)v);
|
||||
}
|
||||
|
@ -498,16 +500,17 @@ builtin_map(self, args)
|
|||
|
||||
object *func, *result;
|
||||
sequence *seqs = NULL, *sqp;
|
||||
int n, len, newfunc = 0;
|
||||
int n, len;
|
||||
register int i, j;
|
||||
|
||||
if (args == NULL || !is_tupleobject(args)) {
|
||||
n = gettuplesize(args);
|
||||
if (n < 2) {
|
||||
err_setstr(TypeError, "map() requires at least two args");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
func = gettupleitem(args, 0);
|
||||
n = gettuplesize(args) - 1;
|
||||
n--;
|
||||
|
||||
if ((seqs = NEW(sequence, n)) == NULL) {
|
||||
err_nomem();
|
||||
|
@ -633,7 +636,8 @@ builtin_setattr(self, args)
|
|||
object *v;
|
||||
object *name;
|
||||
object *value;
|
||||
if (!getargs(args, "(OSO)", &v, &name, &value))
|
||||
|
||||
if (!newgetargs(args, "OSO:setattr", &v, &name, &value))
|
||||
return NULL;
|
||||
if (setattro(v, name, value) != 0)
|
||||
return NULL;
|
||||
|
@ -648,7 +652,8 @@ builtin_delattr(self, args)
|
|||
{
|
||||
object *v;
|
||||
object *name;
|
||||
if (!getargs(args, "(OS)", &v, &name))
|
||||
|
||||
if (!newgetargs(args, "OS:delattr", &v, &name))
|
||||
return NULL;
|
||||
if (setattro(v, name, (object *)NULL) != 0)
|
||||
return NULL;
|
||||
|
@ -663,7 +668,8 @@ builtin_hash(self, args)
|
|||
{
|
||||
object *v;
|
||||
long x;
|
||||
if (!getargs(args, "O", &v))
|
||||
|
||||
if (!newgetargs(args, "O:hash", &v))
|
||||
return NULL;
|
||||
x = hashobject(v);
|
||||
if (x == -1)
|
||||
|
@ -672,13 +678,17 @@ builtin_hash(self, args)
|
|||
}
|
||||
|
||||
static object *
|
||||
builtin_hex(self, v)
|
||||
builtin_hex(self, args)
|
||||
object *self;
|
||||
object *v;
|
||||
object *args;
|
||||
{
|
||||
object *v;
|
||||
number_methods *nb;
|
||||
|
||||
if (!newgetargs(args, "O:hex", &v))
|
||||
return NULL;
|
||||
|
||||
if (v == NULL || (nb = v->ob_type->tp_as_number) == NULL ||
|
||||
if ((nb = v->ob_type->tp_as_number) == NULL ||
|
||||
nb->nb_hex == NULL) {
|
||||
err_setstr(TypeError,
|
||||
"hex() argument can't be converted to hex");
|
||||
|
@ -690,26 +700,37 @@ builtin_hex(self, v)
|
|||
static object *builtin_raw_input PROTO((object *, object *));
|
||||
|
||||
static object *
|
||||
builtin_input(self, v)
|
||||
builtin_input(self, args)
|
||||
object *self;
|
||||
object *v;
|
||||
object *args;
|
||||
{
|
||||
object *line = builtin_raw_input(self, v);
|
||||
object *line;
|
||||
char *str;
|
||||
object *res;
|
||||
|
||||
line = builtin_raw_input(self, args);
|
||||
if (line == NULL)
|
||||
return line;
|
||||
v = exec_eval(line, eval_input);
|
||||
if (!getargs(line, "s;embedded '\\0' in input line", &str))
|
||||
return NULL;
|
||||
while (*str == ' ' || *str == '\t')
|
||||
str++;
|
||||
res = run_string(str, eval_input, (object *)NULL, (object *)NULL);
|
||||
DECREF(line);
|
||||
return v;
|
||||
return res;
|
||||
}
|
||||
|
||||
static object *
|
||||
builtin_int(self, v)
|
||||
builtin_int(self, args)
|
||||
object *self;
|
||||
object *v;
|
||||
object *args;
|
||||
{
|
||||
object *v;
|
||||
number_methods *nb;
|
||||
|
||||
if (v == NULL || (nb = v->ob_type->tp_as_number) == NULL ||
|
||||
|
||||
if (!newgetargs(args, "O:int", &v))
|
||||
return NULL;
|
||||
if ((nb = v->ob_type->tp_as_number) == NULL ||
|
||||
nb->nb_int == NULL) {
|
||||
err_setstr(TypeError,
|
||||
"int() argument can't be converted to int");
|
||||
|
@ -719,16 +740,16 @@ builtin_int(self, v)
|
|||
}
|
||||
|
||||
static object *
|
||||
builtin_len(self, v)
|
||||
builtin_len(self, args)
|
||||
object *self;
|
||||
object *v;
|
||||
object *args;
|
||||
{
|
||||
object *v;
|
||||
long len;
|
||||
typeobject *tp;
|
||||
if (v == NULL) {
|
||||
err_setstr(TypeError, "len() without argument");
|
||||
|
||||
if (!newgetargs(args, "O:len", &v))
|
||||
return NULL;
|
||||
}
|
||||
tp = v->ob_type;
|
||||
if (tp->tp_as_sequence != NULL) {
|
||||
len = (*tp->tp_as_sequence->sq_length)(v);
|
||||
|
@ -747,13 +768,16 @@ builtin_len(self, v)
|
|||
}
|
||||
|
||||
static object *
|
||||
builtin_long(self, v)
|
||||
builtin_long(self, args)
|
||||
object *self;
|
||||
object *v;
|
||||
object *args;
|
||||
{
|
||||
object *v;
|
||||
number_methods *nb;
|
||||
|
||||
if (v == NULL || (nb = v->ob_type->tp_as_number) == NULL ||
|
||||
if (!newgetargs(args, "O:long", &v))
|
||||
return NULL;
|
||||
if ((nb = v->ob_type->tp_as_number) == NULL ||
|
||||
nb->nb_long == NULL) {
|
||||
err_setstr(TypeError,
|
||||
"long() argument can't be converted to long");
|
||||
|
@ -763,17 +787,18 @@ builtin_long(self, v)
|
|||
}
|
||||
|
||||
static object *
|
||||
min_max(v, sign)
|
||||
object *v;
|
||||
min_max(args, sign)
|
||||
object *args;
|
||||
int sign;
|
||||
{
|
||||
int i;
|
||||
object *w, *x;
|
||||
object *v, *w, *x;
|
||||
sequence_methods *sq;
|
||||
if (v == NULL) {
|
||||
err_setstr(TypeError, "min() or max() without argument");
|
||||
|
||||
if (gettuplesize(args) > 1)
|
||||
v = args;
|
||||
else if (!newgetargs(args, "O:min/max", &v))
|
||||
return NULL;
|
||||
}
|
||||
sq = v->ob_type->tp_as_sequence;
|
||||
if (sq == NULL) {
|
||||
err_setstr(TypeError, "min() or max() of non-sequence");
|
||||
|
@ -823,12 +848,15 @@ builtin_max(self, v)
|
|||
}
|
||||
|
||||
static object *
|
||||
builtin_oct(self, v)
|
||||
builtin_oct(self, args)
|
||||
object *self;
|
||||
object *v;
|
||||
object *args;
|
||||
{
|
||||
object *v;
|
||||
number_methods *nb;
|
||||
|
||||
|
||||
if (!newgetargs(args, "O:oct", &v))
|
||||
return NULL;
|
||||
if (v == NULL || (nb = v->ob_type->tp_as_number) == NULL ||
|
||||
nb->nb_oct == NULL) {
|
||||
err_setstr(TypeError,
|
||||
|
@ -847,9 +875,8 @@ builtin_open(self, args)
|
|||
char *mode = "r";
|
||||
int bufsize = -1;
|
||||
object *f;
|
||||
if (!getargs(args, "s", &name) &&
|
||||
(err_clear(), !getargs(args, "(ss)", &name, &mode)) &&
|
||||
(err_clear(), !getargs(args, "(ssi)", &name, &mode, &bufsize)))
|
||||
|
||||
if (!newgetargs(args, "s|si:open", &name, &mode, &bufsize))
|
||||
return NULL;
|
||||
f = newfileobject(name, mode);
|
||||
if (f != NULL)
|
||||
|
@ -862,15 +889,11 @@ builtin_ord(self, args)
|
|||
object *self;
|
||||
object *args;
|
||||
{
|
||||
char *s;
|
||||
int len;
|
||||
if (!getargs(args, "s#", &s, &len))
|
||||
char c;
|
||||
|
||||
if (!newgetargs(args, "c:ord", &c))
|
||||
return NULL;
|
||||
if (len != 1) {
|
||||
err_setstr(ValueError, "ord() arg must have length 1");
|
||||
return NULL;
|
||||
}
|
||||
return newintobject((long)(s[0] & 0xff));
|
||||
return newintobject((long)(c & 0xff));
|
||||
}
|
||||
|
||||
static object *
|
||||
|
@ -878,9 +901,9 @@ builtin_pow(self, args)
|
|||
object *self;
|
||||
object *args;
|
||||
{
|
||||
object *v, *w, *z, *x;
|
||||
z = None;
|
||||
if (!newgetargs(args, "OO|O", &v, &w, &z))
|
||||
object *v, *w, *z = None, *x;
|
||||
|
||||
if (!newgetargs(args, "OO|O:pow", &v, &w, &z))
|
||||
return NULL;
|
||||
if (z == None) {
|
||||
if (is_instanceobject(v) || is_instanceobject(w))
|
||||
|
@ -913,43 +936,25 @@ builtin_pow(self, args)
|
|||
}
|
||||
|
||||
static object *
|
||||
builtin_range(self, v)
|
||||
builtin_range(self, args)
|
||||
object *self;
|
||||
object *v;
|
||||
object *args;
|
||||
{
|
||||
static char *errmsg = "range() requires 1-3 int arguments";
|
||||
long ilow = 0, ihigh = 0, istep = 1;
|
||||
int i, n;
|
||||
long ilow, ihigh, istep;
|
||||
if (v != NULL && is_intobject(v)) {
|
||||
ilow = 0; ihigh = getintvalue(v); istep = 1;
|
||||
}
|
||||
else if (v == NULL || !is_tupleobject(v)) {
|
||||
err_setstr(TypeError, errmsg);
|
||||
return NULL;
|
||||
object *v;
|
||||
|
||||
if (gettuplesize(args) <= 1) {
|
||||
if (!newgetargs(args,
|
||||
"i;range() requires 1-3 int arguments",
|
||||
&ihigh))
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
n = gettuplesize(v);
|
||||
if (n < 1 || n > 3) {
|
||||
err_setstr(TypeError, errmsg);
|
||||
if (!newgetargs(args,
|
||||
"ii|i;range() requires 1-3 int arguments",
|
||||
&ilow, &ihigh, &istep))
|
||||
return NULL;
|
||||
}
|
||||
for (i = 0; i < n; i++) {
|
||||
if (!is_intobject(gettupleitem(v, i))) {
|
||||
err_setstr(TypeError, errmsg);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if (n == 3) {
|
||||
istep = getintvalue(gettupleitem(v, 2));
|
||||
--n;
|
||||
}
|
||||
else
|
||||
istep = 1;
|
||||
ihigh = getintvalue(gettupleitem(v, --n));
|
||||
if (n > 0)
|
||||
ilow = getintvalue(gettupleitem(v, 0));
|
||||
else
|
||||
ilow = 0;
|
||||
}
|
||||
if (istep == 0) {
|
||||
err_setstr(ValueError, "zero step for range()");
|
||||
|
@ -978,73 +983,66 @@ builtin_range(self, v)
|
|||
}
|
||||
|
||||
static object *
|
||||
builtin_xrange(self, v)
|
||||
builtin_xrange(self, args)
|
||||
object *self;
|
||||
object *v;
|
||||
object *args;
|
||||
{
|
||||
static char *errmsg = "xrange() requires 1-3 int arguments";
|
||||
int i, n;
|
||||
long start, stop, step, len;
|
||||
if (v != NULL && is_intobject(v))
|
||||
start = 0, stop = getintvalue(v), step = 1;
|
||||
long ilow = 0, ihigh = 0, istep = 1;
|
||||
int n;
|
||||
object *v;
|
||||
|
||||
else if (v == NULL || !is_tupleobject(v)) {
|
||||
err_setstr(TypeError, errmsg);
|
||||
return NULL;
|
||||
if (gettuplesize(args) <= 1) {
|
||||
if (!newgetargs(args,
|
||||
"i;xrange() requires 1-3 int arguments",
|
||||
&ihigh))
|
||||
return NULL;
|
||||
}
|
||||
else {
|
||||
n = gettuplesize(v);
|
||||
if (n < 1 || n > 3) {
|
||||
err_setstr(TypeError, errmsg);
|
||||
if (!newgetargs(args,
|
||||
"ii|i;xrange() requires 1-3 int arguments",
|
||||
&ilow, &ihigh, &istep))
|
||||
return NULL;
|
||||
}
|
||||
for (i = 0; i < n; i++) {
|
||||
if (!is_intobject(gettupleitem(v, i))) {
|
||||
err_setstr(TypeError, errmsg);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if (n == 3) {
|
||||
step = getintvalue(gettupleitem(v, 2));
|
||||
--n;
|
||||
}
|
||||
else
|
||||
step = 1;
|
||||
stop = getintvalue(gettupleitem(v, --n));
|
||||
if (n > 0)
|
||||
start = getintvalue(gettupleitem(v, 0));
|
||||
else
|
||||
start = 0;
|
||||
}
|
||||
|
||||
if (step == 0) {
|
||||
if (istep == 0) {
|
||||
err_setstr(ValueError, "zero step for xrange()");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
len = (stop - start + step + ((step > 0) ? -1 : 1)) / step;
|
||||
if (len < 0)
|
||||
len = 0;
|
||||
|
||||
return newrangeobject(start, len, step, 1);
|
||||
/* XXX ought to check overflow of subtraction */
|
||||
if (istep > 0)
|
||||
n = (ihigh - ilow + istep - 1) / istep;
|
||||
else
|
||||
n = (ihigh - ilow + istep + 1) / istep;
|
||||
if (n < 0)
|
||||
n = 0;
|
||||
return newrangeobject(ilow, n, istep, 1);
|
||||
}
|
||||
|
||||
static object *
|
||||
builtin_raw_input(self, v)
|
||||
builtin_raw_input(self, args)
|
||||
object *self;
|
||||
object *v;
|
||||
object *args;
|
||||
{
|
||||
object *f = sysget("stdout");
|
||||
if (f == NULL) {
|
||||
err_setstr(RuntimeError, "lost sys.stdout");
|
||||
object *v = NULL;
|
||||
object *f;
|
||||
|
||||
if (!newgetargs(args, "|O:[raw_]input", &v))
|
||||
return NULL;
|
||||
}
|
||||
flushline();
|
||||
if (v != NULL) {
|
||||
f = sysget("stdout");
|
||||
if (f == NULL) {
|
||||
err_setstr(RuntimeError, "lost sys.stdout");
|
||||
return NULL;
|
||||
}
|
||||
flushline();
|
||||
if (writeobject(v, f, PRINT_RAW) != 0)
|
||||
return NULL;
|
||||
}
|
||||
return filegetline(sysget("stdin"), -1);
|
||||
f = sysget("stdin");
|
||||
if (f == NULL) {
|
||||
err_setstr(RuntimeError, "lost sys.stdin");
|
||||
return NULL;
|
||||
}
|
||||
return filegetline(f, -1);
|
||||
}
|
||||
|
||||
static object *
|
||||
|
@ -1052,18 +1050,14 @@ builtin_reduce(self, args)
|
|||
object *self;
|
||||
object *args;
|
||||
{
|
||||
object *seq, *func, *result;
|
||||
object *seq, *func, *result = NULL;
|
||||
sequence_methods *sqf;
|
||||
register int i;
|
||||
|
||||
if (getargs(args, "(OO)", &func, &seq))
|
||||
result = NULL;
|
||||
else {
|
||||
err_clear();
|
||||
if (!getargs(args, "(OOO)", &func, &seq, &result))
|
||||
return NULL;
|
||||
if (!newgetargs(args, "OO|O:reduce", &func, &seq, &result))
|
||||
return NULL;
|
||||
if (result != NULL)
|
||||
INCREF(result);
|
||||
}
|
||||
|
||||
if ((sqf = seq->ob_type->tp_as_sequence) == NULL) {
|
||||
err_setstr(TypeError,
|
||||
|
@ -1116,22 +1110,26 @@ Fail:
|
|||
}
|
||||
|
||||
static object *
|
||||
builtin_reload(self, v)
|
||||
builtin_reload(self, args)
|
||||
object *self;
|
||||
object *v;
|
||||
object *args;
|
||||
{
|
||||
object *v;
|
||||
|
||||
if (!newgetargs(args, "O:reload", &v))
|
||||
return NULL;
|
||||
return reload_module(v);
|
||||
}
|
||||
|
||||
static object *
|
||||
builtin_repr(self, v)
|
||||
builtin_repr(self, args)
|
||||
object *self;
|
||||
object *v;
|
||||
object *args;
|
||||
{
|
||||
if (v == NULL) {
|
||||
err_badarg();
|
||||
object *v;
|
||||
|
||||
if (!newgetargs(args, "O:repr", &v))
|
||||
return NULL;
|
||||
}
|
||||
return reprobject(v);
|
||||
}
|
||||
|
||||
|
@ -1145,13 +1143,10 @@ builtin_round(self, args)
|
|||
double x;
|
||||
double f;
|
||||
int ndigits = 0;
|
||||
int sign = 1;
|
||||
int i;
|
||||
if (!getargs(args, "d", &x)) {
|
||||
err_clear();
|
||||
if (!getargs(args, "(di)", &x, &ndigits))
|
||||
|
||||
if (!newgetargs(args, "d|i:round", &x, &ndigits))
|
||||
return NULL;
|
||||
}
|
||||
f = 1.0;
|
||||
for (i = ndigits; --i >= 0; )
|
||||
f = f*10.0;
|
||||
|
@ -1164,25 +1159,27 @@ builtin_round(self, args)
|
|||
}
|
||||
|
||||
static object *
|
||||
builtin_str(self, v)
|
||||
builtin_str(self, args)
|
||||
object *self;
|
||||
object *v;
|
||||
object *args;
|
||||
{
|
||||
if (v == NULL) {
|
||||
err_badarg();
|
||||
object *v;
|
||||
|
||||
if (!newgetargs(args, "O:str", &v))
|
||||
return NULL;
|
||||
}
|
||||
return strobject(v);
|
||||
}
|
||||
|
||||
static object *
|
||||
builtin_tuple(self, v)
|
||||
builtin_tuple(self, args)
|
||||
object *self;
|
||||
object *v;
|
||||
object *args;
|
||||
{
|
||||
object *v;
|
||||
sequence_methods *sqf;
|
||||
if (v == NULL)
|
||||
v = None; /* Force error later */
|
||||
|
||||
if (!newgetargs(args, "O:tuple", &v))
|
||||
return NULL;
|
||||
if (is_tupleobject(v)) {
|
||||
INCREF(v);
|
||||
return v;
|
||||
|
@ -1235,25 +1232,29 @@ builtin_tuple(self, v)
|
|||
}
|
||||
|
||||
static object *
|
||||
builtin_type(self, v)
|
||||
builtin_type(self, args)
|
||||
object *self;
|
||||
object *v;
|
||||
object *args;
|
||||
{
|
||||
if (v == NULL) {
|
||||
err_setstr(TypeError, "type() requires an argument");
|
||||
object *v;
|
||||
|
||||
if (!newgetargs(args, "O:type", &v))
|
||||
return NULL;
|
||||
}
|
||||
v = (object *)v->ob_type;
|
||||
INCREF(v);
|
||||
return v;
|
||||
}
|
||||
|
||||
static object *
|
||||
builtin_vars(self, v)
|
||||
builtin_vars(self, args)
|
||||
object *self;
|
||||
object *v;
|
||||
object *args;
|
||||
{
|
||||
object *v = NULL;
|
||||
object *d;
|
||||
|
||||
if (!newgetargs(args, "|O:vars", &v))
|
||||
return NULL;
|
||||
if (v == NULL) {
|
||||
d = getlocals();
|
||||
INCREF(d);
|
||||
|
@ -1270,48 +1271,49 @@ builtin_vars(self, v)
|
|||
}
|
||||
|
||||
static struct methodlist builtin_methods[] = {
|
||||
{"abs", builtin_abs},
|
||||
{"apply", builtin_apply},
|
||||
{"callable", builtin_callable},
|
||||
{"chr", builtin_chr},
|
||||
{"cmp", builtin_cmp},
|
||||
{"coerce", builtin_coerce},
|
||||
{"compile", builtin_compile},
|
||||
{"delattr", builtin_delattr},
|
||||
{"dir", builtin_dir},
|
||||
{"divmod", builtin_divmod},
|
||||
{"eval", builtin_eval},
|
||||
{"execfile", builtin_execfile},
|
||||
{"filter", builtin_filter},
|
||||
{"float", builtin_float},
|
||||
{"getattr", builtin_getattr},
|
||||
{"hasattr", builtin_hasattr},
|
||||
{"hash", builtin_hash},
|
||||
{"hex", builtin_hex},
|
||||
{"id", builtin_id},
|
||||
{"input", builtin_input},
|
||||
{"int", builtin_int},
|
||||
{"len", builtin_len},
|
||||
{"long", builtin_long},
|
||||
{"map", builtin_map},
|
||||
{"max", builtin_max},
|
||||
{"min", builtin_min},
|
||||
{"oct", builtin_oct},
|
||||
{"open", builtin_open},
|
||||
{"ord", builtin_ord},
|
||||
{"__import__", builtin___import__, 1},
|
||||
{"abs", builtin_abs, 1},
|
||||
{"apply", builtin_apply, 1},
|
||||
{"callable", builtin_callable, 1},
|
||||
{"chr", builtin_chr, 1},
|
||||
{"cmp", builtin_cmp, 1},
|
||||
{"coerce", builtin_coerce, 1},
|
||||
{"compile", builtin_compile, 1},
|
||||
{"delattr", builtin_delattr, 1},
|
||||
{"dir", builtin_dir, 1},
|
||||
{"divmod", builtin_divmod, 1},
|
||||
{"eval", builtin_eval, 1},
|
||||
{"execfile", builtin_execfile, 1},
|
||||
{"filter", builtin_filter, 1},
|
||||
{"float", builtin_float, 1},
|
||||
{"getattr", builtin_getattr, 1},
|
||||
{"hasattr", builtin_hasattr, 1},
|
||||
{"hash", builtin_hash, 1},
|
||||
{"hex", builtin_hex, 1},
|
||||
{"id", builtin_id, 1},
|
||||
{"input", builtin_input, 1},
|
||||
{"int", builtin_int, 1},
|
||||
{"len", builtin_len, 1},
|
||||
{"long", builtin_long, 1},
|
||||
{"map", builtin_map, 1},
|
||||
{"max", builtin_max, 1},
|
||||
{"min", builtin_min, 1},
|
||||
{"oct", builtin_oct, 1},
|
||||
{"open", builtin_open, 1},
|
||||
{"ord", builtin_ord, 1},
|
||||
{"pow", builtin_pow, 1},
|
||||
{"range", builtin_range},
|
||||
{"raw_input", builtin_raw_input},
|
||||
{"reduce", builtin_reduce},
|
||||
{"reload", builtin_reload},
|
||||
{"repr", builtin_repr},
|
||||
{"round", builtin_round},
|
||||
{"setattr", builtin_setattr},
|
||||
{"str", builtin_str},
|
||||
{"tuple", builtin_tuple},
|
||||
{"type", builtin_type},
|
||||
{"vars", builtin_vars},
|
||||
{"xrange", builtin_xrange},
|
||||
{"range", builtin_range, 1},
|
||||
{"raw_input", builtin_raw_input, 1},
|
||||
{"reduce", builtin_reduce, 1},
|
||||
{"reload", builtin_reload, 1},
|
||||
{"repr", builtin_repr, 1},
|
||||
{"round", builtin_round, 1},
|
||||
{"setattr", builtin_setattr, 1},
|
||||
{"str", builtin_str, 1},
|
||||
{"tuple", builtin_tuple, 1},
|
||||
{"type", builtin_type, 1},
|
||||
{"vars", builtin_vars, 1},
|
||||
{"xrange", builtin_xrange, 1},
|
||||
{NULL, NULL},
|
||||
};
|
||||
|
||||
|
@ -1324,6 +1326,13 @@ getbuiltin(name)
|
|||
return mappinglookup(builtin_dict, name);
|
||||
}
|
||||
|
||||
object *
|
||||
getbuiltins(name)
|
||||
char *name;
|
||||
{
|
||||
return dictlookup(builtin_dict, name);
|
||||
}
|
||||
|
||||
int
|
||||
setbuiltin(cname, value)
|
||||
char *cname;
|
||||
|
|
108
Python/ceval.c
108
Python/ceval.c
|
@ -43,11 +43,11 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
extern int suppress_print; /* Declared in pythonrun.c, set in pythonmain.c */
|
||||
|
||||
/* Turn this on if your compiler chokes on the big switch: */
|
||||
/* #define CASE_TOO_BIG 1 /**/
|
||||
/* #define CASE_TOO_BIG 1 */
|
||||
|
||||
/* Turn this on if you want to debug the interpreter: */
|
||||
/* (This can be on even if NDEBUG is defined) */
|
||||
/* #define DEBUG 1 /**/
|
||||
/* #define DEBUG 1 */
|
||||
|
||||
#if defined(DEBUG) || !defined(NDEBUG)
|
||||
/* For debugging the interpreter: */
|
||||
|
@ -1254,8 +1254,8 @@ eval_code(co, globals, locals, owner, arg)
|
|||
DECREF(v);
|
||||
break;
|
||||
}
|
||||
XDECREF(w);
|
||||
GETLISTITEM(fastlocals, oparg) = v;
|
||||
XDECREF(w);
|
||||
break;
|
||||
|
||||
case DELETE_FAST:
|
||||
|
@ -1270,8 +1270,8 @@ eval_code(co, globals, locals, owner, arg)
|
|||
(object *)NULL);
|
||||
break;
|
||||
}
|
||||
DECREF(x);
|
||||
GETLISTITEM(fastlocals, oparg) = NULL;
|
||||
DECREF(x);
|
||||
break;
|
||||
|
||||
case BUILD_TUPLE:
|
||||
|
@ -1323,10 +1323,22 @@ eval_code(co, globals, locals, owner, arg)
|
|||
break;
|
||||
|
||||
case IMPORT_NAME:
|
||||
name = GETNAME(oparg);
|
||||
x = import_module(name);
|
||||
XINCREF(x);
|
||||
PUSH(x);
|
||||
w = GETNAMEV(oparg);
|
||||
x = getbuiltins("__import__");
|
||||
if (x == NULL) {
|
||||
err_setstr(ImportError,
|
||||
"__import__ not found");
|
||||
break;
|
||||
}
|
||||
w = mkvalue("(O)", w);
|
||||
if (w == NULL) {
|
||||
x = NULL;
|
||||
break;
|
||||
}
|
||||
x = call_object(x, w);
|
||||
DECREF(w);
|
||||
if (x)
|
||||
PUSH(x);
|
||||
break;
|
||||
|
||||
case IMPORT_FROM:
|
||||
|
@ -1408,7 +1420,7 @@ eval_code(co, globals, locals, owner, arg)
|
|||
case SET_LINENO:
|
||||
#ifdef LLTRACE
|
||||
if (lltrace)
|
||||
printf("--- Line %d ---\n", oparg);
|
||||
printf("--- %s:%d \n", filename, oparg);
|
||||
#endif
|
||||
f->f_lineno = oparg;
|
||||
if (f->f_trace != NULL) {
|
||||
|
@ -1497,24 +1509,23 @@ eval_code(co, globals, locals, owner, arg)
|
|||
b->b_type == SETUP_EXCEPT &&
|
||||
why == WHY_EXCEPTION) {
|
||||
if (why == WHY_EXCEPTION) {
|
||||
object *exc, *val;
|
||||
err_get(&exc, &val);
|
||||
object *exc, *val, *tb;
|
||||
err_fetch(&exc, &val, &tb);
|
||||
if (val == NULL) {
|
||||
val = None;
|
||||
INCREF(val);
|
||||
}
|
||||
v = tb_fetch();
|
||||
/* Make the raw exception data
|
||||
available to the handler,
|
||||
so a program can emulate the
|
||||
Python main loop. Don't do
|
||||
this for 'finally'. */
|
||||
if (b->b_type == SETUP_EXCEPT) {
|
||||
sysset("exc_traceback", v);
|
||||
sysset("exc_traceback", tb);
|
||||
sysset("exc_value", val);
|
||||
sysset("exc_type", exc);
|
||||
}
|
||||
PUSH(v);
|
||||
PUSH(tb);
|
||||
PUSH(val);
|
||||
PUSH(exc);
|
||||
}
|
||||
|
@ -1598,26 +1609,25 @@ call_exc_trace(p_trace, p_newtrace, f)
|
|||
{
|
||||
object *type, *value, *traceback, *arg;
|
||||
int err;
|
||||
err_get(&type, &value);
|
||||
err_fetch(&type, &value, &traceback);
|
||||
if (value == NULL) {
|
||||
value = None;
|
||||
INCREF(value);
|
||||
}
|
||||
traceback = tb_fetch();
|
||||
arg = newtupleobject(3);
|
||||
if (arg == NULL)
|
||||
goto cleanup;
|
||||
settupleitem(arg, 0, type);
|
||||
settupleitem(arg, 1, value);
|
||||
settupleitem(arg, 2, traceback);
|
||||
err = call_trace(p_trace, p_newtrace, f, "exception", arg);
|
||||
if (!err) {
|
||||
cleanup:
|
||||
/* Restore original exception */
|
||||
err_setval(type, value);
|
||||
tb_store(traceback);
|
||||
arg = mkvalue("(OOO)", type, value, traceback);
|
||||
if (arg == NULL) {
|
||||
err_restore(type, value, traceback);
|
||||
return;
|
||||
}
|
||||
err = call_trace(p_trace, p_newtrace, f, "exception", arg);
|
||||
DECREF(arg);
|
||||
if (err == 0)
|
||||
err_restore(type, value, traceback);
|
||||
else {
|
||||
XDECREF(type);
|
||||
XDECREF(value);
|
||||
XDECREF(traceback);
|
||||
}
|
||||
XDECREF(arg);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -1723,18 +1733,6 @@ getframe()
|
|||
return (object *)current_frame;
|
||||
}
|
||||
|
||||
void
|
||||
printtraceback(f)
|
||||
object *f;
|
||||
{
|
||||
object *v = tb_fetch();
|
||||
if (v != NULL) {
|
||||
tb_print(v, f);
|
||||
DECREF(v);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
flushline()
|
||||
{
|
||||
|
@ -1818,7 +1816,7 @@ static object *
|
|||
lshift(v, w)
|
||||
object *v, *w;
|
||||
{
|
||||
BINOP("__lshift__", "__rshift__");
|
||||
BINOP("__lshift__", "__rlshift__");
|
||||
if (v->ob_type->tp_as_number != NULL) {
|
||||
object *x;
|
||||
object * (*f) FPROTO((object *, object *));
|
||||
|
@ -1962,6 +1960,9 @@ static object *
|
|||
rem(v, w)
|
||||
object *v, *w;
|
||||
{
|
||||
if (is_stringobject(v)) {
|
||||
return formatstring(v, w);
|
||||
}
|
||||
BINOP("__mod__", "__rmod__");
|
||||
if (v->ob_type->tp_as_number != NULL) {
|
||||
object *x;
|
||||
|
@ -1972,9 +1973,6 @@ rem(v, w)
|
|||
DECREF(w);
|
||||
return x;
|
||||
}
|
||||
if (is_stringobject(v)) {
|
||||
return formatstring(v, w);
|
||||
}
|
||||
err_setstr(TypeError, "bad operand type(s) for %");
|
||||
return NULL;
|
||||
}
|
||||
|
@ -2492,6 +2490,10 @@ import_from(locals, v, name)
|
|||
object *name;
|
||||
{
|
||||
object *w, *x;
|
||||
if (!is_moduleobject(v)) {
|
||||
err_setstr(TypeError, "import-from require module object");
|
||||
return -1;
|
||||
}
|
||||
w = getmoduledict(v);
|
||||
if (getstringvalue(name)[0] == '*') {
|
||||
int pos, err;
|
||||
|
@ -2542,6 +2544,22 @@ build_class(methods, bases, name)
|
|||
err_setstr(SystemError, "build_class with non-tuple bases");
|
||||
return NULL;
|
||||
}
|
||||
if (gettuplesize(bases) > 0) {
|
||||
object *base;
|
||||
base = gettupleitem(bases, 0);
|
||||
/* Call the base's *type*, if it is callable.
|
||||
This code is a hook for Donald Beaudry's type extensions.
|
||||
In unexended Python it will never be triggered since its
|
||||
types are not callable. */
|
||||
if (base->ob_type->ob_type->tp_call) {
|
||||
object *args;
|
||||
object *class;
|
||||
args = mkvalue("(OOO)", name, bases, methods);
|
||||
class = call_object((object *)base->ob_type, args);
|
||||
DECREF(args);
|
||||
return class;
|
||||
}
|
||||
}
|
||||
if (!is_dictobject(methods)) {
|
||||
err_setstr(SystemError, "build_class with non-dictionary");
|
||||
return NULL;
|
||||
|
|
|
@ -336,7 +336,7 @@ com_addbyte(c, byte)
|
|||
if (byte < 0 || byte > 255) {
|
||||
/*
|
||||
fprintf(stderr, "XXX compiling bad byte: %d\n", byte);
|
||||
abort();
|
||||
fatal("com_addbyte: byte out of range");
|
||||
*/
|
||||
err_setstr(SystemError, "com_addbyte: byte out of range");
|
||||
c->c_errors++;
|
||||
|
@ -2379,7 +2379,7 @@ optimize(c)
|
|||
int oparg;
|
||||
object *name;
|
||||
int fast_reserved;
|
||||
object *error_type, *error_value;
|
||||
object *error_type, *error_value, *error_traceback;
|
||||
|
||||
#define NEXTOP() (*next_instr++)
|
||||
#define NEXTARG() (next_instr += 2, (next_instr[-1]<<8) + next_instr[-2])
|
||||
|
@ -2393,7 +2393,7 @@ optimize(c)
|
|||
}
|
||||
nlocals = 0;
|
||||
|
||||
err_get(&error_type, &error_value);
|
||||
err_fetch(&error_type, &error_value, &error_traceback);
|
||||
|
||||
next_instr = (unsigned char *) getstringvalue(c->c_code);
|
||||
for (;;) {
|
||||
|
@ -2493,7 +2493,7 @@ optimize(c)
|
|||
}
|
||||
|
||||
end:
|
||||
err_setval(error_type, error_value);
|
||||
err_restore(error_type, error_value, error_traceback);
|
||||
err:
|
||||
DECREF(locals);
|
||||
}
|
||||
|
|
|
@ -60,6 +60,7 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
|
||||
#include <errno.h>
|
||||
|
||||
#ifndef NT
|
||||
#ifdef macintosh
|
||||
/*
|
||||
** For the mac, there's a function macstrerror in macosmodule.c. We can't
|
||||
|
@ -68,27 +69,37 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
*/
|
||||
#define strerror macstrerror
|
||||
#include "macdefs.h" /* For CW to find EINTR */
|
||||
#endif /* macintosh */
|
||||
|
||||
#endif /* !macintosh */
|
||||
extern char *strerror PROTO((int));
|
||||
#endif /* !NT */
|
||||
|
||||
/* Last exception stored by err_setval() */
|
||||
|
||||
static object *last_exception;
|
||||
static object *last_exc_val;
|
||||
|
||||
void
|
||||
err_restore(exception, value, traceback)
|
||||
object *exception;
|
||||
object *value;
|
||||
object *traceback;
|
||||
{
|
||||
err_clear();
|
||||
|
||||
last_exception = exception;
|
||||
last_exc_val = value;
|
||||
(void) tb_store(traceback);
|
||||
XDECREF(traceback);
|
||||
}
|
||||
|
||||
void
|
||||
err_setval(exception, value)
|
||||
object *exception;
|
||||
object *value;
|
||||
{
|
||||
err_clear();
|
||||
|
||||
XINCREF(exception);
|
||||
last_exception = exception;
|
||||
|
||||
XINCREF(value);
|
||||
last_exc_val = value;
|
||||
err_restore(exception, value, (object *)NULL);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -116,14 +127,16 @@ err_occurred()
|
|||
}
|
||||
|
||||
void
|
||||
err_get(p_exc, p_val)
|
||||
err_fetch(p_exc, p_val, p_tb)
|
||||
object **p_exc;
|
||||
object **p_val;
|
||||
object **p_tb;
|
||||
{
|
||||
*p_exc = last_exception;
|
||||
last_exception = NULL;
|
||||
*p_val = last_exc_val;
|
||||
last_exc_val = NULL;
|
||||
*p_tb = tb_fetch();
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -38,7 +38,7 @@ int vgetargs PROTO((object *, char *, va_list));
|
|||
|
||||
|
||||
/* Forward */
|
||||
static int vgetargs1 PROTO((object *, char *, va_list, int));
|
||||
static int vgetargs1 PROTO((object *, char *, va_list *, int));
|
||||
static void seterror PROTO((int, char *, int *, char *, char *));
|
||||
static char *convertitem PROTO((object *, char **, va_list *, int *, char *));
|
||||
static char *converttuple PROTO((object *, char **, va_list *,
|
||||
|
@ -68,7 +68,7 @@ int getargs(va_alist) va_dcl
|
|||
args = va_arg(va, object *);
|
||||
format = va_arg(va, char *);
|
||||
#endif
|
||||
retval = vgetargs1(args, format, va, 1);
|
||||
retval = vgetargs1(args, format, &va, 1);
|
||||
va_end(va);
|
||||
return retval;
|
||||
}
|
||||
|
@ -95,7 +95,7 @@ int newgetargs(va_alist) va_dcl
|
|||
args = va_arg(va, object *);
|
||||
format = va_arg(va, char *);
|
||||
#endif
|
||||
retval = vgetargs1(args, format, va, 0);
|
||||
retval = vgetargs1(args, format, &va, 0);
|
||||
va_end(va);
|
||||
return retval;
|
||||
}
|
||||
|
@ -107,15 +107,23 @@ vgetargs(args, format, va)
|
|||
char *format;
|
||||
va_list va;
|
||||
{
|
||||
return vgetargs1(args, format, va, 0);
|
||||
va_list lva;
|
||||
|
||||
#ifdef VA_LIST_IS_ARRAY
|
||||
memcpy(lva, va, sizeof(va_list));
|
||||
#else
|
||||
lva = va;
|
||||
#endif
|
||||
|
||||
return vgetargs1(args, format, &lva, 0);
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
vgetargs1(args, format, va, compat)
|
||||
vgetargs1(args, format, p_va, compat)
|
||||
object *args;
|
||||
char *format;
|
||||
va_list va;
|
||||
va_list *p_va;
|
||||
int compat;
|
||||
{
|
||||
char msgbuf[256];
|
||||
|
@ -186,7 +194,7 @@ vgetargs1(args, format, va, compat)
|
|||
err_setstr(TypeError, msgbuf);
|
||||
return 0;
|
||||
}
|
||||
msg = convertitem(args, &format, &va, levels, msgbuf);
|
||||
msg = convertitem(args, &format, p_va, levels, msgbuf);
|
||||
if (msg == NULL)
|
||||
return 1;
|
||||
seterror(levels[0], msg, levels+1, fname, message);
|
||||
|
@ -226,7 +234,7 @@ vgetargs1(args, format, va, compat)
|
|||
for (i = 0; i < len; i++) {
|
||||
if (*format == '|')
|
||||
format++;
|
||||
msg = convertitem(gettupleitem(args, i), &format, &va,
|
||||
msg = convertitem(gettupleitem(args, i), &format, p_va,
|
||||
levels, msgbuf);
|
||||
if (msg) {
|
||||
seterror(i+1, msg, levels, fname, message);
|
||||
|
|
1433
Python/import.c
1433
Python/import.c
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,381 @@
|
|||
/***********************************************************
|
||||
Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
|
||||
Amsterdam, The Netherlands.
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the names of Stichting Mathematisch
|
||||
Centrum or CWI not be used in advertising or publicity pertaining to
|
||||
distribution of the software without specific, written prior permission.
|
||||
|
||||
STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
|
||||
THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
|
||||
FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
/* Support for dynamic loading of extension modules */
|
||||
/* If no dynamic linking is supported, this file still generates some code! */
|
||||
|
||||
#include "allobjects.h"
|
||||
#include "osdefs.h"
|
||||
#include "importdl.h"
|
||||
|
||||
extern int verbose; /* Defined in pythonrun.c */
|
||||
|
||||
/* Explanation of some of the the various #defines used by dynamic linking...
|
||||
|
||||
symbol -- defined for:
|
||||
|
||||
DYNAMIC_LINK -- any kind of dynamic linking
|
||||
USE_RLD -- NeXT dynamic linking
|
||||
USE_DL -- Jack's dl for IRIX 4 or GNU dld with emulation for Jack's dl
|
||||
USE_SHLIB -- SunOS or IRIX 5 (SVR4?) shared libraries
|
||||
_AIX -- AIX style dynamic linking
|
||||
NT -- NT style dynamic linking (using DLLs)
|
||||
_DL_FUNCPTR_DEFINED -- if the typedef dl_funcptr has been defined
|
||||
WITH_MAC_DL -- Mac dynamic linking (highly experimental)
|
||||
SHORT_EXT -- short extension for dynamic module, e.g. ".so"
|
||||
LONG_EXT -- long extension, e.g. "module.so"
|
||||
hpux -- HP-UX Dynamic Linking - defined by the compiler
|
||||
|
||||
(The other WITH_* symbols are used only once, to set the
|
||||
appropriate symbols.)
|
||||
*/
|
||||
|
||||
/* Configure dynamic linking */
|
||||
|
||||
#ifdef hpux
|
||||
#define DYNAMIC_LINK
|
||||
#include <errno.h>
|
||||
typedef void (*dl_funcptr)();
|
||||
#define _DL_FUNCPTR_DEFINED 1
|
||||
#define SHORT_EXT ".sl"
|
||||
#define LONG_EXT "module.sl"
|
||||
#endif
|
||||
|
||||
#ifdef NT
|
||||
#define DYNAMIC_LINK
|
||||
#include <windows.h>
|
||||
typedef FARPROC dl_funcptr;
|
||||
#define _DL_FUNCPTR_DEFINED
|
||||
#define SHORT_EXT ".dll"
|
||||
#define LONG_EXT "module.dll"
|
||||
#endif
|
||||
|
||||
#if defined(NeXT) || defined(WITH_RLD)
|
||||
#define DYNAMIC_LINK
|
||||
#define USE_RLD
|
||||
#endif
|
||||
|
||||
#ifdef WITH_SGI_DL
|
||||
#define DYNAMIC_LINK
|
||||
#define USE_DL
|
||||
#endif
|
||||
|
||||
#ifdef WITH_DL_DLD
|
||||
#define DYNAMIC_LINK
|
||||
#define USE_DL
|
||||
#endif
|
||||
|
||||
#ifdef WITH_MAC_DL
|
||||
#define DYNAMIC_LINK
|
||||
#endif
|
||||
|
||||
#if !defined(DYNAMIC_LINK) && defined(HAVE_DLFCN_H) && defined(HAVE_DLOPEN)
|
||||
#define DYNAMIC_LINK
|
||||
#define USE_SHLIB
|
||||
#endif
|
||||
|
||||
#ifdef _AIX
|
||||
#define DYNAMIC_LINK
|
||||
#include <sys/ldr.h>
|
||||
typedef void (*dl_funcptr)();
|
||||
#define _DL_FUNCPTR_DEFINED
|
||||
static void aix_loaderror(char *name);
|
||||
#endif
|
||||
|
||||
#ifdef DYNAMIC_LINK
|
||||
|
||||
#ifdef USE_SHLIB
|
||||
#include <dlfcn.h>
|
||||
#ifndef _DL_FUNCPTR_DEFINED
|
||||
typedef void (*dl_funcptr)();
|
||||
#endif
|
||||
#ifndef RTLD_LAZY
|
||||
#define RTLD_LAZY 1
|
||||
#endif
|
||||
#define SHORT_EXT ".so"
|
||||
#define LONG_EXT "module.so"
|
||||
#endif /* USE_SHLIB */
|
||||
|
||||
#if defined(USE_DL) || defined(hpux)
|
||||
#include "dl.h"
|
||||
#endif
|
||||
|
||||
#ifdef WITH_MAC_DL
|
||||
#include "dynamic_load.h"
|
||||
#endif
|
||||
|
||||
#ifdef USE_RLD
|
||||
#include <mach-o/rld.h>
|
||||
#define FUNCNAME_PATTERN "_init%.200s"
|
||||
#ifndef _DL_FUNCPTR_DEFINED
|
||||
typedef void (*dl_funcptr)();
|
||||
#endif
|
||||
#endif /* USE_RLD */
|
||||
|
||||
extern char *getprogramname();
|
||||
|
||||
#ifndef FUNCNAME_PATTERN
|
||||
#if defined(__hp9000s300)
|
||||
#define FUNCNAME_PATTERN "_init%.200s"
|
||||
#else
|
||||
#define FUNCNAME_PATTERN "init%.200s"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(SHORT_EXT) && !defined(LONG_EXT)
|
||||
#define SHORT_EXT ".o"
|
||||
#define LONG_EXT "module.o"
|
||||
#endif /* !SHORT_EXT && !LONG_EXT */
|
||||
|
||||
#endif /* DYNAMIC_LINK */
|
||||
|
||||
/* Max length of module suffix searched for -- accommodates "module.so" */
|
||||
#ifndef MAXSUFFIXSIZE
|
||||
#define MAXSUFFIXSIZE 10
|
||||
#endif
|
||||
|
||||
/* Pass it on to import.c */
|
||||
int import_maxsuffixsize = MAXSUFFIXSIZE;
|
||||
|
||||
struct filedescr import_filetab[] = {
|
||||
#ifdef SHORT_EXT
|
||||
{SHORT_EXT, "rb", C_EXTENSION},
|
||||
#endif /* !SHORT_EXT */
|
||||
#ifdef LONG_EXT
|
||||
{LONG_EXT, "rb", C_EXTENSION},
|
||||
#endif /* !LONG_EXT */
|
||||
{".py", "r", PY_SOURCE},
|
||||
{".pyc", "rb", PY_COMPILED},
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
object *
|
||||
load_dynamic_module(name, pathname)
|
||||
char *name;
|
||||
char *pathname;
|
||||
{
|
||||
#ifndef DYNAMIC_LINK
|
||||
err_setstr(ImportError, "dynamically linked modules not supported");
|
||||
return NULL;
|
||||
#else
|
||||
object *m;
|
||||
char funcname[258];
|
||||
dl_funcptr p = NULL;
|
||||
if (m != NULL) {
|
||||
err_setstr(ImportError,
|
||||
"cannot reload dynamically loaded module");
|
||||
return NULL;
|
||||
}
|
||||
sprintf(funcname, FUNCNAME_PATTERN, name);
|
||||
#ifdef WITH_MAC_DL
|
||||
{
|
||||
object *v = dynamic_load(pathname);
|
||||
if (v == NULL)
|
||||
return NULL;
|
||||
}
|
||||
#else /* !WITH_MAC_DL */
|
||||
#ifdef USE_SHLIB
|
||||
{
|
||||
#ifdef RTLD_NOW
|
||||
/* RTLD_NOW: resolve externals now
|
||||
(i.e. core dump now if some are missing) */
|
||||
void *handle = dlopen(pathname, RTLD_NOW);
|
||||
#else
|
||||
void *handle;
|
||||
if (verbose)
|
||||
printf("dlopen(\"%s\", %d);\n", pathname, RTLD_LAZY);
|
||||
handle = dlopen(pathname, RTLD_LAZY);
|
||||
#endif /* RTLD_NOW */
|
||||
if (handle == NULL) {
|
||||
err_setstr(ImportError, dlerror());
|
||||
return NULL;
|
||||
}
|
||||
p = (dl_funcptr) dlsym(handle, funcname);
|
||||
}
|
||||
#endif /* USE_SHLIB */
|
||||
#ifdef _AIX
|
||||
p = (dl_funcptr) load(pathname, 1, 0);
|
||||
if (p == NULL) {
|
||||
aix_loaderror(pathname);
|
||||
return NULL;
|
||||
}
|
||||
#endif /* _AIX */
|
||||
#ifdef NT
|
||||
{
|
||||
HINSTANCE hDLL;
|
||||
hDLL = LoadLibrary(pathname);
|
||||
if (hDLL==NULL){
|
||||
char errBuf[64];
|
||||
sprintf(errBuf, "DLL load failed with error code %d",
|
||||
GetLastError());
|
||||
err_setstr(ImportError, errBuf);
|
||||
return NULL;
|
||||
}
|
||||
p = GetProcAddress(hDLL, funcname);
|
||||
}
|
||||
#endif /* NT */
|
||||
#ifdef USE_DL
|
||||
p = dl_loadmod(getprogramname(), pathname, funcname);
|
||||
#endif /* USE_DL */
|
||||
#ifdef USE_RLD
|
||||
{
|
||||
NXStream *errorStream;
|
||||
struct mach_header *new_header;
|
||||
const char *filenames[2];
|
||||
long ret;
|
||||
unsigned long ptr;
|
||||
|
||||
errorStream = NXOpenMemory(NULL, 0, NX_WRITEONLY);
|
||||
filenames[0] = pathname;
|
||||
filenames[1] = NULL;
|
||||
ret = rld_load(errorStream, &new_header,
|
||||
filenames, NULL);
|
||||
|
||||
/* extract the error messages for the exception */
|
||||
if(!ret) {
|
||||
char *streamBuf;
|
||||
int len, maxLen;
|
||||
|
||||
NXPutc(errorStream, (char)0);
|
||||
|
||||
NXGetMemoryBuffer(errorStream,
|
||||
&streamBuf, &len, &maxLen);
|
||||
err_setstr(ImportError, streamBuf);
|
||||
}
|
||||
|
||||
if(ret && rld_lookup(errorStream, funcname, &ptr))
|
||||
p = (dl_funcptr) ptr;
|
||||
|
||||
NXCloseMemory(errorStream, NX_FREEBUFFER);
|
||||
|
||||
if(!ret)
|
||||
return NULL;
|
||||
}
|
||||
#endif /* USE_RLD */
|
||||
#ifdef hpux
|
||||
{
|
||||
shl_t lib;
|
||||
int flags;
|
||||
|
||||
flags = BIND_DEFERRED;
|
||||
if (verbose)
|
||||
{
|
||||
flags = BIND_IMMEDIATE | BIND_NONFATAL | BIND_VERBOSE;
|
||||
printf("shl_load %s\n",pathname);
|
||||
}
|
||||
lib = shl_load(pathname, flags, 0);
|
||||
if (lib == NULL)
|
||||
{
|
||||
char buf[256];
|
||||
if (verbose)
|
||||
perror(pathname);
|
||||
sprintf(buf, "Failed to load %.200s", pathname);
|
||||
err_setstr(ImportError, buf);
|
||||
return NULL;
|
||||
}
|
||||
if (verbose)
|
||||
printf("shl_findsym %s\n", funcname);
|
||||
shl_findsym(&lib, funcname, TYPE_UNDEFINED, (void *) &p);
|
||||
if (p == NULL && verbose)
|
||||
perror(funcname);
|
||||
}
|
||||
#endif /* hpux */
|
||||
if (p == NULL) {
|
||||
err_setstr(ImportError,
|
||||
"dynamic module does not define init function");
|
||||
return NULL;
|
||||
}
|
||||
(*p)();
|
||||
|
||||
#endif /* !WITH_MAC_DL */
|
||||
m = dictlookup(import_modules, name);
|
||||
if (m == NULL) {
|
||||
if (err_occurred() == NULL)
|
||||
err_setstr(SystemError,
|
||||
"dynamic module not initialized properly");
|
||||
return NULL;
|
||||
}
|
||||
if (verbose)
|
||||
fprintf(stderr,
|
||||
"import %s # dynamically loaded from %s\n",
|
||||
name, pathname);
|
||||
INCREF(m);
|
||||
return m;
|
||||
#endif /* DYNAMIC_LINK */
|
||||
}
|
||||
|
||||
|
||||
#ifdef _AIX
|
||||
|
||||
#include <ctype.h> /* for isdigit() */
|
||||
#include <errno.h> /* for global errno */
|
||||
#include <string.h> /* for strerror() */
|
||||
|
||||
void aix_loaderror(char *pathname)
|
||||
{
|
||||
|
||||
char *message[8], errbuf[1024];
|
||||
int i,j;
|
||||
|
||||
struct errtab {
|
||||
int errno;
|
||||
char *errstr;
|
||||
} load_errtab[] = {
|
||||
{L_ERROR_TOOMANY, "to many errors, rest skipped."},
|
||||
{L_ERROR_NOLIB, "can't load library:"},
|
||||
{L_ERROR_UNDEF, "can't find symbol in library:"},
|
||||
{L_ERROR_RLDBAD,
|
||||
"RLD index out of range or bad relocation type:"},
|
||||
{L_ERROR_FORMAT, "not a valid, executable xcoff file:"},
|
||||
{L_ERROR_MEMBER,
|
||||
"file not an archive or does not contain requested member:"},
|
||||
{L_ERROR_TYPE, "symbol table mismatch:"},
|
||||
{L_ERROR_ALIGN, "text allignment in file is wrong."},
|
||||
{L_ERROR_SYSTEM, "System error:"},
|
||||
{L_ERROR_ERRNO, NULL}
|
||||
};
|
||||
|
||||
#define LOAD_ERRTAB_LEN (sizeof(load_errtab)/sizeof(load_errtab[0]))
|
||||
#define ERRBUF_APPEND(s) strncat(errbuf, s, sizeof(errbuf)-strlen(errbuf)-1)
|
||||
|
||||
sprintf(errbuf, " from module %.200s ", pathname);
|
||||
|
||||
if (!loadquery(1, &message[0], sizeof(message)))
|
||||
ERRBUF_APPEND(strerror(errno));
|
||||
for(i = 0; message[i] && *message[i]; i++) {
|
||||
int nerr = atoi(message[i]);
|
||||
for (j=0; j<LOAD_ERRTAB_LEN ; j++) {
|
||||
if (nerr == load_errtab[i].errno && load_errtab[i].errstr)
|
||||
ERRBUF_APPEND(load_errtab[i].errstr);
|
||||
}
|
||||
while (isdigit(*message[i])) message[i]++ ;
|
||||
ERRBUF_APPEND(message[i]);
|
||||
ERRBUF_APPEND("\n");
|
||||
}
|
||||
errbuf[strlen(errbuf)-1] = '\0'; /* trim off last newline */
|
||||
err_setstr(ImportError, errbuf);
|
||||
return;
|
||||
}
|
||||
|
||||
#endif /* _AIX */
|
|
@ -0,0 +1,39 @@
|
|||
/***********************************************************
|
||||
Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
|
||||
Amsterdam, The Netherlands.
|
||||
|
||||
All Rights Reserved
|
||||
|
||||
Permission to use, copy, modify, and distribute this software and its
|
||||
documentation for any purpose and without fee is hereby granted,
|
||||
provided that the above copyright notice appear in all copies and that
|
||||
both that copyright notice and this permission notice appear in
|
||||
supporting documentation, and that the names of Stichting Mathematisch
|
||||
Centrum or CWI not be used in advertising or publicity pertaining to
|
||||
distribution of the software without specific, written prior permission.
|
||||
|
||||
STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
|
||||
THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
|
||||
FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
||||
OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
******************************************************************/
|
||||
|
||||
/* Definitions for dynamic loading of extension modules */
|
||||
|
||||
enum filetype {SEARCH_ERROR, PY_SOURCE, PY_COMPILED, C_EXTENSION};
|
||||
|
||||
extern struct filedescr {
|
||||
char *suffix;
|
||||
char *mode;
|
||||
enum filetype type;
|
||||
} import_filetab[];
|
||||
|
||||
extern object *import_modules;
|
||||
|
||||
extern object *load_dynamic_module PROTO((char *name, char *pathname));
|
||||
|
||||
extern int import_maxsuffixsize;
|
|
@ -406,6 +406,10 @@ rd_object(fp)
|
|||
FILE *fp;
|
||||
{
|
||||
RFILE rf;
|
||||
if (err_occurred()) {
|
||||
fprintf(stderr, "XXX rd_object called with exception set\n");
|
||||
return NULL;
|
||||
}
|
||||
rf.fp = fp;
|
||||
return r_object(&rf);
|
||||
}
|
||||
|
@ -416,6 +420,10 @@ rds_object(str, len)
|
|||
int len;
|
||||
{
|
||||
RFILE rf;
|
||||
if (err_occurred()) {
|
||||
fprintf(stderr, "XXX rds_object called with exception set\n");
|
||||
return NULL;
|
||||
}
|
||||
rf.fp = NULL;
|
||||
rf.str = NULL;
|
||||
rf.ptr = str;
|
||||
|
|
|
@ -29,7 +29,7 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|||
|
||||
#ifdef MPW /* MPW pushes 'extended' for float and double types with varargs */
|
||||
typedef extended va_double;
|
||||
#else
|
||||
#else
|
||||
typedef double va_double;
|
||||
#endif
|
||||
|
||||
|
@ -42,7 +42,7 @@ object *
|
|||
initmodule2(name, methods, passthrough)
|
||||
char *name;
|
||||
struct methodlist *methods;
|
||||
object *passthrough;
|
||||
object *passthrough;
|
||||
{
|
||||
object *m, *d, *v;
|
||||
struct methodlist *ml;
|
||||
|
@ -58,7 +58,7 @@ initmodule2(name, methods, passthrough)
|
|||
fatal("out of mem for method name");
|
||||
sprintf(namebuf, "%s.%s", name, ml->ml_name);
|
||||
v = newmethodobject(namebuf, ml->ml_meth,
|
||||
(object *)passthrough, ml->ml_varargs);
|
||||
(object *)passthrough, ml->ml_varargs);
|
||||
/* XXX The malloc'ed memory in namebuf is never freed */
|
||||
if (v == NULL || dictinsert(d, ml->ml_name, v) != 0) {
|
||||
fprintf(stderr, "initializing module: %s\n", name);
|
||||
|
@ -90,20 +90,33 @@ static int countformat(format, endchar)
|
|||
int count = 0;
|
||||
int level = 0;
|
||||
while (level > 0 || *format != endchar) {
|
||||
if (*format == '\0') {
|
||||
switch (*format) {
|
||||
case '\0':
|
||||
/* Premature end */
|
||||
err_setstr(SystemError, "unmatched paren in format");
|
||||
return -1;
|
||||
}
|
||||
else if (*format == '(') {
|
||||
case '(':
|
||||
case '[':
|
||||
case '{':
|
||||
if (level == 0)
|
||||
count++;
|
||||
level++;
|
||||
}
|
||||
else if (*format == ')')
|
||||
break;
|
||||
case ')':
|
||||
case ']':
|
||||
case '}':
|
||||
level--;
|
||||
else if (level == 0 && *format != '#')
|
||||
count++;
|
||||
break;
|
||||
case '#':
|
||||
case ',':
|
||||
case ':':
|
||||
case ' ':
|
||||
case '\t':
|
||||
break;
|
||||
default:
|
||||
if (level == 0)
|
||||
count++;
|
||||
}
|
||||
format++;
|
||||
}
|
||||
return count;
|
||||
|
@ -114,8 +127,85 @@ static int countformat(format, endchar)
|
|||
/* After an original idea and first implementation by Steven Miale */
|
||||
|
||||
static object *do_mktuple PROTO((char**, va_list *, int, int));
|
||||
static object *do_mklist PROTO((char**, va_list *, int, int));
|
||||
static object *do_mkdict PROTO((char**, va_list *, int, int));
|
||||
static object *do_mkvalue PROTO((char**, va_list *));
|
||||
|
||||
|
||||
static object *
|
||||
do_mkdict(p_format, p_va, endchar, n)
|
||||
char **p_format;
|
||||
va_list *p_va;
|
||||
int endchar;
|
||||
int n;
|
||||
{
|
||||
object *d;
|
||||
int i;
|
||||
if (n < 0)
|
||||
return NULL;
|
||||
if ((d = newdictobject()) == NULL)
|
||||
return NULL;
|
||||
for (i = 0; i < n; i+= 2) {
|
||||
object *k, *v;
|
||||
k = do_mkvalue(p_format, p_va);
|
||||
if (k == NULL) {
|
||||
DECREF(d);
|
||||
return NULL;
|
||||
}
|
||||
v = do_mkvalue(p_format, p_va);
|
||||
if (v == NULL) {
|
||||
DECREF(k);
|
||||
DECREF(d);
|
||||
return NULL;
|
||||
}
|
||||
if (dict2insert(d, k, v) < 0) {
|
||||
DECREF(k);
|
||||
DECREF(v);
|
||||
DECREF(d);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if (d != NULL && **p_format != endchar) {
|
||||
DECREF(d);
|
||||
d = NULL;
|
||||
err_setstr(SystemError, "Unmatched paren in format");
|
||||
}
|
||||
else if (endchar)
|
||||
++*p_format;
|
||||
return d;
|
||||
}
|
||||
|
||||
static object *
|
||||
do_mklist(p_format, p_va, endchar, n)
|
||||
char **p_format;
|
||||
va_list *p_va;
|
||||
int endchar;
|
||||
int n;
|
||||
{
|
||||
object *v;
|
||||
int i;
|
||||
if (n < 0)
|
||||
return NULL;
|
||||
if ((v = newlistobject(n)) == NULL)
|
||||
return NULL;
|
||||
for (i = 0; i < n; i++) {
|
||||
object *w = do_mkvalue(p_format, p_va);
|
||||
if (w == NULL) {
|
||||
DECREF(v);
|
||||
return NULL;
|
||||
}
|
||||
setlistitem(v, i, w);
|
||||
}
|
||||
if (v != NULL && **p_format != endchar) {
|
||||
DECREF(v);
|
||||
v = NULL;
|
||||
err_setstr(SystemError, "Unmatched paren in format");
|
||||
}
|
||||
else if (endchar)
|
||||
++*p_format;
|
||||
return v;
|
||||
}
|
||||
|
||||
static object *
|
||||
do_mktuple(p_format, p_va, endchar, n)
|
||||
char **p_format;
|
||||
|
@ -152,34 +242,41 @@ do_mkvalue(p_format, p_va)
|
|||
char **p_format;
|
||||
va_list *p_va;
|
||||
{
|
||||
|
||||
switch (*(*p_format)++) {
|
||||
|
||||
case '(':
|
||||
return do_mktuple(p_format, p_va, ')',
|
||||
countformat(*p_format, ')'));
|
||||
|
||||
case 'b':
|
||||
case 'h':
|
||||
case 'i':
|
||||
return newintobject((long)va_arg(*p_va, int));
|
||||
|
||||
case 'l':
|
||||
return newintobject((long)va_arg(*p_va, long));
|
||||
|
||||
case 'f':
|
||||
case 'd':
|
||||
return newfloatobject((double)va_arg(*p_va, va_double));
|
||||
|
||||
case 'c':
|
||||
for (;;) {
|
||||
switch (*(*p_format)++) {
|
||||
case '(':
|
||||
return do_mktuple(p_format, p_va, ')',
|
||||
countformat(*p_format, ')'));
|
||||
|
||||
case '[':
|
||||
return do_mklist(p_format, p_va, ']',
|
||||
countformat(*p_format, ']'));
|
||||
|
||||
case '{':
|
||||
return do_mkdict(p_format, p_va, '}',
|
||||
countformat(*p_format, '}'));
|
||||
|
||||
case 'b':
|
||||
case 'h':
|
||||
case 'i':
|
||||
return newintobject((long)va_arg(*p_va, int));
|
||||
|
||||
case 'l':
|
||||
return newintobject((long)va_arg(*p_va, long));
|
||||
|
||||
case 'f':
|
||||
case 'd':
|
||||
return newfloatobject((double)va_arg(*p_va, double));
|
||||
|
||||
case 'c':
|
||||
{
|
||||
char p[1];
|
||||
p[0] = va_arg(*p_va, int);
|
||||
return newsizedstringobject(p, 1);
|
||||
}
|
||||
|
||||
case 's':
|
||||
case 'z':
|
||||
|
||||
case 's':
|
||||
case 'z':
|
||||
{
|
||||
object *v;
|
||||
char *str = va_arg(*p_va, char *);
|
||||
|
@ -201,33 +298,44 @@ do_mkvalue(p_format, p_va)
|
|||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
case 'S':
|
||||
case 'O':
|
||||
|
||||
case 'S':
|
||||
case 'O':
|
||||
{
|
||||
object *v;
|
||||
v = va_arg(*p_va, object *);
|
||||
if (v != NULL)
|
||||
INCREF(v);
|
||||
else if (!err_occurred())
|
||||
/* If a NULL was passed because a call
|
||||
that should have constructed a value
|
||||
failed, that's OK, and we pass the error
|
||||
on; but if no error occurred it's not
|
||||
clear that the caller knew what she
|
||||
was doing. */
|
||||
/* If a NULL was passed
|
||||
* because a call that should
|
||||
* have constructed a value
|
||||
* failed, that's OK, and we
|
||||
* pass the error on; but if
|
||||
* no error occurred it's not
|
||||
* clear that the caller knew
|
||||
* what she was doing. */
|
||||
err_setstr(SystemError,
|
||||
"NULL object passed to mkvalue");
|
||||
return v;
|
||||
}
|
||||
|
||||
default:
|
||||
err_setstr(SystemError, "bad format char passed to mkvalue");
|
||||
return NULL;
|
||||
|
||||
|
||||
case ':':
|
||||
case ',':
|
||||
case ' ':
|
||||
case '\t':
|
||||
break;
|
||||
|
||||
default:
|
||||
err_setstr(SystemError,
|
||||
"bad format char passed to mkvalue");
|
||||
return NULL;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_STDARG_PROTOTYPES
|
||||
/* VARARGS 2 */
|
||||
object *mkvalue(char *format, ...)
|
||||
|
@ -257,6 +365,14 @@ vmkvalue(format, va)
|
|||
{
|
||||
char *f = format;
|
||||
int n = countformat(f, '\0');
|
||||
va_list lva;
|
||||
|
||||
#ifdef VA_LIST_IS_ARRAY
|
||||
memcpy(lva, va, sizeof(va_list));
|
||||
#else
|
||||
lva = va;
|
||||
#endif
|
||||
|
||||
if (n < 0)
|
||||
return NULL;
|
||||
if (n == 0) {
|
||||
|
@ -264,6 +380,83 @@ vmkvalue(format, va)
|
|||
return None;
|
||||
}
|
||||
if (n == 1)
|
||||
return do_mkvalue(&f, &va);
|
||||
return do_mktuple(&f, &va, '\0', n);
|
||||
return do_mkvalue(&f, &lva);
|
||||
return do_mktuple(&f, &lva, '\0', n);
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_STDARG_PROTOTYPES
|
||||
object *
|
||||
PyEval_CallFunction(object *obj, char *format, ...)
|
||||
#else
|
||||
object *
|
||||
PyEval_CallFunction(obj, format, va_alist)
|
||||
object *obj;
|
||||
char *format;
|
||||
va_dcl
|
||||
#endif
|
||||
{
|
||||
va_list vargs;
|
||||
object *args;
|
||||
object *res;
|
||||
|
||||
#ifdef HAVE_STDARG_PROTOTYPES
|
||||
va_start(vargs, format);
|
||||
#else
|
||||
va_start(vargs);
|
||||
#endif
|
||||
|
||||
args = vmkvalue(format, vargs);
|
||||
va_end(vargs);
|
||||
|
||||
if (args == NULL)
|
||||
return NULL;
|
||||
|
||||
res = call_object(obj, args);
|
||||
DECREF(args);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_STDARG_PROTOTYPES
|
||||
object *
|
||||
PyEval_CallMethod(object *obj, char *method, char *format, ...)
|
||||
#else
|
||||
object *
|
||||
PyEval_CallMethod(obj, method, format, va_alist)
|
||||
object *obj;
|
||||
char *method;
|
||||
char *format;
|
||||
va_dcl
|
||||
#endif
|
||||
{
|
||||
va_list vargs;
|
||||
object *meth;
|
||||
object *args;
|
||||
object *res;
|
||||
|
||||
meth = getattr(obj, method);
|
||||
if (meth == NULL)
|
||||
return NULL;
|
||||
|
||||
#ifdef HAVE_STDARG_PROTOTYPES
|
||||
va_start(vargs, format);
|
||||
#else
|
||||
va_start(vargs);
|
||||
#endif
|
||||
|
||||
args = vmkvalue(format, vargs);
|
||||
va_end(vargs);
|
||||
|
||||
if (args == NULL) {
|
||||
DECREF(meth);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
res = call_object(meth, args);
|
||||
DECREF(meth);
|
||||
DECREF(args);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -242,12 +242,10 @@ run_command(command)
|
|||
void
|
||||
print_error()
|
||||
{
|
||||
object *exception, *v, *f;
|
||||
err_get(&exception, &v);
|
||||
if (exception == NULL) {
|
||||
fprintf(stderr, "print_error called but no exception\n");
|
||||
abort();
|
||||
}
|
||||
object *exception, *v, *tb, *f;
|
||||
err_fetch(&exception, &v, &tb);
|
||||
if (exception == NULL)
|
||||
fatal("print_error called but no exception");
|
||||
if (exception == SystemExit) {
|
||||
if (v == NULL || v == None)
|
||||
goaway(0);
|
||||
|
@ -262,11 +260,12 @@ print_error()
|
|||
}
|
||||
sysset("last_type", exception);
|
||||
sysset("last_value", v);
|
||||
sysset("last_traceback", tb);
|
||||
f = sysget("stderr");
|
||||
if (f == NULL)
|
||||
fprintf(stderr, "lost sys.stderr\n");
|
||||
else {
|
||||
printtraceback(f);
|
||||
tb_print(tb, f);
|
||||
if (exception == SyntaxError) {
|
||||
object *message;
|
||||
char *filename, *text;
|
||||
|
@ -331,6 +330,7 @@ print_error()
|
|||
}
|
||||
XDECREF(exception);
|
||||
XDECREF(v);
|
||||
XDECREF(tb);
|
||||
}
|
||||
|
||||
object *
|
||||
|
@ -421,7 +421,6 @@ compile_string(str, filename, start)
|
|||
int start;
|
||||
{
|
||||
node *n;
|
||||
int err;
|
||||
codeobject *co;
|
||||
n = parse_string(str, start);
|
||||
if (n == NULL)
|
||||
|
|
|
@ -204,7 +204,8 @@ initsys()
|
|||
XDECREF(v);
|
||||
dictinsert(sysdict, "modules", get_modules());
|
||||
dictinsert(sysdict, "builtin_module_names",
|
||||
list_builtin_module_names());
|
||||
v = list_builtin_module_names());
|
||||
XDECREF(v);
|
||||
if (err_occurred())
|
||||
fatal("can't insert sys.* objects in sys dict");
|
||||
}
|
||||
|
|
|
@ -68,7 +68,7 @@ int start_new_thread _P2(func, void (*func) _P((void *)), arg, void *arg)
|
|||
funcarg = (struct func_arg *) malloc(sizeof(struct func_arg));
|
||||
funcarg->func = func;
|
||||
funcarg->arg = arg;
|
||||
if (thr_create(0, 0, new_func, funcarg, THR_NEW_LWP, 0)) {
|
||||
if (thr_create(0, 0, new_func, funcarg, THR_DETACHED, 0)) {
|
||||
perror("thr_create");
|
||||
free((void *) funcarg);
|
||||
success = -1;
|
||||
|
|
|
@ -258,7 +258,6 @@ tb_print(v, f)
|
|||
err_badcall();
|
||||
return -1;
|
||||
}
|
||||
sysset("last_traceback", v);
|
||||
limitv = sysget("tracebacklimit");
|
||||
if (limitv && is_intobject(limitv)) {
|
||||
limit = getintvalue(limitv);
|
||||
|
|
Loading…
Reference in New Issue