xref: /plan9/sys/src/cmd/db/command.c (revision c93608cc76758b2be624199c6208a0f90bad298d)
13e12c5d1SDavid du Colombier /*
23e12c5d1SDavid du Colombier  *
33e12c5d1SDavid du Colombier  *	debugger
43e12c5d1SDavid du Colombier  *
53e12c5d1SDavid du Colombier  */
63e12c5d1SDavid du Colombier 
73e12c5d1SDavid du Colombier #include "defs.h"
83e12c5d1SDavid du Colombier #include "fns.h"
93e12c5d1SDavid du Colombier 
103e12c5d1SDavid du Colombier char	BADEQ[] = "unexpected `='";
113e12c5d1SDavid du Colombier 
123e12c5d1SDavid du Colombier BOOL	executing;
13061a3f44SDavid du Colombier extern	Rune	*lp;
143e12c5d1SDavid du Colombier 
153e12c5d1SDavid du Colombier char	eqformat[ARB] = "z";
163e12c5d1SDavid du Colombier char	stformat[ARB] = "zMi";
173e12c5d1SDavid du Colombier 
183e12c5d1SDavid du Colombier ADDR	ditto;
193e12c5d1SDavid du Colombier 
203e12c5d1SDavid du Colombier ADDR	dot;
21*c93608ccSDavid du Colombier int	dotinc;
223e12c5d1SDavid du Colombier WORD	adrval, cntval, loopcnt;
233e12c5d1SDavid du Colombier int	adrflg, cntflg;
243e12c5d1SDavid du Colombier 
253e12c5d1SDavid du Colombier /* command decoding */
263e12c5d1SDavid du Colombier 
command(char * buf,int defcom)273e12c5d1SDavid du Colombier command(char *buf, int defcom)
283e12c5d1SDavid du Colombier {
29219b2ee8SDavid du Colombier 	char	*reg;
303e12c5d1SDavid du Colombier 	char	savc;
31061a3f44SDavid du Colombier 	Rune	*savlp=lp;
323e12c5d1SDavid du Colombier 	char	savlc = lastc;
333e12c5d1SDavid du Colombier 	char	savpc = peekc;
343e12c5d1SDavid du Colombier 	static char lastcom = '=', savecom = '=';
353e12c5d1SDavid du Colombier 
363e12c5d1SDavid du Colombier 	if (defcom == 0)
373e12c5d1SDavid du Colombier 		defcom = lastcom;
383e12c5d1SDavid du Colombier 	if (buf) {
393e12c5d1SDavid du Colombier 		if (*buf==EOR)
403e12c5d1SDavid du Colombier 			return(FALSE);
413e12c5d1SDavid du Colombier 		clrinp();
42061a3f44SDavid du Colombier 		lp=(Rune*)buf;
433e12c5d1SDavid du Colombier 	}
443e12c5d1SDavid du Colombier 	do {
45219b2ee8SDavid du Colombier 		adrflg=expr(0);		/* first address */
469a747e4fSDavid du Colombier 		if (adrflg){
479a747e4fSDavid du Colombier 			dot=expv;
489a747e4fSDavid du Colombier 			ditto=expv;
499a747e4fSDavid du Colombier 		}
503e12c5d1SDavid du Colombier 		adrval=dot;
51219b2ee8SDavid du Colombier 
52219b2ee8SDavid du Colombier 		if (rdc()==',' && expr(0)) {	/* count */
533e12c5d1SDavid du Colombier 			cntflg=TRUE;
543e12c5d1SDavid du Colombier 			cntval=expv;
553e12c5d1SDavid du Colombier 		} else {
563e12c5d1SDavid du Colombier 			cntflg=FALSE;
573e12c5d1SDavid du Colombier 			cntval=1;
583e12c5d1SDavid du Colombier 			reread();
593e12c5d1SDavid du Colombier 		}
60219b2ee8SDavid du Colombier 
613e12c5d1SDavid du Colombier 		if (!eol(rdc()))
62219b2ee8SDavid du Colombier 			lastcom=lastc;		/* command */
633e12c5d1SDavid du Colombier 		else {
643e12c5d1SDavid du Colombier 			if (adrflg==0)
653e12c5d1SDavid du Colombier 				dot=inkdot(dotinc);
663e12c5d1SDavid du Colombier 			reread();
673e12c5d1SDavid du Colombier 			lastcom=defcom;
683e12c5d1SDavid du Colombier 		}
693e12c5d1SDavid du Colombier 		switch(lastcom) {
703e12c5d1SDavid du Colombier 		case '/':
713e12c5d1SDavid du Colombier 		case '=':
723e12c5d1SDavid du Colombier 		case '?':
733e12c5d1SDavid du Colombier 			savecom = lastcom;
743e12c5d1SDavid du Colombier 			acommand(lastcom);
753e12c5d1SDavid du Colombier 			break;
763e12c5d1SDavid du Colombier 
773e12c5d1SDavid du Colombier 		case '>':
783e12c5d1SDavid du Colombier 			lastcom = savecom;
793e12c5d1SDavid du Colombier 			savc=rdc();
80219b2ee8SDavid du Colombier 			if (reg=regname(savc))
81219b2ee8SDavid du Colombier 				rput(cormap, reg, dot);
823e12c5d1SDavid du Colombier 			else
833e12c5d1SDavid du Colombier 				error("bad variable");
843e12c5d1SDavid du Colombier 			break;
853e12c5d1SDavid du Colombier 
863e12c5d1SDavid du Colombier 		case '!':
873e12c5d1SDavid du Colombier 			lastcom=savecom;
883e12c5d1SDavid du Colombier 			shell();
893e12c5d1SDavid du Colombier 			break;
903e12c5d1SDavid du Colombier 
913e12c5d1SDavid du Colombier 		case '$':
923e12c5d1SDavid du Colombier 			lastcom=savecom;
933e12c5d1SDavid du Colombier 			printtrace(nextchar());
943e12c5d1SDavid du Colombier 			break;
953e12c5d1SDavid du Colombier 
963e12c5d1SDavid du Colombier 		case ':':
973e12c5d1SDavid du Colombier 			if (!executing) {
983e12c5d1SDavid du Colombier 				executing=TRUE;
993e12c5d1SDavid du Colombier 				subpcs(nextchar());
1003e12c5d1SDavid du Colombier 				executing=FALSE;
1013e12c5d1SDavid du Colombier 				lastcom=savecom;
1023e12c5d1SDavid du Colombier 			}
1033e12c5d1SDavid du Colombier 			break;
1043e12c5d1SDavid du Colombier 
1053e12c5d1SDavid du Colombier 		case 0:
1063e12c5d1SDavid du Colombier 			prints(DBNAME);
1073e12c5d1SDavid du Colombier 			break;
1083e12c5d1SDavid du Colombier 
1093e12c5d1SDavid du Colombier 		default:
1103e12c5d1SDavid du Colombier 			error("bad command");
1113e12c5d1SDavid du Colombier 		}
1123e12c5d1SDavid du Colombier 		flushbuf();
1133e12c5d1SDavid du Colombier 	} while (rdc()==';');
1143e12c5d1SDavid du Colombier 	if (buf == 0)
1153e12c5d1SDavid du Colombier 		reread();
1163e12c5d1SDavid du Colombier 	else {
1173e12c5d1SDavid du Colombier 		clrinp();
1183e12c5d1SDavid du Colombier 		lp=savlp;
1193e12c5d1SDavid du Colombier 		lastc = savlc;
1203e12c5d1SDavid du Colombier 		peekc = savpc;
1213e12c5d1SDavid du Colombier 	}
1223e12c5d1SDavid du Colombier 
1233e12c5d1SDavid du Colombier 	if(adrflg)
1243e12c5d1SDavid du Colombier 		return dot;
1253e12c5d1SDavid du Colombier 	return 1;
1263e12c5d1SDavid du Colombier }
1273e12c5d1SDavid du Colombier 
1283e12c5d1SDavid du Colombier /*
1293e12c5d1SDavid du Colombier  * [/?][wml]
1303e12c5d1SDavid du Colombier  */
1313e12c5d1SDavid du Colombier 
1323e12c5d1SDavid du Colombier void
acommand(int pc)1333e12c5d1SDavid du Colombier acommand(int pc)
1343e12c5d1SDavid du Colombier {
1353e12c5d1SDavid du Colombier 	int eqcom;
136219b2ee8SDavid du Colombier 	Map *map;
1373e12c5d1SDavid du Colombier 	char *fmt;
138219b2ee8SDavid du Colombier 	char buf[512];
1393e12c5d1SDavid du Colombier 
1403e12c5d1SDavid du Colombier 	if (pc == '=') {
141219b2ee8SDavid du Colombier 		eqcom = 1;
1423e12c5d1SDavid du Colombier 		fmt = eqformat;
143219b2ee8SDavid du Colombier 		map = dotmap;
1443e12c5d1SDavid du Colombier 	} else {
145219b2ee8SDavid du Colombier 		eqcom = 0;
1463e12c5d1SDavid du Colombier 		fmt = stformat;
147219b2ee8SDavid du Colombier 		if (pc == '/')
1483e12c5d1SDavid du Colombier 			map = cormap;
149219b2ee8SDavid du Colombier 		else
150219b2ee8SDavid du Colombier 			map = symmap;
1513e12c5d1SDavid du Colombier 	}
152219b2ee8SDavid du Colombier 	if (!map) {
1534de34a7eSDavid du Colombier 		snprint(buf, sizeof(buf), "no map for %c", pc);
154219b2ee8SDavid du Colombier 		error(buf);
1553e12c5d1SDavid du Colombier 	}
156219b2ee8SDavid du Colombier 
157219b2ee8SDavid du Colombier 	switch (rdc())
158219b2ee8SDavid du Colombier 	{
1593e12c5d1SDavid du Colombier 	case 'm':
1603e12c5d1SDavid du Colombier 		if (eqcom)
1613e12c5d1SDavid du Colombier 			error(BADEQ);
1623e12c5d1SDavid du Colombier 		cmdmap(map);
1633e12c5d1SDavid du Colombier 		break;
1643e12c5d1SDavid du Colombier 
1653e12c5d1SDavid du Colombier 	case 'L':
1663e12c5d1SDavid du Colombier 	case 'l':
1673e12c5d1SDavid du Colombier 		if (eqcom)
1683e12c5d1SDavid du Colombier 			error(BADEQ);
169219b2ee8SDavid du Colombier 		cmdsrc(lastc, map);
1703e12c5d1SDavid du Colombier 		break;
1713e12c5d1SDavid du Colombier 
1723e12c5d1SDavid du Colombier 	case 'W':
1733e12c5d1SDavid du Colombier 	case 'w':
1743e12c5d1SDavid du Colombier 		if (eqcom)
1753e12c5d1SDavid du Colombier 			error(BADEQ);
176219b2ee8SDavid du Colombier 		cmdwrite(lastc, map);
1773e12c5d1SDavid du Colombier 		break;
1783e12c5d1SDavid du Colombier 
1793e12c5d1SDavid du Colombier 	default:
1803e12c5d1SDavid du Colombier 		reread();
1813e12c5d1SDavid du Colombier 		getformat(fmt);
182219b2ee8SDavid du Colombier 		scanform(cntval, !eqcom, fmt, map, eqcom);
1833e12c5d1SDavid du Colombier 	}
1843e12c5d1SDavid du Colombier }
1853e12c5d1SDavid du Colombier 
1863e12c5d1SDavid du Colombier void
cmdsrc(int c,Map * map)187219b2ee8SDavid du Colombier cmdsrc(int c, Map *map)
1883e12c5d1SDavid du Colombier {
1894de34a7eSDavid du Colombier 	ulong w;
190219b2ee8SDavid du Colombier 	long locval, locmsk;
1913e12c5d1SDavid du Colombier 	ADDR savdot;
1923e12c5d1SDavid du Colombier 	ushort sh;
193219b2ee8SDavid du Colombier 	char buf[512];
194219b2ee8SDavid du Colombier 	int ret;
1953e12c5d1SDavid du Colombier 
1963e12c5d1SDavid du Colombier 	if (c == 'L')
1973e12c5d1SDavid du Colombier 		dotinc = 4;
1983e12c5d1SDavid du Colombier 	else
1993e12c5d1SDavid du Colombier 		dotinc = 2;
2003e12c5d1SDavid du Colombier 	savdot=dot;
2013e12c5d1SDavid du Colombier 	expr(1);
2023e12c5d1SDavid du Colombier 	locval=expv;
2033e12c5d1SDavid du Colombier 	if (expr(0))
2043e12c5d1SDavid du Colombier 		locmsk=expv;
2053e12c5d1SDavid du Colombier 	else
2063e12c5d1SDavid du Colombier 		locmsk = ~0;
207219b2ee8SDavid du Colombier 	if (c == 'L')
208219b2ee8SDavid du Colombier 		while ((ret = get4(map, dot, &w)) > 0 &&  (w&locmsk) != locval)
2093e12c5d1SDavid du Colombier 			dot = inkdot(dotinc);
210219b2ee8SDavid du Colombier 	else
211219b2ee8SDavid du Colombier 		while ((ret = get2(map, dot, &sh)) > 0 && (sh&locmsk) != locval)
2123e12c5d1SDavid du Colombier 			dot = inkdot(dotinc);
213219b2ee8SDavid du Colombier 	if (ret < 0) {
2143e12c5d1SDavid du Colombier 		dot=savdot;
215219b2ee8SDavid du Colombier 		error("%r");
2163e12c5d1SDavid du Colombier 	}
217219b2ee8SDavid du Colombier 	symoff(buf, 512, dot, CANY);
218219b2ee8SDavid du Colombier 	dprint(buf);
2193e12c5d1SDavid du Colombier }
2203e12c5d1SDavid du Colombier 
221219b2ee8SDavid du Colombier static char badwrite[] = "can't write process memory or text image";
222219b2ee8SDavid du Colombier 
2233e12c5d1SDavid du Colombier void
cmdwrite(int wcom,Map * map)224219b2ee8SDavid du Colombier cmdwrite(int wcom, Map *map)
2253e12c5d1SDavid du Colombier {
2263e12c5d1SDavid du Colombier 	ADDR savdot;
227219b2ee8SDavid du Colombier 	char *format;
2283e12c5d1SDavid du Colombier 	int pass;
2293e12c5d1SDavid du Colombier 
230219b2ee8SDavid du Colombier 	if (wcom == 'w')
231219b2ee8SDavid du Colombier 		format = "x";
232219b2ee8SDavid du Colombier 	else
233219b2ee8SDavid du Colombier 		format = "X";
2343e12c5d1SDavid du Colombier 	expr(1);
2353e12c5d1SDavid du Colombier 	pass = 0;
2363e12c5d1SDavid du Colombier 	do {
2373e12c5d1SDavid du Colombier 		pass++;
2383e12c5d1SDavid du Colombier 		savdot=dot;
239219b2ee8SDavid du Colombier 		exform(1, 1, format, map, 0, pass);
2403e12c5d1SDavid du Colombier 		dot=savdot;
241219b2ee8SDavid du Colombier 		if (wcom == 'W') {
242219b2ee8SDavid du Colombier 			if (put4(map, dot, expv) <= 0)
243219b2ee8SDavid du Colombier 				error(badwrite);
244219b2ee8SDavid du Colombier 		} else {
245219b2ee8SDavid du Colombier 			if (put2(map, dot, expv) <= 0)
246219b2ee8SDavid du Colombier 				error(badwrite);
247219b2ee8SDavid du Colombier 		}
2483e12c5d1SDavid du Colombier 		savdot=dot;
2493e12c5d1SDavid du Colombier 		dprint("=%8t");
250219b2ee8SDavid du Colombier 		exform(1, 0, format, map, 0, pass);
2513e12c5d1SDavid du Colombier 		newline();
252219b2ee8SDavid du Colombier 	} while (expr(0));
2533e12c5d1SDavid du Colombier 	dot=savdot;
2543e12c5d1SDavid du Colombier }
2553e12c5d1SDavid du Colombier 
2563e12c5d1SDavid du Colombier /*
2573e12c5d1SDavid du Colombier  * collect a register name; return register offset
2583e12c5d1SDavid du Colombier  * this is not what i'd call a good division of labour
2593e12c5d1SDavid du Colombier  */
2603e12c5d1SDavid du Colombier 
261219b2ee8SDavid du Colombier char *
regname(int regnam)262219b2ee8SDavid du Colombier regname(int regnam)
2633e12c5d1SDavid du Colombier {
264219b2ee8SDavid du Colombier 	static char buf[64];
2653e12c5d1SDavid du Colombier 	char *p;
2663e12c5d1SDavid du Colombier 	int c;
2673e12c5d1SDavid du Colombier 
2683e12c5d1SDavid du Colombier 	p = buf;
2693e12c5d1SDavid du Colombier 	*p++ = regnam;
270219b2ee8SDavid du Colombier 	while (isalnum(c = readchar())) {
271219b2ee8SDavid du Colombier 		if (p >= buf+sizeof(buf)-1)
272219b2ee8SDavid du Colombier 			error("register name too long");
2733e12c5d1SDavid du Colombier 		*p++ = c;
274219b2ee8SDavid du Colombier 	}
2753e12c5d1SDavid du Colombier 	*p = 0;
2763e12c5d1SDavid du Colombier 	reread();
277219b2ee8SDavid du Colombier 	return (buf);
2783e12c5d1SDavid du Colombier }
2793e12c5d1SDavid du Colombier 
2803e12c5d1SDavid du Colombier /*
2813e12c5d1SDavid du Colombier  * shell escape
2823e12c5d1SDavid du Colombier  */
2833e12c5d1SDavid du Colombier 
2843e12c5d1SDavid du Colombier void
shell(void)2853e12c5d1SDavid du Colombier shell(void)
2863e12c5d1SDavid du Colombier {
2873e12c5d1SDavid du Colombier 	int	rc, unixpid;
288061a3f44SDavid du Colombier 	char *argp = (char*)lp;
2893e12c5d1SDavid du Colombier 
2903e12c5d1SDavid du Colombier 	while (lastc!=EOR)
2913e12c5d1SDavid du Colombier 		rdc();
2923e12c5d1SDavid du Colombier 	if ((unixpid=fork())==0) {
2933e12c5d1SDavid du Colombier 		*lp=0;
294f19e7b74SDavid du Colombier 		execl("/bin/rc", "rc", "-c", argp, nil);
2953e12c5d1SDavid du Colombier 		exits("execl");				/* botch */
2963e12c5d1SDavid du Colombier 	} else if (unixpid == -1) {
2973e12c5d1SDavid du Colombier 		error("cannot fork");
2983e12c5d1SDavid du Colombier 	} else {
2993e12c5d1SDavid du Colombier 		mkfault = 0;
3009a747e4fSDavid du Colombier 		while ((rc = waitpid()) != unixpid){
3013e12c5d1SDavid du Colombier 			if(rc == -1 && mkfault){
3023e12c5d1SDavid du Colombier 				mkfault = 0;
3033e12c5d1SDavid du Colombier 				continue;
3043e12c5d1SDavid du Colombier 			}
3053e12c5d1SDavid du Colombier 			break;
3063e12c5d1SDavid du Colombier 		}
3073e12c5d1SDavid du Colombier 		prints("!");
3083e12c5d1SDavid du Colombier 		reread();
3093e12c5d1SDavid du Colombier 	}
3103e12c5d1SDavid du Colombier }
311