/***********************************************************
Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
The Netherlands.

                        All Rights Reserved

Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted,
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in
supporting documentation, and that the names of Stichting Mathematisch
Centrum or CWI or Corporation for National Research Initiatives or
CNRI not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.

While CWI is the initial source for this software, a modified version
is made available by the Corporation for National Research Initiatives
(CNRI) at the Internet address ftp://ftp.python.org.

STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.

******************************************************************/

/* Built-in functions */

#include "allobjects.h"

#include "node.h"
#include "graminit.h"
#include "bltinmodule.h"
#include "import.h"
#include "compile.h"
#include "eval.h"

#include "mymath.h"

/* Forward */
static object *filterstring PROTO((object *, object *));
static object *filtertuple  PROTO((object *, object *));

static object *
builtin___import__(self, args)
	object *self;
	object *args;
{
	char *name;
	object *globals = NULL;
	object *locals = NULL;
	object *fromlist = NULL;

	if (!newgetargs(args, "s|OOO:__import__",
			&name, &globals, &locals, &fromlist))
		return NULL;
	return import_module(name);
}


static object *
builtin_abs(self, args)
	object *self;
	object *args;
{
	object *v;
	number_methods *nm;

	if (!newgetargs(args, "O:abs", &v))
		return NULL;
	if ((nm = v->ob_type->tp_as_number) == NULL) {
		err_setstr(TypeError, "abs() requires numeric argument");
		return NULL;
	}
	return (*nm->nb_absolute)(v);
}

static object *
builtin_apply(self, args)
	object *self;
	object *args;
{
	object *func, *alist = NULL, *kwdict = NULL;

	if (!newgetargs(args, "O|OO:apply", &func, &alist, &kwdict))
		return NULL;
	if (alist != NULL && !is_tupleobject(alist)) {
		err_setstr(TypeError, "apply() 2nd argument must be tuple");
		return NULL;
	}
	if (kwdict != NULL && !is_dictobject(kwdict)) {
		err_setstr(TypeError,
			   "apply() 3rd argument must be dictionary");
		return NULL;
	}
	return PyEval_CallObjectWithKeywords(func, alist, kwdict);
}

static object *
builtin_callable(self, args)
	object *self;
	object *args;
{
	object *v;

	if (!newgetargs(args, "O:callable", &v))
		return NULL;
	return newintobject((long)callable(v));
}

static object *
builtin_filter(self, args)
	object *self;
	object *args;
{
	object *func, *seq, *result;
	sequence_methods *sqf;
	int len;
	register int i, j;

	if (!newgetargs(args, "OO:filter", &func, &seq))
		return NULL;

	if (is_stringobject(seq)) {
		object *r = filterstring(func, seq);
		return r;
	}

	if (is_tupleobject(seq)) {
		object *r = filtertuple(func, seq);
		return r;
	}

	if ((sqf = seq->ob_type->tp_as_sequence) == NULL) {
		err_setstr(TypeError,
			   "argument 2 to filter() must be a sequence type");
		goto Fail_2;
	}

	if ((len = (*sqf->sq_length)(seq)) < 0)
		goto Fail_2;

	if (is_listobject(seq) && seq->ob_refcnt == 1) {
		INCREF(seq);
		result = seq;
	}
	else {
		if ((result = newlistobject(len)) == NULL)
			goto Fail_2;
	}

	for (i = j = 0; ; ++i) {
		object *item, *good;
		int ok;

		if ((item = (*sqf->sq_item)(seq, i)) == NULL) {
			if (i < len)
				goto Fail_1;
			if (err_occurred() == IndexError) {
				err_clear();
				break;
			}
			goto Fail_1;
		}

		if (func == None) {
			good = item;
			INCREF(good);
		}
		else {
			object *arg = mkvalue("(O)", item);
			if (arg == NULL)
				goto Fail_1;
			good = call_object(func, arg);
			DECREF(arg);
			if (good == NULL) {
				DECREF(item);
				goto Fail_1;
			}
		}
		ok = testbool(good);
		DECREF(good);
		if (ok) {
			if (j < len) {
				if (setlistitem(result, j++, item) < 0)
					goto Fail_1;
			}
			else {
				j++;
				if (addlistitem(result, item) < 0)
					goto Fail_1;
			}
		} else {
			DECREF(item);
		}
	}


	if (j < len && setlistslice(result, j, len, NULL) < 0)
		goto Fail_1;

	return result;

Fail_1:
	DECREF(result);
Fail_2:
	return NULL;
}

static object *
builtin_chr(self, args)
	object *self;
	object *args;
{
	long x;
	char s[1];

	if (!newgetargs(args, "l:chr", &x))
		return NULL;
	if (x < 0 || x >= 256) {
		err_setstr(ValueError, "chr() arg not in range(256)");
		return NULL;
	}
	s[0] = x;
	return newsizedstringobject(s, 1);
}

static object *
builtin_cmp(self, args)
	object *self;
	object *args;
{
	object *a, *b;

	if (!newgetargs(args, "OO:cmp", &a, &b))
		return NULL;
	return newintobject((long)cmpobject(a, b));
}

