|
|
1.1 root 1: static char *sccsid = "@(#)sh.parse.c 4.1 10/9/80";
2:
3: #include "sh.h"
4:
5: /*
6: * C shell
7: */
8:
9: /*
10: * Perform aliasing on the word list lex
11: * Do a (very rudimentary) parse to separate into commands.
12: * If word 0 of a command has an alias, do it.
13: * Repeat a maximum of 20 times.
14: */
15: alias(lex)
16: register struct wordent *lex;
17: {
18: int aleft = 21;
19: jmp_buf osetexit;
20:
21: getexit(osetexit);
22: setexit();
23: if (haderr) {
24: resexit(osetexit);
25: reset();
26: }
27: if (--aleft == 0)
28: error("Alias loop");
29: asyntax(lex->next, lex);
30: resexit(osetexit);
31: }
32:
33: asyntax(p1, p2)
34: register struct wordent *p1, *p2;
35: {
36:
37: while (p1 != p2)
38: if (any(p1->word[0], ";&\n"))
39: p1 = p1->next;
40: else {
41: asyn0(p1, p2);
42: return;
43: }
44: }
45:
46: asyn0(p1, p2)
47: struct wordent *p1;
48: register struct wordent *p2;
49: {
50: register struct wordent *p;
51: register int l = 0;
52:
53: for (p = p1; p != p2; p = p->next)
54: switch (p->word[0]) {
55:
56: case '(':
57: l++;
58: continue;
59:
60: case ')':
61: l--;
62: if (l < 0)
63: error("Too many )'s");
64: continue;
65:
66: case '>':
67: if (p->next != p2 && eq(p->next->word, "&"))
68: p = p->next;
69: continue;
70:
71: case '&':
72: case '|':
73: case ';':
74: case '\n':
75: if (l != 0)
76: continue;
77: asyn3(p1, p);
78: asyntax(p->next, p2);
79: return;
80: }
81: if (l == 0)
82: asyn3(p1, p2);
83: }
84:
85: asyn3(p1, p2)
86: struct wordent *p1;
87: register struct wordent *p2;
88: {
89: register struct varent *ap;
90: struct wordent alout;
91: register bool redid;
92:
93: if (p1 == p2)
94: return;
95: if (p1->word[0] == '(') {
96: for (p2 = p2->prev; p2->word[0] != ')'; p2 = p2->prev)
97: if (p2 == p1)
98: return;
99: if (p2 == p1->next)
100: return;
101: asyn0(p1->next, p2);
102: return;
103: }
104: ap = adrof1(p1->word, &aliases);
105: if (ap == 0)
106: return;
107: alhistp = p1->prev;
108: alhistt = p2;
109: alvec = ap->vec;
110: redid = lex(&alout);
111: alhistp = alhistt = 0;
112: alvec = 0;
113: if (err) {
114: freelex(&alout);
115: error(err);
116: }
117: if (p1->word[0] && eq(p1->word, alout.next->word)) {
118: char *cp = alout.next->word;
119:
120: alout.next->word = strspl("\200", cp);
121: xfree(cp);
122: }
123: p1 = freenod(p1, redid ? p2 : p1->next);
124: if (alout.next != &alout) {
125: p1->next->prev = alout.prev->prev;
126: alout.prev->prev->next = p1->next;
127: alout.next->prev = p1;
128: p1->next = alout.next;
129: xfree(alout.prev->word);
130: xfree((char *)(alout.prev));
131: }
132: reset(); /* throw! */
133: }
134:
135: struct wordent *
136: freenod(p1, p2)
137: register struct wordent *p1, *p2;
138: {
139: register struct wordent *retp = p1->prev;
140:
141: while (p1 != p2) {
142: xfree(p1->word);
143: p1 = p1->next;
144: xfree((char *)(p1->prev));
145: }
146: retp->next = p2;
147: p2->prev = retp;
148: return (retp);
149: }
150:
151: #define PHERE 1
152: #define PIN 2
153: #define POUT 4
154: #define PDIAG 8
155:
156: /*
157: * syntax
158: * empty
159: * syn0
160: */
161: struct command *
162: syntax(p1, p2, flags)
163: register struct wordent *p1, *p2;
164: int flags;
165: {
166:
167: while (p1 != p2)
168: if (any(p1->word[0], ";&\n"))
169: p1 = p1->next;
170: else
171: return (syn0(p1, p2, flags));
172: return (0);
173: }
174:
175: /*
176: * syn0
177: * syn1
178: * syn1 & syntax
179: */
180: struct command *
181: syn0(p1, p2, flags)
182: struct wordent *p1, *p2;
183: int flags;
184: {
185: register struct wordent *p;
186: register struct command *t, *t1;
187: int l;
188:
189: l = 0;
190: for (p = p1; p != p2; p = p->next)
191: switch (p->word[0]) {
192:
193: case '(':
194: l++;
195: continue;
196:
197: case ')':
198: l--;
199: if (l < 0)
200: seterr("Too many )'s");
201: continue;
202:
203: case '|':
204: if (p->word[1] == '|')
205: continue;
206: /* fall into ... */
207:
208: case '>':
209: if (p->next != p2 && eq(p->next->word, "&"))
210: p = p->next;
211: continue;
212:
213: case '&':
214: if (l != 0)
215: break;
216: if (p->word[1] == '&')
217: continue;
218: t1 = syn1(p1, p, flags);
219: if (t1->t_dtyp == TLST) {
220: t = (struct command *) calloc(1, sizeof (*t));
221: t->t_dtyp = TPAR;
222: t->t_dflg = FAND|FINT;
223: t->t_dspr = t1;
224: t1 = t;
225: } else
226: t1->t_dflg |= FAND|FINT;
227: t = (struct command *) calloc(1, sizeof (*t));
228: t->t_dtyp = TLST;
229: t->t_dflg = 0;
230: t->t_dcar = t1;
231: t->t_dcdr = syntax(p, p2, flags);
232: return(t);
233: }
234: if (l == 0)
235: return (syn1(p1, p2, flags));
236: seterr("Too many ('s");
237: return (0);
238: }
239:
240: /*
241: * syn1
242: * syn1a
243: * syn1a ; syntax
244: */
245: struct command *
246: syn1(p1, p2, flags)
247: struct wordent *p1, *p2;
248: int flags;
249: {
250: register struct wordent *p;
251: register struct command *t;
252: int l;
253:
254: l = 0;
255: for (p = p1; p != p2; p = p->next)
256: switch (p->word[0]) {
257:
258: case '(':
259: l++;
260: continue;
261:
262: case ')':
263: l--;
264: continue;
265:
266: case ';':
267: case '\n':
268: if (l != 0)
269: break;
270: t = (struct command *) calloc(1, sizeof (*t));
271: t->t_dtyp = TLST;
272: t->t_dcar = syn1a(p1, p, flags);
273: t->t_dcdr = syntax(p->next, p2, flags);
274: if (t->t_dcdr == 0)
275: t->t_dcdr = t->t_dcar, t->t_dcar = 0;
276: return (t);
277: }
278: return (syn1a(p1, p2, flags));
279: }
280:
281: /*
282: * syn1a
283: * syn1b
284: * syn1b || syn1a
285: */
286: struct command *
287: syn1a(p1, p2, flags)
288: struct wordent *p1, *p2;
289: int flags;
290: {
291: register struct wordent *p;
292: register struct command *t;
293: register int l = 0;
294:
295: for (p = p1; p != p2; p = p->next)
296: switch (p->word[0]) {
297:
298: case '(':
299: l++;
300: continue;
301:
302: case ')':
303: l--;
304: continue;
305:
306: case '|':
307: if (p->word[1] != '|')
308: continue;
309: if (l == 0) {
310: t = (struct command *) calloc(1, sizeof (*t));
311: t->t_dtyp = TOR;
312: t->t_dcar = syn1b(p1, p, flags);
313: t->t_dcdr = syn1a(p->next, p2, flags);
314: t->t_dflg = 0;
315: return (t);
316: }
317: continue;
318: }
319: return (syn1b(p1, p2, flags));
320: }
321:
322: /*
323: * syn1b
324: * syn2
325: * syn2 && syn1b
326: */
327: struct command *
328: syn1b(p1, p2, flags)
329: struct wordent *p1, *p2;
330: int flags;
331: {
332: register struct wordent *p;
333: register struct command *t;
334: register int l = 0;
335:
336: l = 0;
337: for (p = p1; p != p2; p = p->next)
338: switch (p->word[0]) {
339:
340: case '(':
341: l++;
342: continue;
343:
344: case ')':
345: l--;
346: continue;
347:
348: case '&':
349: if (p->word[1] == '&' && l == 0) {
350: t = (struct command *) calloc(1, sizeof (*t));
351: t->t_dtyp = TAND;
352: t->t_dcar = syn2(p1, p, flags);
353: t->t_dcdr = syn1b(p->next, p2, flags);
354: t->t_dflg = 0;
355: return (t);
356: }
357: continue;
358: }
359: return (syn2(p1, p2, flags));
360: }
361:
362: /*
363: * syn2
364: * syn3
365: * syn3 | syn2
366: * syn3 |& syn2
367: */
368: struct command *
369: syn2(p1, p2, flags)
370: struct wordent *p1, *p2;
371: int flags;
372: {
373: register struct wordent *p, *pn;
374: register struct command *t;
375: register int l = 0;
376: int f;
377:
378: for (p = p1; p != p2; p = p->next)
379: switch (p->word[0]) {
380:
381: case '(':
382: l++;
383: continue;
384:
385: case ')':
386: l--;
387: continue;
388:
389: case '|':
390: if (l != 0)
391: continue;
392: t = (struct command *) calloc(1, sizeof (*t));
393: f = flags | POUT;
394: pn = p->next;
395: if (pn != p2 && pn->word[0] == '&') {
396: f |= PDIAG;
397: t->t_dflg |= FDIAG;
398: }
399: t->t_dtyp = TFIL;
400: t->t_dcar = syn3(p1, p, f);
401: if (pn != p2 && pn->word[0] == '&')
402: p = pn;
403: t->t_dcdr = syn2(p->next, p2, flags | PIN);
404: return (t);
405: }
406: return (syn3(p1, p2, flags));
407: }
408:
409: char *RELPAR = "<>()";
410:
411: /*
412: * syn3
413: * ( syn0 ) [ < in ] [ > out ]
414: * word word* [ < in ] [ > out ]
415: * KEYWORD ( word* ) word* [ < in ] [ > out ]
416: *
417: * KEYWORD = (@ exit foreach if set switch test while)
418: */
419: struct command *
420: syn3(p1, p2, flags)
421: struct wordent *p1, *p2;
422: int flags;
423: {
424: register struct wordent *p;
425: struct wordent *lp, *rp;
426: register struct command *t;
427: register int l;
428: char **av;
429: int n, c;
430: bool specp = 0;
431:
432: if (p1 != p2) {
433: p = p1;
434: again:
435: switch (srchx(p->word)) {
436:
437: case ZELSE:
438: p = p->next;
439: if (p != p2)
440: goto again;
441: break;
442:
443: case ZEXIT:
444: case ZFOREACH:
445: case ZIF:
446: case ZLET:
447: case ZSET:
448: case ZSWITCH:
449: case ZWHILE:
450: specp = 1;
451: break;
452: }
453: }
454: n = 0;
455: l = 0;
456: for (p = p1; p != p2; p = p->next)
457: switch (p->word[0]) {
458:
459: case '(':
460: if (specp)
461: n++;
462: l++;
463: continue;
464:
465: case ')':
466: if (specp)
467: n++;
468: l--;
469: continue;
470:
471: case '>':
472: case '<':
473: if (l != 0) {
474: if (specp)
475: n++;
476: continue;
477: }
478: if (p->next == p2)
479: continue;
480: if (any(p->next->word[0], RELPAR))
481: continue;
482: n--;
483: continue;
484:
485: default:
486: if (!specp && l != 0)
487: continue;
488: n++;
489: continue;
490: }
491: if (n < 0)
492: n = 0;
493: t = (struct command *) calloc(1, sizeof (*t));
494: av = (char **) calloc(n + 1, sizeof (char **));
495: t->t_dcom = av;
496: n = 0;
497: if (p2->word[0] == ')')
498: t->t_dflg = FPAR;
499: lp = 0;
500: rp = 0;
501: l = 0;
502: for (p = p1; p != p2; p = p->next) {
503: c = p->word[0];
504: switch (c) {
505:
506: case '(':
507: if (l == 0) {
508: if (lp != 0 && !specp)
509: seterr("Badly placed (");
510: lp = p->next;
511: }
512: l++;
513: goto savep;
514:
515: case ')':
516: l--;
517: if (l == 0)
518: rp = p;
519: goto savep;
520:
521: case '>':
522: if (l != 0)
523: goto savep;
524: if (p->word[1] == '>')
525: t->t_dflg |= FCAT;
526: if (p->next != p2 && eq(p->next->word, "&")) {
527: t->t_dflg |= FDIAG, p = p->next;
528: if (flags & (POUT|PDIAG))
529: goto badout;
530: }
531: if (p->next != p2 && eq(p->next->word, "!"))
532: t->t_dflg |= FANY, p = p->next;
533: if (p->next == p2) {
534: missfile:
535: seterr("Missing name for redirect");
536: continue;
537: }
538: p = p->next;
539: if (any(p->word[0], RELPAR))
540: goto missfile;
541: if ((flags & POUT) && (flags & PDIAG) == 0 || t->t_drit)
542: badout:
543: seterr("Ambiguous output redirect");
544: else
545: t->t_drit = savestr(p->word);
546: continue;
547:
548: case '<':
549: if (l != 0)
550: goto savep;
551: if (p->word[1] == '<')
552: t->t_dflg |= FHERE;
553: if (p->next == p2)
554: goto missfile;
555: p = p->next;
556: if (any(p->word[0], RELPAR))
557: goto missfile;
558: if ((flags & PHERE) && (t->t_dflg & FHERE))
559: seterr("Can't << within ()'s");
560: else if ((flags & PIN) || t->t_dlef)
561: seterr("Ambiguous input redirect");
562: else
563: t->t_dlef = savestr(p->word);
564: continue;
565:
566: savep:
567: if (!specp)
568: continue;
569: default:
570: if (l != 0 && !specp)
571: continue;
572: if (err == 0)
573: av[n] = savestr(p->word);
574: n++;
575: continue;
576: }
577: }
578: if (lp != 0 && !specp) {
579: if (n != 0)
580: seterr("Badly placed ()'s");
581: t->t_dtyp = TPAR;
582: t->t_dspr = syn0(lp, rp, PHERE);
583: } else {
584: if (n == 0)
585: seterr("Invalid null command");
586: t->t_dtyp = TCOM;
587: }
588: return (t);
589: }
590:
591: freesyn(t)
592: register struct command *t;
593: {
594: register char **v;
595:
596: if (t == 0)
597: return;
598: switch (t->t_dtyp) {
599:
600: case TCOM:
601: for (v = t->t_dcom; *v; v++)
602: xfree(*v);
603: xfree((char *)(t->t_dcom));
604: goto lr;
605:
606: case TPAR:
607: freesyn(t->t_dspr);
608: /* fall into ... */
609:
610: lr:
611: xfree(t->t_dlef), xfree(t->t_drit);
612: break;
613:
614: case TAND:
615: case TOR:
616: case TFIL:
617: case TLST:
618: freesyn(t->t_dcar), freesyn(t->t_dcdr);
619: break;
620: }
621: xfree((char *)t);
622: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.