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