static object *
builtin_coerce(self, args)
	object *self;
	object *args;
{
	object *v, *w;
	object *res;

	if (!newgetargs(args, "OO:coerce", &v, &w))
		return NULL;
	if (coerce(&v, &w) < 0)
		return NULL;
	res = mkvalue("(OO)", v, w);
	DECREF(v);
	DECREF(w);
	return res;
}

static object *
builtin_compile(self, args)
	object *self;
	object *args;
{
	char *str;
	char *filename;
	char *startstr;
	int start;

	if (!newgetargs(args, "sss:compile", &str, &filename, &startstr))
		return NULL;
	if (strcmp(startstr, "exec") == 0)
		start = file_input;
	else if (strcmp(startstr, "eval") == 0)
		start = eval_input;
	else if (strcmp(startstr, "single") == 0)
		start = single_input;
	else {
		err_setstr(ValueError,
		   "compile() mode must be 'exec' or 'eval' or 'single'");
		return NULL;
	}
	return compile_string(str, filename, start);
}

#ifndef WITHOUT_COMPLEX

static object *
builtin_complex(self, args)
	object *self;
	object *args;
{
	object *r, *i, *tmp;
	number_methods *nbr, *nbi;
	Py_complex cr, ci;

	i = NULL;
	if (!newgetargs(args, "O|O:complex", &r, &i))
		return NULL;
	if ((nbr = r->ob_type->tp_as_number) == NULL ||
	     nbr->nb_float == NULL || (i != NULL &&
	   ((nbi = i->ob_type->tp_as_number) == NULL ||
	     nbi->nb_float == NULL))) {
		err_setstr(TypeError,
			   "complex() argument can't be converted to complex");
		return NULL;
	}
	if (is_complexobject(r))
		cr = ((complexobject*)r)->cval;
	else {
		tmp = (*nbr->nb_float)(r);
		if (tmp == NULL)
			return NULL;
		cr.real = getfloatvalue(tmp);
		DECREF(tmp);
		cr.imag = 0.;
	}
	if (i == NULL) {
		ci.real = 0.;
		ci.imag = 0.;
	}
	else if (is_complexobject(i))
		ci = ((complexobject*)i)->cval;
	else {
		tmp = (*nbr->nb_float)(i);
		if (tmp == NULL)
			return NULL;
		ci.real = getfloatvalue(tmp);
		DECREF(tmp);
		ci.imag = 0.;
	}
	cr.real -= ci.imag;
	cr.imag += ci.real;
	return newcomplexobject(cr);
}

#endif

static object *
builtin_dir(self, args)
	object *self;
	object *args;
{
	object *v = NULL;
	object *d;

	if (!newgetargs(args, "|O:dir", &v))
		return NULL;
	if (v == NULL) {
		d = getlocals();
		INCREF(d);
	}
	else {
		d = getattr(v, "__dict__");
		if (d == NULL) {
			err_setstr(TypeError,
				"dir() argument must have __dict__ attribute");
			return NULL;
		}
	}
	if (is_dictobject(d)) {
		v = getdictkeys(d);
		if (sortlist(v) != 0) {
			DECREF(v);
			v = NULL;
		}
	}
	else {
		v = PyObject_CallMethod(d, "keys", NULL);
		if (v == NULL) {
			PyErr_Clear();
			v = newlistobject(0);
		}
	}
	DECREF(d);
	return v;
}

static object *
do_divmod(v, w)
	object *v, *w;
{
	object *res;

	if (is_instanceobject(v) || is_instanceobject(w))
		return instancebinop(v, w, "__divmod__", "__rdivmod__",
				     do_divmod);
	if (v->ob_type->tp_as_number == NULL ||
				w->ob_type->tp_as_number == NULL) {
		err_setstr(TypeError,
		    "divmod() requires numeric or class instance arguments");
		return NULL;
	}
	if (coerce(&v, &w) != 0)
		return NULL;
	res = (*v->ob_type->tp_as_number->nb_divmod)(v, w);
	DECREF(v);
	DECREF(w);
	return res;
}

static object *
builtin_divmod(self, args)
	object *self;
	object *args;
{
	object *v, *w;

	if (!newgetargs(args, "OO:divmod", &v, &w))
		return NULL;
	return do_divmod(v, w);
}

static object *
builtin_eval(self, args)
	object *self;
	object *args;
{
	object *cmd;
	object *globals = None, *locals = None;
	char *str;

	if (!newgetargs(args, "O|O!O!:eval",
			&cmd,
			&Mappingtype, &globals,
			&Mappingtype, &locals))
		return NULL;
	if (globals == None) {
		globals = getglobals();
		if (locals == None)
			locals = getlocals();
	}
	else if (locals == None)
		locals = globals;
	if (dictlookup(globals, "__builtins__") == NULL) {
		if (dictinsert(globals, "__builtins__", getbuiltins()) != 0)
			return NULL;
	}
	if (is_codeobject(cmd))
		return eval_code((codeobject *) cmd, globals, locals);
	if (!is_stringobject(cmd)) {
		err_setstr(TypeError,
			   "eval() argument 1 must be string or code object");
		return NULL;
	}
	str = getstringvalue(cmd);
	if (strlen(str) != getstringsize(cmd)) {
		err_setstr(ValueError,
			   "embedded '\\0' in string arg");
		return NULL;
	}
	while (*str == ' ' || *str == '\t')
		str++;
	return run_string(str, eval_input, globals, locals);
}

