xref: /plan9/sys/src/cmd/db/command.c (revision 219b2ee8daee37f4aad58d63f21287faa8e4ffdc)
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;
133e12c5d1SDavid du Colombier extern	char	*lp;
143e12c5d1SDavid du Colombier 
153e12c5d1SDavid du Colombier extern	char	lastc, peekc;
163e12c5d1SDavid du Colombier char	eqformat[ARB] = "z";
173e12c5d1SDavid du Colombier char	stformat[ARB] = "zMi";
183e12c5d1SDavid du Colombier 
193e12c5d1SDavid du Colombier ADDR	ditto;
203e12c5d1SDavid du Colombier 
213e12c5d1SDavid du Colombier ADDR	dot;
223e12c5d1SDavid du Colombier WORD	dotinc;
233e12c5d1SDavid du Colombier WORD	adrval, cntval, loopcnt;
243e12c5d1SDavid du Colombier int	adrflg, cntflg;
253e12c5d1SDavid du Colombier 
263e12c5d1SDavid du Colombier /* command decoding */
273e12c5d1SDavid du Colombier 
283e12c5d1SDavid du Colombier command(char *buf, int defcom)
293e12c5d1SDavid du Colombier {
30*219b2ee8SDavid du Colombier 	char	*reg;
313e12c5d1SDavid du Colombier 	char	savc;
323e12c5d1SDavid du Colombier 	char	*savlp=lp;
333e12c5d1SDavid du Colombier 	char	savlc = lastc;
343e12c5d1SDavid du Colombier 	char	savpc = peekc;
353e12c5d1SDavid du Colombier 	static char lastcom = '=', savecom = '=';
363e12c5d1SDavid du Colombier 
373e12c5d1SDavid du Colombier 	if (defcom == 0)
383e12c5d1SDavid du Colombier 		defcom = lastcom;
393e12c5d1SDavid du Colombier 	if (buf) {
403e12c5d1SDavid du Colombier 		if (*buf==EOR)
413e12c5d1SDavid du Colombier 			return(FALSE);
423e12c5d1SDavid du Colombier 		clrinp();
433e12c5d1SDavid du Colombier 		lp=buf;
443e12c5d1SDavid du Colombier 	}
453e12c5d1SDavid du Colombier 	do {
46*219b2ee8SDavid du Colombier 		adrflg=expr(0);		/* first address */
47*219b2ee8SDavid du Colombier 		if (adrflg)
483e12c5d1SDavid du Colombier 			dot=ditto=expv;
493e12c5d1SDavid du Colombier 		adrval=dot;
50*219b2ee8SDavid du Colombier 
51*219b2ee8SDavid du Colombier 		if (rdc()==',' && expr(0)) {	/* count */
523e12c5d1SDavid du Colombier 			cntflg=TRUE;
533e12c5d1SDavid du Colombier 			cntval=expv;
543e12c5d1SDavid du Colombier 		} else {
553e12c5d1SDavid du Colombier 			cntflg=FALSE;
563e12c5d1SDavid du Colombier 			cntval=1;
573e12c5d1SDavid du Colombier 			reread();
583e12c5d1SDavid du Colombier 		}
59*219b2ee8SDavid du Colombier 
603e12c5d1SDavid du Colombier 		if (!eol(rdc()))
61*219b2ee8SDavid du Colombier 			lastcom=lastc;		/* command */
623e12c5d1SDavid du Colombier 		else {
633e12c5d1SDavid du Colombier 			if (adrflg==0)
643e12c5d1SDavid du Colombier 				dot=inkdot(dotinc);
653e12c5d1SDavid du Colombier 			reread();
663e12c5d1SDavid du Colombier 			lastcom=defcom;
673e12c5d1SDavid du Colombier 		}
683e12c5d1SDavid du Colombier 		switch(lastcom) {
693e12c5d1SDavid du Colombier 		case '/':
703e12c5d1SDavid du Colombier 		case '=':
713e12c5d1SDavid du Colombier 		case '?':
723e12c5d1SDavid du Colombier 			savecom = lastcom;
733e12c5d1SDavid du Colombier 			acommand(lastcom);
743e12c5d1SDavid du Colombier 			break;
753e12c5d1SDavid du Colombier 
763e12c5d1SDavid du Colombier 		case '>':
773e12c5d1SDavid du Colombier 			lastcom = savecom;
783e12c5d1SDavid du Colombier 			savc=rdc();
79*219b2ee8SDavid du Colombier 			if (reg=regname(savc))
80*219b2ee8SDavid du Colombier 				rput(cormap, reg, dot);
813e12c5d1SDavid du Colombier 			else
823e12c5d1SDavid du Colombier 				error("bad variable");
833e12c5d1SDavid du Colombier 			break;
843e12c5d1SDavid du Colombier 
853e12c5d1SDavid du Colombier 		case '!':
863e12c5d1SDavid du Colombier 			lastcom=savecom;
873e12c5d1SDavid du Colombier 			shell();
883e12c5d1SDavid du Colombier 			break;
893e12c5d1SDavid du Colombier 
903e12c5d1SDavid du Colombier 		case '$':
913e12c5d1SDavid du Colombier 			lastcom=savecom;
923e12c5d1SDavid du Colombier 			printtrace(nextchar());
933e12c5d1SDavid du Colombier 			break;
943e12c5d1SDavid du Colombier 
953e12c5d1SDavid du Colombier 		case ':':
963e12c5d1SDavid du Colombier 			if (!executing) {
973e12c5d1SDavid du Colombier 				executing=TRUE;
983e12c5d1SDavid du Colombier 				subpcs(nextchar());
993e12c5d1SDavid du Colombier 				executing=FALSE;
1003e12c5d1SDavid du Colombier 				lastcom=savecom;
1013e12c5d1SDavid du Colombier 			}
1023e12c5d1SDavid du Colombier 			break;
1033e12c5d1SDavid du Colombier 
1043e12c5d1SDavid du Colombier 		case 0:
1053e12c5d1SDavid du Colombier 			prints(DBNAME);
1063e12c5d1SDavid du Colombier 			break;
1073e12c5d1SDavid du Colombier 
1083e12c5d1SDavid du Colombier 		default:
1093e12c5d1SDavid du Colombier 			error("bad command");
1103e12c5d1SDavid du Colombier 		}
1113e12c5d1SDavid du Colombier 		flushbuf();
1123e12c5d1SDavid du Colombier 	} while (rdc()==';');
1133e12c5d1SDavid du Colombier 	if (buf == 0)
1143e12c5d1SDavid du Colombier 		reread();
1153e12c5d1SDavid du Colombier 	else {
1163e12c5d1SDavid du Colombier 		clrinp();
1173e12c5d1SDavid du Colombier 		lp=savlp;
1183e12c5d1SDavid du Colombier 		lastc = savlc;
1193e12c5d1SDavid du Colombier 		peekc = savpc;
1203e12c5d1SDavid du Colombier 	}
1213e12c5d1SDavid du Colombier 
1223e12c5d1SDavid du Colombier 	if(adrflg)
1233e12c5d1SDavid du Colombier 		return dot;
1243e12c5d1SDavid du Colombier 	return 1;
1253e12c5d1SDavid du Colombier }
1263e12c5d1SDavid du Colombier 
1273e12c5d1SDavid du Colombier /*
1283e12c5d1SDavid du Colombier  * [/?][wml]
1293e12c5d1SDavid du Colombier  */
1303e12c5d1SDavid du Colombier 
1313e12c5d1SDavid du Colombier void
1323e12c5d1SDavid du Colombier acommand(int pc)
1333e12c5d1SDavid du Colombier {
1343e12c5d1SDavid du Colombier 	int eqcom;
135*219b2ee8SDavid du Colombier 	Map *map;
1363e12c5d1SDavid du Colombier 	char *fmt;
137*219b2ee8SDavid du Colombier 	char buf[512];
1383e12c5d1SDavid du Colombier 
1393e12c5d1SDavid du Colombier 	if (pc == '=') {
140*219b2ee8SDavid du Colombier 		eqcom = 1;
1413e12c5d1SDavid du Colombier 		fmt = eqformat;
142*219b2ee8SDavid du Colombier 		map = dotmap;
1433e12c5d1SDavid du Colombier 	} else {
144*219b2ee8SDavid du Colombier 		eqcom = 0;
1453e12c5d1SDavid du Colombier 		fmt = stformat;
146*219b2ee8SDavid du Colombier 		if (pc == '/')
1473e12c5d1SDavid du Colombier 			map = cormap;
148*219b2ee8SDavid du Colombier 		else
149*219b2ee8SDavid du Colombier 			map = symmap;
1503e12c5d1SDavid du Colombier 	}
151*219b2ee8SDavid du Colombier 	if (!map) {
152*219b2ee8SDavid du Colombier 		sprint(buf, "no map for %c", pc);
153*219b2ee8SDavid du Colombier 		error(buf);
1543e12c5d1SDavid du Colombier 	}
155*219b2ee8SDavid du Colombier 
156*219b2ee8SDavid du Colombier 	switch (rdc())
157*219b2ee8SDavid du Colombier 	{
1583e12c5d1SDavid du Colombier 	case 'm':
1593e12c5d1SDavid du Colombier 		if (eqcom)
1603e12c5d1SDavid du Colombier 			error(BADEQ);
1613e12c5d1SDavid du Colombier 		cmdmap(map);
1623e12c5d1SDavid du Colombier 		break;
1633e12c5d1SDavid du Colombier 
1643e12c5d1SDavid du Colombier 	case 'L':
1653e12c5d1SDavid du Colombier 	case 'l':
1663e12c5d1SDavid du Colombier 		if (eqcom)
1673e12c5d1SDavid du Colombier 			error(BADEQ);
168*219b2ee8SDavid du Colombier 		cmdsrc(lastc, map);
1693e12c5d1SDavid du Colombier 		break;
1703e12c5d1SDavid du Colombier 
1713e12c5d1SDavid du Colombier 	case 'W':
1723e12c5d1SDavid du Colombier 	case 'w':
1733e12c5d1SDavid du Colombier 		if (eqcom)
1743e12c5d1SDavid du Colombier 			error(BADEQ);
175*219b2ee8SDavid du Colombier 		cmdwrite(lastc, map);
1763e12c5d1SDavid du Colombier 		break;
1773e12c5d1SDavid du Colombier 
1783e12c5d1SDavid du Colombier 	default:
1793e12c5d1SDavid du Colombier 		reread();
1803e12c5d1SDavid du Colombier 		getformat(fmt);
181*219b2ee8SDavid du Colombier 		scanform(cntval, !eqcom, fmt, map, eqcom);
1823e12c5d1SDavid du Colombier 	}
1833e12c5d1SDavid du Colombier }
1843e12c5d1SDavid du Colombier 
1853e12c5d1SDavid du Colombier void
186*219b2ee8SDavid du Colombier cmdsrc(int c, Map *map)
1873e12c5d1SDavid du Colombier {
188*219b2ee8SDavid du Colombier 	long w;
189*219b2ee8SDavid du Colombier 	long locval, locmsk;
1903e12c5d1SDavid du Colombier 	ADDR savdot;
1913e12c5d1SDavid du Colombier 	ushort sh;
192*219b2ee8SDavid du Colombier 	char buf[512];
193*219b2ee8SDavid du Colombier 	int ret;
1943e12c5d1SDavid du Colombier 
1953e12c5d1SDavid du Colombier 	if (c == 'L')
1963e12c5d1SDavid du Colombier 		dotinc = 4;
1973e12c5d1SDavid du Colombier 	else
1983e12c5d1SDavid du Colombier 		dotinc = 2;
1993e12c5d1SDavid du Colombier 	savdot=dot;
2003e12c5d1SDavid du Colombier 	expr(1);
2013e12c5d1SDavid du Colombier 	locval=expv;
2023e12c5d1SDavid du Colombier 	if (expr(0))
2033e12c5d1SDavid du Colombier 		locmsk=expv;
2043e12c5d1SDavid du Colombier 	else
2053e12c5d1SDavid du Colombier 		locmsk = ~0;
206*219b2ee8SDavid du Colombier 	if (c == 'L')
207*219b2ee8SDavid du Colombier 		while ((ret = get4(map, dot, &w)) > 0 &&  (w&locmsk) != locval)
2083e12c5d1SDavid du Colombier 			dot = inkdot(dotinc);
209*219b2ee8SDavid du Colombier 	else
210*219b2ee8SDavid du Colombier 		while ((ret = get2(map, dot, &sh)) > 0 && (sh&locmsk) != locval)
2113e12c5d1SDavid du Colombier 			dot = inkdot(dotinc);
212*219b2ee8SDavid du Colombier 	if (ret < 0) {
2133e12c5d1SDavid du Colombier 		dot=savdot;
214*219b2ee8SDavid du Colombier 		error("%r");
2153e12c5d1SDavid du Colombier 	}
216*219b2ee8SDavid du Colombier 	symoff(buf, 512, dot, CANY);
217*219b2ee8SDavid du Colombier 	dprint(buf);
2183e12c5d1SDavid du Colombier }
2193e12c5d1SDavid du Colombier 
220*219b2ee8SDavid du Colombier static char badwrite[] = "can't write process memory or text image";
221*219b2ee8SDavid du Colombier 
2223e12c5d1SDavid du Colombier void
223*219b2ee8SDavid du Colombier cmdwrite(int wcom, Map *map)
2243e12c5d1SDavid du Colombier {
2253e12c5d1SDavid du Colombier 	ADDR savdot;
226*219b2ee8SDavid du Colombier 	char *format;
2273e12c5d1SDavid du Colombier 	int pass;
2283e12c5d1SDavid du Colombier 
229*219b2ee8SDavid du Colombier 	if (wcom == 'w')
230*219b2ee8SDavid du Colombier 		format = "x";
231*219b2ee8SDavid du Colombier 	else
232*219b2ee8SDavid du Colombier 		format = "X";
2333e12c5d1SDavid du Colombier 	expr(1);
2343e12c5d1SDavid du Colombier 	pass = 0;
2353e12c5d1SDavid du Colombier 	do {
2363e12c5d1SDavid du Colombier 		pass++;
2373e12c5d1SDavid du Colombier 		savdot=dot;
238*219b2ee8SDavid du Colombier 		exform(1, 1, format, map, 0, pass);
2393e12c5d1SDavid du Colombier 		dot=savdot;
240*219b2ee8SDavid du Colombier 		if (wcom == 'W') {
241*219b2ee8SDavid du Colombier 			if (put4(map, dot, expv) <= 0)
242*219b2ee8SDavid du Colombier 				error(badwrite);
243*219b2ee8SDavid du Colombier 		} else {
244*219b2ee8SDavid du Colombier 			if (put2(map, dot, expv) <= 0)
245*219b2ee8SDavid du Colombier 				error(badwrite);
246*219b2ee8SDavid du Colombier 		}
2473e12c5d1SDavid du Colombier 		savdot=dot;
2483e12c5d1SDavid du Colombier 		dprint("=%8t");
249*219b2ee8SDavid du Colombier 		exform(1, 0, format, map, 0, pass);
2503e12c5d1SDavid du Colombier 		newline();
251*219b2ee8SDavid du Colombier 	} while (expr(0));
2523e12c5d1SDavid du Colombier 	dot=savdot;
2533e12c5d1SDavid du Colombier }
2543e12c5d1SDavid du Colombier 
2553e12c5d1SDavid du Colombier /*
2563e12c5d1SDavid du Colombier  * collect a register name; return register offset
2573e12c5d1SDavid du Colombier  * this is not what i'd call a good division of labour
2583e12c5d1SDavid du Colombier  */
2593e12c5d1SDavid du Colombier 
260*219b2ee8SDavid du Colombier char *
261*219b2ee8SDavid du Colombier regname(int regnam)
2623e12c5d1SDavid du Colombier {
263*219b2ee8SDavid du Colombier 	static char buf[64];
2643e12c5d1SDavid du Colombier 	char *p;
2653e12c5d1SDavid du Colombier 	int c;
2663e12c5d1SDavid du Colombier 
2673e12c5d1SDavid du Colombier 	p = buf;
2683e12c5d1SDavid du Colombier 	*p++ = regnam;
269*219b2ee8SDavid du Colombier 	while (isalnum(c = readchar())) {
270*219b2ee8SDavid du Colombier 		if (p >= buf+sizeof(buf)-1)
271*219b2ee8SDavid du Colombier 			error("register name too long");
2723e12c5d1SDavid du Colombier 		*p++ = c;
273*219b2ee8SDavid du Colombier 	}
2743e12c5d1SDavid du Colombier 	*p = 0;
2753e12c5d1SDavid du Colombier 	reread();
276*219b2ee8SDavid du Colombier 	return (buf);
2773e12c5d1SDavid du Colombier }
2783e12c5d1SDavid du Colombier 
2793e12c5d1SDavid du Colombier /*
2803e12c5d1SDavid du Colombier  * shell escape
2813e12c5d1SDavid du Colombier  */
2823e12c5d1SDavid du Colombier 
2833e12c5d1SDavid du Colombier void
2843e12c5d1SDavid du Colombier shell(void)
2853e12c5d1SDavid du Colombier {
2863e12c5d1SDavid du Colombier 	int	rc, unixpid;
2873e12c5d1SDavid du Colombier 	char *argp = lp;
2883e12c5d1SDavid du Colombier 
2893e12c5d1SDavid du Colombier 	while (lastc!=EOR)
2903e12c5d1SDavid du Colombier 		rdc();
2913e12c5d1SDavid du Colombier 	if ((unixpid=fork())==0) {
2923e12c5d1SDavid du Colombier 		*lp=0;
2933e12c5d1SDavid du Colombier 		execl("/bin/rc", "rc", "-c", argp, 0);
2943e12c5d1SDavid du Colombier 		exits("execl");				/* botch */
2953e12c5d1SDavid du Colombier 	} else if (unixpid == -1) {
2963e12c5d1SDavid du Colombier 		error("cannot fork");
2973e12c5d1SDavid du Colombier 	} else {
2983e12c5d1SDavid du Colombier 		mkfault = 0;
2993e12c5d1SDavid du Colombier 		while ((rc = wait(0)) != unixpid){
3003e12c5d1SDavid du Colombier 			if(rc == -1 && mkfault){
3013e12c5d1SDavid du Colombier 				mkfault = 0;
3023e12c5d1SDavid du Colombier 				continue;
3033e12c5d1SDavid du Colombier 			}
3043e12c5d1SDavid du Colombier 			break;
3053e12c5d1SDavid du Colombier 		}
3063e12c5d1SDavid du Colombier 		prints("!");
3073e12c5d1SDavid du Colombier 		reread();
3083e12c5d1SDavid du Colombier 	}
3093e12c5d1SDavid du Colombier }
310