#include <u.h>
#include <libc.h>
#include <bio.h>
#include <ctype.h>
#include <mach.h>
#include <regexp.h>
#define Extern extern
#include "acid.h"
#include "y.tab.h"

void	cvtatof(Node*, Node*);
void	cvtatoi(Node*, Node*);
void	cvtitoa(Node*, Node*);
void	bprint(Node*, Node*);
void	funcbound(Node*, Node*);
void	printto(Node*, Node*);
void	getfile(Node*, Node*);
void	fmt(Node*, Node*);
void	pcfile(Node*, Node*);
void	pcline(Node*, Node*);
void	setproc(Node*, Node*);
void	strace(Node*, Node*);
void	follow(Node*, Node*);
void	reason(Node*, Node*);
void	newproc(Node*, Node*);
void	startstop(Node*, Node*);
void	match(Node*, Node*);
void	status(Node*, Node*);
void	xkill(Node*,Node*);
void	waitstop(Node*, Node*);
void waitsyscall(Node*, Node*);
void	stop(Node*, Node*);
void	start(Node*, Node*);
void	filepc(Node*, Node*);
void	doerror(Node*, Node*);
void	rc(Node*, Node*);
void	doaccess(Node*, Node*);
void	map(Node*, Node*);
void	readfile(Node*, Node*);
void	interpret(Node*, Node*);
void	include(Node*, Node*);
void	includepipe(Node*, Node*);
void	regexp(Node*, Node*);
void textfile(Node*, Node*);
void deltextfile(Node*, Node*);
void stringn(Node*, Node*);
void xregister(Node*, Node*);
void refconst(Node*, Node*);
void dolook(Node*, Node*);
void step1(Node*, Node*);

typedef struct Btab Btab;
struct Btab
{
	char	*name;
	void	(*fn)(Node*, Node*);
} tab[] =
{
	"access",	doaccess,
	"atof",		cvtatof,
	"atoi",		cvtatoi,
	"deltextfile",	deltextfile,
	"error",	doerror,
	"file",		getfile,
	"filepc",	filepc,
	"fnbound",	funcbound,
	"fmt",		fmt,
	"follow",	follow,
	"include",	include,
	"includepipe",	includepipe,
	"interpret",	interpret,
	"itoa",		cvtitoa,
	"kill",		xkill,
	"map",		map,
	"match",	match,
	"newproc",	newproc,
	"pcfile",	pcfile,
	"pcline",	pcline,
	"print",	bprint,
	"printto",	printto,
	"rc",		rc,
	"readfile",	readfile,
	"reason",	reason,
	"refconst",	refconst,
	"regexp",	regexp,
	"register",	xregister,
	"setproc",	setproc,
	"start",	start,
	"startstop",	startstop,
	"status",	status,
	"step1",	step1,
	"stop",		stop,
	"strace",	strace,
	"stringn",	stringn,
	"textfile",	textfile,
	"var",	dolook,
	"waitstop",	waitstop,
	"waitsyscall",	waitsyscall,
	0
};

void
mkprint(Lsym *s)
{
	prnt = malloc(sizeof(Node));
	memset(prnt, 0, sizeof(Node));
	prnt->op = OCALL;
	prnt->left = malloc(sizeof(Node));
	memset(prnt->left, 0, sizeof(Node));
	prnt->left->sym = s;
}

void
installbuiltin(void)
{
	Btab *b;
	Lsym *s;

	b = tab;
	while(b->name) {
		s = look(b->name);
		if(s == 0)
			s = enter(b->name, Tid);

		s->builtin = b->fn;
		if(b->fn == bprint)
			mkprint(s);
		b++;
	}
}

void
match(Node *r, Node *args)
{
	int i;
	List *f;
	Node *av[Maxarg];
	Node resi, resl;

	na = 0;
	flatten(av, args);
	if(na != 2)
		error("match(obj, list): arg count");

	expr(av[1], &resl);
	if(resl.type != TLIST)
		error("match(obj, list): need list");
	expr(av[0], &resi);

	r->op = OCONST;
	r->type = TINT;
	r->store.fmt = 'D';
	r->store.u.ival = -1;

	i = 0;
	for(f = resl.store.u.l; f; f = f->next) {
		if(resi.type == f->type) {
			switch(resi.type) {
			case TINT:
				if(resi.store.u.ival == f->store.u.ival) {
					r->store.u.ival = i;
					return;
				}
				break;
			case TFLOAT:
				if(resi.store.u.fval == f->store.u.fval) {
					r->store.u.ival = i;
					return;
				}
				break;
			case TSTRING:
				if(scmp(resi.store.u.string, f->store.u.string)) {
					r->store.u.ival = i;
					return;
				}
				break;
			case TLIST:
				error("match(obj, list): not defined for list");
			}
		}
		i++;
	}
}

