Merge back to main trunk

This commit is contained in:
Guido van Rossum 1994-08-30 08:27:36 +00:00
parent 013142a95f
commit 1d5735e846
37 changed files with 681 additions and 831 deletions

View file

@ -1,5 +1,5 @@
/*********************************************************** /***********************************************************
Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum, Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
Amsterdam, The Netherlands. Amsterdam, The Netherlands.
All Rights Reserved All Rights Reserved

View file

@ -1,5 +1,5 @@
/*********************************************************** /***********************************************************
Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum, Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
Amsterdam, The Netherlands. Amsterdam, The Netherlands.
All Rights Reserved All Rights Reserved
@ -38,16 +38,18 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
Table of primes suitable as keys, in ascending order. Table of primes suitable as keys, in ascending order.
The first line are the largest primes less than some powers of two, The first line are the largest primes less than some powers of two,
the second line is the largest prime less than 6000, the second line is the largest prime less than 6000,
and the third line is a selection from Knuth, Vol. 3, Sec. 6.1, Table 1. the third line is a selection from Knuth, Vol. 3, Sec. 6.1, Table 1,
The final value is a sentinel and should cause the memory allocation and the next three lines were suggested by Steve Kirsch.
of that many entries to fail (if none of the earlier values cause such The final value is a sentinel.
failure already).
*/ */
static unsigned int primes[] = { static long primes[] = {
3, 7, 13, 31, 61, 127, 251, 509, 1021, 2017, 4093, 3, 7, 13, 31, 61, 127, 251, 509, 1021, 2017, 4093,
5987, 5987,
9551, 15683, 19609, 31397, 9551, 15683, 19609, 31397,
0xffffffff /* All bits set -- truncation OK */ 65521L, 131071L, 262139L, 524287L, 1048573L, 2097143L,
4194301L, 8388593L, 16777213L, 33554393L, 67108859L,
134217689L, 268435399L, 536870909L, 1073741789L,
0
}; };
/* Object used as dummy key to fill deleted entries */ /* Object used as dummy key to fill deleted entries */
@ -207,8 +209,18 @@ mappingresize(mp)
register int i; register int i;
newsize = mp->ma_size; newsize = mp->ma_size;
for (i = 0; ; i++) { for (i = 0; ; i++) {
if (primes[i] <= 0) {
/* Ran out of primes */
err_nomem();
return -1;
}
if (primes[i] > mp->ma_used*2) { if (primes[i] > mp->ma_used*2) {
newsize = primes[i]; newsize = primes[i];
if (newsize != primes[i]) {
/* Integer truncation */
err_nomem();
return -1;
}
break; break;
} }
} }
@ -406,15 +418,6 @@ mapping_print(mp, fp, flags)
return 0; return 0;
} }
static void
js(pv, w)
object **pv;
object *w;
{
joinstring(pv, w);
XDECREF(w);
}
static object * static object *
mapping_repr(mp) mapping_repr(mp)
mappingobject *mp; mappingobject *mp;
@ -428,16 +431,16 @@ mapping_repr(mp)
sepa = newstringobject(", "); sepa = newstringobject(", ");
colon = newstringobject(": "); colon = newstringobject(": ");
any = 0; any = 0;
for (i = 0, ep = mp->ma_table; i < mp->ma_size; i++, ep++) { for (i = 0, ep = mp->ma_table; i < mp->ma_size && v; i++, ep++) {
if (ep->me_value != NULL) { if (ep->me_value != NULL) {
if (any++) if (any++)
joinstring(&v, sepa); joinstring(&v, sepa);
js(&v, reprobject(ep->me_key)); joinstring_decref(&v, reprobject(ep->me_key));
joinstring(&v, colon); joinstring(&v, colon);
js(&v, reprobject(ep->me_value)); joinstring_decref(&v, reprobject(ep->me_value));
} }
} }
js(&v, newstringobject("}")); joinstring_decref(&v, newstringobject("}"));
XDECREF(sepa); XDECREF(sepa);
XDECREF(colon); XDECREF(colon);
return v; return v;
@ -483,9 +486,9 @@ mapping_ass_sub(mp, v, w)
} }
static mapping_methods mapping_as_mapping = { static mapping_methods mapping_as_mapping = {
mapping_length, /*mp_length*/ (inquiry)mapping_length, /*mp_length*/
mapping_subscript, /*mp_subscript*/ (binaryfunc)mapping_subscript, /*mp_subscript*/
mapping_ass_sub, /*mp_ass_subscript*/ (objobjargproc)mapping_ass_sub, /*mp_ass_subscript*/
}; };
static object * static object *
@ -607,7 +610,7 @@ getmappingitems(mp)
err_badcall(); err_badcall();
return NULL; return NULL;
} }
return mapping_values((mappingobject *)mp, (object *)NULL); return mapping_items((mappingobject *)mp, (object *)NULL);
} }
static int static int
@ -702,10 +705,10 @@ mapping_has_key(mp, args)
} }
static struct methodlist mapp_methods[] = { static struct methodlist mapp_methods[] = {
{"has_key", mapping_has_key}, {"has_key", (method)mapping_has_key},
{"items", mapping_items}, {"items", (method)mapping_items},
{"keys", mapping_keys}, {"keys", (method)mapping_keys},
{"values", mapping_values}, {"values", (method)mapping_values},
{NULL, NULL} /* sentinel */ {NULL, NULL} /* sentinel */
}; };
@ -723,12 +726,12 @@ typeobject Mappingtype = {
"dictionary", "dictionary",
sizeof(mappingobject), sizeof(mappingobject),
0, 0,
mapping_dealloc, /*tp_dealloc*/ (destructor)mapping_dealloc, /*tp_dealloc*/
mapping_print, /*tp_print*/ (printfunc)mapping_print, /*tp_print*/
mapping_getattr, /*tp_getattr*/ (getattrfunc)mapping_getattr, /*tp_getattr*/
0, /*tp_setattr*/ 0, /*tp_setattr*/
mapping_compare, /*tp_compare*/ (cmpfunc)mapping_compare, /*tp_compare*/
mapping_repr, /*tp_repr*/ (reprfunc)mapping_repr, /*tp_repr*/
0, /*tp_as_number*/ 0, /*tp_as_number*/
0, /*tp_as_sequence*/ 0, /*tp_as_sequence*/
&mapping_as_mapping, /*tp_as_mapping*/ &mapping_as_mapping, /*tp_as_mapping*/

View file

@ -1,5 +1,5 @@
/*********************************************************** /***********************************************************
Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum, Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
Amsterdam, The Netherlands. Amsterdam, The Netherlands.
All Rights Reserved All Rights Reserved
@ -34,15 +34,16 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#define OFF(x) offsetof(frameobject, x) #define OFF(x) offsetof(frameobject, x)
static struct memberlist frame_memberlist[] = { static struct memberlist frame_memberlist[] = {
{"f_back", T_OBJECT, OFF(f_back)}, {"f_back", T_OBJECT, OFF(f_back), RO},
{"f_code", T_OBJECT, OFF(f_code)}, {"f_code", T_OBJECT, OFF(f_code), RO},
{"f_globals", T_OBJECT, OFF(f_globals)}, {"f_globals", T_OBJECT, OFF(f_globals), RO},
{"f_locals", T_OBJECT, OFF(f_locals)}, {"f_locals", T_OBJECT, OFF(f_locals), RO},
{"f_owner", T_OBJECT, OFF(f_owner)}, {"f_owner", T_OBJECT, OFF(f_owner), RO},
/* {"f_fastlocals",T_OBJECT, OFF(f_fastlocals)}, /* XXX Unsafe */ /* {"f_fastlocals",T_OBJECT, OFF(f_fastlocals),RO}, /* XXX Unsafe */
{"f_localmap", T_OBJECT, OFF(f_localmap)}, {"f_localmap", T_OBJECT, OFF(f_localmap),RO},
{"f_lasti", T_INT, OFF(f_lasti)}, {"f_lasti", T_INT, OFF(f_lasti), RO},
{"f_lineno", T_INT, OFF(f_lineno)}, {"f_lineno", T_INT, OFF(f_lineno), RO},
{"f_trace", T_OBJECT, OFF(f_trace)},
{NULL} /* Sentinel */ {NULL} /* Sentinel */
}; };
@ -51,9 +52,20 @@ frame_getattr(f, name)
frameobject *f; frameobject *f;
char *name; char *name;
{ {
if (strcmp(name, "f_locals") == 0)
fast_2_locals(f);
return getmember((char *)f, frame_memberlist, name); return getmember((char *)f, frame_memberlist, name);
} }
static int
frame_setattr(f, name, value)
frameobject *f;
char *name;
object *value;
{
return setmember((char *)f, frame_memberlist, name, value);
}
/* Stack frames are allocated and deallocated at a considerable rate. /* Stack frames are allocated and deallocated at a considerable rate.
In an attempt to improve the speed of function calls, we maintain a In an attempt to improve the speed of function calls, we maintain a
separate free list of stack frames (just like integers are separate free list of stack frames (just like integers are
@ -88,6 +100,7 @@ frame_dealloc(f)
XDECREF(f->f_owner); XDECREF(f->f_owner);
XDECREF(f->f_fastlocals); XDECREF(f->f_fastlocals);
XDECREF(f->f_localmap); XDECREF(f->f_localmap);
XDECREF(f->f_trace);
f->f_back = free_list; f->f_back = free_list;
free_list = f; free_list = f;
} }
@ -98,10 +111,10 @@ typeobject Frametype = {
"frame", "frame",
sizeof(frameobject), sizeof(frameobject),
0, 0,
frame_dealloc, /*tp_dealloc*/ (destructor)frame_dealloc, /*tp_dealloc*/
0, /*tp_print*/ 0, /*tp_print*/
frame_getattr, /*tp_getattr*/ (getattrfunc)frame_getattr, /*tp_getattr*/
0, /*tp_setattr*/ (setattrfunc)frame_setattr, /*tp_setattr*/
0, /*tp_compare*/ 0, /*tp_compare*/
0, /*tp_repr*/ 0, /*tp_repr*/
0, /*tp_as_number*/ 0, /*tp_as_number*/
@ -167,6 +180,7 @@ newframeobject(back, code, globals, locals, owner, nvalues, nblocks)
f->f_iblock = 0; f->f_iblock = 0;
f->f_lasti = 0; f->f_lasti = 0;
f->f_lineno = -1; f->f_lineno = -1;
f->f_trace = NULL;
if (f->f_valuestack == NULL || f->f_blockstack == NULL) { if (f->f_valuestack == NULL || f->f_blockstack == NULL) {
err_nomem(); err_nomem();
DECREF(f); DECREF(f);
@ -225,3 +239,74 @@ pop_block(f)
b = &f->f_blockstack[--f->f_iblock]; b = &f->f_blockstack[--f->f_iblock];
return b; return b;
} }
/* Convert between "fast" version of locals and dictionary version */
void
fast_2_locals(f)
frameobject *f;
{
/* Merge f->f_fastlocals into f->f_locals */
object *locals, *fast, *map;
object *error_type, *error_value;
int j;
if (f == NULL)
return;
locals = f->f_locals;
fast = f->f_fastlocals;
map = f->f_localmap;
if (locals == NULL || fast == NULL || map == NULL)
return;
if (!is_dictobject(locals) || !is_listobject(fast) ||
!is_tupleobject(map))
return;
err_get(&error_type, &error_value);
for (j = gettuplesize(map); --j >= 0; ) {
object *key = gettupleitem(map, j);
object *value = getlistitem(fast, j);
if (value == NULL) {
err_clear();
if (dict2remove(locals, key) != 0)
err_clear();
}
else {
if (dict2insert(locals, key, value) != 0)
err_clear();
}
}
err_setval(error_type, error_value);
}
void
locals_2_fast(f, clear)
frameobject *f;
int clear;
{
/* Merge f->f_locals into f->f_fastlocals */
object *locals, *fast, *map;
object *error_type, *error_value;
int j;
if (f == NULL)
return;
locals = f->f_locals;
fast = f->f_fastlocals;
map = f->f_localmap;
if (locals == NULL || fast == NULL || map == NULL)
return;
if (!is_dictobject(locals) || !is_listobject(fast) ||
!is_tupleobject(map))
return;
err_get(&error_type, &error_value);
for (j = gettuplesize(map); --j >= 0; ) {
object *key = gettupleitem(map, j);
object *value = dict2lookup(locals, key);
if (value == NULL)
err_clear();
else
INCREF(value);
if (value != NULL || clear)
if (setlistitem(fast, j, value) != 0)
err_clear();
}
err_setval(error_type, error_value);
}