static object *
builtin_execfile(self, args)
	object *self;
	object *args;
{
	char *filename;
	object *globals = None, *locals = None;
	object *res;
	FILE* fp;

	if (!newgetargs(args, "s|O!O!:execfile",
			&filename,
			&Mappingtype, &globals,
			&Mappingtype, &locals))
		return NULL;
	if (globals == None) {
		globals = getglobals();
		if (locals == None)
			locals = getlocals();
	}
	else if (locals == None)
		locals = globals;
	if (dictlookup(globals, "__builtins__") == NULL) {
		if (dictinsert(globals, "__builtins__", getbuiltins()) != 0)
			return NULL;
	}
	BGN_SAVE
	fp = fopen(filename, "r");
	END_SAVE
	if (fp == NULL) {
		err_errno(IOError);
		return NULL;
	}
	res = run_file(fp, filename, file_input, globals, locals);
	BGN_SAVE
	fclose(fp);
	END_SAVE
	return res;
}

static object *
builtin_float(self, args)
	object *self;
	object *args;
{
	object *v;
	number_methods *nb;

	if (!newgetargs(args, "O:float", &v))
		return NULL;
	if ((nb = v->ob_type->tp_as_number) == NULL ||
	    nb->nb_float == NULL) {
		err_setstr(TypeError,
			   "float() argument can't be converted to float");
		return NULL;
	}
	return (*nb->nb_float)(v);
}

static object *
builtin_getattr(self, args)
	object *self;
	object *args;
{
	object *v;
	object *name;

	if (!newgetargs(args, "OS:getattr", &v, &name))
		return NULL;
	return getattro(v, name);
}

static object *
builtin_globals(self, args)
	object *self;
	object *args;
{
	object *d;

	if (!newgetargs(args, ""))
		return NULL;
	d = getglobals();
	INCREF(d);
	return d;
}

static object *
builtin_hasattr(self, args)
	object *self;
	object *args;
{
	object *v;
	object *name;

	if (!newgetargs(args, "OS:hasattr", &v, &name))
		return NULL;
	v = getattro(v, name);
	if (v == NULL) {
		err_clear();
		return newintobject(0L);
	}
	DECREF(v);
	return newintobject(1L);
}

static object *
builtin_id(self, args)
	object *self;
	object *args;
{
	object *v;

	if (!newgetargs(args, "O:id", &v))
		return NULL;
	return newintobject((long)v);
}

static object *
builtin_map(self, args)
	object *self;
	object *args;
{
	typedef struct {
		object *seq;
		sequence_methods *sqf;
		int len;
	} sequence;

	object *func, *result;
	sequence *seqs = NULL, *sqp;
	int n, len;
	register int i, j;

	n = gettuplesize(args);
	if (n < 2) {
		err_setstr(TypeError, "map() requires at least two args");
		return NULL;
	}

	func = gettupleitem(args, 0);
	n--;

	if ((seqs = NEW(sequence, n)) == NULL) {
		err_nomem();
		goto Fail_2;
	}

	for (len = 0, i = 0, sqp = seqs; i < n; ++i, ++sqp) {
		int curlen;
	
		if ((sqp->seq = gettupleitem(args, i + 1)) == NULL)
			goto Fail_2;

		if (! (sqp->sqf = sqp->seq->ob_type->tp_as_sequence)) {
			static char errmsg[] =
			    "argument %d to map() must be a sequence object";
			char errbuf[sizeof(errmsg) + 3];

			sprintf(errbuf, errmsg, i+2);
			err_setstr(TypeError, errbuf);
			goto Fail_2;
		}

		if ((curlen = sqp->len = (*sqp->sqf->sq_length)(sqp->seq)) < 0)
			goto Fail_2;

		if (curlen > len)
			len = curlen;
	}

	if ((result = (object *) newlistobject(len)) == NULL)
		goto Fail_2;

	/* XXX Special case map(None, single_list) could be more efficient */
	for (i = 0; ; ++i) {
		object *alist, *item, *value;
		int any = 0;

		if (func == None && n == 1)
			alist = NULL;
		else {
			if ((alist = newtupleobject(n)) == NULL)
				goto Fail_1;
		}

		for (j = 0, sqp = seqs; j < n; ++j, ++sqp) {
			if (sqp->len < 0) {
				INCREF(None);
				item = None;
			}
			else {
				item = (*sqp->sqf->sq_item)(sqp->seq, i);
				if (item == NULL) {
					if (i < sqp->len)
						goto Fail_0;
					if (err_occurred() == IndexError) {
						err_clear();
						INCREF(None);
						item = None;
						sqp->len = -1;
					}
					else {
						goto Fail_0;
					}
				}
				else
					any = 1;

			}
			if (!alist)
				break;
			if (settupleitem(alist, j, item) < 0) {
				DECREF(item);
				goto Fail_0;
			}
			continue;

		Fail_0:
			XDECREF(alist);
			goto Fail_1;
		}

		if (!alist)
			alist = item;

		if (!any) {
			DECREF(alist);
			break;
		}

		if (func == None)
			value = alist;
		else {
			value = call_object(func, alist);
			DECREF(alist);
			if (value == NULL)
				goto Fail_1;
		}
		if (i >= len) {
			if (addlistitem(result, value) < 0)
				goto Fail_1;
		}
		else {
			if (setlistitem(result, i, value) < 0)
				goto Fail_1;
		}
	}