void
newproc(Node *r, Node *args)
{
	int i;
	Node res;
	char *p, *e;
	char *argv[Maxarg], buf[Strsize];

	i = 1;
	argv[0] = symfil;

	if(args) {
		expr(args, &res);
		if(res.type != TSTRING)
			error("newproc(): arg not string");
		if(res.store.u.string->len >= sizeof(buf))
			error("newproc(): too many arguments");
		memmove(buf, res.store.u.string->string, res.store.u.string->len);
		buf[res.store.u.string->len] = '\0';
		p = buf;
		e = buf+res.store.u.string->len;
		for(;;) {
			while(p < e && (*p == '\t' || *p == ' '))
				*p++ = '\0';
			if(p >= e)
				break;
			argv[i++] = p;
			if(i >= Maxarg)
				error("newproc: too many arguments");
			while(p < e && *p != '\t' && *p != ' ')
				p++;
		}
	}
	argv[i] = 0;
	r->op = OCONST;
	r->type = TINT;
	r->store.fmt = 'D';
	r->store.u.ival = nproc(argv);
}

void
step1(Node *r, Node *args)
{
	Node res;

	USED(r);
	if(args == 0)
		error("step1(pid): no pid");
	expr(args, &res);
	if(res.type != TINT)
		error("step1(pid): arg type");

	msg(res.store.u.ival, "step");
	notes(res.store.u.ival);
	dostop(res.store.u.ival);
}

void
startstop(Node *r, Node *args)
{
	Node res;

	USED(r);
	if(args == 0)
		error("startstop(pid): no pid");
	expr(args, &res);
	if(res.type != TINT)
		error("startstop(pid): arg type");

	msg(res.store.u.ival, "startstop");
	notes(res.store.u.ival);
	dostop(res.store.u.ival);
}

void
waitstop(Node *r, Node *args)
{
	Node res;

	USED(r);
	if(args == 0)
		error("waitstop(pid): no pid");
	expr(args, &res);
	if(res.type != TINT)
		error("waitstop(pid): arg type");

	Bflush(bout);
	msg(res.store.u.ival, "waitstop");
	notes(res.store.u.ival);
	dostop(res.store.u.ival);
}

void
waitsyscall(Node *r, Node *args)
{
	Node res;

	USED(r);
	if(args == 0)
		error("waitsyscall(pid): no pid");
	expr(args, &res);
	if(res.type != TINT)
		error("waitsycall(pid): arg type");

	Bflush(bout);
	msg(res.store.u.ival, "sysstop");
	notes(res.store.u.ival);
	dostop(res.store.u.ival);
}

void
start(Node *r, Node *args)
{
	Node res;

	USED(r);
	if(args == 0)
		error("start(pid): no pid");
	expr(args, &res);
	if(res.type != TINT)
		error("start(pid): arg type");

	msg(res.store.u.ival, "start");
}

void
stop(Node *r, Node *args)
{
	Node res;

	USED(r);
	if(args == 0)
		error("stop(pid): no pid");
	expr(args, &res);
	if(res.type != TINT)
		error("stop(pid): arg type");

	Bflush(bout);
	msg(res.store.u.ival, "stop");
	notes(res.store.u.ival);
	dostop(res.store.u.ival);
}

void
xkill(Node *r, Node *args)
{
	Node res;

	USED(r);
	if(args == 0)
		error("kill(pid): no pid");
	expr(args, &res);
	if(res.type != TINT)
		error("kill(pid): arg type");

	msg(res.store.u.ival, "kill");
	deinstall(res.store.u.ival);
}

void
xregister(Node *r, Node *args)
{
	int tid;
	Regdesc *rp;
	Node res, resid;
	Node *av[Maxarg];

	na = 0;
	flatten(av, args);
	if(na != 1/* && na != 2 */)
		error("register(name): arg count");

	expr(av[0], &res);
	if(res.type != TSTRING)
		error("register(name): arg type: name should be string");
	tid = 0;
	if(na == 2){
		expr(av[1], &resid);
		if(resid.type != TINT)
			error("register(name[, threadid]): arg type: threadid should be int");
		tid = resid.store.u.ival;
	}
	if((rp = regdesc(res.store.u.string->string)) == nil)
		error("no such register");
	r->op = OCONST;
	r->type = TREG;
	r->store.fmt = rp->format;
	r->store.u.reg.name = rp->name;
	r->store.u.reg.thread = tid;
}

void
refconst(Node *r, Node *args)
{
	Node *n;

	if(args == 0)
		error("refconst(expr): arg count");

	n = an(OCONST, ZN, ZN);
	expr(args, n);

	r->op = OCONST;
	r->type = TCON;
	r->store.u.con = n;
}

void
dolook(Node *r, Node *args)
{
	Node res;
	Lsym *l;

	if(args == 0)
		error("var(string): arg count");
	expr(args, &res);
	if(res.type != TSTRING)
		error("var(string): arg type");

	r->op = OCONST;
	if((l = look(res.store.u.string->string)) == nil || l->v->set == 0){
		r->type = TLIST;
		r->store.u.l = nil;
	}else{
		r->type = l->v->type;
		r->store = l->v->store;
	}
}