View file

@ -1,5 +1,5 @@
/*********************************************************** /***********************************************************
Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum, Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
Amsterdam, The Netherlands. Amsterdam, The Netherlands.
All Rights Reserved All Rights Reserved
@ -41,6 +41,8 @@ newfuncobject(code, globals)
op->func_globals = globals; op->func_globals = globals;
op->func_name = ((codeobject*)(op->func_code))->co_name; op->func_name = ((codeobject*)(op->func_code))->co_name;
INCREF(op->func_name); INCREF(op->func_name);
op->func_argcount = -1; /* Unknown */
op->func_argdefs = NULL; /* No default arguments */
} }
return (object *)op; return (object *)op;
} }
@ -67,6 +69,44 @@ getfuncglobals(op)
return ((funcobject *) op) -> func_globals; return ((funcobject *) op) -> func_globals;
} }
object *
getfuncargstuff(op, argcount_return)
object *op;
int *argcount_return;
{
if (!is_funcobject(op)) {
err_badcall();
return NULL;
}
*argcount_return = ((funcobject *) op) -> func_argcount;
return ((funcobject *) op) -> func_argdefs;
}
int
setfuncargstuff(op, argcount, argdefs)
object *op;
int argcount;
object *argdefs;
{
if (!is_funcobject(op) ||
argdefs != NULL && !is_tupleobject(argdefs)) {
err_badcall();
return -1;
}
if (argdefs == None)
argdefs = NULL;
else if (is_tupleobject(argdefs))
XINCREF(argdefs);
else {
err_setstr(SystemError, "non-tuple default args");
return -1;
}
((funcobject *) op) -> func_argcount = argcount;
XDECREF(((funcobject *) op) -> func_argdefs);
((funcobject *) op) -> func_argdefs = argdefs;
return 0;
}
/* Methods */ /* Methods */
#define OFF(x) offsetof(funcobject, x) #define OFF(x) offsetof(funcobject, x)
@ -75,6 +115,8 @@ static struct memberlist func_memberlist[] = {
{"func_code", T_OBJECT, OFF(func_code), READONLY}, {"func_code", T_OBJECT, OFF(func_code), READONLY},
{"func_globals",T_OBJECT, OFF(func_globals), READONLY}, {"func_globals",T_OBJECT, OFF(func_globals), READONLY},
{"func_name", T_OBJECT, OFF(func_name), READONLY}, {"func_name", T_OBJECT, OFF(func_name), READONLY},
{"func_argcount",T_INT, OFF(func_argcount), READONLY},
{"func_argdefs",T_OBJECT, OFF(func_argdefs), READONLY},
{NULL} /* Sentinel */ {NULL} /* Sentinel */
}; };
@ -92,6 +134,7 @@ func_dealloc(op)
{ {
DECREF(op->func_code); DECREF(op->func_code);
DECREF(op->func_globals); DECREF(op->func_globals);
XDECREF(op->func_argdefs);
DEL(op); DEL(op);
} }
@ -113,8 +156,15 @@ static int
func_compare(f, g) func_compare(f, g)
funcobject *f, *g; funcobject *f, *g;
{ {
int c;
if (f->func_globals != g->func_globals) if (f->func_globals != g->func_globals)
return (f->func_globals < g->func_globals) ? -1 : 1; return (f->func_globals < g->func_globals) ? -1 : 1;
c = f->func_argcount < g->func_argcount;
if (c != 0)
return c < 0 ? -1 : 1;
c = cmpobject(f->func_argdefs, g->func_argdefs);
if (c != 0)
return c;
return cmpobject(f->func_code, g->func_code); return cmpobject(f->func_code, g->func_code);
} }
@ -136,14 +186,14 @@ typeobject Functype = {
"function", "function",
sizeof(funcobject), sizeof(funcobject),
0, 0,
func_dealloc, /*tp_dealloc*/ (destructor)func_dealloc, /*tp_dealloc*/
0, /*tp_print*/ 0, /*tp_print*/
func_getattr, /*tp_getattr*/ (getattrfunc)func_getattr, /*tp_getattr*/
0, /*tp_setattr*/ 0, /*tp_setattr*/
func_compare, /*tp_compare*/ (cmpfunc)func_compare, /*tp_compare*/
func_repr, /*tp_repr*/ (reprfunc)func_repr, /*tp_repr*/
0, /*tp_as_number*/ 0, /*tp_as_number*/
0, /*tp_as_sequence*/ 0, /*tp_as_sequence*/
0, /*tp_as_mapping*/ 0, /*tp_as_mapping*/
func_hash, /*tp_hash*/ (hashfunc)func_hash, /*tp_hash*/
}; };

View file

@ -1,5 +1,5 @@
/*********************************************************** /***********************************************************
Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum, Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
Amsterdam, The Netherlands. Amsterdam, The Netherlands.
All Rights Reserved All Rights Reserved
@ -38,16 +38,18 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
Table of primes suitable as keys, in ascending order. Table of primes suitable as keys, in ascending order.
The first line are the largest primes less than some powers of two, The first line are the largest primes less than some powers of two,
the second line is the largest prime less than 6000, the second line is the largest prime less than 6000,
and the third line is a selection from Knuth, Vol. 3, Sec. 6.1, Table 1. the third line is a selection from Knuth, Vol. 3, Sec. 6.1, Table 1,
The final value is a sentinel and should cause the memory allocation and the next three lines were suggested by Steve Kirsch.
of that many entries to fail (if none of the earlier values cause such The final value is a sentinel.
failure already).
*/ */
static unsigned int primes[] = { static long primes[] = {
3, 7, 13, 31, 61, 127, 251, 509, 1021, 2017, 4093, 3, 7, 13, 31, 61, 127, 251, 509, 1021, 2017, 4093,
5987, 5987,
9551, 15683, 19609, 31397, 9551, 15683, 19609, 31397,
0xffffffff /* All bits set -- truncation OK */ 65521L, 131071L, 262139L, 524287L, 1048573L, 2097143L,
4194301L, 8388593L, 16777213L, 33554393L, 67108859L,
134217689L, 268435399L, 536870909L, 1073741789L,
0
}; };
/* Object used as dummy key to fill deleted entries */ /* Object used as dummy key to fill deleted entries */
@ -207,8 +209,18 @@ mappingresize(mp)
register int i; register int i;
newsize = mp->ma_size; newsize = mp->ma_size;
for (i = 0; ; i++) { for (i = 0; ; i++) {
if (primes[i] <= 0) {
/* Ran out of primes */
err_nomem();
return -1;
}
if (primes[i] > mp->ma_used*2) { if (primes[i] > mp->ma_used*2) {
newsize = primes[i]; newsize = primes[i];
if (newsize != primes[i]) {
/* Integer truncation */
err_nomem();
return -1;
}
break; break;
} }
} }
@ -406,15 +418,6 @@ mapping_print(mp, fp, flags)
return 0; return 0;
} }
static void
js(pv, w)
object **pv;
object *w;
{
joinstring(pv, w);
XDECREF(w);
}
static object * static object *
mapping_repr(mp) mapping_repr(mp)
mappingobject *mp; mappingobject *mp;
@ -428,16 +431,16 @@ mapping_repr(mp)
sepa = newstringobject(", "); sepa = newstringobject(", ");
colon = newstringobject(": "); colon = newstringobject(": ");
any = 0; any = 0;
for (i = 0, ep = mp->ma_table; i < mp->ma_size; i++, ep++) { for (i = 0, ep = mp->ma_table; i < mp->ma_size && v; i++, ep++) {
if (ep->me_value != NULL) { if (ep->me_value != NULL) {
if (any++) if (any++)
joinstring(&v, sepa); joinstring(&v, sepa);
js(&v, reprobject(ep->me_key)); joinstring_decref(&v, reprobject(ep->me_key));
joinstring(&v, colon); joinstring(&v, colon);
js(&v, reprobject(ep->me_value)); joinstring_decref(&v, reprobject(ep->me_value));
} }
} }
js(&v, newstringobject("}")); joinstring_decref(&v, newstringobject("}"));
XDECREF(sepa); XDECREF(sepa);
XDECREF(colon); XDECREF(colon);
return v; return v;
@ -483,9 +486,9 @@ mapping_ass_sub(mp, v, w)
} }
static mapping_methods mapping_as_mapping = { static mapping_methods mapping_as_mapping = {
mapping_length, /*mp_length*/ (inquiry)mapping_length, /*mp_length*/
mapping_subscript, /*mp_subscript*/ (binaryfunc)mapping_subscript, /*mp_subscript*/
mapping_ass_sub, /*mp_ass_subscript*/ (objobjargproc)mapping_ass_sub, /*mp_ass_subscript*/
}; };
static object * static object *
@ -607,7 +610,7 @@ getmappingitems(mp)
err_badcall(); err_badcall();
return NULL; return NULL;
} }
return mapping_values((mappingobject *)mp, (object *)NULL); return mapping_items((mappingobject *)mp, (object *)NULL);
} }
static int static int
@ -702,10 +705,10 @@ mapping_has_key(mp, args)
} }
static struct methodlist mapp_methods[] = { static struct methodlist mapp_methods[] = {
{"has_key", mapping_has_key}, {"has_key", (method)mapping_has_key},
{"items", mapping_items}, {"items", (method)mapping_items},
{"keys", mapping_keys}, {"keys", (method)mapping_keys},
{"values", mapping_values}, {"values", (method)mapping_values},
{NULL, NULL} /* sentinel */ {NULL, NULL} /* sentinel */
}; };
@ -723,12 +726,12 @@ typeobject Mappingtype = {
"dictionary", "dictionary",
sizeof(mappingobject), sizeof(mappingobject),
0, 0,
mapping_dealloc, /*tp_dealloc*/ (destructor)mapping_dealloc, /*tp_dealloc*/
mapping_print, /*tp_print*/ (printfunc)mapping_print, /*tp_print*/
mapping_getattr, /*tp_getattr*/ (getattrfunc)mapping_getattr, /*tp_getattr*/
0, /*tp_setattr*/ 0, /*tp_setattr*/
mapping_compare, /*tp_compare*/ (cmpfunc)mapping_compare, /*tp_compare*/
mapping_repr, /*tp_repr*/ (reprfunc)mapping_repr, /*tp_repr*/
0, /*tp_as_number*/ 0, /*tp_as_number*/
0, /*tp_as_sequence*/ 0, /*tp_as_sequence*/
&mapping_as_mapping, /*tp_as_mapping*/ &mapping_as_mapping, /*tp_as_mapping*/

View file

@ -1,5 +1,5 @@
/*********************************************************** /***********************************************************
Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum, Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
Amsterdam, The Netherlands. Amsterdam, The Netherlands.
All Rights Reserved All Rights Reserved
@ -149,16 +149,16 @@ typeobject Methodtype = {
"builtin_function_or_method", "builtin_function_or_method",
sizeof(methodobject), sizeof(methodobject),
0, 0,
meth_dealloc, /*tp_dealloc*/ (destructor)meth_dealloc, /*tp_dealloc*/
0, /*tp_print*/ 0, /*tp_print*/
0, /*tp_getattr*/ 0, /*tp_getattr*/
0, /*tp_setattr*/ 0, /*tp_setattr*/
meth_compare, /*tp_compare*/ (cmpfunc)meth_compare, /*tp_compare*/
meth_repr, /*tp_repr*/ (reprfunc)meth_repr, /*tp_repr*/
0, /*tp_as_number*/ 0, /*tp_as_number*/
0, /*tp_as_sequence*/ 0, /*tp_as_sequence*/
0, /*tp_as_mapping*/ 0, /*tp_as_mapping*/
meth_hash, /*tp_hash*/ (hashfunc)meth_hash, /*tp_hash*/
}; };
static object *listmethods PROTO((struct methodlist *)); /* Forward */ static object *listmethods PROTO((struct methodlist *)); /* Forward */

