1: #
2: /*
3: * UNIX shell
4: *
5: * S. R. Bourne
6: * Bell Telephone Laboratories
7: *
8: */
9:
10: #include "defs.h"
11: #include "sym.h"
12:
13: LOCAL CHAR quote; /* used locally */
14: LOCAL CHAR quoted; /* used locally */
15:
16:
17:
18: LOCAL STRING copyto(endch)
19: REG CHAR endch;
20: {
21: REG CHAR c;
22:
23: WHILE (c=getch(endch))!=endch ANDF c
24: DO pushstak(c|quote) OD
25: zerostak();
26: IF c!=endch THEN error(badsub) FI
27: }
28:
29: LOCAL skipto(endch)
30: REG CHAR endch;
31: {
32: /* skip chars up to } */
33: REG CHAR c;
34: WHILE (c=readc()) ANDF c!=endch
35: DO SWITCH c IN
36:
37: case SQUOTE: skipto(SQUOTE); break;
38:
39: case DQUOTE: skipto(DQUOTE); break;
40:
41: case DOLLAR: IF readc()==BRACE
42: THEN skipto('}');
43: FI
44: ENDSW
45: OD
46: IF c!=endch THEN error(badsub) FI
47: }
48:
49: LOCAL getch(endch)
50: CHAR endch;
51: {
52: REG CHAR d;
53:
54: retry:
55: d=readc();
56: IF !subchar(d)
57: THEN return(d);
58: FI
59: IF d==DOLLAR
60: THEN REG INT c;
61: IF (c=readc(), dolchar(c))
62: THEN NAMPTR n=NIL;
63: INT dolg=0;
64: BOOL bra;
65: REG STRING argp, v;
66: CHAR idb[2];
67: STRING id=idb;
68:
69: IF bra=(c==BRACE) THEN c=readc() FI
70: IF letter(c)
71: THEN argp=relstak();
72: WHILE alphanum(c) DO pushstak(c); c=readc() OD
73: zerostak();
74: n=lookup(absstak(argp)); setstak(argp);
75: v = n->namval; id = n->namid;
76: peekc = c|MARK;;
77: ELIF digchar(c)
78: THEN *id=c; idb[1]=0;
79: IF astchar(c)
80: THEN dolg=1; c='1';
81: FI
82: c -= '0';
83: v=((c==0) ? cmdadr : (c<=dolc) ? dolv[c] : (dolg=0));
84: ELIF c=='$'
85: THEN v=pidadr;
86: ELIF c=='!'
87: THEN v=pcsadr;
88: ELIF c=='#'
89: THEN v=dolladr;
90: ELIF c=='?'
91: THEN v=exitadr;
92: ELIF c=='-'
93: THEN v=flagadr;
94: ELIF bra THEN error(badsub);
95: ELSE goto retry;
96: FI
97: c = readc();
98: IF !defchar(c) ANDF bra
99: THEN error(badsub);
100: FI
101: argp=0;
102: IF bra
103: THEN IF c!='}'
104: THEN argp=relstak();
105: IF (v==0)NEQ(setchar(c))
106: THEN copyto('}');
107: ELSE skipto('}');
108: FI
109: argp=absstak(argp);
110: FI
111: ELSE peekc = c|MARK; c = 0;
112: FI
113: IF v
114: THEN IF c!='+'
115: THEN LOOP WHILE c = *v++
116: DO pushstak(c|quote); OD
117: IF dolg==0 ORF (++dolg>dolc)
118: THEN break;
119: ELSE v=dolv[dolg]; pushstak(SP|(*id=='*' ? quote : 0));
120: FI
121: POOL
122: FI
123: ELIF argp
124: THEN IF c=='?'
125: THEN failed(id,*argp?argp:badparam);
126: ELIF c=='='
127: THEN IF n
128: THEN assign(n,argp);
129: ELSE error(badsub);
130: FI
131: FI
132: ELIF flags&setflg
133: THEN failed(id,badparam);
134: FI
135: goto retry;
136: ELSE peekc=c|MARK;
137: FI
138: ELIF d==endch
139: THEN return(d);
140: ELIF d==SQUOTE
141: THEN comsubst(); goto retry;
142: ELIF d==DQUOTE
143: THEN quoted++; quote^=QUOTE; goto retry;
144: FI
145: return(d);
146: }
147:
148: STRING macro(as)
149: STRING as;
150: {
151: /* Strip "" and do $ substitution
152: * Leaves result on top of stack
153: */
154: REG BOOL savqu =quoted;
155: REG CHAR savq = quote;
156: FILEHDR fb;
157:
158: push(&fb); estabf(as);
159: usestak();
160: quote=0; quoted=0;
161: copyto(0);
162: pop();
163: IF quoted ANDF (stakbot==staktop) THEN pushstak(QUOTE) FI
164: quote=savq; quoted=savqu;
165: return(fixstak());
166: }
167:
168: LOCAL comsubst()
169: {
170: /* command substn */
171: FILEBLK cb;
172: REG CHAR d;
173: REG STKPTR savptr = fixstak();
174:
175: usestak();
176: WHILE (d=readc())!=SQUOTE ANDF d
177: DO pushstak(d) OD
178:
179: BEGIN
180: REG STRING argc;
181: trim(argc=fixstak());
182: push(&cb); estabf(argc);
183: END
184: BEGIN
185: REG TREPTR t = makefork(FPOU,cmd(EOFSYM,MTFLG|NLFLG));
186: INT pv[2];
187:
188: /* this is done like this so that the pipe
189: * is open only when needed
190: */
191: chkpipe(pv);
192: initf(pv[INPIPE]);
193: execute(t, 0, 0, pv);
194: close(pv[OTPIPE]);
195: END
196: tdystak(savptr); staktop=movstr(savptr,stakbot);
197: WHILE d=readc() DO pushstak(d|quote) OD
198: await(0);
199: WHILE stakbot!=staktop
200: DO IF (*--staktop&STRIP)!=NL
201: THEN ++staktop; break;
202: FI
203: OD
204: pop();
205: }
206:
207: #define CPYSIZ 512
208:
209: subst(in,ot)
210: INT in, ot;
211: {
212: REG CHAR c;
213: FILEBLK fb;
214: REG INT count=CPYSIZ;
215:
216: push(&fb); initf(in);
217: /* DQUOTE used to stop it from quoting */
218: WHILE c=(getch(DQUOTE)&STRIP)
219: DO pushstak(c);
220: IF --count == 0
221: THEN flush(ot); count=CPYSIZ;
222: FI
223: OD
224: flush(ot);
225: pop();
226: }
227:
228: LOCAL flush(ot)
229: {
230: write(ot,stakbot,staktop-stakbot);
231: IF flags&execpr THEN write(output,stakbot,staktop-stakbot) FI
232: staktop=stakbot;
233: }
Defined functions
getch
defined in line
49; used 2 times
Defined macros