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