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