View file

@ -1,5 +1,5 @@
/*********************************************************** /***********************************************************
Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum, Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
Amsterdam, The Netherlands. Amsterdam, The Netherlands.
All Rights Reserved All Rights Reserved
@ -162,10 +162,10 @@ typeobject Moduletype = {
"module", /*tp_name*/ "module", /*tp_name*/
sizeof(moduleobject), /*tp_size*/ sizeof(moduleobject), /*tp_size*/
0, /*tp_itemsize*/ 0, /*tp_itemsize*/
module_dealloc, /*tp_dealloc*/ (destructor)module_dealloc, /*tp_dealloc*/
0, /*tp_print*/ 0, /*tp_print*/
module_getattr, /*tp_getattr*/ (getattrfunc)module_getattr, /*tp_getattr*/
module_setattr, /*tp_setattr*/ (setattrfunc)module_setattr, /*tp_setattr*/
0, /*tp_compare*/ 0, /*tp_compare*/
module_repr, /*tp_repr*/ (reprfunc)module_repr, /*tp_repr*/
}; };

View file

@ -1,5 +1,5 @@
/*********************************************************** /***********************************************************
Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum, Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
Amsterdam, The Netherlands. Amsterdam, The Netherlands.
All Rights Reserved All Rights Reserved
@ -107,10 +107,8 @@ printobject(op, fp, flags)
int flags; int flags;
{ {
int ret = 0; int ret = 0;
if (intrcheck()) { if (sigcheck())
err_set(KeyboardInterrupt);
return -1; return -1;
}
if (op == NULL) { if (op == NULL) {
fprintf(fp, "<nil>"); fprintf(fp, "<nil>");
} }
@ -159,10 +157,8 @@ object *
reprobject(v) reprobject(v)
object *v; object *v;
{ {
if (intrcheck()) { if (sigcheck())
err_set(KeyboardInterrupt);
return NULL; return NULL;
}
if (v == NULL) if (v == NULL)
return newstringobject("<NULL>"); return newstringobject("<NULL>");
else if (v->ob_type->tp_repr == NULL) { else if (v->ob_type->tp_repr == NULL) {
@ -349,7 +345,7 @@ static typeobject Notype = {
0, /*tp_getattr*/ 0, /*tp_getattr*/
0, /*tp_setattr*/ 0, /*tp_setattr*/
0, /*tp_compare*/ 0, /*tp_compare*/
none_repr, /*tp_repr*/ (reprfunc)none_repr, /*tp_repr*/
0, /*tp_as_number*/ 0, /*tp_as_number*/
0, /*tp_as_sequence*/ 0, /*tp_as_sequence*/
0, /*tp_as_mapping*/ 0, /*tp_as_mapping*/

View file

@ -1,5 +1,5 @@
/*********************************************************** /***********************************************************
Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum, Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
Amsterdam, The Netherlands. Amsterdam, The Netherlands.
All Rights Reserved All Rights Reserved
@ -180,26 +180,19 @@ static object *
tuplerepr(v) tuplerepr(v)
tupleobject *v; tupleobject *v;
{ {
object *s, *t, *comma; object *s, *comma;
int i; int i;
s = newstringobject("("); s = newstringobject("(");
comma = newstringobject(", "); comma = newstringobject(", ");
for (i = 0; i < v->ob_size && s != NULL; i++) { for (i = 0; i < v->ob_size && s != NULL; i++) {
if (i > 0) if (i > 0)
joinstring(&s, comma); joinstring(&s, comma);
t = reprobject(v->ob_item[i]); joinstring_decref(&s, reprobject(v->ob_item[i]));
joinstring(&s, t);
XDECREF(t);
} }
DECREF(comma); DECREF(comma);
if (v->ob_size == 1) { if (v->ob_size == 1)
t = newstringobject(","); joinstring_decref(&s, newstringobject(","));
joinstring(&s, t); joinstring_decref(&s, newstringobject(")"));
DECREF(t);
}
t = newstringobject(")");
joinstring(&s, t);
DECREF(t);
return s; return s;
} }
@ -365,11 +358,11 @@ tuplerepeat(a, n)
} }
static sequence_methods tuple_as_sequence = { static sequence_methods tuple_as_sequence = {
tuplelength, /*sq_length*/ (inquiry)tuplelength, /*sq_length*/
tupleconcat, /*sq_concat*/ (binaryfunc)tupleconcat, /*sq_concat*/
tuplerepeat, /*sq_repeat*/ (intargfunc)tuplerepeat, /*sq_repeat*/
tupleitem, /*sq_item*/ (intargfunc)tupleitem, /*sq_item*/
tupleslice, /*sq_slice*/ (intintargfunc)tupleslice, /*sq_slice*/
0, /*sq_ass_item*/ 0, /*sq_ass_item*/
0, /*sq_ass_slice*/ 0, /*sq_ass_slice*/
}; };
@ -380,16 +373,16 @@ typeobject Tupletype = {
"tuple", "tuple",
sizeof(tupleobject) - sizeof(object *), sizeof(tupleobject) - sizeof(object *),
sizeof(object *), sizeof(object *),
tupledealloc, /*tp_dealloc*/ (destructor)tupledealloc, /*tp_dealloc*/
tupleprint, /*tp_print*/ (printfunc)tupleprint, /*tp_print*/
0, /*tp_getattr*/ 0, /*tp_getattr*/
0, /*tp_setattr*/ 0, /*tp_setattr*/
tuplecompare, /*tp_compare*/ (cmpfunc)tuplecompare, /*tp_compare*/
tuplerepr, /*tp_repr*/ (reprfunc)tuplerepr, /*tp_repr*/
0, /*tp_as_number*/ 0, /*tp_as_number*/
&tuple_as_sequence, /*tp_as_sequence*/ &tuple_as_sequence, /*tp_as_sequence*/
0, /*tp_as_mapping*/ 0, /*tp_as_mapping*/
tuplehash, /*tp_hash*/ (hashfunc)tuplehash, /*tp_hash*/
}; };
/* The following function breaks the notion that tuples are immutable: /* The following function breaks the notion that tuples are immutable:

View file

@ -1,5 +1,5 @@
/*********************************************************** /***********************************************************
Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum, Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
Amsterdam, The Netherlands. Amsterdam, The Netherlands.
All Rights Reserved All Rights Reserved
@ -48,5 +48,5 @@ typeobject Typetype = {
0, /*tp_getattr*/ 0, /*tp_getattr*/
0, /*tp_setattr*/ 0, /*tp_setattr*/
0, /*tp_compare*/ 0, /*tp_compare*/
type_repr, /*tp_repr*/ (reprfunc)type_repr, /*tp_repr*/
}; };

View file