	DEL(seqs);
	return result;

Fail_1:
	DECREF(result);
Fail_2:
	if (seqs) DEL(seqs);
	return NULL;
}

static object *
builtin_setattr(self, args)
	object *self;
	object *args;
{
	object *v;
	object *name;
	object *value;

	if (!newgetargs(args, "OSO:setattr", &v, &name, &value))
		return NULL;
	if (setattro(v, name, value) != 0)
		return NULL;
	INCREF(None);
	return None;
}

static object *
builtin_delattr(self, args)
	object *self;
	object *args;
{
	object *v;
	object *name;

	if (!newgetargs(args, "OS:delattr", &v, &name))
		return NULL;
	if (setattro(v, name, (object *)NULL) != 0)
		return NULL;
	INCREF(None);
	return None;
}

static object *
builtin_hash(self, args)
	object *self;
	object *args;
{
	object *v;
	long x;

	if (!newgetargs(args, "O:hash", &v))
		return NULL;
	x = hashobject(v);
	if (x == -1)
		return NULL;
	return newintobject(x);
}

static object *
builtin_hex(self, args)
	object *self;
	object *args;
{
	object *v;
	number_methods *nb;

	if (!newgetargs(args, "O:hex", &v))
		return NULL;
	
	if ((nb = v->ob_type->tp_as_number) == NULL ||
	    nb->nb_hex == NULL) {
		err_setstr(TypeError,
			   "hex() argument can't be converted to hex");
		return NULL;
	}
	return (*nb->nb_hex)(v);
}

static object *builtin_raw_input PROTO((object *, object *));

static object *
builtin_input(self, args)
	object *self;
	object *args;
{
	object *line;
	char *str;
	object *res;
	object *globals, *locals;

	line = builtin_raw_input(self, args);
	if (line == NULL)
		return line;
	if (!getargs(line, "s;embedded '\\0' in input line", &str))
		return NULL;
	while (*str == ' ' || *str == '\t')
			str++;
	globals = getglobals();
	locals = getlocals();
	if (dictlookup(globals, "__builtins__") == NULL) {
		if (dictinsert(globals, "__builtins__", getbuiltins()) != 0)
			return NULL;
	}
	res = run_string(str, eval_input, globals, locals);
	DECREF(line);
	return res;
}

static object *
builtin_int(self, args)
	object *self;
	object *args;
{
	object *v;
	number_methods *nb;

	if (!newgetargs(args, "O:int", &v))
		return NULL;
	if ((nb = v->ob_type->tp_as_number) == NULL ||
	    nb->nb_int == NULL) {
		err_setstr(TypeError,
			   "int() argument can't be converted to int");
		return NULL;
	}
	return (*nb->nb_int)(v);
}

static object *
builtin_len(self, args)
	object *self;
	object *args;
{
	object *v;
	long len;
	typeobject *tp;

	if (!newgetargs(args, "O:len", &v))
		return NULL;
	tp = v->ob_type;
	if (tp->tp_as_sequence != NULL) {
		len = (*tp->tp_as_sequence->sq_length)(v);
	}
	else if (tp->tp_as_mapping != NULL) {
		len = (*tp->tp_as_mapping->mp_length)(v);
	}
	else {
		err_setstr(TypeError, "len() of unsized object");
		return NULL;
	}
	if (len < 0)
		return NULL;
	else
		return newintobject(len);
}

static object *
builtin_list(self, args)
	object *self;
	object *args;
{
	object *v;
	sequence_methods *sqf;

	if (!newgetargs(args, "O:list", &v))
		return NULL;
	if ((sqf = v->ob_type->tp_as_sequence) != NULL) {
		int n = (*sqf->sq_length)(v);
		int i;
		object *l;
		if (n < 0)
			return NULL;
		l = newlistobject(n);
		if (l == NULL)
			return NULL;
		for (i = 0; i < n; i++) {
			object *item = (*sqf->sq_item)(v, i);
			if (item == NULL) {
				DECREF(l);
				l = NULL;
				break;
			}
			setlistitem(l, i, item);
		}
		/* XXX Should support indefinite-length sequences */
		return l;
	}
	err_setstr(TypeError, "list() argument must be a sequence");
	return NULL;
}


static PyObject *
builtin_slice(self, args)
     PyObject *self;
     PyObject *args;
{
  PyObject *start, *stop, *step;

  start = stop = step = NULL;

  if (!PyArg_ParseTuple(args, "O|OO:slice", &start, &stop, &step))
    return NULL;

  /*This swapping of stop and start is to maintain compatibility with
    the range builtin.*/
  if (stop == NULL) {
    stop = start;
    start = NULL;
  }
  return PySlice_New(start, stop, step);
}

