1: #ifndef lint
2: static char sccsid[] = "@(#)cmd.c 4.2 8/11/83";
3: #endif
4:
5: #
6: /*
7: * UNIX shell
8: *
9: * S. R. Bourne
10: * Bell Telephone Laboratories
11: *
12: */
13:
14: #include "defs.h"
15: #include "sym.h"
16:
17: PROC IOPTR inout();
18: PROC VOID chkword();
19: PROC VOID chksym();
20: PROC TREPTR term();
21: PROC TREPTR makelist();
22: PROC TREPTR list();
23: PROC REGPTR syncase();
24: PROC TREPTR item();
25: PROC VOID skipnl();
26: PROC VOID prsym();
27: PROC VOID synbad();
28:
29:
30: /* ======== command line decoding ========*/
31:
32:
33:
34:
35: TREPTR makefork(flgs, i)
36: INT flgs;
37: TREPTR i;
38: {
39: REG TREPTR t;
40:
41: t=getstak(FORKTYPE);
42: t->forktyp=flgs|TFORK; t->forktre=i; t->forkio=0;
43: return(t);
44: }
45:
46: LOCAL TREPTR makelist(type,i,r)
47: INT type;
48: TREPTR i, r;
49: {
50: REG TREPTR t;
51:
52: IF i==0 ORF r==0
53: THEN synbad();
54: ELSE t = getstak(LSTTYPE);
55: t->lsttyp = type;
56: t->lstlef = i; t->lstrit = r;
57: FI
58: return(t);
59: }
60:
61: /*
62: * cmd
63: * empty
64: * list
65: * list & [ cmd ]
66: * list [ ; cmd ]
67: */
68:
69: TREPTR cmd(sym,flg)
70: REG INT sym;
71: INT flg;
72: {
73: REG TREPTR i, e;
74:
75: i = list(flg);
76:
77: IF wdval==NL
78: THEN IF flg&NLFLG
79: THEN wdval=';'; chkpr(NL);
80: FI
81: ELIF i==0 ANDF (flg&MTFLG)==0
82: THEN synbad();
83: FI
84:
85: SWITCH wdval IN
86:
87: case '&':
88: IF i
89: THEN i = makefork(FINT|FPRS|FAMP, i);
90: ELSE synbad();
91: FI
92:
93: case ';':
94: IF e=cmd(sym,flg|MTFLG)
95: THEN i=makelist(TLST, i, e);
96: FI
97: break;
98:
99: case EOFSYM:
100: IF sym==NL
101: THEN break;
102: FI
103:
104: default:
105: IF sym
106: THEN chksym(sym);
107: FI
108:
109: ENDSW
110: return(i);
111: }
112:
113: /*
114: * list
115: * term
116: * list && term
117: * list || term
118: */
119:
120: LOCAL TREPTR list(flg)
121: {
122: REG TREPTR r;
123: REG INT b;
124:
125: r = term(flg);
126: WHILE r ANDF ((b=(wdval==ANDFSYM)) ORF wdval==ORFSYM)
127: DO r = makelist((b ? TAND : TORF), r, term(NLFLG));
128: OD
129: return(r);
130: }
131:
132: /*
133: * term
134: * item
135: * item |^ term
136: */
137:
138: LOCAL TREPTR term(flg)
139: {
140: REG TREPTR t;
141:
142: reserv++;
143: IF flg&NLFLG
144: THEN skipnl();
145: ELSE word();
146: FI
147:
148: IF (t=item(TRUE)) ANDF (wdval=='^' ORF wdval=='|')
149: THEN return(makelist(TFIL, makefork(FPOU,t), makefork(FPIN|FPCL,term(NLFLG))));
150: ELSE return(t);
151: FI
152: }
153:
154: LOCAL REGPTR syncase(esym)
155: REG INT esym;
156: {
157: skipnl();
158: IF wdval==esym
159: THEN return(0);
160: ELSE REG REGPTR r=getstak(REGTYPE);
161: r->regptr=0;
162: LOOP wdarg->argnxt=r->regptr;
163: r->regptr=wdarg;
164: IF wdval ORF ( word()!=')' ANDF wdval!='|' )
165: THEN synbad();
166: FI
167: IF wdval=='|'
168: THEN word();
169: ELSE break;
170: FI
171: POOL
172: r->regcom=cmd(0,NLFLG|MTFLG);
173: IF wdval==ECSYM
174: THEN r->regnxt=syncase(esym);
175: ELSE chksym(esym);
176: r->regnxt=0;
177: FI
178: return(r);
179: FI
180: }
181:
182: /*
183: * item
184: *
185: * ( cmd ) [ < in ] [ > out ]
186: * word word* [ < in ] [ > out ]
187: * if ... then ... else ... fi
188: * for ... while ... do ... done
189: * case ... in ... esac
190: * begin ... end
191: */
192:
193: LOCAL TREPTR item(flag)
194: BOOL flag;
195: {
196: REG TREPTR t;
197: REG IOPTR io;
198:
199: IF flag
200: THEN io=inout((IOPTR)0);
201: ELSE io=0;
202: FI
203:
204: SWITCH wdval IN
205:
206: case CASYM:
207: BEGIN
208: t=getstak(SWTYPE);
209: chkword();
210: t->swarg=wdarg->argval;
211: skipnl(); chksym(INSYM|BRSYM);
212: t->swlst=syncase(wdval==INSYM?ESSYM:KTSYM);
213: t->swtyp=TSW;
214: break;
215: END
216:
217: case IFSYM:
218: BEGIN
219: REG INT w;
220: t=getstak(IFTYPE);
221: t->iftyp=TIF;
222: t->iftre=cmd(THSYM,NLFLG);
223: t->thtre=cmd(ELSYM|FISYM|EFSYM,NLFLG);
224: t->eltre=((w=wdval)==ELSYM ? cmd(FISYM,NLFLG) : (w==EFSYM ? (wdval=IFSYM, item(0)) : 0));
225: IF w==EFSYM THEN return(t) FI
226: break;
227: END
228:
229: case FORSYM:
230: BEGIN
231: t=getstak(FORTYPE);
232: t->fortyp=TFOR;
233: t->forlst=0;
234: chkword();
235: t->fornam=wdarg->argval;
236: IF skipnl()==INSYM
237: THEN chkword();
238: t->forlst=item(0);
239: IF wdval!=NL ANDF wdval!=';'
240: THEN synbad();
241: FI
242: chkpr(wdval); skipnl();
243: FI
244: chksym(DOSYM|BRSYM);
245: t->fortre=cmd(wdval==DOSYM?ODSYM:KTSYM,NLFLG);
246: break;
247: END
248:
249: case WHSYM:
250: case UNSYM:
251: BEGIN
252: t=getstak(WHTYPE);
253: t->whtyp=(wdval==WHSYM ? TWH : TUN);
254: t->whtre = cmd(DOSYM,NLFLG);
255: t->dotre = cmd(ODSYM,NLFLG);
256: break;
257: END
258:
259: case BRSYM:
260: t=cmd(KTSYM,NLFLG);
261: break;
262:
263: case '(':
264: BEGIN
265: REG PARPTR p;
266: p=getstak(PARTYPE);
267: p->partre=cmd(')',NLFLG);
268: p->partyp=TPAR;
269: t=makefork(0,p);
270: break;
271: END
272:
273: default:
274: IF io==0
275: THEN return(0);
276: FI
277:
278: case 0:
279: BEGIN
280: REG ARGPTR argp;
281: REG ARGPTR *argtail;
282: REG ARGPTR *argset=0;
283: INT keywd=1;
284: t=getstak(COMTYPE);
285: t->comio=io; /*initial io chain*/
286: argtail = &(t->comarg);
287: WHILE wdval==0
288: DO argp = wdarg;
289: IF wdset ANDF keywd
290: THEN argp->argnxt=argset; argset=argp;
291: ELSE *argtail=argp; argtail = &(argp->argnxt); keywd=flags&keyflg;
292: FI
293: word();
294: IF flag
295: THEN t->comio=inout(t->comio);
296: FI
297: OD
298:
299: t->comtyp=TCOM; t->comset=argset; *argtail=0;
300: return(t);
301: END
302:
303: ENDSW
304: reserv++; word();
305: IF io=inout(io)
306: THEN t=makefork(0,t); t->treio=io;
307: FI
308: return(t);
309: }
310:
311:
312: LOCAL VOID skipnl()
313: {
314: WHILE (reserv++, word()==NL) DO chkpr(NL) OD
315: return(wdval);
316: }
317:
318: LOCAL IOPTR inout(lastio)
319: IOPTR lastio;
320: {
321: REG INT iof;
322: REG IOPTR iop;
323: REG CHAR c;
324:
325: iof=wdnum;
326:
327: SWITCH wdval IN
328:
329: case DOCSYM:
330: iof |= IODOC; break;
331:
332: case APPSYM:
333: case '>':
334: IF wdnum==0 THEN iof |= 1 FI
335: iof |= IOPUT;
336: IF wdval==APPSYM
337: THEN iof |= IOAPP; break;
338: FI
339:
340: case '<':
341: IF (c=nextc(0))=='&'
342: THEN iof |= IOMOV;
343: ELIF c=='>'
344: THEN iof |= IORDW;
345: ELSE peekc=c|MARK;
346: FI
347: break;
348:
349: default:
350: return(lastio);
351: ENDSW
352:
353: chkword();
354: iop=getstak(IOTYPE); iop->ioname=wdarg->argval; iop->iofile=iof;
355: IF iof&IODOC
356: THEN iop->iolst=iopend; iopend=iop;
357: FI
358: word(); iop->ionxt=inout(lastio);
359: return(iop);
360: }
361:
362: LOCAL VOID chkword()
363: {
364: IF word()
365: THEN synbad();
366: FI
367: }
368:
369: LOCAL VOID chksym(sym)
370: {
371: REG INT x = sym&wdval;
372: IF ((x&SYMFLG) ? x : sym) != wdval
373: THEN synbad();
374: FI
375: }
376:
377: LOCAL VOID prsym(sym)
378: {
379: IF sym&SYMFLG
380: THEN REG SYSPTR sp=reserved;
381: WHILE sp->sysval
382: ANDF sp->sysval!=sym
383: DO sp++ OD
384: prs(sp->sysnam);
385: ELIF sym==EOFSYM
386: THEN prs(endoffile);
387: ELSE IF sym&SYMREP THEN prc(sym) FI
388: IF sym==NL
389: THEN prs("newline");
390: ELSE prc(sym);
391: FI
392: FI
393: }
394:
395: LOCAL VOID synbad()
396: {
397: prp(); prs(synmsg);
398: IF (flags&ttyflg)==0
399: THEN prs(atline); prn(standin->flin);
400: FI
401: prs(colon);
402: prc(LQ);
403: IF wdval
404: THEN prsym(wdval);
405: ELSE prs(wdarg->argval);
406: FI
407: prc(RQ); prs(unexpected);
408: newline();
409: exitsh(SYNBAD);
410: }
Defined functions
cmd
defined in line
69; used 14 times
item
defined in line
193; used 4 times
list
defined in line
120; used 2 times
term
defined in line
138; used 4 times
Defined variables
sccsid
defined in line
2;
never used