|
|
1.1 root 1: /* Copyright (c) 1979 Regents of the University of California */
2: #include "sh.h"
3:
4: /*
5: * C shell
6: */
7:
8: #define ADDOP 1
9: #define MULOP 2
10: #define EQOP 4
11: #define RELOP 8
12: #define RESTOP 16
13: #define ANYOP 31
14:
15: #define EQEQ 1
16: #define GTR 2
17: #define LSS 4
18: #define NOTEQ 6
19:
20: exp(vp)
21: register char ***vp;
22: {
23:
24: return (exp0(vp, 0));
25: }
26:
27: exp0(vp, ignore)
28: register char ***vp;
29: bool ignore;
30: {
31: register int p1 = exp1(vp, ignore);
32:
33: #ifdef EDEBUG
34: etraci("exp0 p1", p1, vp);
35: #endif
36: if (**vp && eq(**vp, "||")) {
37: register int p2;
38:
39: (*vp)++;
40: p2 = exp0(vp, ignore || p1);
41: #ifdef EDEBUG
42: etraci("exp0 p2", p2, vp);
43: #endif
44: return (p1 || p2);
45: }
46: return (p1);
47: }
48:
49: exp1(vp, ignore)
50: register char ***vp;
51: {
52: register int p1 = exp2(vp, ignore);
53:
54: #ifdef EDEBUG
55: etraci("exp1 p1", p1, vp);
56: #endif
57: if (**vp && eq(**vp, "&&")) {
58: register int p2;
59:
60: (*vp)++;
61: p2 = exp1(vp, ignore || !p1);
62: #ifdef EDEBUG
63: etraci("exp1 p2", p2, vp);
64: #endif
65: return (p1 && p2);
66: }
67: return (p1);
68: }
69:
70: exp2(vp, ignore)
71: register char ***vp;
72: bool ignore;
73: {
74: register int p1 = exp2a(vp, ignore);
75:
76: #ifdef EDEBUG
77: etraci("exp3 p1", p1, vp);
78: #endif
79: if (**vp && eq(**vp, "|")) {
80: register int p2;
81:
82: (*vp)++;
83: p2 = exp2(vp, ignore);
84: #ifdef EDEBUG
85: etraci("exp3 p2", p2, vp);
86: #endif
87: return (p1 | p2);
88: }
89: return (p1);
90: }
91:
92: exp2a(vp, ignore)
93: register char ***vp;
94: bool ignore;
95: {
96: register int p1 = exp2b(vp, ignore);
97:
98: #ifdef EDEBUG
99: etraci("exp2a p1", p1, vp);
100: #endif
101: if (**vp && eq(**vp, "^")) {
102: register int p2;
103:
104: (*vp)++;
105: p2 = exp2a(vp, ignore);
106: #ifdef EDEBUG
107: etraci("exp2a p2", p2, vp);
108: #endif
109: return (p1 ^ p2);
110: }
111: return (p1);
112: }
113:
114: exp2b(vp, ignore)
115: register char ***vp;
116: bool ignore;
117: {
118: register int p1 = exp2c(vp, ignore);
119:
120: #ifdef EDEBUG
121: etraci("exp2b p1", p1, vp);
122: #endif
123: if (**vp && eq(**vp, "&")) {
124: register int p2;
125:
126: (*vp)++;
127: p2 = exp2b(vp, ignore);
128: #ifdef EDEBUG
129: etraci("exp2b p2", p2, vp);
130: #endif
131: return (p1 & p2);
132: }
133: return (p1);
134: }
135:
136: exp2c(vp, ignore)
137: register char ***vp;
138: bool ignore;
139: {
140: register char *p1 = exp3(vp, ignore);
141: register char *p2;
142: register int i;
143:
144: #ifdef EDEBUG
145: etracc("exp2c p1", p1, vp);
146: #endif
147: if (i = isa(**vp, EQOP)) {
148: (*vp)++;
149: p2 = exp3(vp, ignore);
150: #ifdef EDEBUG
151: etracc("exp2c p2", p2, vp);
152: #endif
153: if (!ignore) switch (i) {
154:
155: case EQEQ:
156: i = eq(p1, p2);
157: break;
158:
159: case NOTEQ:
160: i = !eq(p1, p2);
161: break;
162: }
163: xfree(p1), xfree(p2);
164: return (i);
165: }
166: i = egetn(p1);
167: xfree(p1);
168: return (i);
169: }
170:
171: char *
172: exp3(vp, ignore)
173: register char ***vp;
174: bool ignore;
175: {
176: register char *p1, *p2;
177: register int i;
178:
179: p1 = exp3a(vp, ignore);
180: #ifdef EDEBUG
181: etracc("exp3 p1", p1, vp);
182: #endif
183: if (i = isa(**vp, RELOP)) {
184: (*vp)++;
185: if (**vp && eq(**vp, "="))
186: i |= 1, (*vp)++;
187: p2 = exp3(vp, ignore);
188: #ifdef EDEBUG
189: etracc("exp3 p2", p2, vp);
190: #endif
191: if (!ignore) switch (i) {
192:
193: case GTR:
194: i = egetn(p1) > egetn(p2);
195: break;
196:
197: case GTR|1:
198: i = egetn(p1) >= egetn(p2);
199: break;
200:
201: case LSS:
202: i = egetn(p1) < egetn(p2);
203: break;
204:
205: case LSS|1:
206: i = egetn(p1) <= egetn(p2);
207: break;
208: }
209: xfree(p1), xfree(p2);
210: return (putn(i));
211: }
212: return (p1);
213: }
214:
215: char *
216: exp3a(vp, ignore)
217: register char ***vp;
218: bool ignore;
219: {
220: register char *p1, *p2, *op;
221: register int i;
222:
223: p1 = exp4(vp, ignore);
224: #ifdef EDEBUG
225: etracc("exp3a p1", p1, vp);
226: #endif
227: op = **vp;
228: if (op && any(op[0], "<>") && op[0] == op[1]) {
229: (*vp)++;
230: p2 = exp3a(vp, ignore);
231: #ifdef EDEBUG
232: etracc("exp3a p2", p2, vp);
233: #endif
234: if (op[0] == '<')
235: i = egetn(p1) << egetn(p2);
236: else
237: i = egetn(p1) >> egetn(p2);
238: xfree(p1), xfree(p2);
239: return (putn(i));
240: }
241: return (p1);
242: }
243:
244: char *
245: exp4(vp, ignore)
246: register char ***vp;
247: bool ignore;
248: {
249: register char *p1, *p2;
250: register int i = 0;
251:
252: p1 = exp5(vp, ignore);
253: #ifdef EDEBUG
254: etracc("exp4 p1", p1, vp);
255: #endif
256: if (isa(**vp, ADDOP)) {
257: register char *op = *(*vp)++;
258:
259: p2 = exp4(vp, ignore);
260: #ifdef EDEBUG
261: etracc("exp4 p2", p2, vp);
262: #endif
263: if (!ignore) switch (op[0]) {
264:
265: case '+':
266: i = egetn(p1) + egetn(p2);
267: break;
268:
269: case '-':
270: i = egetn(p1) - egetn(p2);
271: break;
272: }
273: xfree(p1), xfree(p2);
274: return (putn(i));
275: }
276: return (p1);
277: }
278:
279: char *
280: exp5(vp, ignore)
281: register char ***vp;
282: bool ignore;
283: {
284: register char *p1, *p2;
285: register int i = 0;
286:
287: p1 = exp6(vp, ignore);
288: #ifdef EDEBUG
289: etracc("exp5 p1", p1, vp);
290: #endif
291: if (isa(**vp, MULOP)) {
292: register char *op = *(*vp)++;
293:
294: p2 = exp5(vp, ignore);
295: #ifdef EDEBUG
296: etracc("exp5 p2", p2, vp);
297: #endif
298: if (!ignore) switch (op[0]) {
299:
300: case '*':
301: i = egetn(p1) * egetn(p2);
302: break;
303:
304: case '/':
305: i = egetn(p2);
306: if (i == 0)
307: error("Divide by 0");
308: i = egetn(p1) / i;
309: break;
310:
311: case '%':
312: i = egetn(p2);
313: if (i == 0)
314: error("Mod by 0");
315: i = egetn(p1) % i;
316: break;
317: }
318: xfree(p1), xfree(p2);
319: return (putn(i));
320: }
321: return (p1);
322: }
323:
324: char *
325: exp6(vp, ignore)
326: register char ***vp;
327: {
328: int ccode, i;
329: register char *cp, *dp, *ep;
330:
331: if (eq(**vp, "!")) {
332: (*vp)++;
333: cp = exp6(vp, ignore);
334: #ifdef EDEBUG
335: etracc("exp6 ! cp", cp, vp);
336: #endif
337: i = egetn(cp);
338: xfree(cp);
339: return (putn(!i));
340: }
341: if (eq(**vp, "~")) {
342: (*vp)++;
343: cp = exp6(vp, ignore);
344: #ifdef EDEBUG
345: etracc("exp6 ~ cp", cp, vp);
346: #endif
347: i = egetn(cp);
348: xfree(cp);
349: return (putn(~i));
350: }
351: if (eq(**vp, "(")) {
352: (*vp)++;
353: ccode = exp0(vp, ignore);
354: #ifdef EDEBUG
355: etraci("exp6 () ccode", ccode, vp);
356: #endif
357: if (*vp == 0 || **vp == 0 || ***vp != ')')
358: bferr("Expression syntax");
359: (*vp)++;
360: return (putn(ccode));
361: }
362: if (eq(**vp, "{")) {
363: int pid;
364: register char **v;
365:
366: (*vp)++;
367: v = *vp;
368: for (;;) {
369: if (!**vp)
370: bferr("Missing }");
371: if (eq(*(*vp)++, "}"))
372: break;
373: }
374: if (ignore)
375: return ("");
376: pid = fork();
377: if (pid < 0)
378: Perror("fork");
379: if (pid == 0) {
380: if (setintr)
381: signal(SIGINT, SIG_DFL);
382: *--(*vp) = 0;
383: evalav(v);
384: exitstat();
385: }
386: cadd(pid, "{}");
387: pwait(pid);
388: #ifdef EDEBUG
389: etraci("exp6 {} status", egetn(value("status")), vp);
390: #endif
391: return (putn(egetn(value("status")) == 0));
392: }
393: if (isa(**vp, ANYOP))
394: return ("");
395: cp = *(*vp)++;
396: if (*cp == '-' && any(cp[1], "erwxfdzo")) {
397: struct stat stb;
398:
399: if (isa(**vp, ANYOP))
400: bferr("Missing file name");
401: dp = *(*vp)++;
402: if (ignore)
403: return ("");
404: ep = globone(dp);
405: switch (cp[1]) {
406:
407: case 'r':
408: i = !access(ep, 4);
409: break;
410:
411: case 'w':
412: i = !access(ep, 2);
413: break;
414:
415: case 'x':
416: i = !access(ep, 1);
417: break;
418:
419: default:
420: if (stat(ep, &stb)) {
421: xfree(ep);
422: return ("0");
423: }
424: switch (cp[1]) {
425:
426: case 'f':
427: i = (stb.st_mode & S_IFMT) == S_IFREG;
428: break;
429:
430: case 'd':
431: i = (stb.st_mode & S_IFMT) == S_IFDIR;
432: break;
433:
434: case 'z':
435: i = stb.st_size == 0;
436: break;
437:
438: case 'e':
439: i = 1;
440: break;
441:
442: case 'o':
443: i = stb.st_uid == uid;
444: break;
445: }
446: }
447: #ifdef EDEBUG
448: etraci("exp6 -? i", i, vp);
449: #endif
450: xfree(ep);
451: return (putn(i));
452: }
453: #ifdef EDEBUG
454: etracc("exp6 default", cp, vp);
455: #endif
456: return (globone(cp));
457: }
458:
459: evalav(v)
460: register char **v;
461: {
462: struct wordent paraml;
463: register struct wordent *hp = ¶ml;
464: struct command *t;
465: register struct wordent *wdp = hp;
466:
467: child++;
468: set("status", "0");
469: hp->prev = hp->next = hp;
470: hp->word = "";
471: while (*v) {
472: register struct wordent *new = (struct wordent *) calloc(1, sizeof *wdp);
473:
474: new->prev = wdp;
475: new->next = hp;
476: wdp->next = new;
477: wdp = new;
478: wdp->word = savestr(*v++);
479: }
480: hp->prev = wdp;
481: alias(¶ml);
482: t = syntax(paraml.next, ¶ml);
483: if (err)
484: error(err);
485: execute(t);
486: freelex(¶ml), freesyn(t);
487: }
488:
489: isa(cp, what)
490: register char *cp;
491: register int what;
492: {
493:
494: if (cp == 0)
495: return ((what & RESTOP) != 0);
496: if (cp[1] == 0) {
497: if ((what & ADDOP) && any(cp[0], "+-"))
498: return (1);
499: if ((what & MULOP) && any(cp[0], "*/%"))
500: return (1);
501: if ((what & RESTOP) && any(cp[0], "()!~^"))
502: return (1);
503: }
504: if ((what & RESTOP) && (any(cp[0], "|&") || eq(cp, "<<") || eq(cp, ">>")))
505: return (1);
506: if (what & EQOP) {
507: if (eq(cp, "=="))
508: return (EQEQ);
509: if (eq(cp, "!="))
510: return (NOTEQ);
511: }
512: if (!(what & RELOP))
513: return (0);
514: if (*cp == '<')
515: return (LSS);
516: if (*cp == '>')
517: return (GTR);
518: return (0);
519: }
520:
521: egetn(cp)
522: register char *cp;
523: {
524:
525: if (*cp && *cp != '-' && !digit(*cp))
526: bferr("Expression syntax");
527: return (getn(cp));
528: }
529:
530: /* Phew! */
531:
532: #ifdef EDEBUG
533: etraci(str, i, vp)
534: char *str;
535: int i;
536: char ***vp;
537: {
538:
539: printf("%s=%d\t", str, i);
540: blkpr(*vp);
541: printf("\n");
542: }
543:
544: etracc(str, cp, vp)
545: char *str, *cp;
546: char ***vp;
547: {
548:
549: printf("%s=%s\t", str, cp);
550: blkpr(*vp);
551: printf("\n");
552: }
553: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.