void
status(Node *r, Node *args)
{
	Node res;
	char *p;

	USED(r);
	if(args == 0)
		error("status(pid): no pid");
	expr(args, &res);
	if(res.type != TINT)
		error("status(pid): arg type");

	p = getstatus(res.store.u.ival);
	r->store.u.string = strnode(p);
	r->op = OCONST;
	r->store.fmt = 's';
	r->type = TSTRING;
}

void
reason(Node *r, Node *args)
{
	Node res;

	if(args == 0)
		error("reason(cause): no cause");
	expr(args, &res);
	if(res.type != TINT)
		error("reason(cause): arg type");

	r->op = OCONST;
	r->type = TSTRING;
	r->store.fmt = 's';
	r->store.u.string = strnode((*mach->exc)(cormap, acidregs));
}

void
follow(Node *r, Node *args)
{
	int n, i;
	Node res;
	u64int f[10];
	List **tail, *l;

	if(args == 0)
		error("follow(addr): no addr");
	expr(args, &res);
	if(res.type != TINT)
		error("follow(addr): arg type");

	n = (*mach->foll)(cormap, acidregs, res.store.u.ival, f);
	if (n < 0)
		error("follow(addr): %r");
	tail = &r->store.u.l;
	for(i = 0; i < n; i++) {
		l = al(TINT);
		l->store.u.ival = f[i];
		l->store.fmt = 'X';
		*tail = l;
		tail = &l->next;
	}
}

void
funcbound(Node *r, Node *args)
{
	int n;
	Node res;
	u64int bounds[2];
	List *l;

	if(args == 0)
		error("fnbound(addr): no addr");
	expr(args, &res);
	if(res.type != TINT)
		error("fnbound(addr): arg type");

	n = fnbound(res.store.u.ival, bounds);
	if (n >= 0) {
		r->store.u.l = al(TINT);
		l = r->store.u.l;
		l->store.u.ival = bounds[0];
		l->store.fmt = 'X';
		l->next = al(TINT);
		l = l->next;
		l->store.u.ival = bounds[1];
		l->store.fmt = 'X';
	}
}

void
setproc(Node *r, Node *args)
{
	Node res;

	USED(r);
	if(args == 0)
		error("setproc(pid): no pid");
	expr(args, &res);
	if(res.type != TINT)
		error("setproc(pid): arg type");

	sproc(res.store.u.ival);
}

void
filepc(Node *r, Node *args)
{
	int i;
	Node res;
	char *p, c;
	u64int v;

	if(args == 0)
		error("filepc(filename:line): arg count");
	expr(args, &res);
	if(res.type != TSTRING)
		error("filepc(filename:line): arg type");

	p = strchr(res.store.u.string->string, ':');
	if(p == 0)
		error("filepc(filename:line): bad arg format");

	c = *p;
	*p++ = '\0';
	i = file2pc(res.store.u.string->string, atoi(p), &v);
	p[-1] = c;
	if(i < 0)
		error("filepc(filename:line): can't find address");

	r->op = OCONST;
	r->type = TINT;
	r->store.fmt = 'D';
	r->store.u.ival = v;
}

void
interpret(Node *r, Node *args)
{
	Node res;
	int isave;

	if(args == 0)
		error("interpret(string): arg count");
	expr(args, &res);
	if(res.type != TSTRING)
		error("interpret(string): arg type");

	pushstr(&res);

	isave = interactive;
	interactive = 0;
	r->store.u.ival = yyparse();
	interactive = isave;
	popio();
	r->op = OCONST;
	r->type = TINT;
	r->store.fmt = 'D';
}

void
include(Node *r, Node *args)
{
	char *file, *libfile;
	static char buf[1024];
	Node res;
	int isave;

	if(args == 0)
		error("include(string): arg count");
	expr(args, &res);
	if(res.type != TSTRING)
		error("include(string): arg type");

	Bflush(bout);

	libfile = nil;
	file = res.store.u.string->string;
	if(access(file, AREAD) < 0 && file[0] != '/'){
		snprint(buf, sizeof buf, "#9/acid/%s", file);
		libfile = unsharp(buf);
		if(access(libfile, AREAD) >= 0){
			strecpy(buf, buf+sizeof buf, libfile);
			file = buf;
		}
		free(libfile);
	}

	pushfile(file);
	isave = interactive;
	interactive = 0;
	r->store.u.ival = yyparse();
	interactive = isave;
	popio();
	r->op = OCONST;
	r->type = TINT;
	r->store.fmt = 'D';
}