static object *
builtin_locals(self, args)
	object *self;
	object *args;
{
	object *d;

	if (!newgetargs(args, ""))
		return NULL;
	d = getlocals();
	INCREF(d);
	return d;
}

static object *
builtin_long(self, args)
	object *self;
	object *args;
{
	object *v;
	number_methods *nb;
	
	if (!newgetargs(args, "O:long", &v))
		return NULL;
	if ((nb = v->ob_type->tp_as_number) == NULL ||
	    nb->nb_long == NULL) {
		err_setstr(TypeError,
			   "long() argument can't be converted to long");
		return NULL;
	}
	return (*nb->nb_long)(v);
}

static object *
min_max(args, sign)
	object *args;
	int sign;
{
	int i;
	object *v, *w, *x;
	sequence_methods *sq;

	if (gettuplesize(args) > 1)
		v = args;
	else if (!newgetargs(args, "O:min/max", &v))
		return NULL;
	sq = v->ob_type->tp_as_sequence;
	if (sq == NULL) {
		err_setstr(TypeError, "min() or max() of non-sequence");
		return NULL;
	}
	w = NULL;
	for (i = 0; ; i++) {
		x = (*sq->sq_item)(v, i); /* Implies INCREF */
		if (x == NULL) {
			if (err_occurred() == IndexError) {
				err_clear();
				break;
			}
			XDECREF(w);
			return NULL;
		}
		if (w == NULL)
			w = x;
		else {
			if (cmpobject(x, w) * sign > 0) {
				DECREF(w);
				w = x;
			}
			else
				DECREF(x);
		}
	}
	if (w == NULL)
		err_setstr(ValueError, "min() or max() of empty sequence");
	return w;
}

static object *
builtin_min(self, v)
	object *self;
	object *v;
{
	return min_max(v, -1);
}

static object *
builtin_max(self, v)
	object *self;
	object *v;
{
	return min_max(v, 1);
}

static object *
builtin_oct(self, args)
	object *self;
	object *args;
{
	object *v;
	number_methods *nb;

	if (!newgetargs(args, "O:oct", &v))
		return NULL;
	if (v == NULL || (nb = v->ob_type->tp_as_number) == NULL ||
	    nb->nb_oct == NULL) {
		err_setstr(TypeError,
			   "oct() argument can't be converted to oct");
		return NULL;
	}
	return (*nb->nb_oct)(v);
}

static object *
builtin_open(self, args)
	object *self;
	object *args;
{
	char *name;
	char *mode = "r";
	int bufsize = -1;
	object *f;

	if (!newgetargs(args, "s|si:open", &name, &mode, &bufsize))
		return NULL;
	f = newfileobject(name, mode);
	if (f != NULL)
		setfilebufsize(f, bufsize);
	return f;
}

static object *
builtin_ord(self, args)
	object *self;
	object *args;
{
	char c;

	if (!newgetargs(args, "c:ord", &c))
		return NULL;
	return newintobject((long)(c & 0xff));
}

static object *
do_pow(v, w)
	object *v, *w;
{
	object *res;
	if (is_instanceobject(v) || is_instanceobject(w))
		return instancebinop(v, w, "__pow__", "__rpow__", do_pow);
	if (v->ob_type->tp_as_number == NULL ||
	    w->ob_type->tp_as_number == NULL) {
		err_setstr(TypeError, "pow() requires numeric arguments");
		return NULL;
	}
	if (
#ifndef WITHOUT_COMPLEX
            !is_complexobject(v) && 
#endif
            is_floatobject(w) && getfloatvalue(v) < 0.0) {
		if (!err_occurred())
		    err_setstr(ValueError, "negative number to float power");
		return NULL;
	}
	if (coerce(&v, &w) != 0)
		return NULL;
	res = (*v->ob_type->tp_as_number->nb_power)(v, w, None);
	DECREF(v);
	DECREF(w);
	return res;
}

static object *
builtin_pow(self, args)
	object *self;
	object *args;
{
	object *v, *w, *z = None, *res;
	object *v1, *z1, *w2, *z2;

	if (!newgetargs(args, "OO|O:pow", &v, &w, &z))
		return NULL;
	if (z == None)
		return do_pow(v, w);
	/* XXX The ternary version doesn't do class instance coercions */
	if (is_instanceobject(v))
		return v->ob_type->tp_as_number->nb_power(v, w, z);
	if (v->ob_type->tp_as_number == NULL ||
	    z->ob_type->tp_as_number == NULL ||
	    w->ob_type->tp_as_number == NULL) {
		err_setstr(TypeError, "pow() requires numeric arguments");
		return NULL;
	}
	if (coerce(&v, &w) != 0)
		return NULL;
	res = NULL;
	v1 = v;
	z1 = z;
	if (coerce(&v1, &z1) != 0)
		goto error2;
	w2 = w;
	z2 = z1;
 	if (coerce(&w2, &z2) != 0)
		goto error1;
	res = (*v1->ob_type->tp_as_number->nb_power)(v1, w2, z2);
	DECREF(w2);
	DECREF(z2);
 error1:
	DECREF(v1);
	DECREF(z1);
 error2:
	DECREF(v);
	DECREF(w);
	return res;
}

