bltinmodule.c revision 006bcd42ac082f05560f60577c08c957a8d38371
1/***********************************************************
2Copyright 1991 by Stichting Mathematisch Centrum, Amsterdam, The
3Netherlands.
4
5                        All Rights Reserved
6
7Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
9provided that the above copyright notice appear in all copies and that
10both that copyright notice and this permission notice appear in
11supporting documentation, and that the names of Stichting Mathematisch
12Centrum or CWI not be used in advertising or publicity pertaining to
13distribution of the software without specific, written prior permission.
14
15STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22
23******************************************************************/
24
25/* Built-in functions */
26
27#include "allobjects.h"
28
29#include "node.h"
30#include "graminit.h"
31#include "errcode.h"
32#include "sysmodule.h"
33#include "bltinmodule.h"
34#include "import.h"
35#include "pythonrun.h"
36#include "compile.h" /* For ceval.h */
37#include "ceval.h"
38#include "modsupport.h"
39
40/* Should be in longobject.h */
41extern stringobject *long_format PROTO((object *, int));
42
43static object *
44builtin_abs(self, v)
45	object *self;
46	object *v;
47{
48	number_methods *nm;
49	if (v == NULL || (nm = v->ob_type->tp_as_number) == NULL) {
50		err_setstr(TypeError, "abs() requires numeric argument");
51		return NULL;
52	}
53	return (*nm->nb_absolute)(v);
54}
55
56static object *
57builtin_chr(self, v)
58	object *self;
59	object *v;
60{
61	long x;
62	char s[1];
63	if (v == NULL || !is_intobject(v)) {
64		err_setstr(TypeError, "chr() requires int argument");
65		return NULL;
66	}
67	x = getintvalue(v);
68	if (x < 0 || x >= 256) {
69		err_setstr(RuntimeError, "chr() arg not in range(256)");
70		return NULL;
71	}
72	s[0] = x;
73	return newsizedstringobject(s, 1);
74}
75
76static object *
77builtin_dir(self, v)
78	object *self;
79	object *v;
80{
81	object *d;
82	if (v == NULL) {
83		d = getlocals();
84		INCREF(d);
85	}
86	else {
87		d = getattr(v, "__dict__");
88		if (d == NULL) {
89			err_setstr(TypeError,
90				"dir() argument must have __dict__ attribute");
91			return NULL;
92		}
93	}
94	if (is_dictobject(d)) {
95		v = getdictkeys(d);
96		if (sortlist(v) != 0) {
97			DECREF(v);
98			v = NULL;
99		}
100	}
101	else {
102		v = newlistobject(0);
103	}
104	DECREF(d);
105	return v;
106}
107
108static object *
109builtin_divmod(self, args)
110	object *self;
111	object *args;
112{
113	object *v, *w, *x;
114	if (args == NULL || !is_tupleobject(args) || gettuplesize(args) != 2) {
115		err_setstr(TypeError, "divmod() requires 2 arguments");
116		return NULL;
117	}
118	v = gettupleitem(args, 0);
119	w = gettupleitem(args, 1);
120	if (v->ob_type->tp_as_number == NULL ||
121				w->ob_type->tp_as_number == NULL) {
122		err_setstr(TypeError, "divmod() requires numeric arguments");
123		return NULL;
124	}
125	if (coerce(&v, &w) != 0)
126		return NULL;
127	x = (*v->ob_type->tp_as_number->nb_divmod)(v, w);
128	DECREF(v);
129	DECREF(w);
130	return x;
131}
132
133static object *
134exec_eval(v, start)
135	object *v;
136	int start;
137{
138	object *str = NULL, *globals = NULL, *locals = NULL;
139	int n;
140	if (v != NULL) {
141		if (is_stringobject(v))
142			str = v;
143		else if (is_tupleobject(v) &&
144				((n = gettuplesize(v)) == 2 || n == 3)) {
145			str = gettupleitem(v, 0);
146			globals = gettupleitem(v, 1);
147			if (n == 3)
148				locals = gettupleitem(v, 2);
149		}
150	}
151	if (str == NULL || !is_stringobject(str) ||
152			globals != NULL && !is_dictobject(globals) ||
153			locals != NULL && !is_dictobject(locals)) {
154		err_setstr(TypeError,
155		    "exec/eval arguments must be string[,dict[,dict]]");
156		return NULL;
157	}
158	return run_string(getstringvalue(str), start, globals, locals);
159}
160
161static object *
162builtin_eval(self, v)
163	object *self;
164	object *v;
165{
166	return exec_eval(v, eval_input);
167}
168
169static object *
170builtin_exec(self, v)
171	object *self;
172	object *v;
173{
174	return exec_eval(v, file_input);
175}
176
177static object *
178builtin_float(self, v)
179	object *self;
180	object *v;
181{
182	if (v == NULL) {
183		/* */
184	}
185	else if (is_intobject(v)) {
186		long x = getintvalue(v);
187		return newfloatobject((double)x);
188	}
189	else if (is_longobject(v)) {
190		return newfloatobject(dgetlongvalue(v));
191	}
192	else if (is_floatobject(v)) {
193		INCREF(v);
194		return v;
195	}
196	err_setstr(TypeError, "float() argument must be int, long or float");
197	return NULL;
198}
199
200static object *
201builtin_hex(self, v)
202	object *self;
203	object *v;
204{
205	if (v != NULL) {
206		if (is_intobject(v)) {
207			char buf[20];
208			long x = getintvalue(v);
209			if (x >= 0)
210				sprintf(buf, "0x%lx", x);
211			else
212				sprintf(buf, "-0x%lx", -x);
213			return newstringobject(buf);
214		}
215		if (is_longobject(v)) {
216			return (object *) long_format(v, 16);
217		}
218	}
219	err_setstr(TypeError, "hex() requires int/long argument");
220	return NULL;
221}
222
223static object *
224builtin_input(self, v)
225	object *self;
226	object *v;
227{
228	FILE *in = sysgetfile("stdin", stdin);
229	FILE *out = sysgetfile("stdout", stdout);
230	node *n;
231	int err;
232	object *m, *d;
233	flushline();
234	if (v != NULL) {
235		if (printobject(v, out, PRINT_RAW) != 0)
236			return NULL;
237	}
238	m = add_module("__main__");
239	d = getmoduledict(m);
240	return run_file(in, "<stdin>", expr_input, d, d);
241}
242
243static object *
244builtin_int(self, v)
245	object *self;
246	object *v;
247{
248	if (v == NULL) {
249		/* */
250	}
251	else if (is_intobject(v)) {
252		INCREF(v);
253		return v;
254	}
255	else if (is_longobject(v)) {
256		long x;
257		x = getlongvalue(v);
258		if (err_occurred())
259			return NULL;
260		return newintobject(x);
261	}
262	else if (is_floatobject(v)) {
263		double x = getfloatvalue(v);
264		/* XXX should check for overflow */
265		return newintobject((long)x);
266	}
267	err_setstr(TypeError, "int() argument must be int, long or float");
268	return NULL;
269}
270
271static object *
272builtin_len(self, v)
273	object *self;
274	object *v;
275{
276	long len;
277	typeobject *tp;
278	if (v == NULL) {
279		err_setstr(TypeError, "len() without argument");
280		return NULL;
281	}
282	tp = v->ob_type;
283	if (tp->tp_as_sequence != NULL) {
284		len = (*tp->tp_as_sequence->sq_length)(v);
285	}
286	else if (tp->tp_as_mapping != NULL) {
287		len = (*tp->tp_as_mapping->mp_length)(v);
288	}
289	else {
290		err_setstr(TypeError, "len() of unsized object");
291		return NULL;
292	}
293	return newintobject(len);
294}
295
296static object *
297builtin_long(self, v)
298	object *self;
299	object *v;
300{
301	if (v == NULL) {
302		/* */
303	}
304	else if (is_intobject(v)) {
305		return newlongobject(getintvalue(v));
306	}
307	else if (is_longobject(v)) {
308		INCREF(v);
309		return v;
310	}
311	else if (is_floatobject(v)) {
312		double x = getfloatvalue(v);
313		return dnewlongobject(x);
314	}
315	err_setstr(TypeError, "long() argument must be int, long or float");
316	return NULL;
317}
318
319static object *
320min_max(v, sign)
321	object *v;
322	int sign;
323{
324	int i, n, cmp;
325	object *w, *x;
326	sequence_methods *sq;
327	if (v == NULL) {
328		err_setstr(TypeError, "min() or max() without argument");
329		return NULL;
330	}
331	sq = v->ob_type->tp_as_sequence;
332	if (sq == NULL) {
333		err_setstr(TypeError, "min() or max() of non-sequence");
334		return NULL;
335	}
336	n = (*sq->sq_length)(v);
337	if (n == 0) {
338		err_setstr(RuntimeError, "min() or max() of empty sequence");
339		return NULL;
340	}
341	w = (*sq->sq_item)(v, 0); /* Implies INCREF */
342	for (i = 1; i < n; i++) {
343		x = (*sq->sq_item)(v, i); /* Implies INCREF */
344		cmp = cmpobject(x, w);
345		if (cmp * sign > 0) {
346			DECREF(w);
347			w = x;
348		}
349		else
350			DECREF(x);
351	}
352	return w;
353}
354
355static object *
356builtin_min(self, v)
357	object *self;
358	object *v;
359{
360	return min_max(v, -1);
361}
362
363static object *
364builtin_max(self, v)
365	object *self;
366	object *v;
367{
368	return min_max(v, 1);
369}
370
371static object *
372builtin_oct(self, v)
373	object *self;
374	object *v;
375{
376	if (v != NULL) {
377		if (is_intobject(v)) {
378			char buf[20];
379			long x = getintvalue(v);
380			if (x >= 0)
381				sprintf(buf, "0%lo", x);
382			else
383				sprintf(buf, "-0%lo", -x);
384			return newstringobject(buf);
385		}
386		if (is_longobject(v)) {
387			return (object *) long_format(v, 8);
388		}
389	}
390	err_setstr(TypeError, "oct() requires int/long argument");
391	return NULL;
392}
393
394static object *
395builtin_open(self, v)
396	object *self;
397	object *v;
398{
399	object *name, *mode;
400	if (v == NULL || !is_tupleobject(v) || gettuplesize(v) != 2 ||
401		!is_stringobject(name = gettupleitem(v, 0)) ||
402		!is_stringobject(mode = gettupleitem(v, 1))) {
403		err_setstr(TypeError, "open() requires 2 string arguments");
404		return NULL;
405	}
406	v = newfileobject(getstringvalue(name), getstringvalue(mode));
407	return v;
408}
409
410static object *
411builtin_ord(self, v)
412	object *self;
413	object *v;
414{
415	if (v == NULL || !is_stringobject(v)) {
416		err_setstr(TypeError, "ord() must have string argument");
417		return NULL;
418	}
419	if (getstringsize(v) != 1) {
420		err_setstr(RuntimeError, "ord() arg must have length 1");
421		return NULL;
422	}
423	return newintobject((long)(getstringvalue(v)[0] & 0xff));
424}
425
426static object *
427builtin_pow(self, args)
428	object *self;
429	object *args;
430{
431	object *v, *w, *x;
432	if (args == NULL || !is_tupleobject(args) || gettuplesize(args) != 2) {
433		err_setstr(TypeError, "pow() requires 2 arguments");
434		return NULL;
435	}
436	v = gettupleitem(args, 0);
437	w = gettupleitem(args, 1);
438	if (v->ob_type->tp_as_number == NULL ||
439				w->ob_type->tp_as_number == NULL) {
440		err_setstr(TypeError, "pow() requires numeric arguments");
441		return NULL;
442	}
443	if (coerce(&v, &w) != 0)
444		return NULL;
445	x = (*v->ob_type->tp_as_number->nb_power)(v, w);
446	DECREF(v);
447	DECREF(w);
448	return x;
449}
450
451static object *
452builtin_range(self, v)
453	object *self;
454	object *v;
455{
456	static char *errmsg = "range() requires 1-3 int arguments";
457	int i, n;
458	long ilow, ihigh, istep;
459	if (v != NULL && is_intobject(v)) {
460		ilow = 0; ihigh = getintvalue(v); istep = 1;
461	}
462	else if (v == NULL || !is_tupleobject(v)) {
463		err_setstr(TypeError, errmsg);
464		return NULL;
465	}
466	else {
467		n = gettuplesize(v);
468		if (n < 1 || n > 3) {
469			err_setstr(TypeError, errmsg);
470			return NULL;
471		}
472		for (i = 0; i < n; i++) {
473			if (!is_intobject(gettupleitem(v, i))) {
474				err_setstr(TypeError, errmsg);
475				return NULL;
476			}
477		}
478		if (n == 3) {
479			istep = getintvalue(gettupleitem(v, 2));
480			--n;
481		}
482		else
483			istep = 1;
484		ihigh = getintvalue(gettupleitem(v, --n));
485		if (n > 0)
486			ilow = getintvalue(gettupleitem(v, 0));
487		else
488			ilow = 0;
489	}
490	if (istep == 0) {
491		err_setstr(RuntimeError, "zero step for range()");
492		return NULL;
493	}
494	/* XXX ought to check overflow of subtraction */
495	if (istep > 0)
496		n = (ihigh - ilow + istep - 1) / istep;
497	else
498		n = (ihigh - ilow + istep + 1) / istep;
499	if (n < 0)
500		n = 0;
501	v = newlistobject(n);
502	if (v == NULL)
503		return NULL;
504	for (i = 0; i < n; i++) {
505		object *w = newintobject(ilow);
506		if (w == NULL) {
507			DECREF(v);
508			return NULL;
509		}
510		setlistitem(v, i, w);
511		ilow += istep;
512	}
513	return v;
514}
515
516static object *
517builtin_raw_input(self, v)
518	object *self;
519	object *v;
520{
521	FILE *out = sysgetfile("stdout", stdout);
522	flushline();
523	if (v != NULL) {
524		if (printobject(v, out, PRINT_RAW) != 0)
525			return NULL;
526	}
527	return filegetline(sysget("stdin"), -1);
528}
529
530static object *
531builtin_reload(self, v)
532	object *self;
533	object *v;
534{
535	return reload_module(v);
536}
537
538static object *
539builtin_type(self, v)
540	object *self;
541	object *v;
542{
543	if (v == NULL) {
544		err_setstr(TypeError, "type() requres an argument");
545		return NULL;
546	}
547	v = (object *)v->ob_type;
548	INCREF(v);
549	return v;
550}
551
552static struct methodlist builtin_methods[] = {
553	{"abs", builtin_abs},
554	{"chr", builtin_chr},
555	{"dir", builtin_dir},
556	{"divmod", builtin_divmod},
557	{"eval", builtin_eval},
558	{"exec", builtin_exec},
559	{"float", builtin_float},
560	{"hex", builtin_hex},
561	{"input", builtin_input},
562	{"int", builtin_int},
563	{"len", builtin_len},
564	{"long", builtin_long},
565	{"max", builtin_max},
566	{"min", builtin_min},
567	{"oct", builtin_oct},
568	{"open", builtin_open}, /* XXX move to OS module */
569	{"ord", builtin_ord},
570	{"pow", builtin_pow},
571	{"range", builtin_range},
572	{"raw_input", builtin_raw_input},
573	{"reload", builtin_reload},
574	{"type", builtin_type},
575	{NULL, NULL},
576};
577
578static object *builtin_dict;
579
580object *
581getbuiltin(name)
582	object *name;
583{
584	return dict2lookup(builtin_dict, name);
585}
586
587/* Predefined exceptions */
588
589object *RuntimeError;
590object *EOFError;
591object *TypeError;
592object *MemoryError;
593object *NameError;
594object *SystemError;
595object *KeyboardInterrupt;
596
597static object *
598newstdexception(name, message)
599	char *name, *message;
600{
601	object *v = newstringobject(message);
602	if (v == NULL || dictinsert(builtin_dict, name, v) != 0)
603		fatal("no mem for new standard exception");
604	return v;
605}
606
607static void
608initerrors()
609{
610	RuntimeError = newstdexception("RuntimeError", "run-time error");
611	EOFError = newstdexception("EOFError", "end-of-file read");
612	TypeError = newstdexception("TypeError", "type error");
613	MemoryError = newstdexception("MemoryError", "out of memory");
614	NameError = newstdexception("NameError", "undefined name");
615	SystemError = newstdexception("SystemError", "system error");
616	KeyboardInterrupt =
617		newstdexception("KeyboardInterrupt", "keyboard interrupt");
618}
619
620void
621initbuiltin()
622{
623	object *m;
624	m = initmodule("builtin", builtin_methods);
625	builtin_dict = getmoduledict(m);
626	INCREF(builtin_dict);
627	initerrors();
628	(void) dictinsert(builtin_dict, "None", None);
629}
630
631/* Coerce two numeric types to the "larger" one.
632   Increment the reference count on each argument.
633   Return -1 and raise an exception if no coercion is possible
634   (and then no reference count is incremented).
635   XXX This should be distributed over the various numeric types,
636   XXX but for now I don't see how to implement that.
637   XXX So, for now, if you add a new numeric type,
638   XXX you must add to this function as well. */
639
640int
641coerce(pv, pw)
642	object **pv, **pw;
643{
644	register object *v = *pv;
645	register object *w = *pw;
646	if (v->ob_type == w->ob_type) {
647		INCREF(v);
648		INCREF(w);
649		return 0;
650	}
651	if (v->ob_type->tp_as_number == NULL ||
652					w->ob_type->tp_as_number == NULL) {
653		err_setstr(TypeError, "mixing number and non-number");
654		return -1;
655	}
656	if (is_floatobject(v) || is_floatobject(w)) {
657		v = builtin_float((object *)0, v);
658		w = builtin_float((object *)0, w);
659	}
660	else if (is_longobject(v) || is_longobject(w)) {
661		v = builtin_long((object *)0, v);
662		w = builtin_long((object *)0, w);
663	}
664	else {
665		err_setstr(TypeError, "can't coerce numeric types?!?!?");
666		return -1;
667	}
668	if (v == NULL || w == NULL) {
669		XDECREF(v);
670		XDECREF(w);
671		return -1;
672	}
673	*pv = v;
674	*pw = w;
675	return 0;
676}
677