|
|
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.6 (Berkeley) 5/3/90
7: */
8:
9: #include "../kdb/defs.h"
10:
11: char *kdbBADSYM;
12: char *kdbBADVAR;
13: char *kdbBADKET;
14: char *kdbBADSYN;
15: char *kdbNOCFN;
16: char *kdbNOADR;
17: char *kdbBADLOC;
18:
19: ADDR kdblastframe;
20: ADDR kdbsavlastf;
21: ADDR kdbsavframe;
22: ADDR kdbsavpc;
23: ADDR kdbcallpc;
24:
25: char *kdblp;
26: int kdbradix;
27: char kdbisymbol[1024];
28:
29: char kdblastc, kdbpeekc;
30:
31: long kdbditto;
32: long kdbexpv;
33:
34: static long
35: kdbround(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: kdbexpr(a)
48: {
49: register rc;
50: register long lhs;
51:
52: (void) kdbrdc(); kdblp--; rc=kdbterm(a);
53:
54: while (rc) {
55: lhs = kdbexpv;
56: switch ((int)kdbreadchar()) {
57: case '+':
58: (void) kdbterm(a|1); kdbexpv += lhs; break;
59: case '-':
60: (void) kdbterm(a|1); kdbexpv = lhs - kdbexpv; break;
61: case '#':
62: (void) kdbterm(a|1); kdbexpv = kdbround(lhs,kdbexpv); break;
63: case '*':
64: (void) kdbterm(a|1); kdbexpv *= lhs; break;
65: case '%':
66: (void) kdbterm(a|1); kdbexpv = lhs/kdbexpv; break;
67: case '&':
68: (void) kdbterm(a|1); kdbexpv &= lhs; break;
69: case '|':
70: (void) kdbterm(a|1); kdbexpv |= lhs; break;
71: case ')':
72: if ((a&2)==0)
73: kdberror(kdbBADKET);
74: default:
75: kdblp--;
76: return (rc);
77: }
78: }
79: return (rc);
80: }
81:
82: /* item | monadic item | (expr) | */
83: static
84: kdbterm(a)
85: {
86:
87: switch ((int)kdbreadchar()) {
88: case '*':
89: (void) kdbterm(a|1); kdbexpv=kdbchkget(kdbexpv,DSP);
90: return(1);
91: case '@':
92: (void) kdbterm(a|1); kdbexpv=kdbchkget(kdbexpv,ISP);
93: return(1);
94: case '-':
95: (void) kdbterm(a|1); kdbexpv = -kdbexpv;
96: return(1);
97: case '~':
98: (void) kdbterm(a|1); kdbexpv = ~kdbexpv;
99: return(1);
100: case '#':
101: (void) kdbterm(a|1); kdbexpv = !kdbexpv;
102: return(1);
103: case '(':
104: (void) kdbexpr(2);
105: if (*kdblp!=')')
106: kdberror(kdbBADSYN);
107: kdblp++;
108: return(1);
109: }
110: kdblp--;
111: return (kdbitem(a));
112: }
113:
114: /* name [ . local ] | number | . | ^ | <var | <register | 'x | | */
115: static
116: kdbitem(a)
117: {
118: register base, d, regptr;
119: char savc;
120: register long frame;
121: register struct nlist *symp;
122:
123: (void) kdbreadchar();
124: if (kdbsymchar(0)) {
125: kdbreadsym();
126: if (kdblastc=='.') {
127: frame = kdbpcb.pcb_fp; kdblastframe = 0;
128: kdbcallpc = kdbpcb.pcb_pc;
129: while (!kdberrflg) {
130: kdbsavpc = kdbcallpc;
131: (void) kdbfindsym((long)kdbcallpc,ISYM);
132: if (kdbeqsym(kdbcursym->n_un.n_name,kdbisymbol,'~'))
133: break;
134: kdbcallpc = getprevpc(frame);
135: kdblastframe = frame;
136: frame = getprevframe(frame);
137: if (frame == NOFRAME)
138: kdberror(kdbNOCFN);
139: }
140: kdbsavlastf = kdblastframe; kdbsavframe = frame;
141: (void) kdbreadchar();
142: if (kdbsymchar(0))
143: kdbchkloc(kdbexpv=frame);
144: } else if ((symp=kdblookup(kdbisymbol))==0)
145: kdberror(kdbBADSYM);
146: else
147: kdbexpv = symp->n_value;
148: kdblp--;
149: return (1);
150: }
151: if (kdbgetnum())
152: return (1);
153: switch (kdblastc) {
154: case '.':
155: (void) kdbreadchar();
156: if (kdbsymchar(0)) {
157: kdblastframe=kdbsavlastf; kdbcallpc=kdbsavpc;
158: kdbchkloc((long)kdbsavframe);
159: } else
160: kdbexpv=kdbdot;
161: kdblp--;
162: break;
163: case '"':
164: kdbexpv=kdbditto;
165: break;
166: case '+':
167: kdbexpv=kdbinkdot(kdbdotinc);
168: break;
169: case '^':
170: kdbexpv=kdbinkdot(-kdbdotinc);
171: break;
172: case '<':
173: savc=kdbrdc();
174: if ((regptr=kdbgetreg(savc)) != -1)
175: kdbexpv = *(int *)regptr;
176: else if ((base=kdbvarchk(savc)) != -1)
177: kdbexpv=kdbvar[base];
178: else
179: kdberror(kdbBADVAR);
180: break;
181: case '\'':
182: d=4; kdbexpv=0;
183: while (kdbquotchar()) {
184: if (d--) {
185: kdbexpv <<= 8;
186: kdbexpv |= kdblastc;
187: } else
188: kdberror(kdbBADSYN);
189: }
190: break;
191: default:
192: if (a)
193: kdberror(kdbNOADR);
194: kdblp--;
195: return(0);
196: }
197: return (1);
198: }
199:
200: /* service routines for expression reading */
201: static
202: kdbgetnum()
203: {
204: register base,d,frpt;
205:
206: if (!isdigit(kdblastc))
207: return (0);
208: if ((base = kdbradix) < 0)
209: base = -base;
210: kdbexpv = 0;
211: while (base>10 ? isxdigit(kdblastc) : isdigit(kdblastc)) {
212: register m = MAXINT/base;
213:
214: if (kdbexpv>m) /* avoid overflow */
215: kdbexpv = (kdbexpv-m)*base+m*base;
216: else
217: kdbexpv *= base;
218: if ((d=kdbconvdig(kdblastc))>=base || d<0)
219: kdberror(kdbBADSYN);
220: kdbexpv += d; (void) kdbreadchar();
221: if (kdbexpv==0) {
222: if (kdblastc=='x' || kdblastc=='X') {
223: base=16; (void) kdbreadchar();
224: } else if (kdblastc=='t' || kdblastc=='T') {
225: base=10; (void) kdbreadchar();
226: } else if (kdblastc=='o' || kdblastc=='O') {
227: base=8; (void) kdbreadchar();
228: }
229: }
230: }
231: if (kdblastc=='.' && (base==10 || kdbexpv==0)) {
232: frpt=0; base=10;
233: while (isdigit(kdbreadchar())) {
234: if (frpt)
235: continue;
236: frpt++;
237: if (kdblastc - '0' >= 5)
238: kdbexpv++;
239: }
240: }
241: kdbpeekc=kdblastc;
242: return (1);
243: }
244:
245: static
246: kdbreadsym()
247: {
248: register char *p;
249:
250: p = kdbisymbol;
251: do {
252: if (p < &kdbisymbol[sizeof(kdbisymbol)-1])
253: *p++ = kdblastc;
254: (void) kdbreadchar();
255: } while (kdbsymchar(1));
256: *p++ = 0;
257: }
258:
259: static
260: kdbconvdig(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: kdbsymchar(dig)
272: {
273:
274: if (kdblastc=='\\') {
275: (void) kdbreadchar();
276: return (1);
277: }
278: return (isalpha(kdblastc) || kdblastc=='_' || dig && isdigit(kdblastc));
279: }
280:
281: kdbvarchk(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: kdbchkloc(frame)
293: long frame;
294: {
295:
296: kdbreadsym();
297: do {
298: if (kdblocalsym(frame)==0)
299: kdberror(kdbBADLOC);
300: kdbexpv=kdblocalval;
301: } while (!kdbeqsym(kdbcursym->n_un.n_name,kdbisymbol,'~'));
302: }
303:
304: kdbeqsym(s1, s2, c)
305: register char *s1, *s2;
306: {
307:
308: if (kdbstreq(s1,s2))
309: return (1);
310: if (*s1 == c && kdbstreq(s1+1, s2))
311: return (1);
312: return (0);
313: }
314:
315: static
316: kdbstreq(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.