static object *
builtin_range(self, args)
	object *self;
	object *args;
{
	long ilow = 0, ihigh = 0, istep = 1;
	int i, n;
	object *v;

	if (gettuplesize(args) <= 1) {
		if (!newgetargs(args,
				"l;range() requires 1-3 int arguments",
				&ihigh))
			return NULL;
	}
	else {
		if (!newgetargs(args,
				"ll|l;range() requires 1-3 int arguments",
				&ilow, &ihigh, &istep))
			return NULL;
	}
	if (istep == 0) {
		err_setstr(ValueError, "zero step for range()");
		return NULL;
	}
	/* XXX ought to check overflow of subtraction */
	if (istep > 0)
		n = (ihigh - ilow + istep - 1) / istep;
	else
		n = (ihigh - ilow + istep + 1) / istep;
	if (n < 0)
		n = 0;
	v = newlistobject(n);
	if (v == NULL)
		return NULL;
	for (i = 0; i < n; i++) {
		object *w = newintobject(ilow);
		if (w == NULL) {
			DECREF(v);
			return NULL;
		}
		setlistitem(v, i, w);
		ilow += istep;
	}
	return v;
}

static object *
builtin_xrange(self, args)
	object *self;
	object *args;
{
	long ilow = 0, ihigh = 0, istep = 1;
	long n;

	if (gettuplesize(args) <= 1) {
		if (!newgetargs(args,
				"l;xrange() requires 1-3 int arguments",
				&ihigh))
			return NULL;
	}
	else {
		if (!newgetargs(args,
				"ll|l;xrange() requires 1-3 int arguments",
				&ilow, &ihigh, &istep))
			return NULL;
	}
	if (istep == 0) {
		err_setstr(ValueError, "zero step for xrange()");
		return NULL;
	}
	/* XXX ought to check overflow of subtraction */
	if (istep > 0)
		n = (ihigh - ilow + istep - 1) / istep;
	else
		n = (ihigh - ilow + istep + 1) / istep;
	if (n < 0)
		n = 0;
	return newrangeobject(ilow, n, istep, 1);
}

extern char *my_readline PROTO((char *));

static object *
builtin_raw_input(self, args)
	object *self;
	object *args;
{
	object *v = NULL;
	object *f;

	if (!newgetargs(args, "|O:[raw_]input", &v))
		return NULL;
	if (getfilefile(sysget("stdin")) == stdin &&
	    getfilefile(sysget("stdout")) == stdout &&
	    isatty(fileno(stdin)) && isatty(fileno(stdout))) {
		object *po;
		char *prompt;
		char *s;
		object *result;
		if (v != NULL) {
			po = strobject(v);
			if (po == NULL)
				return NULL;
			prompt = getstringvalue(po);
		}
		else {
			po = NULL;
			prompt = "";
		}
		s = my_readline(prompt);
		XDECREF(po);
		if (s == NULL) {
			err_set(KeyboardInterrupt);
			return NULL;
		}
		if (*s == '\0') {
			err_set(EOFError);
			result = NULL;
		}
		else { /* strip trailing '\n' */
			result = newsizedstringobject(s, strlen(s)-1);
		}
		free(s);
		return result;
	}
	if (v != NULL) {
		f = sysget("stdout");
		if (f == NULL) {
			err_setstr(RuntimeError, "lost sys.stdout");
			return NULL;
		}
		flushline();
		if (writeobject(v, f, PRINT_RAW) != 0)
			return NULL;
	}
	f = sysget("stdin");
	if (f == NULL) {
		err_setstr(RuntimeError, "lost sys.stdin");
		return NULL;
	}
	return filegetline(f, -1);
}

static object *
builtin_reduce(self, args)
	object *self;
	object *args;
{
	object *seq, *func, *result = NULL;
	sequence_methods *sqf;
	register int i;

	if (!newgetargs(args, "OO|O:reduce", &func, &seq, &result))
		return NULL;
	if (result != NULL)
		INCREF(result);

	if ((sqf = seq->ob_type->tp_as_sequence) == NULL) {
		err_setstr(TypeError,
		    "2nd argument to reduce() must be a sequence object");
		return NULL;
	}

	if ((args = newtupleobject(2)) == NULL)
		goto Fail;

	for (i = 0; ; ++i) {
		object *op2;

		if (args->ob_refcnt > 1) {
			DECREF(args);
			if ((args = newtupleobject(2)) == NULL)
				goto Fail;
		}

		if ((op2 = (*sqf->sq_item)(seq, i)) == NULL) {
			if (err_occurred() == IndexError) {
				err_clear();
				break;
			}
			goto Fail;
		}

		if (result == NULL)
			result = op2;
		else {
			settupleitem(args, 0, result);
			settupleitem(args, 1, op2);
			if ((result = call_object(func, args)) == NULL)
				goto Fail;
		}
	}

	DECREF(args);

	if (result == NULL)
		err_setstr(TypeError,
			   "reduce of empty sequence with no initial value");

	return result;

Fail:
	XDECREF(args);
	XDECREF(result);
	return NULL;
}

static object *
builtin_reload(self, args)
	object *self;
	object *args;
{
	object *v;