void
includepipe(Node *r, Node *args)
{
	Node res;
	int i, isave, pid, pip[2];
	char *argv[4];
	Waitmsg *w;

	USED(r);
	if(args == 0)
		error("includepipe(string): arg count");
	expr(args, &res);
	if(res.type != TSTRING)
		error("includepipe(string): arg type");

	Bflush(bout);

	argv[0] = "rc";
	argv[1] = "-c";
	argv[2] = res.store.u.string->string;
	argv[3] = 0;

	if(pipe(pip) < 0)
		error("pipe: %r");
		
	pid = fork();
	switch(pid) {
	case -1:
		close(pip[0]);
		close(pip[1]);
		error("fork: %r");
	case 0:
		close(pip[0]);
		close(0);
		open("/dev/null", OREAD);
		dup(pip[1], 1);
		if(pip[1] > 1)
			close(pip[1]);
		for(i=3; i<100; i++)
			close(i);
		exec("rc", argv);
		sysfatal("exec rc: %r");
	}

	close(pip[1]);
	pushfd(pip[0]);
	
	isave = interactive;
	interactive = 0;
	r->store.u.ival = yyparse();
	interactive = isave;
	popio();

	r->op = OCONST;
	r->type = TINT;
	r->store.fmt = 'D';

	w = waitfor(pid);
	if(w->msg && w->msg[0])
		error("includepipe(\"%s\"): %s", argv[2], w->msg);	/* leaks w */
	free(w);
}

void
rc(Node *r, Node *args)
{
	Node res;
	int pid;
	char *p, *q, *argv[4];
	Waitmsg *w;

	USED(r);
	if(args == 0)
		error("rc(string): arg count");
	expr(args, &res);
	if(res.type != TSTRING)
		error("rc(string): arg type");

	argv[0] = "rc";
	argv[1] = "-c";
	argv[2] = res.store.u.string->string;
	argv[3] = 0;

	pid = fork();
	switch(pid) {
	case -1:
		error("fork %r");
	case 0:
		exec("rc", argv);
		exits(0);
	default:
		w = waitfor(pid);
		break;
	}
	p = w->msg;
	q = strrchr(p, ':');
	if (q)
		p = q+1;

	r->op = OCONST;
	r->type = TSTRING;
	r->store.u.string = strnode(p);
	free(w);
	r->store.fmt = 's';
}

void
doerror(Node *r, Node *args)
{
	Node res;

	USED(r);
	if(args == 0)
		error("error(string): arg count");
	expr(args, &res);
	if(res.type != TSTRING)
		error("error(string): arg type");

	error(res.store.u.string->string);
}

void
doaccess(Node *r, Node *args)
{
	Node res;

	if(args == 0)
		error("access(filename): arg count");
	expr(args, &res);
	if(res.type != TSTRING)
		error("access(filename): arg type");

	r->op = OCONST;
	r->type = TINT;
	r->store.fmt = 'D';
	r->store.u.ival = 0;		
	if(access(res.store.u.string->string, 4) == 0)
		r->store.u.ival = 1;
}

void
readfile(Node *r, Node *args)
{
	Node res;
	int n, fd;
	char *buf;
	Dir *db;

	if(args == 0)
		error("readfile(filename): arg count");
	expr(args, &res);
	if(res.type != TSTRING)
		error("readfile(filename): arg type");

	fd = open(res.store.u.string->string, OREAD);
	if(fd < 0)
		return;

	db = dirfstat(fd);
	if(db == nil || db->length == 0)
		n = 8192;
	else
		n = db->length;
	free(db);

	buf = malloc(n);
	n = read(fd, buf, n);

	if(n > 0) {
		r->op = OCONST;
		r->type = TSTRING;
		r->store.u.string = strnodlen(buf, n);
		r->store.fmt = 's';
	}
	free(buf);
	close(fd);
}

void
getfile(Node *r, Node *args)
{
	int n;
	char *p;
	Node res;
	String *s;
	Biobuf *bp;
	List **l, *new;

	if(args == 0)
		error("file(filename): arg count");
	expr(args, &res);
	if(res.type != TSTRING)
		error("file(filename): arg type");

	r->op = OCONST;
	r->type = TLIST;
	r->store.u.l = 0;

	p = res.store.u.string->string;
	bp = Bopen(p, OREAD);
	if(bp == 0)
		return;

	l = &r->store.u.l;
	for(;;) {
		p = Brdline(bp, '\n');
		n = Blinelen(bp);
		if(p == 0) {
			if(n == 0)
				break;
			s = strnodlen(0, n);
			Bread(bp, s->string, n);
		}
		else
			s = strnodlen(p, n-1);

		new = al(TSTRING);
		new->store.u.string = s;
		new->store.fmt = 's';
		*l = new;
		l = &new->next;
	}
	Bterm(bp);
}

void
cvtatof(Node *r, Node *args)
{
	Node res;

	if(args == 0)
		error("atof(string): arg count");
	expr(args, &res);
	if(res.type != TSTRING)
		error("atof(string): arg type");

	r->op = OCONST;
	r->type = TFLOAT;
	r->store.u.fval = atof(res.store.u.string->string);
	r->store.fmt = 'f';
}

void
cvtatoi(Node *r, Node *args)
{
	Node res;

	if(args == 0)
		error("atoi(string): arg count");
	expr(args, &res);
	if(res.type != TSTRING)
		error("atoi(string): arg type");

	r->op = OCONST;
	r->type = TINT;
	r->store.u.ival = strtoull(res.store.u.string->string, 0, 0);
	r->store.fmt = 'D';
}

