Blame


1 f08fdedc 2003-11-23 devnull #include "rc.h"
2 f08fdedc 2003-11-23 devnull #include "exec.h"
3 f08fdedc 2003-11-23 devnull #include "io.h"
4 f08fdedc 2003-11-23 devnull #include "getflags.h"
5 f08fdedc 2003-11-23 devnull #include "fns.h"
6 f08fdedc 2003-11-23 devnull int getnext(void);
7 f08fdedc 2003-11-23 devnull int wordchr(int c)
8 f08fdedc 2003-11-23 devnull {
9 f08fdedc 2003-11-23 devnull return !strchr("\n \t#;&|^$=`'{}()<>", c) && c!=EOF;
10 f08fdedc 2003-11-23 devnull }
11 f08fdedc 2003-11-23 devnull int idchr(int c)
12 f08fdedc 2003-11-23 devnull {
13 f08fdedc 2003-11-23 devnull /*
14 f08fdedc 2003-11-23 devnull * Formerly:
15 f08fdedc 2003-11-23 devnull * return 'a'<=c && c<='z' || 'A'<=c && c<='Z' || '0'<=c && c<='9'
16 f08fdedc 2003-11-23 devnull * || c=='_' || c=='*';
17 f08fdedc 2003-11-23 devnull */
18 f08fdedc 2003-11-23 devnull return c>' ' && !strchr("!\"#$%&'()+,-./:;<=>?@[\\]^`{|}~", c);
19 f08fdedc 2003-11-23 devnull }
20 f08fdedc 2003-11-23 devnull int future=EOF;
21 f08fdedc 2003-11-23 devnull int doprompt=1;
22 f08fdedc 2003-11-23 devnull int inquote;
23 f08fdedc 2003-11-23 devnull /*
24 f08fdedc 2003-11-23 devnull * Look ahead in the input stream
25 f08fdedc 2003-11-23 devnull */
26 f08fdedc 2003-11-23 devnull int nextc(void){
27 f08fdedc 2003-11-23 devnull if(future==EOF) future=getnext();
28 f08fdedc 2003-11-23 devnull return future;
29 f08fdedc 2003-11-23 devnull }
30 f08fdedc 2003-11-23 devnull /*
31 f08fdedc 2003-11-23 devnull * Consume the lookahead character.
32 f08fdedc 2003-11-23 devnull */
33 f08fdedc 2003-11-23 devnull int advance(void){
34 f08fdedc 2003-11-23 devnull int c=nextc();
35 f08fdedc 2003-11-23 devnull lastc=future;
36 f08fdedc 2003-11-23 devnull future=EOF;
37 f08fdedc 2003-11-23 devnull return c;
38 f08fdedc 2003-11-23 devnull }
39 f08fdedc 2003-11-23 devnull /*
40 f08fdedc 2003-11-23 devnull * read a character from the input stream
41 f08fdedc 2003-11-23 devnull */
42 f08fdedc 2003-11-23 devnull int getnext(void){
43 f08fdedc 2003-11-23 devnull register int c;
44 f08fdedc 2003-11-23 devnull static int peekc=EOF;
45 f08fdedc 2003-11-23 devnull if(peekc!=EOF){
46 f08fdedc 2003-11-23 devnull c=peekc;
47 f08fdedc 2003-11-23 devnull peekc=EOF;
48 f08fdedc 2003-11-23 devnull return c;
49 f08fdedc 2003-11-23 devnull }
50 f08fdedc 2003-11-23 devnull if(runq->eof) return EOF;
51 f08fdedc 2003-11-23 devnull if(doprompt) pprompt();
52 f08fdedc 2003-11-23 devnull c=rchr(runq->cmdfd);
53 f08fdedc 2003-11-23 devnull if(!inquote && c=='\\'){
54 f08fdedc 2003-11-23 devnull c=rchr(runq->cmdfd);
55 f08fdedc 2003-11-23 devnull if(c=='\n'){
56 f08fdedc 2003-11-23 devnull doprompt=1;
57 f08fdedc 2003-11-23 devnull c=' ';
58 f08fdedc 2003-11-23 devnull }
59 f08fdedc 2003-11-23 devnull else{
60 f08fdedc 2003-11-23 devnull peekc=c;
61 f08fdedc 2003-11-23 devnull c='\\';
62 f08fdedc 2003-11-23 devnull }
63 f08fdedc 2003-11-23 devnull }
64 f08fdedc 2003-11-23 devnull doprompt=doprompt || c=='\n' || c==EOF;
65 f08fdedc 2003-11-23 devnull if(c==EOF) runq->eof++;
66 f08fdedc 2003-11-23 devnull else if(flag['V'] || ndot>=2 && flag['v']) pchr(err, c);
67 f08fdedc 2003-11-23 devnull return c;
68 f08fdedc 2003-11-23 devnull }
69 f08fdedc 2003-11-23 devnull void pprompt(void){
70 f08fdedc 2003-11-23 devnull var *prompt;
71 f08fdedc 2003-11-23 devnull if(runq->iflag){
72 f08fdedc 2003-11-23 devnull pstr(err, promptstr);
73 f08fdedc 2003-11-23 devnull flush(err);
74 f08fdedc 2003-11-23 devnull prompt=vlook("prompt");
75 f08fdedc 2003-11-23 devnull if(prompt->val && prompt->val->next)
76 f08fdedc 2003-11-23 devnull promptstr=prompt->val->next->word;
77 f08fdedc 2003-11-23 devnull else
78 f08fdedc 2003-11-23 devnull promptstr="\t";
79 f08fdedc 2003-11-23 devnull }
80 f08fdedc 2003-11-23 devnull runq->lineno++;
81 f08fdedc 2003-11-23 devnull doprompt=0;
82 f08fdedc 2003-11-23 devnull }
83 f08fdedc 2003-11-23 devnull void skipwhite(void){
84 f08fdedc 2003-11-23 devnull int c;
85 f08fdedc 2003-11-23 devnull for(;;){
86 f08fdedc 2003-11-23 devnull c=nextc();
87 f08fdedc 2003-11-23 devnull if(c=='#'){ /* Why did this used to be if(!inquote && c=='#') ?? */
88 f08fdedc 2003-11-23 devnull for(;;){
89 f08fdedc 2003-11-23 devnull c=nextc();
90 f08fdedc 2003-11-23 devnull if(c=='\n' || c==EOF) break;
91 f08fdedc 2003-11-23 devnull advance();
92 f08fdedc 2003-11-23 devnull }
93 f08fdedc 2003-11-23 devnull }
94 f08fdedc 2003-11-23 devnull if(c==' ' || c=='\t') advance();
95 f08fdedc 2003-11-23 devnull else return;
96 f08fdedc 2003-11-23 devnull }
97 f08fdedc 2003-11-23 devnull }
98 f08fdedc 2003-11-23 devnull void skipnl(void){
99 f08fdedc 2003-11-23 devnull register int c;
100 f08fdedc 2003-11-23 devnull for(;;){
101 f08fdedc 2003-11-23 devnull skipwhite();
102 f08fdedc 2003-11-23 devnull c=nextc();
103 f08fdedc 2003-11-23 devnull if(c!='\n') return;
104 f08fdedc 2003-11-23 devnull advance();
105 f08fdedc 2003-11-23 devnull }
106 f08fdedc 2003-11-23 devnull }
107 f08fdedc 2003-11-23 devnull int nextis(int c){
108 f08fdedc 2003-11-23 devnull if(nextc()==c){
109 f08fdedc 2003-11-23 devnull advance();
110 f08fdedc 2003-11-23 devnull return 1;
111 f08fdedc 2003-11-23 devnull }
112 f08fdedc 2003-11-23 devnull return 0;
113 f08fdedc 2003-11-23 devnull }
114 f08fdedc 2003-11-23 devnull char *addtok(char *p, int val){
115 f08fdedc 2003-11-23 devnull if(p==0) return 0;
116 17157e4a 2006-03-20 devnull if(p==&tok[NTOK-1]){
117 f08fdedc 2003-11-23 devnull *p=0;
118 f08fdedc 2003-11-23 devnull yyerror("token buffer too short");
119 f08fdedc 2003-11-23 devnull return 0;
120 f08fdedc 2003-11-23 devnull }
121 f08fdedc 2003-11-23 devnull *p++=val;
122 f08fdedc 2003-11-23 devnull return p;
123 f08fdedc 2003-11-23 devnull }
124 f08fdedc 2003-11-23 devnull char *addutf(char *p, int c){
125 f08fdedc 2003-11-23 devnull p=addtok(p, c);
126 f08fdedc 2003-11-23 devnull if(twobyte(c)) /* 2-byte escape */
127 f08fdedc 2003-11-23 devnull return addtok(p, advance());
128 f08fdedc 2003-11-23 devnull if(threebyte(c)){ /* 3-byte escape */
129 f08fdedc 2003-11-23 devnull p=addtok(p, advance());
130 f08fdedc 2003-11-23 devnull return addtok(p, advance());
131 f08fdedc 2003-11-23 devnull }
132 f08fdedc 2003-11-23 devnull return p;
133 f08fdedc 2003-11-23 devnull }
134 f08fdedc 2003-11-23 devnull int lastdol; /* was the last token read '$' or '$#' or '"'? */
135 f08fdedc 2003-11-23 devnull int lastword; /* was the last token read a word or compound word terminator? */
136 f08fdedc 2003-11-23 devnull int yylex(void){
137 f08fdedc 2003-11-23 devnull register int c, d=nextc();
138 f08fdedc 2003-11-23 devnull register char *w=tok;
139 f08fdedc 2003-11-23 devnull register struct tree *t;
140 f08fdedc 2003-11-23 devnull yylval.tree=0;
141 f08fdedc 2003-11-23 devnull /*
142 f08fdedc 2003-11-23 devnull * Embarassing sneakiness: if the last token read was a quoted or unquoted
143 f08fdedc 2003-11-23 devnull * WORD then we alter the meaning of what follows. If the next character
144 f08fdedc 2003-11-23 devnull * is `(', we return SUB (a subscript paren) and consume the `('. Otherwise,
145 f08fdedc 2003-11-23 devnull * if the next character is the first character of a simple or compound word,
146 f08fdedc 2003-11-23 devnull * we insert a `^' before it.
147 f08fdedc 2003-11-23 devnull */
148 f08fdedc 2003-11-23 devnull if(lastword){
149 f08fdedc 2003-11-23 devnull lastword=0;
150 f08fdedc 2003-11-23 devnull if(d=='('){
151 f08fdedc 2003-11-23 devnull advance();
152 f08fdedc 2003-11-23 devnull strcpy(tok, "( [SUB]");
153 f08fdedc 2003-11-23 devnull return SUB;
154 f08fdedc 2003-11-23 devnull }
155 f08fdedc 2003-11-23 devnull if(wordchr(d) || d=='\'' || d=='`' || d=='$' || d=='"'){
156 f08fdedc 2003-11-23 devnull strcpy(tok, "^");
157 f08fdedc 2003-11-23 devnull return '^';
158 f08fdedc 2003-11-23 devnull }
159 f08fdedc 2003-11-23 devnull }
160 f08fdedc 2003-11-23 devnull inquote=0;
161 f08fdedc 2003-11-23 devnull skipwhite();
162 f08fdedc 2003-11-23 devnull switch(c=advance()){
163 f08fdedc 2003-11-23 devnull case EOF:
164 f08fdedc 2003-11-23 devnull lastdol=0;
165 f08fdedc 2003-11-23 devnull strcpy(tok, "EOF");
166 f08fdedc 2003-11-23 devnull return EOF;
167 f08fdedc 2003-11-23 devnull case '$':
168 f08fdedc 2003-11-23 devnull lastdol=1;
169 f08fdedc 2003-11-23 devnull if(nextis('#')){
170 f08fdedc 2003-11-23 devnull strcpy(tok, "$#");
171 f08fdedc 2003-11-23 devnull return COUNT;
172 f08fdedc 2003-11-23 devnull }
173 f08fdedc 2003-11-23 devnull if(nextis('"')){
174 f08fdedc 2003-11-23 devnull strcpy(tok, "$\"");
175 f08fdedc 2003-11-23 devnull return '"';
176 f08fdedc 2003-11-23 devnull }
177 f08fdedc 2003-11-23 devnull strcpy(tok, "$");
178 f08fdedc 2003-11-23 devnull return '$';
179 f08fdedc 2003-11-23 devnull case '&':
180 f08fdedc 2003-11-23 devnull lastdol=0;
181 f08fdedc 2003-11-23 devnull if(nextis('&')){
182 f08fdedc 2003-11-23 devnull skipnl();
183 f08fdedc 2003-11-23 devnull strcpy(tok, "&&");
184 f08fdedc 2003-11-23 devnull return ANDAND;
185 f08fdedc 2003-11-23 devnull }
186 f08fdedc 2003-11-23 devnull strcpy(tok, "&");
187 f08fdedc 2003-11-23 devnull return '&';
188 f08fdedc 2003-11-23 devnull case '|':
189 f08fdedc 2003-11-23 devnull lastdol=0;
190 f08fdedc 2003-11-23 devnull if(nextis(c)){
191 f08fdedc 2003-11-23 devnull skipnl();
192 f08fdedc 2003-11-23 devnull strcpy(tok, "||");
193 f08fdedc 2003-11-23 devnull return OROR;
194 f08fdedc 2003-11-23 devnull }
195 f08fdedc 2003-11-23 devnull case '<':
196 f08fdedc 2003-11-23 devnull case '>':
197 f08fdedc 2003-11-23 devnull lastdol=0;
198 f08fdedc 2003-11-23 devnull /*
199 f08fdedc 2003-11-23 devnull * funny redirection tokens:
200 f08fdedc 2003-11-23 devnull * redir: arrow | arrow '[' fd ']'
201 f08fdedc 2003-11-23 devnull * arrow: '<' | '<<' | '>' | '>>' | '|'
202 f08fdedc 2003-11-23 devnull * fd: digit | digit '=' | digit '=' digit
203 f08fdedc 2003-11-23 devnull * digit: '0'|'1'|'2'|'3'|'4'|'5'|'6'|'7'|'8'|'9'
204 f08fdedc 2003-11-23 devnull * some possibilities are nonsensical and get a message.
205 f08fdedc 2003-11-23 devnull */
206 f08fdedc 2003-11-23 devnull *w++=c;
207 f08fdedc 2003-11-23 devnull t=newtree();
208 f08fdedc 2003-11-23 devnull switch(c){
209 f08fdedc 2003-11-23 devnull case '|':
210 f08fdedc 2003-11-23 devnull t->type=PIPE;
211 f08fdedc 2003-11-23 devnull t->fd0=1;
212 f08fdedc 2003-11-23 devnull t->fd1=0;
213 f08fdedc 2003-11-23 devnull break;
214 f08fdedc 2003-11-23 devnull case '>':
215 f08fdedc 2003-11-23 devnull t->type=REDIR;
216 f08fdedc 2003-11-23 devnull if(nextis(c)){
217 f08fdedc 2003-11-23 devnull t->rtype=APPEND;
218 f08fdedc 2003-11-23 devnull *w++=c;
219 f08fdedc 2003-11-23 devnull }
220 f08fdedc 2003-11-23 devnull else t->rtype=WRITE;
221 f08fdedc 2003-11-23 devnull t->fd0=1;
222 f08fdedc 2003-11-23 devnull break;
223 f08fdedc 2003-11-23 devnull case '<':
224 f08fdedc 2003-11-23 devnull t->type=REDIR;
225 f08fdedc 2003-11-23 devnull if(nextis(c)){
226 f08fdedc 2003-11-23 devnull t->rtype=HERE;
227 f08fdedc 2003-11-23 devnull *w++=c;
228 f08fdedc 2003-11-23 devnull }
229 f08fdedc 2003-11-23 devnull else t->rtype=READ;
230 f08fdedc 2003-11-23 devnull t->fd0=0;
231 f08fdedc 2003-11-23 devnull break;
232 f08fdedc 2003-11-23 devnull }
233 f08fdedc 2003-11-23 devnull if(nextis('[')){
234 f08fdedc 2003-11-23 devnull *w++='[';
235 f08fdedc 2003-11-23 devnull c=advance();
236 f08fdedc 2003-11-23 devnull if(c<'0' || '9'<c){
237 f08fdedc 2003-11-23 devnull RedirErr:
238 168518a9 2005-03-18 devnull *w++ = c;
239 f08fdedc 2003-11-23 devnull *w=0;
240 f08fdedc 2003-11-23 devnull yyerror(t->type==PIPE?"pipe syntax"
241 f08fdedc 2003-11-23 devnull :"redirection syntax");
242 f08fdedc 2003-11-23 devnull return EOF;
243 f08fdedc 2003-11-23 devnull }
244 f08fdedc 2003-11-23 devnull t->fd0=0;
245 f08fdedc 2003-11-23 devnull do{
246 f08fdedc 2003-11-23 devnull t->fd0=t->fd0*10+c-'0';
247 f08fdedc 2003-11-23 devnull *w++=c;
248 f08fdedc 2003-11-23 devnull c=advance();
249 f08fdedc 2003-11-23 devnull }while('0'<=c && c<='9');
250 f08fdedc 2003-11-23 devnull if(c=='='){
251 f08fdedc 2003-11-23 devnull *w++='=';
252 f08fdedc 2003-11-23 devnull if(t->type==REDIR) t->type=DUP;
253 f08fdedc 2003-11-23 devnull c=advance();
254 f08fdedc 2003-11-23 devnull if('0'<=c && c<='9'){
255 f08fdedc 2003-11-23 devnull t->rtype=DUPFD;
256 f08fdedc 2003-11-23 devnull t->fd1=t->fd0;
257 f08fdedc 2003-11-23 devnull t->fd0=0;
258 f08fdedc 2003-11-23 devnull do{
259 f08fdedc 2003-11-23 devnull t->fd0=t->fd0*10+c-'0';
260 f08fdedc 2003-11-23 devnull *w++=c;
261 f08fdedc 2003-11-23 devnull c=advance();
262 f08fdedc 2003-11-23 devnull }while('0'<=c && c<='9');
263 f08fdedc 2003-11-23 devnull }
264 f08fdedc 2003-11-23 devnull else{
265 f08fdedc 2003-11-23 devnull if(t->type==PIPE) goto RedirErr;
266 f08fdedc 2003-11-23 devnull t->rtype=CLOSE;
267 f08fdedc 2003-11-23 devnull }
268 f08fdedc 2003-11-23 devnull }
269 168518a9 2005-03-18 devnull *w=0;
270 f08fdedc 2003-11-23 devnull if(c!=']'
271 f08fdedc 2003-11-23 devnull || t->type==DUP && (t->rtype==HERE || t->rtype==APPEND))
272 f08fdedc 2003-11-23 devnull goto RedirErr;
273 f08fdedc 2003-11-23 devnull *w++=']';
274 f08fdedc 2003-11-23 devnull }
275 f08fdedc 2003-11-23 devnull *w='\0';
276 f08fdedc 2003-11-23 devnull yylval.tree=t;
277 f08fdedc 2003-11-23 devnull if(t->type==PIPE) skipnl();
278 f08fdedc 2003-11-23 devnull return t->type;
279 f08fdedc 2003-11-23 devnull case '\'':
280 f08fdedc 2003-11-23 devnull lastdol=0;
281 f08fdedc 2003-11-23 devnull lastword=1;
282 f08fdedc 2003-11-23 devnull inquote=1;
283 f08fdedc 2003-11-23 devnull for(;;){
284 f08fdedc 2003-11-23 devnull c=advance();
285 f08fdedc 2003-11-23 devnull if(c==EOF) break;
286 f08fdedc 2003-11-23 devnull if(c=='\''){
287 f08fdedc 2003-11-23 devnull if(nextc()!='\'')
288 f08fdedc 2003-11-23 devnull break;
289 f08fdedc 2003-11-23 devnull advance();
290 f08fdedc 2003-11-23 devnull }
291 f08fdedc 2003-11-23 devnull w=addutf(w, c);
292 f08fdedc 2003-11-23 devnull }
293 f08fdedc 2003-11-23 devnull if(w!=0) *w='\0';
294 f08fdedc 2003-11-23 devnull t=token(tok, WORD);
295 f08fdedc 2003-11-23 devnull t->quoted=1;
296 f08fdedc 2003-11-23 devnull yylval.tree=t;
297 f08fdedc 2003-11-23 devnull return t->type;
298 f08fdedc 2003-11-23 devnull }
299 f08fdedc 2003-11-23 devnull if(!wordchr(c)){
300 f08fdedc 2003-11-23 devnull lastdol=0;
301 f08fdedc 2003-11-23 devnull tok[0]=c;
302 f08fdedc 2003-11-23 devnull tok[1]='\0';
303 f08fdedc 2003-11-23 devnull return c;
304 f08fdedc 2003-11-23 devnull }
305 f08fdedc 2003-11-23 devnull for(;;){
306 f08fdedc 2003-11-23 devnull /* next line should have (char)c==GLOB, but ken's compiler is broken */
307 f08fdedc 2003-11-23 devnull if(c=='*' || c=='[' || c=='?' || c==(unsigned char)GLOB)
308 f08fdedc 2003-11-23 devnull w=addtok(w, GLOB);
309 f08fdedc 2003-11-23 devnull w=addutf(w, c);
310 f08fdedc 2003-11-23 devnull c=nextc();
311 f08fdedc 2003-11-23 devnull if(lastdol?!idchr(c):!wordchr(c)) break;
312 f08fdedc 2003-11-23 devnull advance();
313 f08fdedc 2003-11-23 devnull }
314 f08fdedc 2003-11-23 devnull
315 f08fdedc 2003-11-23 devnull lastword=1;
316 f08fdedc 2003-11-23 devnull lastdol=0;
317 f08fdedc 2003-11-23 devnull if(w!=0) *w='\0';
318 f08fdedc 2003-11-23 devnull t=klook(tok);
319 f08fdedc 2003-11-23 devnull if(t->type!=WORD) lastword=0;
320 f08fdedc 2003-11-23 devnull t->quoted=0;
321 f08fdedc 2003-11-23 devnull yylval.tree=t;
322 f08fdedc 2003-11-23 devnull return t->type;
323 f08fdedc 2003-11-23 devnull }
324 168518a9 2005-03-18 devnull