@ -1,5 +1,5 @@
/*********************************************************** /***********************************************************
Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum, Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
Amsterdam, The Netherlands. Amsterdam, The Netherlands.
All Rights Reserved All Rights Reserved
@ -35,6 +35,7 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include "pgenheaders.h" #include "pgenheaders.h"
#include "grammar.h" #include "grammar.h"
#include "node.h"
#include "token.h" #include "token.h"
#include "parser.h" #include "parser.h"
@ -104,7 +105,7 @@ fixstate(g, s)
for (ibit = 0; ibit < g->g_ll.ll_nlabels; ibit++) { for (ibit = 0; ibit < g->g_ll.ll_nlabels; ibit++) {
if (testbit(d1->d_first, ibit)) { if (testbit(d1->d_first, ibit)) {
#ifdef applec #ifdef applec
#define MPW_881_bug /* Undefine if bug below is fixed */ #define MPW_881_BUG /* Undefine if bug below is fixed */
#endif #endif
#ifdef MPW_881_BUG #ifdef MPW_881_BUG
/* In 881 mode MPW 3.1 has a code /* In 881 mode MPW 3.1 has a code

View file

@ -1,5 +1,5 @@
/*********************************************************** /***********************************************************
Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum, Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
Amsterdam, The Netherlands. Amsterdam, The Netherlands.
All Rights Reserved All Rights Reserved

View file

@ -1,5 +1,5 @@
/*********************************************************** /***********************************************************
Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum, Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
Amsterdam, The Netherlands. Amsterdam, The Netherlands.
All Rights Reserved All Rights Reserved

View file

@ -1,5 +1,5 @@
/*********************************************************** /***********************************************************
Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum, Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
Amsterdam, The Netherlands. Amsterdam, The Netherlands.
All Rights Reserved All Rights Reserved
@ -203,7 +203,7 @@ translabel(g, lb)
if (lb->lb_type == STRING) { if (lb->lb_type == STRING) {
if (isalpha(lb->lb_str[1])) { if (isalpha(lb->lb_str[1])) {
char *p, *strchr(); char *p;
if (debugging) if (debugging)
printf("Label %s is a keyword\n", lb->lb_str); printf("Label %s is a keyword\n", lb->lb_str);
lb->lb_type = NAME; lb->lb_type = NAME;

View file

@ -1,5 +1,5 @@
/*********************************************************** /***********************************************************
Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum, Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
Amsterdam, The Netherlands. Amsterdam, The Netherlands.
All Rights Reserved All Rights Reserved

View file

@ -1,5 +1,5 @@
/*********************************************************** /***********************************************************
Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum, Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
Amsterdam, The Netherlands. Amsterdam, The Netherlands.
All Rights Reserved All Rights Reserved
@ -25,17 +25,66 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
/* Check for interrupts */ /* Check for interrupts */
#ifdef THINK_C #ifdef THINK_C
/* This is for THINK C 4.0.
For 3.0, you may have to remove the signal stuff. */
#include <MacHeaders> #include <MacHeaders>
#define macintosh #define macintosh
#endif #endif
#include "PROTO.h" #ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "myproto.h"
#include "intrcheck.h" #include "intrcheck.h"
#ifdef MSDOS #ifdef QUICKWIN
#include <io.h>
void
initintr()
{
}
int
intrcheck()
{
_wyield();
}
#define OK
#endif /* QUICKWIN */
#ifdef _M_IX86
#include <io.h>
#endif
#if defined(MSDOS) && !defined(QUICKWIN)
#ifdef __GNUC__
/* This is for DJGPP's GO32 extender. I don't know how to trap
* control-C (There's no API for ctrl-C, and I don't want to mess with
* the interrupt vectors.) However, this DOES catch control-break.
* --Amrit
*/
#include <go32.h>
void
initintr()
{
_go32_want_ctrl_break(1 /* TRUE */);
}
int
intrcheck()
{
return _go32_was_ctrl_break_hit();
}
#else /* !__GNUC__ */
/* This might work for MS-DOS (untested though): */ /* This might work for MS-DOS (untested though): */
@ -55,9 +104,11 @@ intrcheck()
return interrupted; return interrupted;
} }
#endif /* __GNUC__ */
#define OK #define OK
#endif #endif /* MSDOS && !QUICKWIN */
#ifdef macintosh #ifdef macintosh
@ -65,15 +116,14 @@ intrcheck()
#ifdef applec /* MPW */ #ifdef applec /* MPW */
#include <OSEvents.h> #include <OSEvents.h>
#include <SysEqu.h> #include <SysEqu.h>
#endif #endif /* applec */
#include <signal.h> #include <signal.h>
#include "sigtype.h"
static int interrupted; static int interrupted;
static SIGTYPE intcatcher PROTO((int)); static RETSIGTYPE intcatcher PROTO((int));
static SIGTYPE static RETSIGTYPE
intcatcher(sig) intcatcher(sig)
int sig; int sig;
{ {
@ -121,15 +171,19 @@ intrcheck()
/* Default version -- for real operating systems and for Standard C */ /* Default version -- for real operating systems and for Standard C */
#include <stdio.h> #include <stdio.h>
#include <string.h>
#include <signal.h> #include <signal.h>
#include "sigtype.h"
static int interrupted; static int interrupted;
/* ARGSUSED */ /* ARGSUSED */
static SIGTYPE static RETSIGTYPE
#ifdef _M_IX86
intcatcher(int sig) /* So the C compiler shuts up */
#else /* _M_IX86 */
intcatcher(sig) intcatcher(sig)
int sig; /* Not used by required by interface */ int sig; /* Not used by required by interface */
#endif /* _M_IX86 */
{ {
extern void goaway PROTO((int)); extern void goaway PROTO((int));
static char message[] = static char message[] =
@ -153,7 +207,7 @@ initintr()
{ {
if (signal(SIGINT, SIG_IGN) != SIG_IGN) if (signal(SIGINT, SIG_IGN) != SIG_IGN)
signal(SIGINT, intcatcher); signal(SIGINT, intcatcher);
#ifdef SV_INTERRUPT #ifdef HAVE_SIGINTERRUPT
/* This is for SunOS and other modern BSD derivatives. /* This is for SunOS and other modern BSD derivatives.
It means that system calls (like read()) are not restarted It means that system calls (like read()) are not restarted
after an interrupt. This is necessary so interrupting a after an interrupt. This is necessary so interrupting a
@ -161,7 +215,7 @@ initintr()
XXX On old BSD (pure 4.2 or older) you may have to do this XXX On old BSD (pure 4.2 or older) you may have to do this
differently! */ differently! */
siginterrupt(SIGINT, 1); siginterrupt(SIGINT, 1);
#endif #endif /* HAVE_SIGINTERRUPT */
} }
int int

View file

@ -1,5 +1,5 @@
/*********************************************************** /***********************************************************
Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum, Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
Amsterdam, The Netherlands. Amsterdam, The Netherlands.
All Rights Reserved All Rights Reserved

View file

@ -1,5 +1,5 @@
/*********************************************************** /***********************************************************
Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum, Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
Amsterdam, The Netherlands. Amsterdam, The Netherlands.
All Rights Reserved All Rights Reserved

View file

@ -1,5 +1,5 @@
/*********************************************************** /***********************************************************
Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum, Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
Amsterdam, The Netherlands. Amsterdam, The Netherlands.
All Rights Reserved All Rights Reserved

View file

@ -1,5 +1,5 @@
/*********************************************************** /***********************************************************
Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum, Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
Amsterdam, The Netherlands. Amsterdam, The Netherlands.
All Rights Reserved All Rights Reserved

View file

@ -5,7 +5,7 @@ extern "C" {
#endif #endif
/*********************************************************** /***********************************************************
Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum, Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
Amsterdam, The Netherlands. Amsterdam, The Netherlands.
All Rights Reserved All Rights Reserved
@ -32,25 +32,25 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#define MAXSTACK 500 #define MAXSTACK 500
typedef struct _stackentry { typedef struct {
int s_state; /* State in current DFA */ int s_state; /* State in current DFA */
dfa *s_dfa; /* Current DFA */ dfa *s_dfa; /* Current DFA */
struct _node *s_parent; /* Where to add next node */ struct _node *s_parent; /* Where to add next node */
} stackentry; } stackentry;
typedef struct _stack { typedef struct {
stackentry *s_top; /* Top entry */ stackentry *s_top; /* Top entry */
stackentry s_base[MAXSTACK];/* Array of stack entries */ stackentry s_base[MAXSTACK];/* Array of stack entries */
/* NB The stack grows down */ /* NB The stack grows down */
} stack; } stack;
typedef struct { typedef struct {
struct _stack p_stack; /* Stack of parser states */ stack p_stack; /* Stack of parser states */
struct _grammar *p_grammar; /* Grammar to use */ grammar *p_grammar; /* Grammar to use */
struct _node *p_tree; /* Top of parse tree */ node *p_tree; /* Top of parse tree */
} parser_state; } parser_state;
parser_state *newparser PROTO((struct _grammar *g, int start)); parser_state *newparser PROTO((grammar *g, int start));
void delparser PROTO((parser_state *ps)); void delparser PROTO((parser_state *ps));
int addtoken PROTO((parser_state *ps, int type, char *str, int lineno)); int addtoken PROTO((parser_state *ps, int type, char *str, int lineno));
void addaccelerators PROTO((grammar *g)); void addaccelerators PROTO((grammar *g));

View file

@ -1,5 +1,5 @@
/*********************************************************** /***********************************************************
Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum, Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
Amsterdam, The Netherlands. Amsterdam, The Netherlands.
All Rights Reserved All Rights Reserved

View file

@ -5,7 +5,7 @@ extern "C" {
#endif #endif
/*********************************************************** /***********************************************************
Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum, Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
Amsterdam, The Netherlands. Amsterdam, The Netherlands.
All Rights Reserved All Rights Reserved
@ -30,8 +30,6 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
/* Parser generator interface */ /* Parser generator interface */
extern grammar gram;
extern grammar *meta_grammar PROTO((void)); extern grammar *meta_grammar PROTO((void));
struct _node; struct _node;

View file

@ -1,5 +1,5 @@
/*********************************************************** /***********************************************************
Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum, Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
Amsterdam, The Netherlands. Amsterdam, The Netherlands.
All Rights Reserved All Rights Reserved
@ -32,6 +32,10 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
Error messages and status info during the generation process are Error messages and status info during the generation process are
written to stdout, or sometimes to stderr. */ written to stdout, or sometimes to stderr. */
/* XXX TO DO:
- check for duplicate definitions of names (instead of fatal err)
*/
#include "pgenheaders.h" #include "pgenheaders.h"
#include "grammar.h" #include "grammar.h"
#include "node.h" #include "node.h"
@ -42,7 +46,7 @@ int debugging;
/* Forward */ /* Forward */
grammar *getgrammar PROTO((char *filename)); grammar *getgrammar PROTO((char *filename));
#ifdef macintosh #ifdef THINK_C
int main PROTO((int, char **)); int main PROTO((int, char **));
char *askfile PROTO((void)); char *askfile PROTO((void));
#endif #endif
@ -64,7 +68,7 @@ main(argc, argv)
FILE *fp; FILE *fp;
char *filename; char *filename;
#ifdef macintosh #ifdef THINK_C
filename = askfile(); filename = askfile();
#else #else
if (argc != 2) { if (argc != 2) {
@ -100,6 +104,7 @@ getgrammar(filename)
FILE *fp; FILE *fp;
node *n; node *n;
grammar *g0, *g; grammar *g0, *g;
perrdetail err;
fp = fopen(filename, "r"); fp = fopen(filename, "r");
if (fp == NULL) { if (fp == NULL) {
@ -107,11 +112,27 @@ getgrammar(filename)
goaway(1); goaway(1);
} }
g0 = meta_grammar(); g0 = meta_grammar();
n = NULL; n = parsefile(fp, filename, g0, g0->g_start,
parsefile(fp, filename, g0, g0->g_start, (char *)NULL, (char *)NULL, &n); (char *)NULL, (char *)NULL, &err);
fclose(fp); fclose(fp);
if (n == NULL) { if (n == NULL) {
fprintf(stderr, "Parsing error.\n"); fprintf(stderr, "Parsing error %d, line %d.\n",
err.error, err.lineno);
if (err.text != NULL) {
int i;
fprintf(stderr, "%s", err.text);
i = strlen(err.text);
if (i == 0 || err.text[i-1] != '\n')
fprintf(stderr, "\n");
for (i = 0; i < err.offset; i++) {
if (err.text[i] == '\t')
putc('\t', stderr);
else
putc(' ', stderr);
}
fprintf(stderr, "^\n");
free(err.text);
}
goaway(1); goaway(1);
} }
g = pgen(n); g = pgen(n);
@ -122,7 +143,7 @@ getgrammar(filename)
return g; return g;
} }
#ifdef macintosh #ifdef THINK_C
char * char *
askfile() askfile()
{ {
@ -160,6 +181,25 @@ guesstabsize(path)
} }
#endif #endif
/* XXX TO DO: /* No-nonsense my_readline() for tokenizer.c */
- check for duplicate definitions of names (instead of fatal err)
*/ char *
my_readline(prompt)
char *prompt;
{
int n = 1000;
char *p = malloc(n);
char *q;
if (p == NULL)
return NULL;
fprintf(stderr, "%s", prompt);
q = fgets(p, n, stdin);
if (q == NULL) {
*p = '\0';
return p;
}
n = strlen(p);
if (n > 0 && p[n-1] != '\n')
p[n-1] = '\n';
return realloc(p, n+1);
}

View file

@ -1,5 +1,5 @@
/*********************************************************** /***********************************************************
Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum, Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
Amsterdam, The Netherlands. Amsterdam, The Netherlands.
All Rights Reserved All Rights Reserved

View file

@ -5,7 +5,7 @@ extern "C" {
#endif #endif
/*********************************************************** /***********************************************************
Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum, Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
Amsterdam, The Netherlands. Amsterdam, The Netherlands.
All Rights Reserved All Rights Reserved
@ -42,6 +42,7 @@ struct tok_state {
char *cur; /* Next character in buffer */ char *cur; /* Next character in buffer */
char *inp; /* End of data in buffer */ char *inp; /* End of data in buffer */
char *end; /* End of input buffer if buf != NULL */ char *end; /* End of input buffer if buf != NULL */
char *start; /* Start of current token if not NULL */
int done; /* E_OK normally, E_EOF at EOF, otherwise error code */ int done; /* E_OK normally, E_EOF at EOF, otherwise error code */
/* NB If done != E_OK, cur must be == inp!!! */ /* NB If done != E_OK, cur must be == inp!!! */
FILE *fp; /* Rest of input; NULL if tokenizing a string */ FILE *fp; /* Rest of input; NULL if tokenizing a string */

View file

@ -1,5 +1,5 @@
/*********************************************************** /***********************************************************
Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum, Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
Amsterdam, The Netherlands. Amsterdam, The Netherlands.
All Rights Reserved All Rights Reserved

View file

@ -1,5 +1,5 @@
/*********************************************************** /***********************************************************
Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum, Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
Amsterdam, The Netherlands. Amsterdam, The Netherlands.
All Rights Reserved All Rights Reserved

View file

@ -1,5 +1,5 @@
/*********************************************************** /***********************************************************
Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum, Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
Amsterdam, The Netherlands. Amsterdam, The Netherlands.
All Rights Reserved All Rights Reserved
@ -28,9 +28,14 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
extern char *getenv(); extern char *getenv();
extern char *getversion();
extern char *getcopyright();
extern int debugging; extern int debugging;
extern int verbose; extern int verbose;
extern int killprint; extern int suppress_print;
static char *argv0;
main(argc, argv) main(argc, argv)
int argc; int argc;
@ -39,17 +44,29 @@ main(argc, argv)
char *p; char *p;
int n, sts; int n, sts;
int inspect = 0; int inspect = 0;
int unbuffered = 0;
argv0 = argv[0];
if ((p = getenv("PYTHONDEBUG")) && *p != '\0') if ((p = getenv("PYTHONDEBUG")) && *p != '\0')
debugging = 1; debugging = 1;
if ((p = getenv("PYTHONSUPPRESS")) && *p != '\0')
suppress_print = 1;
if ((p = getenv("PYTHONVERBOSE")) && *p != '\0') if ((p = getenv("PYTHONVERBOSE")) && *p != '\0')
verbose = 1; verbose = 1;
if ((p = getenv("PYTHONINSPECT")) && *p != '\0') if ((p = getenv("PYTHONINSPECT")) && *p != '\0')
inspect = 1; inspect = 1;
if ((p = getenv("PYTHONKILLPRINT")) && *p != '\0') if ((p = getenv("PYTHONUNBUFFERED")) && *p != '\0')
killprint = 1; unbuffered = 1;
initargs(&argc, &argv); if (unbuffered) {
setbuf(stdout, (char *)NULL);
setbuf(stderr, (char *)NULL);
}
if (verbose)
fprintf(stderr, "Python %s\n%s\n",
getversion(), getcopyright());
initall(); initall();
setpythonargv(argc, argv); setpythonargv(argc, argv);
@ -69,3 +86,9 @@ main(argc, argv)
goaway(sts); goaway(sts);
/*NOTREACHED*/ /*NOTREACHED*/
} }
char *
getprogramname()
{
return argv0;
}