	if (!newgetargs(args, "O:reload", &v))
		return NULL;
	return reload_module(v);
}

static object *
builtin_repr(self, args)
	object *self;
	object *args;
{
	object *v;

	if (!newgetargs(args, "O:repr", &v))
		return NULL;
	return reprobject(v);
}

static object *
builtin_round(self, args)
	object *self;
	object *args;
{
	double x;
	double f;
	int ndigits = 0;
	int i;

	if (!newgetargs(args, "d|i:round", &x, &ndigits))
			return NULL;
	f = 1.0;
	for (i = ndigits; --i >= 0; )
		f = f*10.0;
	for (i = ndigits; ++i <= 0; )
		f = f*0.1;
	if (x >= 0.0)
		return newfloatobject(floor(x*f + 0.5) / f);
	else
		return newfloatobject(ceil(x*f - 0.5) / f);
}

static object *
builtin_str(self, args)
	object *self;
	object *args;
{
	object *v;

	if (!newgetargs(args, "O:str", &v))
		return NULL;
	return strobject(v);
}

static object *
builtin_tuple(self, args)
	object *self;
	object *args;
{
	object *v;
	sequence_methods *sqf;

	if (!newgetargs(args, "O:tuple", &v))
		return NULL;
	if (is_tupleobject(v)) {
		INCREF(v);
		return v;
	}
	if (is_listobject(v))
		return listtuple(v);
	if (is_stringobject(v)) {
		int n = getstringsize(v);
		object *t = newtupleobject(n);
		if (t != NULL) {
			int i;
			char *p = getstringvalue(v);
			for (i = 0; i < n; i++) {
				object *item = newsizedstringobject(p+i, 1);
				if (item == NULL) {
					DECREF(t);
					t = NULL;
					break;
				}
				settupleitem(t, i, item);
			}
		}
		return t;
	}
	/* Generic sequence object */
	if ((sqf = v->ob_type->tp_as_sequence) != NULL) {
		int n = (*sqf->sq_length)(v);
		int i;
		object *t;
		if (n < 0)
			return NULL;
		t = newtupleobject(n);
		if (t == NULL)
			return NULL;
		for (i = 0; i < n; i++) {
			object *item = (*sqf->sq_item)(v, i);
			if (item == NULL) {
				DECREF(t);
				t = NULL;
				break;
			}
			settupleitem(t, i, item);
		}
		/* XXX Should support indefinite-length sequences */
		return t;
	}
	/* None of the above */
	err_setstr(TypeError, "tuple() argument must be a sequence");
	return NULL;
}

static object *
builtin_type(self, args)
	object *self;
	object *args;
{
	object *v;

	if (!newgetargs(args, "O:type", &v))
		return NULL;
	v = (object *)v->ob_type;
	INCREF(v);
	return v;
}

static object *
builtin_vars(self, args)
	object *self;
	object *args;
{
	object *v = NULL;
	object *d;

	if (!newgetargs(args, "|O:vars", &v))
		return NULL;
	if (v == NULL) {
		d = getlocals();
		if (d == NULL) {
			if (!err_occurred())
				err_setstr(SystemError, "no locals!?");
		}
		else
			INCREF(d);
	}
	else {
		d = getattr(v, "__dict__");
		if (d == NULL) {
			err_setstr(TypeError,
			    "vars() argument must have __dict__ attribute");
			return NULL;
		}
	}
	return d;
}

static struct methodlist builtin_methods[] = {
	{"__import__",	builtin___import__, 1},
	{"abs",		builtin_abs, 1},
	{"apply",	builtin_apply, 1},
	{"callable",	builtin_callable, 1},
	{"chr",		builtin_chr, 1},
	{"cmp",		builtin_cmp, 1},
	{"coerce",	builtin_coerce, 1},
	{"compile",	builtin_compile, 1},
#ifndef WITHOUT_COMPLEX
	{"complex",	builtin_complex, 1},
#endif
	{"delattr",	builtin_delattr, 1},
	{"dir",		builtin_dir, 1},
	{"divmod",	builtin_divmod, 1},
	{"eval",	builtin_eval, 1},
	{"execfile",	builtin_execfile, 1},
	{"filter",	builtin_filter, 1},
	{"float",	builtin_float, 1},
	{"getattr",	builtin_getattr, 1},
	{"globals",	builtin_globals, 1},
	{"hasattr",	builtin_hasattr, 1},
	{"hash",	builtin_hash, 1},
	{"hex",		builtin_hex, 1},
	{"id",		builtin_id, 1},
	{"input",	builtin_input, 1},
	{"int",		builtin_int, 1},
	{"len",		builtin_len, 1},
	{"list",	builtin_list, 1},
	{"locals",	builtin_locals, 1},
	{"long",	builtin_long, 1},
	{"map",		builtin_map, 1},
	{"max",		builtin_max, 1},
	{"min",		builtin_min, 1},
	{"oct",		builtin_oct, 1},
	{"open",	builtin_open, 1},
	{"ord",		builtin_ord, 1},
	{"pow",		builtin_pow, 1},
	{"range",	builtin_range, 1},
	{"raw_input",	builtin_raw_input, 1},
	{"reduce",	builtin_reduce, 1},
	{"reload",	builtin_reload, 1},
	{"repr",	builtin_repr, 1},
	{"round",	builtin_round, 1},
	{"setattr",	builtin_setattr, 1},
	{"slice",       builtin_slice, 1},
	{"str",		builtin_str, 1},
	{"tuple",	builtin_tuple, 1},
	{"type",	builtin_type, 1},
	{"vars",	builtin_vars, 1},
	{"xrange",	builtin_xrange, 1},
	{NULL,		NULL},
};