void
cvtitoa(Node *r, Node *args)
{
	Node res;
	Node *av[Maxarg];
	s64int ival;
	char buf[128], *fmt;

	if(args == 0)
err:
		error("itoa(number [, printformat]): arg count");
	na = 0;
	flatten(av, args);
	if(na == 0 || na > 2)
		goto err;
	expr(av[0], &res);
	if(res.type != TINT)
		error("itoa(integer): arg type");
	ival = (int)res.store.u.ival;
	fmt = "%d";
	if(na == 2){
		expr(av[1], &res);
		if(res.type != TSTRING)
			error("itoa(integer, string): arg type");
		fmt = res.store.u.string->string;
	}

	sprint(buf, fmt, ival);
	r->op = OCONST;
	r->type = TSTRING;
	r->store.u.string = strnode(buf);
	r->store.fmt = 's';
}

List*
mapent(Map *m)
{
	int i;
	List *l, *n, **t, *h;

	h = 0;
	t = &h;
	for(i = 0; i < m->nseg; i++) {
		l = al(TSTRING);
		n = al(TLIST);
		n->store.u.l = l;
		*t = n;
		t = &n->next;
		l->store.u.string = strnode(m->seg[i].name);
		l->store.fmt = 's';
		l->next = al(TSTRING);
		l = l->next;
		l->store.u.string = strnode(m->seg[i].file ? m->seg[i].file : "");
		l->store.fmt = 's';
		l->next = al(TINT);
		l = l->next;
		l->store.u.ival = m->seg[i].base;
		l->store.fmt = 'X';
		l->next = al(TINT);
		l = l->next;
		l->store.u.ival = m->seg[i].base + m->seg[i].size;
		l->store.fmt = 'X';
		l->next = al(TINT);
		l = l->next;
		l->store.u.ival = m->seg[i].offset;
		l->store.fmt = 'X';
	}
	return h;
}

void
map(Node *r, Node *args)
{
	int i;
	Map *m;
	List *l;
	char *nam, *fil;
	Node *av[Maxarg], res;

	na = 0;
	flatten(av, args);

	if(na != 0) {
		expr(av[0], &res);
		if(res.type != TLIST)
			error("map(list): map needs a list");
		if(listlen(res.store.u.l) != 5)
			error("map(list): list must have 5 entries");

		l = res.store.u.l;
		if(l->type != TSTRING)
			error("map name must be a string");
		nam = l->store.u.string->string;
		l = l->next;
		if(l->type != TSTRING)
			error("map file must be a string");
		fil = l->store.u.string->string;
		m = symmap;
		i = findseg(m, nam, fil);
		if(i < 0) {
			m = cormap;
			i = findseg(m, nam, fil);
		}
		if(i < 0)
			error("%s %s is not a map entry", nam, fil);	
		l = l->next;
		if(l->type != TINT)
			error("map entry not int");
		m->seg[i].base = l->store.u.ival;
/*
		if (strcmp(ent, "text") == 0)
			textseg(l->store.u.ival, &fhdr);
*/
		l = l->next;
		if(l->type != TINT)
			error("map entry not int");
		m->seg[i].size = l->store.u.ival - m->seg[i].base;
		l = l->next;
		if(l->type != TINT)
			error("map entry not int");
		m->seg[i].offset = l->store.u.ival;
	}

	r->type = TLIST;
	r->store.u.l = 0;
	if(symmap)
		r->store.u.l = mapent(symmap);
	if(cormap) {
		if(r->store.u.l == 0)
			r->store.u.l = mapent(cormap);
		else {
			for(l = r->store.u.l; l->next; l = l->next)
				;
			l->next = mapent(cormap);
		}
	}
}

void 
flatten(Node **av, Node *n)
{
	if(n == 0)
		return;

	switch(n->op) {
	case OLIST:
		flatten(av, n->left);
		flatten(av, n->right);
		break;
	default:
		av[na++] = n;
		if(na >= Maxarg)
			error("too many function arguments");
		break;
	}
}

static struct
{
	char *name;
	u64int val;
} sregs[Maxarg/2];
static int nsregs;

static int
straceregrw(Regs *regs, char *name, u64int *val, int isr)
{
	int i;

	if(!isr){
		werrstr("saved registers cannot be written");
		return -1;
	}
	for(i=0; i<nsregs; i++)
		if(strcmp(sregs[i].name, name) == 0){
			*val = sregs[i].val;
			return 0;
		}
	return rget(acidregs, name, val);
}

