Blob
1 /*2 *3 * debugger4 *5 */7 #include "defs.h"8 #include "fns.h"10 static long dbround(long, long);12 extern ADDR ditto;13 vlong expv;15 static WORD16 ascval(void)17 {18 Rune r;20 if (readchar() == 0)21 return (0);22 r = lastc;23 while(quotchar()) /*discard chars to ending quote */24 ;25 return((WORD) r);26 }28 /*29 * read a floating point number30 * the result must fit in a WORD31 */33 static WORD34 fpin(char *buf)35 {36 union {37 WORD w;38 float f;39 } x;41 x.f = atof(buf);42 return (x.w);43 }45 WORD46 defval(WORD w)47 {48 if (expr(0))49 return (expv);50 else51 return (w);52 }54 int55 expr(int a)56 { /* term | term dyadic expr | */57 int rc;58 WORD lhs;60 rdc();61 reread();62 rc=term(a);63 while (rc) {64 lhs = expv;65 switch ((int)readchar()) {67 case '+':68 term(a|1);69 expv += lhs;70 break;72 case '-':73 term(a|1);74 expv = lhs - expv;75 break;77 case '#':78 term(a|1);79 expv = dbround(lhs,expv);80 break;82 case '*':83 term(a|1);84 expv *= lhs;85 break;87 case '%':88 term(a|1);89 if(expv != 0)90 expv = lhs/expv;91 else{92 if(lhs)93 expv = 1;94 else95 expv = 0;96 }97 break;99 case '&':100 term(a|1);101 expv &= lhs;102 break;104 case '|':105 term(a|1);106 expv |= lhs;107 break;109 case ')':110 if ((a&2)==0)111 error("unexpected `)'");113 default:114 reread();115 return(rc);116 }117 }118 return(rc);119 }121 int122 term(int a)123 { /* item | monadic item | (expr) | */124 u32int u;126 switch ((int)readchar()) {128 case '*':129 term(a|1);130 if (get4(cormap, (ADDR)expv, &u) < 0)131 error("%r");132 expv = u;133 return(1);135 case '@':136 term(a|1);137 if (get4(symmap, (ADDR)expv, &u) < 0)138 error("%r");139 expv = u;140 return(1);142 case '-':143 term(a|1);144 expv = -expv;145 return(1);147 case '~':148 term(a|1);149 expv = ~expv;150 return(1);152 case '(':153 expr(2);154 if (readchar()!=')')155 error("syntax error: `)' expected");156 return(1);158 default:159 reread();160 return(item(a));161 }162 }164 int165 item(int a)166 { /* name [ . local ] | number | . | ^ | <register | 'x | | */167 char *base;168 char savc;169 ulong u;170 Symbol s;171 char gsym[MAXSYM], lsym[MAXSYM];173 readchar();174 if (isfileref()) {175 readfname(gsym);176 rdc(); /* skip white space */177 if (lastc == ':') { /* it better be */178 rdc(); /* skip white space */179 if (!getnum(readchar))180 error("bad number");181 if (expv == 0)182 expv = 1; /* file begins at line 1 */183 if(file2pc(gsym, expv, &u) < 0)184 error("%r");185 expv = u;186 return 1;187 }188 error("bad file location");189 } else if (symchar(0)) {190 readsym(gsym);191 if (lastc=='.') {192 readchar(); /* ugh */193 if (lastc == '.') {194 lsym[0] = '.';195 readchar();196 readsym(lsym+1);197 } else if (symchar(0)) {198 readsym(lsym);199 } else200 lsym[0] = 0;201 if (localaddr(cormap, correg, gsym, lsym, &u) < 0)202 error("%r");203 expv = u;204 }205 else {206 if (lookupsym(0, gsym, &s) < 0)207 error("symbol not found");208 if (s.loc.type != LADDR)209 error("symbol not kept in memory");210 expv = s.loc.addr;211 }212 reread();213 } else if (getnum(readchar)) {214 ;215 } else if (lastc=='.') {216 readchar();217 if (!symchar(0) && lastc != '.') {218 expv = dot;219 } else {220 if (findsym(locaddr(dbrget(cormap, mach->pc)), CTEXT, &s) < 0)221 error("no current function");222 if (lastc == '.') {223 lsym[0] = '.';224 readchar();225 readsym(lsym+1);226 } else227 readsym(lsym);228 if (localaddr(cormap, correg, s.name, lsym, &u) < 0)229 error("%r");230 expv = u;231 }232 reread();233 } else if (lastc=='"') {234 expv=ditto;235 } else if (lastc=='+') {236 expv=inkdot(dotinc);237 } else if (lastc=='^') {238 expv=inkdot(-dotinc);239 } else if (lastc=='<') {240 savc=rdc();241 base = regname(savc);242 expv = dbrget(cormap, base);243 }244 else if (lastc=='\'')245 expv = ascval();246 else if (a)247 error("address expected");248 else {249 reread();250 return(0);251 }252 return(1);253 }255 #define MAXBASE 16257 /* service routines for expression reading */258 int259 getnum(int (*rdf)(void))260 {261 char *cp;262 int base, d;263 BOOL fpnum;264 char num[MAXLIN];266 base = 0;267 fpnum = FALSE;268 if (lastc == '#') {269 base = 16;270 (*rdf)();271 }272 if (convdig(lastc) >= MAXBASE)273 return (0);274 if (lastc == '0')275 switch ((*rdf)()) {276 case 'x':277 case 'X':278 base = 16;279 (*rdf)();280 break;282 case 't':283 case 'T':284 base = 10;285 (*rdf)();286 break;288 case 'o':289 case 'O':290 base = 8;291 (*rdf)();292 break;293 default:294 if (base == 0)295 base = 8;296 break;297 }298 if (base == 0)299 base = 10;300 expv = 0;301 for (cp = num, *cp = lastc; ;(*rdf)()) {302 if ((d = convdig(lastc)) < base) {303 expv *= base;304 expv += d;305 *cp++ = lastc;306 }307 else if (lastc == '.') {308 fpnum = TRUE;309 *cp++ = lastc;310 } else {311 reread();312 break;313 }314 }315 if (fpnum)316 expv = fpin(num);317 return (1);318 }320 void321 readsym(char *isymbol)322 {323 char *p;324 Rune r;326 p = isymbol;327 do {328 if (p < &isymbol[MAXSYM-UTFmax-1]){329 r = lastc;330 p += runetochar(p, &r);331 }332 readchar();333 } while (symchar(1));334 *p = 0;335 }337 void338 readfname(char *filename)339 {340 char *p;341 Rune c;343 /* snarf chars until un-escaped char in terminal char set */344 p = filename;345 do {346 if ((c = lastc) != '\\' && p < &filename[MAXSYM-UTFmax-1])347 p += runetochar(p, &c);348 readchar();349 } while (c == '\\' || strchr(CMD_VERBS, lastc) == 0);350 *p = 0;351 reread();352 }354 int355 convdig(int c)356 {357 if (isdigit(c))358 return(c-'0');359 else if (!isxdigit(c))360 return(MAXBASE);361 else if (isupper(c))362 return(c-'A'+10);363 else364 return(c-'a'+10);365 }367 int368 symchar(int dig)369 {370 if (lastc=='\\') {371 readchar();372 return(TRUE);373 }374 return(isalpha(lastc) || lastc>0x80 || lastc=='_' || dig && isdigit(lastc));375 }377 static long378 dbround(long a, long b)379 {380 long w;382 w = (a/b)*b;383 if (a!=w)384 w += b;385 return(w);386 }388 ulong389 dbrget(Map *map, char *name)390 {391 ulong u;393 USED(map);394 if(rget(correg, name, &u) < 0)395 return ~(ulong)0;396 return u;397 }