View file

@ -1,5 +1,5 @@
/*********************************************************** /***********************************************************
Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum, Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
Amsterdam, The Netherlands. Amsterdam, The Netherlands.
All Rights Reserved All Rights Reserved
@ -25,16 +25,20 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
/* Two PD getcwd() implementations. /* Two PD getcwd() implementations.
Author: Guido van Rossum, CWI Amsterdam, Jan 1991, <guido@cwi.nl>. */ Author: Guido van Rossum, CWI Amsterdam, Jan 1991, <guido@cwi.nl>. */
/* #define NO_GETWD /* Turn this on to popen pwd instead of calling getwd() */
#include <stdio.h> #include <stdio.h>
#include <errno.h> #include <errno.h>
#ifndef NO_GETWD #ifdef HAVE_GETWD
/* Default: Version for BSD systems -- use getwd() */ /* Version for BSD systems -- use getwd() */
#include "sys/param.h" #ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#endif
#ifndef MAXPATHLEN
#define MAXPATHLEN 1024
#endif
extern char *getwd(); extern char *getwd();
@ -63,11 +67,13 @@ getcwd(buf, size)
return buf; return buf;
} }
#else #else /* !HAVE_GETWD */
/* NO_GETWD defined: Version for backward UNIXes -- popen /bin/pwd */ /* Version for really old UNIX systems -- use pipe from pwd */
#ifndef PWD_CMD
#define PWD_CMD "/bin/pwd" #define PWD_CMD "/bin/pwd"
#endif
char * char *
getcwd(buf, size) getcwd(buf, size)
@ -97,4 +103,4 @@ getcwd(buf, size)
return buf; return buf;
} }
#endif #endif /* !HAVE_GETWD */

View file