void
strace(Node *r, Node *args)
{
	Node *av[Maxarg], res;
	List *l;
	Regs regs;

	na = 0;
	flatten(av, args);

	if(na != 1)
		error("strace(list): want one arg");

	expr(av[0], &res);
	if(res.type != TLIST)
		error("strace(list): strace needs a list");
	l = res.store.u.l;
	if(listlen(l)%2)
		error("strace(list): strace needs an even-length list");
	for(nsregs=0; l; nsregs++){
		if(l->type != TSTRING)
			error("strace({r,v,r,v,...}): non-string name");
		sregs[nsregs].name = l->store.u.string->string;
		if(regdesc(sregs[nsregs].name) == nil)
			error("strace: bad register '%s'", sregs[nsregs].name);
		l = l->next;

		if(l == nil)
			error("cannot happen in strace");
		if(l->type != TINT)
			error("strace: non-int value for %s", sregs[nsregs].name);
		sregs[nsregs].val = l->store.u.ival;
		l = l->next;
	}
	regs.rw = straceregrw;
	
	tracelist = 0;
	if(stacktrace(cormap, &regs, trlist) <= 0)
		error("no stack frame");
	r->type = TLIST;
	r->store.u.l = tracelist;
}

void
regerror(char *msg)
{
	error(msg);
}

void
regexp(Node *r, Node *args)
{
	Node res;
	Reprog *rp;
	Node *av[Maxarg];

	na = 0;
	flatten(av, args);
	if(na != 2)
		error("regexp(pattern, string): arg count");
	expr(av[0], &res);
	if(res.type != TSTRING)
		error("regexp(pattern, string): pattern must be string");
	rp = regcomp(res.store.u.string->string);
	if(rp == 0)
		return;

	expr(av[1], &res);
	if(res.type != TSTRING)
		error("regexp(pattern, string): bad string");

	r->store.fmt = 'D';
	r->type = TINT;
	r->store.u.ival = regexec(rp, res.store.u.string->string, 0, 0);
	free(rp);
}

char vfmt[] = "aBbcCdDfFgGiIoOqQrRsSuUVxXYZ";

void
fmt(Node *r, Node *args)
{
	Node res;
	Node *av[Maxarg];

	na = 0;
	flatten(av, args);
	if(na != 2)
		error("fmt(obj, fmt): arg count");
	expr(av[1], &res);
	if(res.type != TINT || strchr(vfmt, res.store.u.ival) == 0)
		error("fmt(obj, fmt): bad format '%c'", (char)res.store.u.ival);
	expr(av[0], r);
	r->store.fmt = res.store.u.ival;
}

void
patom(char type, Store *res)
{
	int i;
	char buf[512];
	extern char *typenames[];
	Node *n;

	switch(type){
	case TREG:
		if(res->u.reg.thread)
			Bprint(bout, "register(\"%s\", %#ux)", res->u.reg.name, res->u.reg.thread);
		else
			Bprint(bout, "register(\"%s\")", res->u.reg.name);
		return;
	case TCON:
		Bprint(bout, "refconst(");
		n = res->u.con;
		patom(n->type, &n->store);
		Bprint(bout, ")");
		return;
	}

	switch(res->fmt){
	case 'c':
	case 'C':
	case 'r':
	case 'B':
	case 'b':
	case 'X':
	case 'x':
	case 'W':
	case 'D':
	case 'd':
	case 'u':
	case 'U':
	case 'Z':
	case 'V':
	case 'Y':
	case 'o':
	case 'O':
	case 'q':
	case 'Q':
	case 'a':
	case 'A':
	case 'I':
	case 'i':
		if(type != TINT){
		badtype:
			Bprint(bout, "*%s\\%c*", typenames[(uchar)type], res->fmt);
			return;
		}
		break;

	case 'f':
	case 'F':
		if(type != TFLOAT)
			goto badtype;
		break;

	case 's':
	case 'g':
	case 'G':
	case 'R':
		if(type != TSTRING)
			goto badtype;
		break;
	}

	switch(res->fmt) {
	case 'c':
		Bprint(bout, "%c", (int)res->u.ival);
		break;
	case 'C':
		if(res->u.ival < ' ' || res->u.ival >= 0x7f)
			Bprint(bout, "%3d", (int)res->u.ival&0xff);
		else
			Bprint(bout, "%3c", (int)res->u.ival);
		break;
	case 'r':
		Bprint(bout, "%C", (int)res->u.ival);
		break;
	case 'B':
		memset(buf, '0', 34);
		buf[1] = 'b';
		for(i = 0; i < 32; i++) {
			if(res->u.ival & (1<<i))
				buf[33-i] = '1';
		}
		buf[35] = '\0';
		Bprint(bout, "%s", buf);
		break;
	case 'b':
		Bprint(bout, "%#.2x", (int)res->u.ival&0xff);
		break;
	case 'X':
		Bprint(bout, "%#.8lux", (ulong)res->u.ival);
		break;
	case 'x':
		Bprint(bout, "%#.4lux", (ulong)res->u.ival&0xffff);
		break;
	case 'W':
		Bprint(bout, "%#.16llux", res->u.ival);
		break;
	case 'D':
		Bprint(bout, "%d", (int)res->u.ival);
		break;
	case 'd':
		Bprint(bout, "%d", (ushort)res->u.ival);
		break;
	case 'u':
		Bprint(bout, "%d", (int)res->u.ival&0xffff);
		break;
	case 'U':
		Bprint(bout, "%lud", (ulong)res->u.ival);
		break;
	case 'Z':
		Bprint(bout, "%llud", res->u.ival);
		break;
	case 'V':
		Bprint(bout, "%lld", res->u.ival);
		break;
	case 'Y':
		Bprint(bout, "%#.16llux", res->u.ival);
		break;
	case 'o':
		Bprint(bout, "%#.11uo", (int)res->u.ival&0xffff);
		break;
	case 'O':
		Bprint(bout, "%#.6uo", (int)res->u.ival);
		break;
	case 'q':
		Bprint(bout, "%#.11o", (short)(res->u.ival&0xffff));
		break;
	case 'Q':
		Bprint(bout, "%#.6o", (int)res->u.ival);
		break;
	case 'f':
	case 'F':
		Bprint(bout, "%g", res->u.fval);
		break;
	case 's':
	case 'g':
	case 'G':
		Bwrite(bout, res->u.string->string, res->u.string->len);
		break;
	case 'R':
		Bprint(bout, "%S", (Rune*)res->u.string->string);
		break;
	case 'a':
	case 'A':
		symoff(buf, sizeof(buf), res->u.ival, CANY);
		Bprint(bout, "%s", buf);
		break;
	case 'I':
	case 'i':
		if (symmap == nil || (*mach->das)(symmap, res->u.ival, res->fmt, buf, sizeof(buf)) < 0)
			Bprint(bout, "no instruction");
		else
			Bprint(bout, "%s", buf);
		break;
	}
}

