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