@ -1,5 +1,5 @@
/*********************************************************** /***********************************************************
Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum, Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
Amsterdam, The Netherlands. Amsterdam, The Netherlands.
All Rights Reserved All Rights Reserved
@ -304,10 +304,8 @@ r_object(p)
case TYPE_FLOAT: case TYPE_FLOAT:
{ {
extern double strtod PROTO((const char *, char **)); extern double atof PROTO((const char *));
char buf[256]; char buf[256];
double res;
char *end;
n = r_byte(p); n = r_byte(p);
if (r_string(buf, (int)n, p) != n) { if (r_string(buf, (int)n, p) != n) {
err_setstr(EOFError, err_setstr(EOFError,
@ -315,18 +313,7 @@ r_object(p)
return NULL; return NULL;
} }
buf[n] = '\0'; buf[n] = '\0';
errno = 0; return newfloatobject(atof(buf));
res = strtod(buf, &end);
if (*end != '\0') {
err_setstr(ValueError, "bad float syntax");
return NULL;
}
if (errno != 0) {
err_setstr(ValueError,
"float constant too large");
return NULL;
}
return newfloatobject(res);
} }
case TYPE_STRING: case TYPE_STRING:

View file

@ -1,5 +1,5 @@
/*********************************************************** /***********************************************************
Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum, Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
Amsterdam, The Netherlands. Amsterdam, The Netherlands.
All Rights Reserved All Rights Reserved
@ -28,10 +28,22 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include "modsupport.h" #include "modsupport.h"
#include "import.h" #include "import.h"
#ifdef MPW /* MPW pushes 'extended' for float and double types with varargs */
typedef extended va_double;
#else
typedef double va_double;
#endif
/* initmodule2() has an additional parameter, 'passthrough', which is
passed as 'self' to functions defined in the module. This is used
e.g. by dynamically loaded modules on the Mac. */
object * object *
initmodule(name, methods) initmodule2(name, methods, passthrough)
char *name; char *name;
struct methodlist *methods; struct methodlist *methods;
object *passthrough;
{ {
object *m, *d, *v; object *m, *d, *v;
struct methodlist *ml; struct methodlist *ml;
@ -47,7 +59,7 @@ initmodule(name, methods)
fatal("out of mem for method name"); fatal("out of mem for method name");
sprintf(namebuf, "%s.%s", name, ml->ml_name); sprintf(namebuf, "%s.%s", name, ml->ml_name);
v = newmethodobject(namebuf, ml->ml_meth, v = newmethodobject(namebuf, ml->ml_meth,
(object *)NULL, ml->ml_varargs); (object *)passthrough, ml->ml_varargs);
/* XXX The malloc'ed memory in namebuf is never freed */ /* XXX The malloc'ed memory in namebuf is never freed */
if (v == NULL || dictinsert(d, ml->ml_name, v) != 0) { if (v == NULL || dictinsert(d, ml->ml_name, v) != 0) {
fprintf(stderr, "initializing module: %s\n", name); fprintf(stderr, "initializing module: %s\n", name);
@ -58,6 +70,16 @@ initmodule(name, methods)
return m; return m;
} }
/* The standard initmodule() passes NULL for 'self' */
object *
initmodule(name, methods)
char *name;
struct methodlist *methods;
{
return initmodule2(name, methods, (object *)NULL);
}
/* Helper for mkvalue() to scan the length of a format */ /* Helper for mkvalue() to scan the length of a format */
@ -99,7 +121,6 @@ do_arg(arg, p_format, p_va)
va_list *p_va; va_list *p_va;
{ {
char *format = *p_format; char *format = *p_format;
va_list va = *p_va;
if (arg == NULL) if (arg == NULL)
return 0; /* Incomplete tuple or list */ return 0; /* Incomplete tuple or list */
@ -112,7 +133,7 @@ do_arg(arg, p_format, p_va)
return 0; return 0;
n = gettuplesize(arg); n = gettuplesize(arg);
for (i = 0; i < n; i++) { for (i = 0; i < n; i++) {
if (!do_arg(gettupleitem(arg, i), &format, &va)) if (!do_arg(gettupleitem(arg, i), &format, p_va))
return 0; return 0;
} }
if (*format++ != ')') if (*format++ != ')')
@ -124,65 +145,67 @@ do_arg(arg, p_format, p_va)
return 0; return 0;
case 'b': /* byte -- very short int */ { case 'b': /* byte -- very short int */ {
char *p = va_arg(va, char *); char *p = va_arg(*p_va, char *);
if (is_intobject(arg)) long ival = getintvalue(arg);
*p = getintvalue(arg); if (ival == -1 && err_occurred())
else
return 0; return 0;
else
*p = ival;
break; break;
} }
case 'h': /* short int */ { case 'h': /* short int */ {
short *p = va_arg(va, short *); short *p = va_arg(*p_va, short *);
if (is_intobject(arg)) long ival = getintvalue(arg);
*p = getintvalue(arg); if (ival == -1 && err_occurred())
else
return 0; return 0;
else
*p = ival;
break; break;
} }
case 'i': /* int */ { case 'i': /* int */ {
int *p = va_arg(va, int *); int *p = va_arg(*p_va, int *);
if (is_intobject(arg)) long ival = getintvalue(arg);
*p = getintvalue(arg); if (ival == -1 && err_occurred())
else
return 0; return 0;
else
*p = ival;
break; break;
} }
case 'l': /* long int */ { case 'l': /* long int */ {
long *p = va_arg(va, long *); long *p = va_arg(*p_va, long *);
if (is_intobject(arg)) long ival = getintvalue(arg);
*p = getintvalue(arg); if (ival == -1 && err_occurred())
else
return 0; return 0;
else
*p = ival;
break; break;
} }
case 'f': /* float */ { case 'f': /* float */ {
float *p = va_arg(va, float *); float *p = va_arg(*p_va, float *);
if (is_floatobject(arg)) double dval = getfloatvalue(arg);
*p = getfloatvalue(arg); if (err_occurred())
else if (is_intobject(arg))
*p = (float)getintvalue(arg);
else
return 0; return 0;
else
*p = dval;
break; break;
} }
case 'd': /* double */ { case 'd': /* double */ {
double *p = va_arg(va, double *); double *p = va_arg(*p_va, double *);
if (is_floatobject(arg)) double dval = getfloatvalue(arg);
*p = getfloatvalue(arg); if (err_occurred())
else if (is_intobject(arg))
*p = (double)getintvalue(arg);
else
return 0; return 0;
else
*p = dval;
break; break;
} }
case 'c': /* char */ { case 'c': /* char */ {
char *p = va_arg(va, char *); char *p = va_arg(*p_va, char *);
if (is_stringobject(arg) && getstringsize(arg) == 1) if (is_stringobject(arg) && getstringsize(arg) == 1)
*p = getstringvalue(arg)[0]; *p = getstringvalue(arg)[0];
else else
@ -191,13 +214,13 @@ do_arg(arg, p_format, p_va)
} }
case 's': /* string */ { case 's': /* string */ {
char **p = va_arg(va, char **); char **p = va_arg(*p_va, char **);
if (is_stringobject(arg)) if (is_stringobject(arg))
*p = getstringvalue(arg); *p = getstringvalue(arg);
else else
return 0; return 0;
if (*format == '#') { if (*format == '#') {
int *q = va_arg(va, int *); int *q = va_arg(*p_va, int *);
*q = getstringsize(arg); *q = getstringsize(arg);
format++; format++;
} }
@ -209,7 +232,7 @@ do_arg(arg, p_format, p_va)
} }
case 'z': /* string, may be NULL (None) */ { case 'z': /* string, may be NULL (None) */ {
char **p = va_arg(va, char **); char **p = va_arg(*p_va, char **);
if (arg == None) if (arg == None)
*p = 0; *p = 0;
else if (is_stringobject(arg)) else if (is_stringobject(arg))
@ -217,7 +240,7 @@ do_arg(arg, p_format, p_va)
else else
return 0; return 0;
if (*format == '#') { if (*format == '#') {
int *q = va_arg(va, int *); int *q = va_arg(*p_va, int *);
if (arg == None) if (arg == None)
*q = 0; *q = 0;
else else
@ -232,7 +255,7 @@ do_arg(arg, p_format, p_va)
} }
case 'S': /* string object */ { case 'S': /* string object */ {
object **p = va_arg(va, object **); object **p = va_arg(*p_va, object **);
if (is_stringobject(arg)) if (is_stringobject(arg))
*p = arg; *p = arg;
else else
@ -241,8 +264,37 @@ do_arg(arg, p_format, p_va)
} }
case 'O': /* object */ { case 'O': /* object */ {
object **p = va_arg(va, object **); typeobject *type;
*p = arg; object **p;
if (*format == '!') {
format++;
type = va_arg(*p_va, typeobject*);
if (arg->ob_type != type)
return 0;
else {
p = va_arg(*p_va, object **);
*p = arg;
}
}
else if (*format == '?') {
inquiry pred = va_arg(*p_va, inquiry);
format++;
if ((*pred)(arg)) {
p = va_arg(*p_va, object **);
*p = arg;
}
}
else if (*format == '&') {
binaryfunc convert = va_arg(*p_va, binaryfunc);
void *addr = va_arg(*p_va, void *);
format++;
if (! (*convert)(arg, addr))
return 0;
}
else {
p = va_arg(*p_va, object **);
*p = arg;
}
break; break;
} }
@ -253,13 +305,12 @@ do_arg(arg, p_format, p_va)
} }
*p_va = va;
*p_format = format; *p_format = format;
return 1; return 1;
} }
#ifdef USE_STDARG #ifdef HAVE_STDARG_PROTOTYPES
/* VARARGS2 */ /* VARARGS2 */
int getargs(object *arg, char *format, ...) int getargs(object *arg, char *format, ...)
#else #else
@ -270,7 +321,7 @@ int getargs(va_alist) va_dcl
char *f; char *f;
int ok; int ok;
va_list va; va_list va;
#ifdef USE_STDARG #ifdef HAVE_STDARG_PROTOTYPES
va_start(va, format); va_start(va, format);
#else #else
@ -458,7 +509,7 @@ do_mkvalue(p_format, p_va)
case 'f': case 'f':
case 'd': case 'd':
return newfloatobject((double)va_arg(*p_va, double)); return newfloatobject((double)va_arg(*p_va, va_double));
case 'c': case 'c':
{ {
@ -517,7 +568,7 @@ do_mkvalue(p_format, p_va)
} }
} }
#ifdef USE_STDARG #ifdef HAVE_STDARG_PROTOTYPES
/* VARARGS 2 */ /* VARARGS 2 */
object *mkvalue(char *format, ...) object *mkvalue(char *format, ...)
#else #else
@ -527,7 +578,7 @@ object *mkvalue(va_alist) va_dcl
{ {
va_list va; va_list va;
object* retval; object* retval;
#ifdef USE_STDARG #ifdef HAVE_STDARG_PROTOTYPES
va_start(va, format); va_start(va, format);
#else #else
char *format; char *format;

View file

@ -1,5 +1,5 @@
/*********************************************************** /***********************************************************
Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum, Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
Amsterdam, The Netherlands. Amsterdam, The Netherlands.
All Rights Reserved All Rights Reserved
@ -26,9 +26,9 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#include "allobjects.h" #include "allobjects.h"
extern int debugging; /* Defined in parser.c */ extern int debugging; /* Needed in parser.c, declared in pythonrun.c */
extern int verbose; /* Defined in import.c */ extern int verbose; /* Needed in import.c, declared in pythonrun.c */
extern int killprint; /* Defined in ceval.c */ extern int suppress_print; /* Needed in ceval.c, declared in pythonrun.c */
/* Interface to getopt(): */ /* Interface to getopt(): */
extern int optind; extern int optind;
@ -37,7 +37,11 @@ extern int getopt(); /* PROTO((int, char **, char *)); -- not standardized */
extern char *getenv(); extern char *getenv();
main(argc, argv) extern char *getversion();
extern char *getcopyright();
int
realmain(argc, argv)
int argc; int argc;
char **argv; char **argv;
{ {
@ -48,19 +52,20 @@ main(argc, argv)
FILE *fp = stdin; FILE *fp = stdin;
char *p; char *p;
int inspect = 0; int inspect = 0;
int unbuffered = 0;
if ((p = getenv("PYTHONDEBUG")) && *p != '\0') if ((p = getenv("PYTHONDEBUG")) && *p != '\0')
debugging = 1; debugging = 1;
if ((p = getenv("PYTHONSUPPRESS")) && *p != '\0')
suppress_print = 1;
if ((p = getenv("PYTHONVERBOSE")) && *p != '\0') if ((p = getenv("PYTHONVERBOSE")) && *p != '\0')
verbose = 1; verbose = 1;
if ((p = getenv("PYTHONINSPECT")) && *p != '\0') if ((p = getenv("PYTHONINSPECT")) && *p != '\0')
inspect = 1; inspect = 1;
if ((p = getenv("PYTHONKILLPRINT")) && *p != '\0') if ((p = getenv("PYTHONUNBUFFERED")) && *p != '\0')
killprint = 1; unbuffered = 1;
initargs(&argc, &argv);
while ((c = getopt(argc, argv, "c:dikv")) != EOF) { while ((c = getopt(argc, argv, "c:disuv")) != EOF) {
if (c == 'c') { if (c == 'c') {
/* -c is the last option; following arguments /* -c is the last option; following arguments
that look like options are left for the that look like options are left for the
@ -82,8 +87,12 @@ main(argc, argv)
inspect++; inspect++;
break; break;
case 'k': case 's':
killprint++; suppress_print++;
break;
case 'u':
unbuffered++;
break; break;
case 'v': case 'v':
@ -94,16 +103,21 @@ main(argc, argv)
default: default:
fprintf(stderr, fprintf(stderr,
"usage: %s [-d] [-i] [-k] [-v] [-c cmd | file | -] [arg] ...\n", "usage: %s [-d] [-i] [-s] [-u ] [-v] [-c cmd | file | -] [arg] ...\n",
argv[0]); argv[0]);
fprintf(stderr, "\ fprintf(stderr, "\
\n\ \n\
Options and arguments (and corresponding environment variables):\n\ Options and arguments (and corresponding environment variables):\n\
-d : debug output from parser (also PYTHONDEBUG=x)\n\ -d : debug output from parser (also PYTHONDEBUG=x)\n\
-i : inspect interactively after running script (also PYTHONINSPECT=x)\n\ -i : inspect interactively after running script (also PYTHONINSPECT=x)\n\
-k : kill printing expression statement (also PYTHONKILLPRINT=x)\n\ -s : suppress the printing of top level expressions (also PYTHONSUPPRESS=x)\n\
-u : unbuffered stdout and stderr (also PYTHONUNBUFFERED=x)\n\
-v : verbose (trace import statements) (also PYTHONVERBOSE=x)\n\ -v : verbose (trace import statements) (also PYTHONVERBOSE=x)\n\
-c cmd : program passed in as string (terminates option list)\n\ -c cmd : program passed in as string (terminates option list)\n\
");
/* ANSI does not allow strings > 512 chars
and MPW doesn't like it either -- so split it! */
fprintf(stderr, "\
file : program read from script file\n\ file : program read from script file\n\
- : program read from stdin (default; interactive mode if a tty)\n\ - : program read from stdin (default; interactive mode if a tty)\n\
arg ...: arguments passed to program in sys.argv[1:]\n\ arg ...: arguments passed to program in sys.argv[1:]\n\
@ -118,9 +132,25 @@ PYTHONPATH : colon-separated list of directories prefixed to the\n\
} }
} }
if (unbuffered) {
#ifndef MPW
setbuf(stdout, (char *)NULL);
setbuf(stderr, (char *)NULL);
#else
/* On MPW (3.2) unbuffered seems to hang */
setvbuf(stdout, (char *)NULL, _IOLBF, BUFSIZ);
setvbuf(stderr, (char *)NULL, _IOLBF, BUFSIZ);
#endif
}
if (command == NULL && optind < argc && strcmp(argv[optind], "-") != 0) if (command == NULL && optind < argc && strcmp(argv[optind], "-") != 0)
filename = argv[optind]; filename = argv[optind];
if (verbose ||
command == NULL && filename == NULL && isatty((int)fileno(fp)))
fprintf(stderr, "Python %s\n%s\n",
getversion(), getcopyright());
if (filename != NULL) { if (filename != NULL) {
if ((fp = fopen(filename, "r")) == NULL) { if ((fp = fopen(filename, "r")) == NULL) {
@ -146,15 +176,22 @@ PYTHONPATH : colon-separated list of directories prefixed to the\n\
else { else {
if (filename == NULL && isatty((int)fileno(fp))) { if (filename == NULL && isatty((int)fileno(fp))) {
char *startup = getenv("PYTHONSTARTUP"); char *startup = getenv("PYTHONSTARTUP");
#ifdef macintosh
if (startup == NULL)
startup = "PythonStartup";
#endif
if (startup != NULL && startup[0] != '\0') { if (startup != NULL && startup[0] != '\0') {
FILE *fp = fopen(startup, "r"); FILE *fp = fopen(startup, "r");
if (fp != NULL) { if (fp != NULL) {
(void) run_script(fp, startup); (void) run_script(fp, startup);
err_clear(); err_clear();
fclose(fp);
} }
} }
} }
sts = run(fp, filename == NULL ? "<stdin>" : filename) != 0; sts = run(fp, filename == NULL ? "<stdin>" : filename) != 0;
if (filename != NULL)
fclose(fp);
} }
if (inspect && isatty((int)fileno(stdin)) && if (inspect && isatty((int)fileno(stdin)) &&

View file

@ -1,5 +1,5 @@
/*********************************************************** /***********************************************************
Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum, Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
Amsterdam, The Netherlands. Amsterdam, The Netherlands.
All Rights Reserved All Rights Reserved
@ -41,7 +41,7 @@ strerror(err)
return buf; return buf;
} }
#ifdef THINK_C #ifdef macintosh
int sys_nerr = 0; int sys_nerr = 0;
char *sys_errlist[1] = 0; char *sys_errlist[1] = 0;
#endif #endif

View file

@ -1,5 +1,5 @@
/*********************************************************** /***********************************************************
Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum, Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
Amsterdam, The Netherlands. Amsterdam, The Netherlands.
All Rights Reserved All Rights Reserved
@ -144,6 +144,11 @@ setmember(addr, mlist, name, v)
err_setstr(TypeError, "readonly attribute"); err_setstr(TypeError, "readonly attribute");
return -1; return -1;
} }
if (v == NULL && l->type != T_OBJECT) {
err_setstr(TypeError,
"can't delete numeric/char attribute");
return -1;
}
addr += l->offset; addr += l->offset;
switch (l->type) { switch (l->type) {
case T_BYTE: case T_BYTE:

View file

@ -1,5 +1,5 @@
/*********************************************************** /***********************************************************
Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum, Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
Amsterdam, The Netherlands. Amsterdam, The Netherlands.
All Rights Reserved All Rights Reserved
@ -168,16 +168,22 @@ list_builtin_module_names()
addlistitem(list, name); addlistitem(list, name);
DECREF(name); DECREF(name);
} }
if (sortlist(list) != 0) {
DECREF(list);
list = NULL;
}
return list; return list;
} }
void void
initsys() initsys()
{ {
extern long getmaxint PROTO((void));
extern char *getversion PROTO((void));
extern char *getcopyright PROTO((void));
extern int fclose PROTO((FILE *)); extern int fclose PROTO((FILE *));
extern char version[];
object *v = newstringobject(version);
object *m = initmodule("sys", sys_methods); object *m = initmodule("sys", sys_methods);
object *v;
sysdict = getmoduledict(m); sysdict = getmoduledict(m);
INCREF(sysdict); INCREF(sysdict);
/* NB keep an extra ref to the std files to avoid closing them /* NB keep an extra ref to the std files to avoid closing them
@ -186,17 +192,21 @@ initsys()
sysout = newopenfileobject(stdout, "<stdout>", "w", fclose); sysout = newopenfileobject(stdout, "<stdout>", "w", fclose);
syserr = newopenfileobject(stderr, "<stderr>", "w", fclose); syserr = newopenfileobject(stderr, "<stderr>", "w", fclose);
if (err_occurred()) if (err_occurred())
fatal("can't create sys.* objects"); fatal("can't initialize sys.std{in,out,err}");
dictinsert(sysdict, "stdin", sysin); dictinsert(sysdict, "stdin", sysin);
dictinsert(sysdict, "stdout", sysout); dictinsert(sysdict, "stdout", sysout);
dictinsert(sysdict, "stderr", syserr); dictinsert(sysdict, "stderr", syserr);
dictinsert(sysdict, "version", v); dictinsert(sysdict, "version", v = newstringobject(getversion()));
XDECREF(v);
dictinsert(sysdict, "copyright", v = newstringobject(getcopyright()));
XDECREF(v);
dictinsert(sysdict, "maxint", v = newintobject(getmaxint()));
XDECREF(v);
dictinsert(sysdict, "modules", get_modules()); dictinsert(sysdict, "modules", get_modules());
dictinsert(sysdict, "builtin_module_names", dictinsert(sysdict, "builtin_module_names",
list_builtin_module_names()); list_builtin_module_names());
if (err_occurred()) if (err_occurred())
fatal("can't insert sys.* objects in sys dict"); fatal("can't insert sys.* objects in sys dict");
DECREF(v);
} }
static object * static object *

View file

@ -1,5 +1,5 @@
/*********************************************************** /***********************************************************
Copyright 1991, 1992, 1993 by Stichting Mathematisch Centrum, Copyright 1991, 1992, 1993, 1994 by Stichting Mathematisch Centrum,
Amsterdam, The Netherlands. Amsterdam, The Netherlands.
All Rights Reserved All Rights Reserved
@ -22,66 +22,44 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
******************************************************************/ ******************************************************************/
/* Thread package.
This is intended to be usable independently from Python.
The implementation for system foobar is in a file thread_foobar.h
which is included by this file dependent on config settings.
Stuff shared by all thread_*.h files is collected here. */
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#else
extern char *getenv();
#endif
#include "thread.h" #include "thread.h"
#ifdef DEBUG #ifdef __ksr__
static int thread_debug = 0; #define _POSIX_THREADS
#define dprintf(args) ((thread_debug & 1) && printf args)
#define d2printf(args) ((thread_debug & 8) && printf args)
#else
#define dprintf(args)
#define d2printf(args)
#endif #endif
#ifndef _POSIX_THREADS
#ifdef __sgi #ifdef __sgi
#include <stdlib.h> #define SGI_THREADS
#include <stdio.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/prctl.h>
#include <ulocks.h>
#include <errno.h>
#define HDR_SIZE 2680 /* sizeof(ushdr_t) */
#define MAXPROC 100 /* max # of threads that can be started */
static usptr_t *shared_arena;
static ulock_t count_lock; /* protection for some variables */
static ulock_t wait_lock; /* lock used to wait for other threads */
static int waiting_for_threads; /* protected by count_lock */
static int nthreads; /* protected by count_lock */
static int exit_status;
static int do_exit; /* indicates that the program is to exit */
static int exiting; /* we're already exiting (for maybe_exit) */
static pid_t my_pid; /* PID of main thread */
static pid_t pidlist[MAXPROC]; /* PIDs of other threads */
static int maxpidindex; /* # of PIDs in pidlist */
#endif /* __sgi */
#ifdef SOLARIS
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include </usr/include/thread.h>
#undef sun
#endif #endif
#ifdef sun
#include <lwp/lwp.h>
#include <lwp/stackdep.h>
#define STACKSIZE 1000 /* stacksize for a thread */ #ifdef HAVE_THREAD_H
#define NSTACKS 2 /* # stacks to be put in cache initialy */ #define SOLARIS_THREADS
#endif
#if defined(sun) && !defined(SOLARIS_THREADS)
#define SUN_LWP
#endif
struct lock {
int lock_locked;
cv_t lock_condvar;
mon_t lock_monitor;
};
#endif /* sun */
#ifdef C_THREADS
#include <cthreads.h>
#endif /* C_THREADS */
#ifdef _POSIX_THREADS
#include <pthread.h>
#endif /* _POSIX_THREADS */ #endif /* _POSIX_THREADS */
#ifdef __STDC__ #ifdef __STDC__
@ -96,58 +74,21 @@ struct lock {
#define _P2(v1,t1,v2,t2) (v1,v2) t1; t2; #define _P2(v1,t1,v2,t2) (v1,v2) t1; t2;
#endif /* __STDC__ */ #endif /* __STDC__ */
#ifdef DEBUG
static int thread_debug = 0;
#define dprintf(args) ((thread_debug & 1) && printf args)
#define d2printf(args) ((thread_debug & 8) && printf args)
#else
#define dprintf(args)
#define d2printf(args)
#endif
static int initialized; static int initialized;
#ifdef __sgi static void _init_thread(); /* Forward */
/*
* This routine is called as a signal handler when another thread
* exits. When that happens, we must see whether we have to exit as
* well (because of an exit_prog()) or whether we should continue on.
*/
static void exit_sig _P0()
{
d2printf(("exit_sig called\n"));
if (exiting && getpid() == my_pid) {
d2printf(("already exiting\n"));
return;
}
if (do_exit) {
d2printf(("exiting in exit_sig\n"));
#ifdef DEBUG
if ((thread_debug & 8) == 0)
thread_debug &= ~1; /* don't produce debug messages */
#endif
exit_thread();
}
}
/*
* This routine is called when a process calls exit(). If that wasn't
* done from the library, we do as if an exit_prog() was intended.
*/
static void maybe_exit _P0()
{
dprintf(("maybe_exit called\n"));
if (exiting) {
dprintf(("already exiting\n"));
return;
}
exit_prog(0);
}
#endif /* __sgi */
/*
* Initialization.
*/
void init_thread _P0() void init_thread _P0()
{ {
#ifdef __sgi
struct sigaction s;
#ifdef USE_DL
long addr, size;
#endif /* USE_DL */
#endif /* __sgi */
#ifdef DEBUG #ifdef DEBUG
char *p = getenv("THREADDEBUG"); char *p = getenv("THREADDEBUG");
@ -162,465 +103,31 @@ void init_thread _P0()
return; return;
initialized = 1; initialized = 1;
dprintf(("init_thread called\n")); dprintf(("init_thread called\n"));
_init_thread();
#ifdef __sgi
#ifdef USE_DL
if ((size = usconfig(CONF_INITSIZE, 64*1024)) < 0)
perror("usconfig - CONF_INITSIZE (check)");
if (usconfig(CONF_INITSIZE, size) < 0)
perror("usconfig - CONF_INITSIZE (reset)");
addr = (long) dl_getrange(size + HDR_SIZE);
dprintf(("trying to use addr %lx-%lx for shared arena\n", addr, addr+size));
errno = 0;
if ((addr = usconfig(CONF_ATTACHADDR, addr)) < 0 && errno != 0)
perror("usconfig - CONF_ATTACHADDR (set)");
#endif /* USE_DL */
if (usconfig(CONF_INITUSERS, 16) < 0)
perror("usconfig - CONF_INITUSERS");
my_pid = getpid(); /* so that we know which is the main thread */
atexit(maybe_exit);
s.sa_handler = exit_sig;
sigemptyset(&s.sa_mask);
/*sigaddset(&s.sa_mask, SIGUSR1);*/
s.sa_flags = 0;
sigaction(SIGUSR1, &s, 0);
if (prctl(PR_SETEXITSIG, SIGUSR1) < 0)
perror("prctl - PR_SETEXITSIG");
if (usconfig(CONF_ARENATYPE, US_SHAREDONLY) < 0)
perror("usconfig - CONF_ARENATYPE");
#ifdef DEBUG
if (thread_debug & 4)
usconfig(CONF_LOCKTYPE, US_DEBUGPLUS);
else if (thread_debug & 2)
usconfig(CONF_LOCKTYPE, US_DEBUG);
#endif /* DEBUG */
if ((shared_arena = usinit(tmpnam(0))) == 0)
perror("usinit");
#ifdef USE_DL
if (usconfig(CONF_ATTACHADDR, addr) < 0) /* reset address */
perror("usconfig - CONF_ATTACHADDR (reset)");
#endif /* USE_DL */
if ((count_lock = usnewlock(shared_arena)) == NULL)
perror("usnewlock (count_lock)");
(void) usinitlock(count_lock);
if ((wait_lock = usnewlock(shared_arena)) == NULL)
perror("usnewlock (wait_lock)");
dprintf(("arena start: %lx, arena size: %ld\n", (long) shared_arena, (long) usconfig(CONF_GETSIZE, shared_arena)));
#endif /* __sgi */
#ifdef SOLARIS
/* nothing */
#endif
#ifdef sun
lwp_setstkcache(STACKSIZE, NSTACKS);
#endif /* sun */
#ifdef C_THREADS
cthread_init();
#endif /* C_THREADS */
} }
/* #ifdef SGI_THREADS
* Thread support. #include "thread_sgi.h"
*/
#ifdef SOLARIS
struct func_arg {
void (*func) _P((void *));
void *arg;
};
static void *new_func _P1(funcarg, void *funcarg)
{
void (*func) _P((void *));
void *arg;
func = ((struct func_arg *) funcarg)->func;
arg = ((struct func_arg *) funcarg)->arg;
free(funcarg);
(*func)(arg);
return 0;
}
#endif /* SOLARIS */
int start_new_thread _P2(func, void (*func) _P((void *)), arg, void *arg)
{
#ifdef SOLARIS
struct func_arg *funcarg;
#endif #endif
#ifdef sun
thread_t tid; #ifdef SOLARIS_THREADS
#endif /* sun */ #include "thread_solaris.h"
#if defined(__sgi) && defined(USE_DL) #endif
long addr, size;
static int local_initialized = 0; #ifdef SUN_LWP
#endif /* __sgi and USE_DL */ #include "thread_lwp.h"
#endif
#ifdef _POSIX_THREADS #ifdef _POSIX_THREADS
pthread_t th; #include "thread_pthread.h"
#endif #endif
int success = 0; /* init not needed when SOLARIS and */
/* C_THREADS implemented properly */
dprintf(("start_new_thread called\n"));
if (!initialized)
init_thread();
#ifdef __sgi
switch (ussetlock(count_lock)) {
case 0: return 0;
case -1: perror("ussetlock (count_lock)");
}
if (maxpidindex >= MAXPROC)
success = -1;
else {
#ifdef USE_DL
if (!local_initialized) {
if ((size = usconfig(CONF_INITSIZE, 64*1024)) < 0)
perror("usconfig - CONF_INITSIZE (check)");
if (usconfig(CONF_INITSIZE, size) < 0)
perror("usconfig - CONF_INITSIZE (reset)");
addr = (long) dl_getrange(size + HDR_SIZE);
dprintf(("trying to use addr %lx-%lx for sproc\n", addr, addr+size));
errno = 0;
if ((addr = usconfig(CONF_ATTACHADDR, addr)) < 0 && errno != 0)
perror("usconfig - CONF_ATTACHADDR (set)");
}
#endif /* USE_DL */
if ((success = sproc(func, PR_SALL, arg)) < 0)
perror("sproc");
#ifdef USE_DL
if (!local_initialized) {
if (usconfig(CONF_ATTACHADDR, addr) < 0) /* reset address */
perror("usconfig - CONF_ATTACHADDR (reset)");
local_initialized = 1;
}
#endif /* USE_DL */
if (success >= 0) {
nthreads++;
pidlist[maxpidindex++] = success;
}
}
if (usunsetlock(count_lock) < 0)
perror("usunsetlock (count_lock)");
#endif /* __sgi */
#ifdef SOLARIS
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)) {
perror("thr_create");
free((void *) funcarg);
success = -1;
}
#endif /* SOLARIS */
#ifdef sun
success = lwp_create(&tid, func, MINPRIO, 0, lwp_newstk(), 1, arg);
#endif /* sun */
#ifdef C_THREADS #ifdef C_THREADS
(void) cthread_fork(func, arg); #include "thread_cthread.h"
#endif /* C_THREADS */
#ifdef _POSIX_THREADS
pthread_create(&th, NULL, func, arg);
#endif #endif
return success < 0 ? 0 : 1;
}
static void do_exit_thread _P1(no_cleanup, int no_cleanup)
{
dprintf(("exit_thread called\n"));
if (!initialized)
if (no_cleanup)
_exit(0);
else
exit(0);
#ifdef __sgi
if (ussetlock(count_lock) < 0)
perror("ussetlock (count_lock)");
nthreads--;
if (getpid() == my_pid) {
/* main thread; wait for other threads to exit */
exiting = 1;
if (do_exit) {
int i;
/* notify other threads */
if (nthreads >= 0) {
dprintf(("kill other threads\n"));
for (i = 0; i < maxpidindex; i++)
(void) kill(pidlist[i], SIGKILL);
_exit(exit_status);
}
}
waiting_for_threads = 1;
if (ussetlock(wait_lock) < 0)
perror("ussetlock (wait_lock)");
for (;;) {
if (nthreads < 0) {
dprintf(("really exit (%d)\n", exit_status));
if (no_cleanup)
_exit(exit_status);
else
exit(exit_status);
}
if (usunsetlock(count_lock) < 0)
perror("usunsetlock (count_lock)");
dprintf(("waiting for other threads (%d)\n", nthreads));
if (ussetlock(wait_lock) < 0)
perror("ussetlock (wait_lock)");
if (ussetlock(count_lock) < 0)
perror("ussetlock (count_lock)");
}
}
/* not the main thread */
if (waiting_for_threads) {
dprintf(("main thread is waiting\n"));
if (usunsetlock(wait_lock) < 0)
perror("usunsetlock (wait_lock)");
} else if (do_exit)
(void) kill(my_pid, SIGUSR1);
if (usunsetlock(count_lock) < 0)
perror("usunsetlock (count_lock)");
_exit(0);
#endif /* __sgi */
#ifdef SOLARIS
thr_exit(0);
#endif /* SOLARIS */
#ifdef sun
lwp_destroy(SELF);
#endif /* sun */
#ifdef C_THREADS
cthread_exit(0);
#endif /* C_THREADS */
}
void exit_thread _P0()
{
do_exit_thread(0);
}
void _exit_thread _P0()
{
do_exit_thread(1);
}
static void do_exit_prog _P2(status, int status, no_cleanup, int no_cleanup)
{
dprintf(("exit_prog(%d) called\n", status));
if (!initialized)
if (no_cleanup)
_exit(status);
else
exit(status);
#ifdef __sgi
do_exit = 1;
exit_status = status;
do_exit_thread(no_cleanup);
#endif
#ifdef SOLARIS
if (no_cleanup)
_exit(status);
else
exit(status);
#endif
#ifdef sun
pod_exit(status);
#endif
}
void exit_prog _P1(status, int status)
{
do_exit_prog(status, 0);
}
void _exit_prog _P1(status, int status)
{
do_exit_prog(status, 1);
}
/* /*
* Lock support. #ifdef FOOBAR_THREADS
*/ #include "thread_foobar.h"
type_lock allocate_lock _P0()
{
#ifdef __sgi
ulock_t lock;
#endif #endif
#ifdef SOLARIS */
mutex_t *lock;
#endif
#ifdef sun
struct lock *lock;
extern char *malloc();
#endif
dprintf(("allocate_lock called\n"));
if (!initialized)
init_thread();
#ifdef __sgi
if ((lock = usnewlock(shared_arena)) == NULL)
perror("usnewlock");
(void) usinitlock(lock);
#endif /* __sgi */
#ifdef SOLARIS
lock = (mutex_t *) malloc(sizeof(mutex_t));
if (mutex_init(lock, USYNC_THREAD, 0)) {
perror("mutex_init");
free((void *) lock);
lock = 0;
}
#endif /* SOLARIS */
#ifdef sun
lock = (struct lock *) malloc(sizeof(struct lock));
lock->lock_locked = 0;
(void) mon_create(&lock->lock_monitor);
(void) cv_create(&lock->lock_condvar, lock->lock_monitor);
#endif /* sun */
dprintf(("allocate_lock() -> %lx\n", (long)lock));
return (type_lock) lock;
}
void free_lock _P1(lock, type_lock lock)
{
dprintf(("free_lock(%lx) called\n", (long)lock));
#ifdef __sgi
usfreelock((ulock_t) lock, shared_arena);
#endif /* __sgi */
#ifdef SOLARIS
mutex_destroy((mutex_t *) lock);
free((void *) lock);
#endif
#ifdef sun
mon_destroy(((struct lock *) lock)->lock_monitor);
free((char *) lock);
#endif /* sun */
}
int acquire_lock _P2(lock, type_lock lock, waitflag, int waitflag)
{
int success;
dprintf(("acquire_lock(%lx, %d) called\n", (long)lock, waitflag));
#ifdef __sgi
errno = 0; /* clear it just in case */
if (waitflag)
success = ussetlock((ulock_t) lock);
else
success = uscsetlock((ulock_t) lock, 1); /* Try it once */
if (success < 0)
perror(waitflag ? "ussetlock" : "uscsetlock");
#endif /* __sgi */
#ifdef SOLARIS
if (waitflag)
success = mutex_lock((mutex_t *) lock);
else
success = mutex_trylock((mutex_t *) lock);
if (success < 0)
perror(waitflag ? "mutex_lock" : "mutex_trylock");
else
success = !success; /* solaris does it the other way round */
#endif /* SOLARIS */
#ifdef sun
success = 0;
(void) mon_enter(((struct lock *) lock)->lock_monitor);
if (waitflag)
while (((struct lock *) lock)->lock_locked)
cv_wait(((struct lock *) lock)->lock_condvar);
if (!((struct lock *) lock)->lock_locked) {
success = 1;
((struct lock *) lock)->lock_locked = 1;
}
cv_broadcast(((struct lock *) lock)->lock_condvar);
mon_exit(((struct lock *) lock)->lock_monitor);
#endif /* sun */
dprintf(("acquire_lock(%lx, %d) -> %d\n", (long)lock, waitflag, success));
return success;
}
void release_lock _P1(lock, type_lock lock)
{
dprintf(("release_lock(%lx) called\n", (long)lock));
#ifdef __sgi
if (usunsetlock((ulock_t) lock) < 0)
perror("usunsetlock");
#endif /* __sgi */
#ifdef SOLARIS
if (mutex_unlock((mutex_t *) lock))
perror("mutex_unlock");
#endif /* SOLARIS */
#ifdef sun
(void) mon_enter(((struct lock *) lock)->lock_monitor);
((struct lock *) lock)->lock_locked = 0;
cv_broadcast(((struct lock *) lock)->lock_condvar);
mon_exit(((struct lock *) lock)->lock_monitor);
#endif /* sun */
}
/*
* Semaphore support.
*/
type_sema allocate_sema _P1(value, int value)
{
#ifdef __sgi
usema_t *sema;
#endif /* __sgi */
#ifdef SOLARIS
sema_t *sema;
#endif
dprintf(("allocate_sema called\n"));
if (!initialized)
init_thread();
#ifdef __sgi
if ((sema = usnewsema(shared_arena, value)) == NULL)
perror("usnewsema");
#endif /* __sgi */
#ifdef SOLARIS
sema = (sema_t *) malloc(sizeof(sema_t));
if (sema_init(sema, value, USYNC_THREAD, 0)) {
perror("sema_init");
free((void *) sema);
sema = 0;
}
#endif /* SOLARIS */
dprintf(("allocate_sema() -> %lx\n", (long) sema));
return (type_sema) sema;
}
void free_sema _P1(sema, type_sema sema)
{
dprintf(("free_sema(%lx) called\n", (long) sema));
#ifdef __sgi
usfreesema((usema_t *) sema, shared_arena);
#endif /* __sgi */
#ifdef SOLARIS
if (sema_destroy((sema_t *) sema))
perror("sema_destroy");
free((void *) sema);
#endif /* SOLARIS */
}
void down_sema _P1(sema, type_sema sema)
{
dprintf(("down_sema(%lx) called\n", (long) sema));
#ifdef __sgi
if (uspsema((usema_t *) sema) < 0)
perror("uspsema");
#endif
#ifdef SOLARIS
if (sema_wait((sema_t *) sema))
perror("sema_wait");
#endif
dprintf(("down_sema(%lx) return\n", (long) sema));
}
void up_sema _P1(sema, type_sema sema)
{
dprintf(("up_sema(%lx)\n", (long) sema));
#ifdef __sgi
if (usvsema((usema_t *) sema) < 0)
perror("usvsema");
#endif /* __sgi */
#ifdef SOLARIS
if (sema_post((sema_t *) sema))
perror("sema_post");
#endif
}