static object *builtin_mod;
static object *builtin_dict;

object *
getbuiltinmod()
{
	return builtin_mod;
}

object *
getbuiltindict()
{
	return builtin_dict;
}

/* Predefined exceptions */

object *AccessError;
object *AttributeError;
object *ConflictError;
object *EOFError;
object *IOError;
object *ImportError;
object *IndexError;
object *KeyError;
object *KeyboardInterrupt;
object *MemoryError;
object *NameError;
object *OverflowError;
object *RuntimeError;
object *SyntaxError;
object *SystemError;
object *SystemExit;
object *TypeError;
object *ValueError;
object *ZeroDivisionError;

static object *
newstdexception(name)
	char *name;
{
	object *v = newstringobject(name);
	if (v == NULL || dictinsert(builtin_dict, name, v) != 0)
		fatal("no mem for new standard exception");
	return v;
}

static void
initerrors()
{
	AccessError = newstdexception("AccessError");
	AttributeError = newstdexception("AttributeError");
	ConflictError = newstdexception("ConflictError");
	EOFError = newstdexception("EOFError");
	IOError = newstdexception("IOError");
	ImportError = newstdexception("ImportError");
	IndexError = newstdexception("IndexError");
	KeyError = newstdexception("KeyError");
	KeyboardInterrupt = newstdexception("KeyboardInterrupt");
	MemoryError = newstdexception("MemoryError");
	NameError = newstdexception("NameError");
	OverflowError = newstdexception("OverflowError");
	RuntimeError = newstdexception("RuntimeError");
	SyntaxError = newstdexception("SyntaxError");
	SystemError = newstdexception("SystemError");
	SystemExit = newstdexception("SystemExit");
	TypeError = newstdexception("TypeError");
	ValueError = newstdexception("ValueError");
	ZeroDivisionError = newstdexception("ZeroDivisionError");
}

void
initbuiltin()
{
	builtin_mod = initmodule("__builtin__", builtin_methods);
	builtin_dict = getmoduledict(builtin_mod);
	INCREF(builtin_dict);
	initerrors();
	(void) dictinsert(builtin_dict, "None", None);
	(void) dictinsert(builtin_dict, "Ellipsis", Py_Ellipsis);
}


/* Helper for filter(): filter a tuple through a function */

static object *
filtertuple(func, tuple)
	object *func;
	object *tuple;
{
	object *result;
	register int i, j;
	int len = gettuplesize(tuple);

	if (len == 0) {
		INCREF(tuple);
		return tuple;
	}

	if ((result = newtupleobject(len)) == NULL)
		return NULL;

	for (i = j = 0; i < len; ++i) {
		object *item, *good;
		int ok;

		if ((item = gettupleitem(tuple, i)) == NULL)
			goto Fail_1;
		if (func == None) {
			INCREF(item);
			good = item;
		}
		else {
			object *arg = mkvalue("(O)", item);
			if (arg == NULL)
				goto Fail_1;
			good = call_object(func, arg);
			DECREF(arg);
			if (good == NULL)
				goto Fail_1;
		}
		ok = testbool(good);
		DECREF(good);
		if (ok) {
			INCREF(item);
			if (settupleitem(result, j++, item) < 0)
				goto Fail_1;
		}
	}

	if (resizetuple(&result, j, 0) < 0)
		return NULL;

	return result;

Fail_1:
	DECREF(result);
	return NULL;
}


/* Helper for filter(): filter a string through a function */

static object *
filterstring(func, strobj)
	object *func;
	object *strobj;
{
	object *result;
	register int i, j;
	int len = getstringsize(strobj);

	if (func == None) {
		/* No character is ever false -- share input string */
		INCREF(strobj);
		return strobj;
	}
	if ((result = newsizedstringobject(NULL, len)) == NULL)
		return NULL;

	for (i = j = 0; i < len; ++i) {
		object *item, *arg, *good;
		int ok;

		item = (*strobj->ob_type->tp_as_sequence->sq_item)(strobj, i);
		if (item == NULL)
			goto Fail_1;
		arg = mkvalue("(O)", item);
		DECREF(item);
		if (arg == NULL)
			goto Fail_1;
		good = call_object(func, arg);
		DECREF(arg);
		if (good == NULL)
			goto Fail_1;
		ok = testbool(good);
		DECREF(good);
		if (ok)
			GETSTRINGVALUE((stringobject *)result)[j++] =
				GETSTRINGVALUE((stringobject *)item)[0];
	}

	if (j < len && resizestring(&result, j) < 0)
		return NULL;

	return result;

Fail_1:
	DECREF(result);
	return NULL;
}
