|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1986 Regents of the University of California. ! 3: * All rights reserved. The Berkeley software License Agreement ! 4: * specifies the terms and conditions for redistribution. ! 5: * ! 6: * @(#)kdb_expr.c 7.5 (Berkeley) 5/29/89 ! 7: */ ! 8: ! 9: #include "../kdb/defs.h" ! 10: ! 11: char *BADSYM; ! 12: char *BADVAR; ! 13: char *BADKET; ! 14: char *BADSYN; ! 15: char *NOCFN; ! 16: char *NOADR; ! 17: char *BADLOC; ! 18: ! 19: ADDR lastframe; ! 20: ADDR savlastf; ! 21: ADDR savframe; ! 22: ADDR savpc; ! 23: ADDR callpc; ! 24: ! 25: char *lp; ! 26: int radix; ! 27: char isymbol[1024]; ! 28: ! 29: char lastc, peekc; ! 30: ! 31: long ditto; ! 32: long expv; ! 33: ! 34: static long ! 35: round(a,b) ! 36: register long a, b; ! 37: { ! 38: register long w; ! 39: ! 40: w = (a/b)*b; ! 41: if (a!=w) ! 42: w += b; ! 43: return (w); ! 44: } ! 45: ! 46: /* term | term dyadic expr | */ ! 47: expr(a) ! 48: { ! 49: register rc; ! 50: register long lhs; ! 51: ! 52: (void) rdc(); lp--; rc=term(a); ! 53: ! 54: while (rc) { ! 55: lhs = expv; ! 56: switch ((int)readchar()) { ! 57: case '+': ! 58: (void) term(a|1); expv += lhs; break; ! 59: case '-': ! 60: (void) term(a|1); expv = lhs - expv; break; ! 61: case '#': ! 62: (void) term(a|1); expv = round(lhs,expv); break; ! 63: case '*': ! 64: (void) term(a|1); expv *= lhs; break; ! 65: case '%': ! 66: (void) term(a|1); expv = lhs/expv; break; ! 67: case '&': ! 68: (void) term(a|1); expv &= lhs; break; ! 69: case '|': ! 70: (void) term(a|1); expv |= lhs; break; ! 71: case ')': ! 72: if ((a&2)==0) ! 73: error(BADKET); ! 74: default: ! 75: lp--; ! 76: return (rc); ! 77: } ! 78: } ! 79: return (rc); ! 80: } ! 81: ! 82: /* item | monadic item | (expr) | */ ! 83: static ! 84: term(a) ! 85: { ! 86: ! 87: switch ((int)readchar()) { ! 88: case '*': ! 89: (void) term(a|1); expv=chkget(expv,DSP); ! 90: return(1); ! 91: case '@': ! 92: (void) term(a|1); expv=chkget(expv,ISP); ! 93: return(1); ! 94: case '-': ! 95: (void) term(a|1); expv = -expv; ! 96: return(1); ! 97: case '~': ! 98: (void) term(a|1); expv = ~expv; ! 99: return(1); ! 100: case '#': ! 101: (void) term(a|1); expv = !expv; ! 102: return(1); ! 103: case '(': ! 104: (void) expr(2); ! 105: if (*lp!=')') ! 106: error(BADSYN); ! 107: lp++; ! 108: return(1); ! 109: } ! 110: lp--; ! 111: return (item(a)); ! 112: } ! 113: ! 114: /* name [ . local ] | number | . | ^ | <var | <register | 'x | | */ ! 115: static ! 116: item(a) ! 117: { ! 118: register base, d, regptr; ! 119: char savc; ! 120: register long frame; ! 121: register struct nlist *symp; ! 122: ! 123: (void) readchar(); ! 124: if (symchar(0)) { ! 125: readsym(); ! 126: if (lastc=='.') { ! 127: frame = pcb.pcb_fp; lastframe = 0; ! 128: callpc = pcb.pcb_pc; ! 129: while (!errflg) { ! 130: savpc = callpc; ! 131: (void) findsym((long)callpc,ISYM); ! 132: if (eqsym(cursym->n_un.n_name,isymbol,'~')) ! 133: break; ! 134: callpc = getprevpc(frame); ! 135: lastframe = frame; ! 136: frame = getprevframe(frame); ! 137: if (frame == NOFRAME) ! 138: error(NOCFN); ! 139: } ! 140: savlastf = lastframe; savframe = frame; ! 141: (void) readchar(); ! 142: if (symchar(0)) ! 143: chkloc(expv=frame); ! 144: } else if ((symp=lookup(isymbol))==0) ! 145: error(BADSYM); ! 146: else ! 147: expv = symp->n_value; ! 148: lp--; ! 149: return (1); ! 150: } ! 151: if (getnum()) ! 152: return (1); ! 153: switch (lastc) { ! 154: case '.': ! 155: (void) readchar(); ! 156: if (symchar(0)) { ! 157: lastframe=savlastf; callpc=savpc; ! 158: chkloc((long)savframe); ! 159: } else ! 160: expv=dot; ! 161: lp--; ! 162: break; ! 163: case '"': ! 164: expv=ditto; ! 165: break; ! 166: case '+': ! 167: expv=inkdot(dotinc); ! 168: break; ! 169: case '^': ! 170: expv=inkdot(-dotinc); ! 171: break; ! 172: case '<': ! 173: savc=rdc(); ! 174: if ((regptr=getreg(savc)) != -1) ! 175: expv = *(int *)regptr; ! 176: else if ((base=varchk(savc)) != -1) ! 177: expv=var[base]; ! 178: else ! 179: error(BADVAR); ! 180: break; ! 181: case '\'': ! 182: d=4; expv=0; ! 183: while (quotchar()) { ! 184: if (d--) { ! 185: expv <<= 8; ! 186: expv |= lastc; ! 187: } else ! 188: error(BADSYN); ! 189: } ! 190: break; ! 191: default: ! 192: if (a) ! 193: error(NOADR); ! 194: lp--; ! 195: return(0); ! 196: } ! 197: return (1); ! 198: } ! 199: ! 200: /* service routines for expression reading */ ! 201: static ! 202: getnum() ! 203: { ! 204: register base,d,frpt; ! 205: ! 206: if (!isdigit(lastc)) ! 207: return (0); ! 208: if ((base = radix) < 0) ! 209: base = -base; ! 210: expv = 0; ! 211: while (base>10 ? isxdigit(lastc) : isdigit(lastc)) { ! 212: register m = MAXINT/base; ! 213: ! 214: if (expv>m) /* avoid overflow */ ! 215: expv = (expv-m)*base+m*base; ! 216: else ! 217: expv *= base; ! 218: if ((d=convdig(lastc))>=base || d<0) ! 219: error(BADSYN); ! 220: expv += d; (void) readchar(); ! 221: if (expv==0) { ! 222: if (lastc=='x' || lastc=='X') { ! 223: base=16; (void) readchar(); ! 224: } else if (lastc=='t' || lastc=='T') { ! 225: base=10; (void) readchar(); ! 226: } else if (lastc=='o' || lastc=='O') { ! 227: base=8; (void) readchar(); ! 228: } ! 229: } ! 230: } ! 231: if (lastc=='.' && (base==10 || expv==0)) { ! 232: frpt=0; base=10; ! 233: while (isdigit(readchar())) { ! 234: if (frpt) ! 235: continue; ! 236: frpt++; ! 237: if (lastc - '0' >= 5) ! 238: expv++; ! 239: } ! 240: } ! 241: peekc=lastc; ! 242: return (1); ! 243: } ! 244: ! 245: static ! 246: readsym() ! 247: { ! 248: register char *p; ! 249: ! 250: p = isymbol; ! 251: do { ! 252: if (p < &isymbol[sizeof(isymbol)-1]) ! 253: *p++ = lastc; ! 254: (void) readchar(); ! 255: } while (symchar(1)); ! 256: *p++ = 0; ! 257: } ! 258: ! 259: static ! 260: convdig(c) ! 261: char c; ! 262: { ! 263: if (isdigit(c)) ! 264: return (c-'0'); ! 265: if (isxdigit(c)) ! 266: return (c-'a'+10); ! 267: return (-1); ! 268: } ! 269: ! 270: static ! 271: symchar(dig) ! 272: { ! 273: ! 274: if (lastc=='\\') { ! 275: (void) readchar(); ! 276: return (1); ! 277: } ! 278: return (isalpha(lastc) || lastc=='_' || dig && isdigit(lastc)); ! 279: } ! 280: ! 281: varchk(name) ! 282: register name; ! 283: { ! 284: if (isdigit(name)) ! 285: return (name-'0'); ! 286: if (isalpha(name)) ! 287: return ((name&037)-1+10); ! 288: return (-1); ! 289: } ! 290: ! 291: static ! 292: chkloc(frame) ! 293: long frame; ! 294: { ! 295: ! 296: readsym(); ! 297: do { ! 298: if (localsym(frame)==0) ! 299: error(BADLOC); ! 300: expv=localval; ! 301: } while (!eqsym(cursym->n_un.n_name,isymbol,'~')); ! 302: } ! 303: ! 304: eqsym(s1, s2, c) ! 305: register char *s1, *s2; ! 306: { ! 307: ! 308: if (streq(s1,s2)) ! 309: return (1); ! 310: if (*s1 == c && streq(s1+1, s2)) ! 311: return (1); ! 312: return (0); ! 313: } ! 314: ! 315: static ! 316: streq(s1, s2) ! 317: char *s1, *s2; ! 318: { ! 319: ! 320: while (*s1 == *s2++) ! 321: if (*s1++ == '\0') ! 322: return (1); ! 323: return (0); ! 324: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.