void
blprint(List *l)
{
	Store *res;

	Bprint(bout, "{");
	while(l) {
		switch(l->type) {
		case TINT:
			res = &l->store;
			if(res->fmt == 'c'){
				Bprint(bout, "\'%c\'", (int)res->u.ival);
				break;
			}else if(res->fmt == 'r'){
				Bprint(bout, "\'%C\'", (int)res->u.ival);
				break;
			}
			/* fall through */
		default:
			patom(l->type, &l->store);
			break;
		case TSTRING:
			Bputc(bout, '"');
			patom(l->type, &l->store);
			Bputc(bout, '"');
			break;
		case TLIST:
			blprint(l->store.u.l);
			break;
		case TCODE:
			pcode(l->store.u.cc, 0);
			break;
		}
		l = l->next;
		if(l)
			Bprint(bout, ", ");
	}
	Bprint(bout, "}");
}

int
comx(Node res)
{
	Lsym *sl;
	Node *n, xx;

	if(res.store.fmt != 'a' && res.store.fmt != 'A')
		return 0;

	if(res.store.comt == 0 || res.store.comt->base == 0)
		return 0;

	sl = res.store.comt->base;
	if(sl->proc) {
		res.left = ZN;
		res.right = ZN;
		n = an(ONAME, ZN, ZN);
		n->sym = sl;
		n = an(OCALL, n, &res);
			n->left->sym = sl;
		expr(n, &xx);
		return 1;
	}
	print("(%s)", sl->name);
	return 0;
}

void
bprint(Node *r, Node *args)
{
	int i, nas;
	Node res, *av[Maxarg];

	USED(r);
	na = 0;
	flatten(av, args);
	nas = na;
	for(i = 0; i < nas; i++) {
		expr(av[i], &res);
		switch(res.type) {
		default:
			if(comx(res))
				break;
			patom(res.type, &res.store);
			break;
		case TCODE:
			pcode(res.store.u.cc, 0);
			break;
		case TLIST:
			blprint(res.store.u.l);
			break;
		}
	}
	if(ret == 0)
		Bputc(bout, '\n');
}

void
printto(Node *r, Node *args)
{
	int fd;
	Biobuf *b;
	int i, nas;
	Node res, *av[Maxarg];

	USED(r);
	na = 0;
	flatten(av, args);
	nas = na;

	expr(av[0], &res);
	if(res.type != TSTRING)
		error("printto(string, ...): need string");

	fd = create(res.store.u.string->string, OWRITE, 0666);
	if(fd < 0)
		fd = open(res.store.u.string->string, OWRITE);
	if(fd < 0)
		error("printto: open %s: %r", res.store.u.string->string);

	b = gmalloc(sizeof(Biobuf));
	Binit(b, fd, OWRITE);

	Bflush(bout);
	io[iop++] = bout;
	bout = b;

	for(i = 1; i < nas; i++) {
		expr(av[i], &res);
		switch(res.type) {
		default:
			if(comx(res))
				break;
			patom(res.type, &res.store);
			break;
		case TLIST:
			blprint(res.store.u.l);
			break;
		}
	}
	if(ret == 0)
		Bputc(bout, '\n');

	Bterm(b);
	close(fd);
	free(b);
	bout = io[--iop];
}

