xref: /plan9-contrib/sys/src/cmd/db/format.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 extern	char	lastc, peekc;
113e12c5d1SDavid du Colombier 
123e12c5d1SDavid du Colombier void
13*219b2ee8SDavid du Colombier scanform(long icount, int prt, char *ifp, Map *map, int literal)
143e12c5d1SDavid du Colombier {
153e12c5d1SDavid du Colombier 	char	*fp;
163e12c5d1SDavid du Colombier 	char	c;
173e12c5d1SDavid du Colombier 	int	fcount;
183e12c5d1SDavid du Colombier 	ADDR	savdot;
193e12c5d1SDavid du Colombier 	int firstpass;
203e12c5d1SDavid du Colombier 
213e12c5d1SDavid du Colombier 	firstpass = 1;
223e12c5d1SDavid du Colombier 	while (icount) {
233e12c5d1SDavid du Colombier 		fp=ifp;
243e12c5d1SDavid du Colombier 		savdot=dot;
253e12c5d1SDavid du Colombier 		/*now loop over format*/
26*219b2ee8SDavid du Colombier 		while (*fp) {
273e12c5d1SDavid du Colombier 			if (!isdigit(*fp))
283e12c5d1SDavid du Colombier 				fcount = 1;
293e12c5d1SDavid du Colombier 			else {
303e12c5d1SDavid du Colombier 				fcount = 0;
313e12c5d1SDavid du Colombier 				while (isdigit(c = *fp++)) {
323e12c5d1SDavid du Colombier 					fcount *= 10;
333e12c5d1SDavid du Colombier 					fcount += c-'0';
343e12c5d1SDavid du Colombier 				}
353e12c5d1SDavid du Colombier 				fp--;
363e12c5d1SDavid du Colombier 			}
373e12c5d1SDavid du Colombier 			if (*fp==0)
383e12c5d1SDavid du Colombier 				break;
39*219b2ee8SDavid du Colombier 			fp=exform(fcount,prt,fp,map,literal,firstpass);
403e12c5d1SDavid du Colombier 			firstpass = 0;
413e12c5d1SDavid du Colombier 		}
423e12c5d1SDavid du Colombier 		dotinc=dot-savdot;
433e12c5d1SDavid du Colombier 		dot=savdot;
443e12c5d1SDavid du Colombier 		if (--icount)
453e12c5d1SDavid du Colombier 			dot=inkdot(dotinc);
463e12c5d1SDavid du Colombier 	}
473e12c5d1SDavid du Colombier }
483e12c5d1SDavid du Colombier 
493e12c5d1SDavid du Colombier char *
50*219b2ee8SDavid du Colombier exform(int fcount, int prt, char *ifp, Map *map, int literal, int firstpass)
513e12c5d1SDavid du Colombier {
523e12c5d1SDavid du Colombier 	/* execute single format item `fcount' times
533e12c5d1SDavid du Colombier 	 * sets `dotinc' and moves `dot'
543e12c5d1SDavid du Colombier 	 * returns address of next format item
553e12c5d1SDavid du Colombier 	 */
56*219b2ee8SDavid du Colombier 	int	w;
57*219b2ee8SDavid du Colombier 	ulong	savdot;
58*219b2ee8SDavid du Colombier 	char	*fp, *p;
593e12c5d1SDavid du Colombier 	char	c, modifier;
603e12c5d1SDavid du Colombier 	int	i;
61*219b2ee8SDavid du Colombier 	ushort sh, *sp;
62*219b2ee8SDavid du Colombier 	uchar ch, *cp;
633e12c5d1SDavid du Colombier 	Symbol s;
64*219b2ee8SDavid du Colombier 	char buf[512];
653e12c5d1SDavid du Colombier 
663e12c5d1SDavid du Colombier 	fp = 0;
673e12c5d1SDavid du Colombier 	while (fcount > 0) {
683e12c5d1SDavid du Colombier 		fp = ifp;
693e12c5d1SDavid du Colombier 		c = *fp;
703e12c5d1SDavid du Colombier 		modifier = *fp++;
713e12c5d1SDavid du Colombier 		if (firstpass) {
723e12c5d1SDavid du Colombier 			firstpass = 0;
73*219b2ee8SDavid du Colombier 			if (!literal  && (c == 'i' || c == 'I' || c == 'M')
743e12c5d1SDavid du Colombier 					&& (dot & (mach->pcquant-1))) {
753e12c5d1SDavid du Colombier 				dprint("warning: instruction not aligned");
76*219b2ee8SDavid du Colombier 				printc('\n');
773e12c5d1SDavid du Colombier 			}
78*219b2ee8SDavid du Colombier 			if (prt && modifier != 'a' && modifier != 'A') {
79*219b2ee8SDavid du Colombier 				symoff(buf, 512, dot, CANY);
80*219b2ee8SDavid du Colombier 				dprint("%s%c%16t", buf, map==symmap? '?':'/');
813e12c5d1SDavid du Colombier 			}
82*219b2ee8SDavid du Colombier 		}
83*219b2ee8SDavid du Colombier 		if (charpos()==0 && modifier != 'a' && modifier != 'A')
843e12c5d1SDavid du Colombier 			dprint("\t\t");
853e12c5d1SDavid du Colombier 		switch(modifier) {
863e12c5d1SDavid du Colombier 
873e12c5d1SDavid du Colombier 		case SPC:
883e12c5d1SDavid du Colombier 		case TB:
893e12c5d1SDavid du Colombier 			dotinc = 0;
903e12c5d1SDavid du Colombier 			break;
913e12c5d1SDavid du Colombier 
923e12c5d1SDavid du Colombier 		case 't':
933e12c5d1SDavid du Colombier 		case 'T':
943e12c5d1SDavid du Colombier 			dprint("%*t", fcount);
953e12c5d1SDavid du Colombier 			dotinc = 0;
963e12c5d1SDavid du Colombier 			return(fp);
973e12c5d1SDavid du Colombier 
983e12c5d1SDavid du Colombier 		case 'a':
99*219b2ee8SDavid du Colombier 			symoff(buf, sizeof(buf), dot, CANY);
100*219b2ee8SDavid du Colombier 			dprint("%s%c%16t", buf, map==symmap? '?':'/');
101*219b2ee8SDavid du Colombier 			dotinc = 0;
102*219b2ee8SDavid du Colombier 			break;
103*219b2ee8SDavid du Colombier 
104*219b2ee8SDavid du Colombier 		case 'A':
105*219b2ee8SDavid du Colombier 			dprint("%lux%10t", dot);
1063e12c5d1SDavid du Colombier 			dotinc = 0;
1073e12c5d1SDavid du Colombier 			break;
1083e12c5d1SDavid du Colombier 
1093e12c5d1SDavid du Colombier 		case 'p':
110*219b2ee8SDavid du Colombier 			if (get4(map, dot, &w) < 0)
111*219b2ee8SDavid du Colombier 				error("%r");
112*219b2ee8SDavid du Colombier 			symoff(buf, sizeof(buf), w, CANY);
113*219b2ee8SDavid du Colombier 			dprint("%s%16t", buf);
1143e12c5d1SDavid du Colombier 			dotinc = mach->szaddr;
1153e12c5d1SDavid du Colombier 			break;
1163e12c5d1SDavid du Colombier 
1173e12c5d1SDavid du Colombier 		case 'u':
1183e12c5d1SDavid du Colombier 		case 'd':
1193e12c5d1SDavid du Colombier 		case 'x':
1203e12c5d1SDavid du Colombier 		case 'o':
1213e12c5d1SDavid du Colombier 		case 'q':
122*219b2ee8SDavid du Colombier 			if (literal)
123*219b2ee8SDavid du Colombier 				sh = (ushort) dot;
124*219b2ee8SDavid du Colombier 			else if (get2(map, dot, &sh) < 0)
125*219b2ee8SDavid du Colombier 				error("%r");
1263e12c5d1SDavid du Colombier 			w = sh;
1273e12c5d1SDavid du Colombier 			dotinc = 2;
1283e12c5d1SDavid du Colombier 			if (c == 'u')
1293e12c5d1SDavid du Colombier 				dprint("%-8lud", w);
1303e12c5d1SDavid du Colombier 			else if (c == 'x')
1313e12c5d1SDavid du Colombier 				dprint("%-8lux", w);
1323e12c5d1SDavid du Colombier 			else if (c == 'd')
1333e12c5d1SDavid du Colombier 				dprint("%-8ld", w);
1343e12c5d1SDavid du Colombier 			else if (c == 'o')
1353e12c5d1SDavid du Colombier 				dprint("%-8#luo", w);
1363e12c5d1SDavid du Colombier 			else if (c == 'q')
1373e12c5d1SDavid du Colombier 				dprint("%-8#lo", w);
1383e12c5d1SDavid du Colombier 			break;
1393e12c5d1SDavid du Colombier 
1403e12c5d1SDavid du Colombier 		case 'U':
1413e12c5d1SDavid du Colombier 		case 'D':
1423e12c5d1SDavid du Colombier 		case 'X':
1433e12c5d1SDavid du Colombier 		case 'O':
1443e12c5d1SDavid du Colombier 		case 'Q':
145*219b2ee8SDavid du Colombier 			if (literal)
146*219b2ee8SDavid du Colombier 				w = (long) dot;
147*219b2ee8SDavid du Colombier 			else if (get4(map, dot, &w) < 0)
148*219b2ee8SDavid du Colombier 				error("%r");
1493e12c5d1SDavid du Colombier 			dotinc = 4;
1503e12c5d1SDavid du Colombier 			if (c == 'U')
1513e12c5d1SDavid du Colombier 				dprint("%-16lud", w);
1523e12c5d1SDavid du Colombier 			else if (c == 'X')
1533e12c5d1SDavid du Colombier 				dprint("%-16lux", w);
1543e12c5d1SDavid du Colombier 			else if (c == 'D')
1553e12c5d1SDavid du Colombier 				dprint("%-16ld", w);
1563e12c5d1SDavid du Colombier 			else if (c == 'O')
1573e12c5d1SDavid du Colombier 				dprint("%-#16luo", w);
1583e12c5d1SDavid du Colombier 			else if (c == 'Q')
1593e12c5d1SDavid du Colombier 				dprint("%-#16lo", w);
1603e12c5d1SDavid du Colombier 			break;
1613e12c5d1SDavid du Colombier 		case 'B':
1623e12c5d1SDavid du Colombier 		case 'b':
1633e12c5d1SDavid du Colombier 		case 'c':
1643e12c5d1SDavid du Colombier 		case 'C':
165*219b2ee8SDavid du Colombier 			if (literal)
166*219b2ee8SDavid du Colombier 				ch = (uchar) dot;
167*219b2ee8SDavid du Colombier 			else if (get1(map, dot, &ch, 1)  < 0)
168*219b2ee8SDavid du Colombier 				error("%r");
1693e12c5d1SDavid du Colombier 			if (modifier == 'C')
1703e12c5d1SDavid du Colombier 				printesc(ch);
1713e12c5d1SDavid du Colombier 			else if (modifier == 'B' || modifier == 'b')
1723e12c5d1SDavid du Colombier 				dprint("%-8lux", (long) ch);
1733e12c5d1SDavid du Colombier 			else
1743e12c5d1SDavid du Colombier 				printc(ch);
1753e12c5d1SDavid du Colombier 			dotinc = 1;
1763e12c5d1SDavid du Colombier 			break;
1773e12c5d1SDavid du Colombier 
1783e12c5d1SDavid du Colombier 		case 'r':
179*219b2ee8SDavid du Colombier 			if (literal)
180*219b2ee8SDavid du Colombier 				sh = (ushort) dot;
181*219b2ee8SDavid du Colombier 			else if (get2(map, dot, &sh) < 0)
182*219b2ee8SDavid du Colombier 				error("%r");
183*219b2ee8SDavid du Colombier 			dprint("%C", sh);
1843e12c5d1SDavid du Colombier 			dotinc = 2;
1853e12c5d1SDavid du Colombier 			break;
1863e12c5d1SDavid du Colombier 
1873e12c5d1SDavid du Colombier 		case 'R':
188*219b2ee8SDavid du Colombier 			if (literal) {
189*219b2ee8SDavid du Colombier 				sp = (ushort*) &dot;
190*219b2ee8SDavid du Colombier 				dprint("%C%C", sp[0], sp[1]);
191*219b2ee8SDavid du Colombier 				endline();
192*219b2ee8SDavid du Colombier 				dotinc = 4;
193*219b2ee8SDavid du Colombier 				break;
194*219b2ee8SDavid du Colombier 			}
1953e12c5d1SDavid du Colombier 			savdot=dot;
196*219b2ee8SDavid du Colombier 			while ((i = get2(map, dot, &sh) > 0) && sh) {
1973e12c5d1SDavid du Colombier 				dot=inkdot(2);
1983e12c5d1SDavid du Colombier 				dprint("%C", sh);
1993e12c5d1SDavid du Colombier 				endline();
2003e12c5d1SDavid du Colombier 			}
201*219b2ee8SDavid du Colombier 			if (i < 0)
202*219b2ee8SDavid du Colombier 				error("%r");
2033e12c5d1SDavid du Colombier 			dotinc = dot-savdot+2;
2043e12c5d1SDavid du Colombier 			dot=savdot;
2053e12c5d1SDavid du Colombier 			break;
2063e12c5d1SDavid du Colombier 
2073e12c5d1SDavid du Colombier 		case 's':
208*219b2ee8SDavid du Colombier 			if (literal) {
209*219b2ee8SDavid du Colombier 				cp = (uchar*) &dot;
210*219b2ee8SDavid du Colombier 				for (i = 0; i < 4; i++)
211*219b2ee8SDavid du Colombier 					buf[i] = cp[i];
212*219b2ee8SDavid du Colombier 				buf[i] = 0;
213*219b2ee8SDavid du Colombier 				dprint("%s", buf);
214*219b2ee8SDavid du Colombier 				endline();
215*219b2ee8SDavid du Colombier 				dotinc = 4;
216*219b2ee8SDavid du Colombier 				break;
217*219b2ee8SDavid du Colombier 			}
2183e12c5d1SDavid du Colombier 			savdot = dot;
2193e12c5d1SDavid du Colombier 			for(;;){
2203e12c5d1SDavid du Colombier 				i = 0;
2213e12c5d1SDavid du Colombier 				do{
222*219b2ee8SDavid du Colombier 					if (get1(map, dot, (uchar*)&buf[i], 1) < 0)
223*219b2ee8SDavid du Colombier 						error("%r");
2243e12c5d1SDavid du Colombier 					dot = inkdot(1);
2253e12c5d1SDavid du Colombier 					i++;
2263e12c5d1SDavid du Colombier 				}while(!fullrune(buf, i));
2273e12c5d1SDavid du Colombier 				if(buf[0] == 0)
2283e12c5d1SDavid du Colombier 					break;
2293e12c5d1SDavid du Colombier 				buf[i] = 0;
2303e12c5d1SDavid du Colombier 				dprint("%s", buf);
2313e12c5d1SDavid du Colombier 				endline();
2323e12c5d1SDavid du Colombier 			}
2333e12c5d1SDavid du Colombier 			dotinc = dot-savdot+1;
2343e12c5d1SDavid du Colombier 			dot = savdot;
2353e12c5d1SDavid du Colombier 			break;
2363e12c5d1SDavid du Colombier 
2373e12c5d1SDavid du Colombier 		case 'S':
238*219b2ee8SDavid du Colombier 			if (literal) {
239*219b2ee8SDavid du Colombier 				cp = (uchar*) &dot;
240*219b2ee8SDavid du Colombier 				for (i = 0; i < 4; i++)
241*219b2ee8SDavid du Colombier 					printesc(cp[i]);
242*219b2ee8SDavid du Colombier 				endline();
243*219b2ee8SDavid du Colombier 				dotinc = 4;
244*219b2ee8SDavid du Colombier 				break;
245*219b2ee8SDavid du Colombier 			}
2463e12c5d1SDavid du Colombier 			savdot=dot;
247*219b2ee8SDavid du Colombier 			while ((i = get1(map, dot, &ch, 1) > 0) && ch) {
2483e12c5d1SDavid du Colombier 				dot=inkdot(1);
2493e12c5d1SDavid du Colombier 				printesc(ch);
2503e12c5d1SDavid du Colombier 				endline();
2513e12c5d1SDavid du Colombier 			}
252*219b2ee8SDavid du Colombier 			if (i < 0)
253*219b2ee8SDavid du Colombier 				error("%r");
2543e12c5d1SDavid du Colombier 			dotinc = dot-savdot+1;
2553e12c5d1SDavid du Colombier 			dot=savdot;
2563e12c5d1SDavid du Colombier 			break;
2573e12c5d1SDavid du Colombier 
2583e12c5d1SDavid du Colombier 		case 'Y':
259*219b2ee8SDavid du Colombier 			if (literal)
260*219b2ee8SDavid du Colombier 				w = (long) dot;
261*219b2ee8SDavid du Colombier 			else if (get4(map, dot, &w) < 0)
262*219b2ee8SDavid du Colombier 				error("%r");
263*219b2ee8SDavid du Colombier 			p = ctime(w);
264*219b2ee8SDavid du Colombier 			p[strlen(p)-1] = 0;	/* stomp on newline */
265*219b2ee8SDavid du Colombier 			dprint("%-25s", p);
2663e12c5d1SDavid du Colombier 			dotinc = 4;
2673e12c5d1SDavid du Colombier 			break;
2683e12c5d1SDavid du Colombier 
2693e12c5d1SDavid du Colombier 		case 'I':
2703e12c5d1SDavid du Colombier 		case 'i':
271*219b2ee8SDavid du Colombier 			dotinc = machdata->das(map, dot, modifier, buf, sizeof(buf));
272*219b2ee8SDavid du Colombier 			if (dotinc < 0)
273*219b2ee8SDavid du Colombier 				error("%r");
274*219b2ee8SDavid du Colombier 			dprint("%s\n", buf);
2753e12c5d1SDavid du Colombier 			break;
2763e12c5d1SDavid du Colombier 
2773e12c5d1SDavid du Colombier 		case 'M':
278*219b2ee8SDavid du Colombier 			dotinc = machdata->hexinst(map, dot, buf, sizeof(buf));
279*219b2ee8SDavid du Colombier 			if (dotinc < 0)
280*219b2ee8SDavid du Colombier 				error("%r");
281*219b2ee8SDavid du Colombier 			dprint("%s", buf);
282*219b2ee8SDavid du Colombier 			if (*fp) {
283*219b2ee8SDavid du Colombier 				dotinc = 0;
284*219b2ee8SDavid du Colombier 				dprint("%48t");
285*219b2ee8SDavid du Colombier 			} else
286*219b2ee8SDavid du Colombier 				dprint("\n");
2873e12c5d1SDavid du Colombier 			break;
2883e12c5d1SDavid du Colombier 
2893e12c5d1SDavid du Colombier 		case 'f':
290*219b2ee8SDavid du Colombier 			if (get1(map, dot, (uchar*)buf, mach->szfloat) < 0)
291*219b2ee8SDavid du Colombier 				error("%r");
292*219b2ee8SDavid du Colombier 			machdata->sftos(buf, sizeof(buf), (void*) buf);
293*219b2ee8SDavid du Colombier 			dprint("%s\n", buf);
2943e12c5d1SDavid du Colombier 			dotinc = mach->szfloat;
2953e12c5d1SDavid du Colombier 			break;
2963e12c5d1SDavid du Colombier 
2973e12c5d1SDavid du Colombier 		case 'F':
298*219b2ee8SDavid du Colombier 			if (get1(map, dot, (uchar*)buf, mach->szdouble) < 0)
299*219b2ee8SDavid du Colombier 				error("%r");
300*219b2ee8SDavid du Colombier 			machdata->dftos(buf, sizeof(buf), (void*) buf);
301*219b2ee8SDavid du Colombier 			dprint("%s\n", buf);
3023e12c5d1SDavid du Colombier 			dotinc = mach->szdouble;
3033e12c5d1SDavid du Colombier 			break;
3043e12c5d1SDavid du Colombier 
3053e12c5d1SDavid du Colombier 		case 'n':
3063e12c5d1SDavid du Colombier 		case 'N':
3073e12c5d1SDavid du Colombier 			printc('\n');
3083e12c5d1SDavid du Colombier 			dotinc=0;
3093e12c5d1SDavid du Colombier 			break;
3103e12c5d1SDavid du Colombier 
3113e12c5d1SDavid du Colombier 		case '"':
3123e12c5d1SDavid du Colombier 			dotinc=0;
3133e12c5d1SDavid du Colombier 			while (*fp != '"' && *fp)
3143e12c5d1SDavid du Colombier 				printc(*fp++);
3153e12c5d1SDavid du Colombier 			if (*fp)
3163e12c5d1SDavid du Colombier 				fp++;
3173e12c5d1SDavid du Colombier 			break;
3183e12c5d1SDavid du Colombier 
3193e12c5d1SDavid du Colombier 		case '^':
3203e12c5d1SDavid du Colombier 			dot=inkdot(-dotinc*fcount);
3213e12c5d1SDavid du Colombier 			return(fp);
3223e12c5d1SDavid du Colombier 
3233e12c5d1SDavid du Colombier 		case '+':
3243e12c5d1SDavid du Colombier 			dot=inkdot((WORD)fcount);
3253e12c5d1SDavid du Colombier 			return(fp);
3263e12c5d1SDavid du Colombier 
3273e12c5d1SDavid du Colombier 		case '-':
3283e12c5d1SDavid du Colombier 			dot=inkdot(-(WORD)fcount);
3293e12c5d1SDavid du Colombier 			return(fp);
3303e12c5d1SDavid du Colombier 
3313e12c5d1SDavid du Colombier 		case 'z':
3323e12c5d1SDavid du Colombier 			if (findsym(dot, CTEXT, &s))
3333e12c5d1SDavid du Colombier 				dprint("%s() ", s.name);
3343e12c5d1SDavid du Colombier 			printsource(dot);
3353e12c5d1SDavid du Colombier 			printc(EOR);
3363e12c5d1SDavid du Colombier 			return fp;
3373e12c5d1SDavid du Colombier 
3383e12c5d1SDavid du Colombier 		default:
3393e12c5d1SDavid du Colombier 			error("bad modifier");
3403e12c5d1SDavid du Colombier 		}
341*219b2ee8SDavid du Colombier 		if (map->fd >= 0)
3423e12c5d1SDavid du Colombier 			dot=inkdot(dotinc);
3433e12c5d1SDavid du Colombier 		fcount--;
3443e12c5d1SDavid du Colombier 		endline();
3453e12c5d1SDavid du Colombier 	}
3463e12c5d1SDavid du Colombier 
3473e12c5d1SDavid du Colombier 	return(fp);
3483e12c5d1SDavid du Colombier }
3493e12c5d1SDavid du Colombier 
3503e12c5d1SDavid du Colombier void
3513e12c5d1SDavid du Colombier printesc(int c)
3523e12c5d1SDavid du Colombier {
3533e12c5d1SDavid du Colombier 	static char hex[] = "0123456789abcdef";
3543e12c5d1SDavid du Colombier 
3553e12c5d1SDavid du Colombier 	if (c < SPC || c >= 0177)
3563e12c5d1SDavid du Colombier 		dprint("\\x%c%c", hex[(c&0xF0)>>4], hex[c&0xF]);
3573e12c5d1SDavid du Colombier 	else
3583e12c5d1SDavid du Colombier 		printc(c);
3593e12c5d1SDavid du Colombier }
3603e12c5d1SDavid du Colombier 
3613e12c5d1SDavid du Colombier ADDR
3623e12c5d1SDavid du Colombier inkdot(WORD incr)
3633e12c5d1SDavid du Colombier {
3643e12c5d1SDavid du Colombier 	ADDR	newdot;
3653e12c5d1SDavid du Colombier 
3663e12c5d1SDavid du Colombier 	newdot=dot+incr;
3673e12c5d1SDavid du Colombier 	if ((incr >= 0 && newdot < dot)
3683e12c5d1SDavid du Colombier 	||  (incr < 0 && newdot > dot))
3693e12c5d1SDavid du Colombier 		error("address wraparound");
3703e12c5d1SDavid du Colombier 	return(newdot);
3713e12c5d1SDavid du Colombier }
372