void
pcfile(Node *r, Node *args)
{
	Node res;
	char *p, buf[128];

	if(args == 0)
		error("pcfile(addr): arg count");
	expr(args, &res);
	if(res.type != TINT)
		error("pcfile(addr): arg type");

	r->type = TSTRING;
	r->store.fmt = 's';
	if(fileline(res.store.u.ival, buf, sizeof(buf)) < 0) {
		r->store.u.string = strnode("?file?");
		return;
	}
	p = strrchr(buf, ':');
	if(p == 0)
		error("pcfile(addr): funny file %s", buf);
	*p = '\0';
	r->store.u.string = strnode(buf);	
}

void
pcline(Node *r, Node *args)
{
	Node res;
	char *p, buf[128];

	if(args == 0)
		error("pcline(addr): arg count");
	expr(args, &res);
	if(res.type != TINT)
		error("pcline(addr): arg type");

	r->type = TINT;
	r->store.fmt = 'D';
	if(fileline(res.store.u.ival, buf, sizeof(buf)) < 0) {
		r->store.u.ival = 0;
		return;
	}

	p = strrchr(buf, ':');
	if(p == 0)
		error("pcline(addr): funny file %s", buf);
	r->store.u.ival = atoi(p+1);	
}

void
textfile(Node *r, Node *args)
{
	char *file;
	long base;
	Fhdr *fp;
	Node res, *av[Maxarg];
	List *l, *l2, **tail, *list, *tl;

	na = 0;
	flatten(av, args);

	if(na != 0) {
		expr(av[0], &res);
		if(res.type != TLIST)
			error("textfile(list): textfile needs a list");
		if(listlen(res.store.u.l) != 2)
			error("textfile(list): list must have 2 entries");

		l = res.store.u.l;
		if(l->type != TSTRING)
			error("textfile name must be a string");
		file = l->store.u.string->string;

		l = l->next;
		if(l->type != TINT)
			error("textfile base must be an int");
		base = l->store.u.ival;

		if((fp = crackhdr(file, OREAD)) == nil)
			error("crackhdr %s: %r", file);
		Bflush(bout);
		fp->base = base;
		fprint(2, "%s: %s %s %s\n", file, fp->aname, fp->mname, fp->fname);
		if(mapfile(fp, base, symmap, nil) < 0)
			fprint(2, "mapping %s: %r\n", file);
		if(corhdr){
			unmapfile(corhdr, cormap);
			mapfile(fp, base, cormap, nil);
			free(correg);
			correg = nil;
			mapfile(corhdr, 0, cormap, &correg);
		}
		if(symopen(fp) < 0)
			fprint(2, "symopen %s: %r\n", file);
		else
			addvarsym(fp);
		return;
	}

	l2 = nil;
	tail = &l2;
	for(fp=fhdrlist; fp; fp=fp->next){
		if(fp->ftype == FCORE)
			continue;
		tl = al(TLIST);
		*tail = tl;
		tail = &tl->next;

		list = al(TSTRING);
		tl->store.u.l = list;
		list->store.u.string = strnode(fp->filename);
		list->store.fmt = 's';
		list->next = al(TINT);
		list = list->next;
		list->store.fmt = 'X';
		list->store.u.ival = fp->base;
	}

	r->type = TLIST;
	r->store.u.l = l2;
}

void
deltextfile(Node *r, Node *args)
{
	int did;
	char *file;
	Fhdr *fp, *fpnext;
	Node res, *av[Maxarg];

	na = 0;
	flatten(av, args);

	if(na != 1)
		error("deltextfile(string): arg count");

	expr(av[0], &res);
	if(res.type != TSTRING)
		error("deltextfile(string): arg type");
	file = res.store.u.string->string;

	did = 0;
	for(fp=fhdrlist; fp; fp=fpnext){
		fpnext = fp->next;
		if(fp->ftype == FCORE)
			continue;
		if(strcmp(file, fp->filename) == 0){
			did = 1;
			if(fp == symhdr)
				error("cannot remove symbols from main text file");
			unmapfile(fp, symmap);
			uncrackhdr(fp);
		}
	}

	delvarsym(file);
	if(!did)
		error("symbol file %s not open", file);
}

void
stringn(Node *r, Node *args)
{
	uint addr;
	int i, n, ret;
	Node res, *av[Maxarg];
	char *buf;

	na = 0;
	flatten(av, args);
	if(na != 2)
		error("stringn(addr, n): arg count");

	expr(av[0], &res);
	if(res.type != TINT)
		error("stringn(addr, n): arg type");
	addr = res.store.u.ival;

	expr(av[1], &res);
	if(res.type != TINT)
		error("stringn(addr,n): arg type");
	n = res.store.u.ival;

	buf = malloc(n+1);
	if(buf == nil)
		error("out of memory");

	r->type = TSTRING;
	for(i=0; i<n; i++){
		ret = get1(cormap, addr, (uchar*)&buf[i], 1);
		if(ret < 0){
			free(buf);
			error("indir: %r");
		}
		addr++;
	}
	buf[n] = 0;
	r->store.u.string = strnode(buf);
	free(buf);
}
