1 | #define Extern extern
|
---|
2 | #include <sys/types.h>
|
---|
3 | #include <signal.h>
|
---|
4 | #include <errno.h>
|
---|
5 | #include <setjmp.h>
|
---|
6 | #include "sh.h"
|
---|
7 |
|
---|
8 | /* -------- csyn.c -------- */
|
---|
9 | /*
|
---|
10 | * shell: syntax (C version)
|
---|
11 | */
|
---|
12 |
|
---|
13 | typedef union {
|
---|
14 | char *cp;
|
---|
15 | char **wp;
|
---|
16 | int i;
|
---|
17 | struct op *o;
|
---|
18 | } YYSTYPE;
|
---|
19 | #define WORD 256
|
---|
20 | #define LOGAND 257
|
---|
21 | #define LOGOR 258
|
---|
22 | #define BREAK 259
|
---|
23 | #define IF 260
|
---|
24 | #define THEN 261
|
---|
25 | #define ELSE 262
|
---|
26 | #define ELIF 263
|
---|
27 | #define FI 264
|
---|
28 | #define CASE 265
|
---|
29 | #define ESAC 266
|
---|
30 | #define FOR 267
|
---|
31 | #define WHILE 268
|
---|
32 | #define UNTIL 269
|
---|
33 | #define DO 270
|
---|
34 | #define DONE 271
|
---|
35 | #define IN 272
|
---|
36 | #define YYERRCODE 300
|
---|
37 |
|
---|
38 | /* flags to yylex */
|
---|
39 | #define CONTIN 01 /* skip new lines to complete command */
|
---|
40 |
|
---|
41 | /* #include "sh.h" */
|
---|
42 | #define SYNTAXERR zzerr()
|
---|
43 | static int startl;
|
---|
44 | static int peeksym;
|
---|
45 | static int nlseen;
|
---|
46 | static int iounit = IODEFAULT;
|
---|
47 |
|
---|
48 | static YYSTYPE yylval;
|
---|
49 |
|
---|
50 | _PROTOTYPE(static struct op *pipeline, (int cf ));
|
---|
51 | _PROTOTYPE(static struct op *andor, (void));
|
---|
52 | _PROTOTYPE(static struct op *c_list, (void));
|
---|
53 | _PROTOTYPE(static int synio, (int cf ));
|
---|
54 | _PROTOTYPE(static void musthave, (int c, int cf ));
|
---|
55 | _PROTOTYPE(static struct op *simple, (void));
|
---|
56 | _PROTOTYPE(static struct op *nested, (int type, int mark ));
|
---|
57 | _PROTOTYPE(static struct op *command, (int cf ));
|
---|
58 | _PROTOTYPE(static struct op *dogroup, (int onlydone ));
|
---|
59 | _PROTOTYPE(static struct op *thenpart, (void));
|
---|
60 | _PROTOTYPE(static struct op *elsepart, (void));
|
---|
61 | _PROTOTYPE(static struct op *caselist, (void));
|
---|
62 | _PROTOTYPE(static struct op *casepart, (void));
|
---|
63 | _PROTOTYPE(static char **pattern, (void));
|
---|
64 | _PROTOTYPE(static char **wordlist, (void));
|
---|
65 | _PROTOTYPE(static struct op *list, (struct op *t1, struct op *t2 ));
|
---|
66 | _PROTOTYPE(static struct op *block, (int type, struct op *t1, struct op *t2, char **wp ));
|
---|
67 | _PROTOTYPE(static struct op *newtp, (void));
|
---|
68 | _PROTOTYPE(static struct op *namelist, (struct op *t ));
|
---|
69 | _PROTOTYPE(static char **copyw, (void));
|
---|
70 | _PROTOTYPE(static void word, (char *cp ));
|
---|
71 | _PROTOTYPE(static struct ioword **copyio, (void));
|
---|
72 | _PROTOTYPE(static struct ioword *io, (int u, int f, char *cp ));
|
---|
73 | _PROTOTYPE(static void zzerr, (void));
|
---|
74 | _PROTOTYPE(void yyerror, (char *s ));
|
---|
75 | _PROTOTYPE(static int yylex, (int cf ));
|
---|
76 | _PROTOTYPE(int collect, (int c, int c1 ));
|
---|
77 | _PROTOTYPE(int dual, (int c ));
|
---|
78 | _PROTOTYPE(static void diag, (int ec ));
|
---|
79 | _PROTOTYPE(static char *tree, (unsigned size ));
|
---|
80 | _PROTOTYPE(void printf, (char *s ));
|
---|
81 |
|
---|
82 | int
|
---|
83 | yyparse()
|
---|
84 | {
|
---|
85 | startl = 1;
|
---|
86 | peeksym = 0;
|
---|
87 | yynerrs = 0;
|
---|
88 | outtree = c_list();
|
---|
89 | musthave('\n', 0);
|
---|
90 | return(yynerrs!=0);
|
---|
91 | }
|
---|
92 |
|
---|
93 | static struct op *
|
---|
94 | pipeline(cf)
|
---|
95 | int cf;
|
---|
96 | {
|
---|
97 | register struct op *t, *p;
|
---|
98 | register int c;
|
---|
99 |
|
---|
100 | t = command(cf);
|
---|
101 | if (t != NULL) {
|
---|
102 | while ((c = yylex(0)) == '|') {
|
---|
103 | if ((p = command(CONTIN)) == NULL)
|
---|
104 | SYNTAXERR;
|
---|
105 | if (t->type != TPAREN && t->type != TCOM) {
|
---|
106 | /* shell statement */
|
---|
107 | t = block(TPAREN, t, NOBLOCK, NOWORDS);
|
---|
108 | }
|
---|
109 | t = block(TPIPE, t, p, NOWORDS);
|
---|
110 | }
|
---|
111 | peeksym = c;
|
---|
112 | }
|
---|
113 | return(t);
|
---|
114 | }
|
---|
115 |
|
---|
116 | static struct op *
|
---|
117 | andor()
|
---|
118 | {
|
---|
119 | register struct op *t, *p;
|
---|
120 | register int c;
|
---|
121 |
|
---|
122 | t = pipeline(0);
|
---|
123 | if (t != NULL) {
|
---|
124 | while ((c = yylex(0)) == LOGAND || c == LOGOR) {
|
---|
125 | if ((p = pipeline(CONTIN)) == NULL)
|
---|
126 | SYNTAXERR;
|
---|
127 | t = block(c == LOGAND? TAND: TOR, t, p, NOWORDS);
|
---|
128 | }
|
---|
129 | peeksym = c;
|
---|
130 | }
|
---|
131 | return(t);
|
---|
132 | }
|
---|
133 |
|
---|
134 | static struct op *
|
---|
135 | c_list()
|
---|
136 | {
|
---|
137 | register struct op *t, *p;
|
---|
138 | register int c;
|
---|
139 |
|
---|
140 | t = andor();
|
---|
141 | if (t != NULL) {
|
---|
142 | if((peeksym = yylex(0)) == '&')
|
---|
143 | t = block(TASYNC, t, NOBLOCK, NOWORDS);
|
---|
144 | while ((c = yylex(0)) == ';' || c == '&' || (multiline && c == '\n')) {
|
---|
145 | if ((p = andor()) == NULL)
|
---|
146 | return(t);
|
---|
147 | if((peeksym = yylex(0)) == '&')
|
---|
148 | p = block(TASYNC, p, NOBLOCK, NOWORDS);
|
---|
149 | t = list(t, p);
|
---|
150 | }
|
---|
151 | peeksym = c;
|
---|
152 | }
|
---|
153 | return(t);
|
---|
154 | }
|
---|
155 |
|
---|
156 |
|
---|
157 | static int
|
---|
158 | synio(cf)
|
---|
159 | int cf;
|
---|
160 | {
|
---|
161 | register struct ioword *iop;
|
---|
162 | register int i;
|
---|
163 | register int c;
|
---|
164 |
|
---|
165 | if ((c = yylex(cf)) != '<' && c != '>') {
|
---|
166 | peeksym = c;
|
---|
167 | return(0);
|
---|
168 | }
|
---|
169 | i = yylval.i;
|
---|
170 | musthave(WORD, 0);
|
---|
171 | iop = io(iounit, i, yylval.cp);
|
---|
172 | iounit = IODEFAULT;
|
---|
173 | if (i & IOHERE)
|
---|
174 | markhere(yylval.cp, iop);
|
---|
175 | return(1);
|
---|
176 | }
|
---|
177 |
|
---|
178 | static void
|
---|
179 | musthave(c, cf)
|
---|
180 | int c, cf;
|
---|
181 | {
|
---|
182 | if ((peeksym = yylex(cf)) != c)
|
---|
183 | SYNTAXERR;
|
---|
184 | peeksym = 0;
|
---|
185 | }
|
---|
186 |
|
---|
187 | static struct op *
|
---|
188 | simple()
|
---|
189 | {
|
---|
190 | register struct op *t;
|
---|
191 |
|
---|
192 | t = NULL;
|
---|
193 | for (;;) {
|
---|
194 | switch (peeksym = yylex(0)) {
|
---|
195 | case '<':
|
---|
196 | case '>':
|
---|
197 | (void) synio(0);
|
---|
198 | break;
|
---|
199 |
|
---|
200 | case WORD:
|
---|
201 | if (t == NULL) {
|
---|
202 | t = newtp();
|
---|
203 | t->type = TCOM;
|
---|
204 | }
|
---|
205 | peeksym = 0;
|
---|
206 | word(yylval.cp);
|
---|
207 | break;
|
---|
208 |
|
---|
209 | default:
|
---|
210 | return(t);
|
---|
211 | }
|
---|
212 | }
|
---|
213 | }
|
---|
214 |
|
---|
215 | static struct op *
|
---|
216 | nested(type, mark)
|
---|
217 | int type, mark;
|
---|
218 | {
|
---|
219 | register struct op *t;
|
---|
220 |
|
---|
221 | multiline++;
|
---|
222 | t = c_list();
|
---|
223 | musthave(mark, 0);
|
---|
224 | multiline--;
|
---|
225 | return(block(type, t, NOBLOCK, NOWORDS));
|
---|
226 | }
|
---|
227 |
|
---|
228 | static struct op *
|
---|
229 | command(cf)
|
---|
230 | int cf;
|
---|
231 | {
|
---|
232 | register struct op *t;
|
---|
233 | struct wdblock *iosave;
|
---|
234 | register int c;
|
---|
235 |
|
---|
236 | iosave = iolist;
|
---|
237 | iolist = NULL;
|
---|
238 | if (multiline)
|
---|
239 | cf |= CONTIN;
|
---|
240 | while (synio(cf))
|
---|
241 | cf = 0;
|
---|
242 | switch (c = yylex(cf)) {
|
---|
243 | default:
|
---|
244 | peeksym = c;
|
---|
245 | if ((t = simple()) == NULL) {
|
---|
246 | if (iolist == NULL)
|
---|
247 | return((struct op *)NULL);
|
---|
248 | t = newtp();
|
---|
249 | t->type = TCOM;
|
---|
250 | }
|
---|
251 | break;
|
---|
252 |
|
---|
253 | case '(':
|
---|
254 | t = nested(TPAREN, ')');
|
---|
255 | break;
|
---|
256 |
|
---|
257 | case '{':
|
---|
258 | t = nested(TBRACE, '}');
|
---|
259 | break;
|
---|
260 |
|
---|
261 | case FOR:
|
---|
262 | t = newtp();
|
---|
263 | t->type = TFOR;
|
---|
264 | musthave(WORD, 0);
|
---|
265 | startl = 1;
|
---|
266 | t->str = yylval.cp;
|
---|
267 | multiline++;
|
---|
268 | t->words = wordlist();
|
---|
269 | if ((c = yylex(0)) != '\n' && c != ';')
|
---|
270 | peeksym = c;
|
---|
271 | t->left = dogroup(0);
|
---|
272 | multiline--;
|
---|
273 | break;
|
---|
274 |
|
---|
275 | case WHILE:
|
---|
276 | case UNTIL:
|
---|
277 | multiline++;
|
---|
278 | t = newtp();
|
---|
279 | t->type = c == WHILE? TWHILE: TUNTIL;
|
---|
280 | t->left = c_list();
|
---|
281 | t->right = dogroup(1);
|
---|
282 | t->words = NULL;
|
---|
283 | multiline--;
|
---|
284 | break;
|
---|
285 |
|
---|
286 | case CASE:
|
---|
287 | t = newtp();
|
---|
288 | t->type = TCASE;
|
---|
289 | musthave(WORD, 0);
|
---|
290 | t->str = yylval.cp;
|
---|
291 | startl++;
|
---|
292 | multiline++;
|
---|
293 | musthave(IN, CONTIN);
|
---|
294 | startl++;
|
---|
295 | t->left = caselist();
|
---|
296 | musthave(ESAC, 0);
|
---|
297 | multiline--;
|
---|
298 | break;
|
---|
299 |
|
---|
300 | case IF:
|
---|
301 | multiline++;
|
---|
302 | t = newtp();
|
---|
303 | t->type = TIF;
|
---|
304 | t->left = c_list();
|
---|
305 | t->right = thenpart();
|
---|
306 | musthave(FI, 0);
|
---|
307 | multiline--;
|
---|
308 | break;
|
---|
309 | }
|
---|
310 | while (synio(0))
|
---|
311 | ;
|
---|
312 | t = namelist(t);
|
---|
313 | iolist = iosave;
|
---|
314 | return(t);
|
---|
315 | }
|
---|
316 |
|
---|
317 | static struct op *
|
---|
318 | dogroup(onlydone)
|
---|
319 | int onlydone;
|
---|
320 | {
|
---|
321 | register int c;
|
---|
322 | register struct op *list;
|
---|
323 |
|
---|
324 | c = yylex(CONTIN);
|
---|
325 | if (c == DONE && onlydone)
|
---|
326 | return((struct op *)NULL);
|
---|
327 | if (c != DO)
|
---|
328 | SYNTAXERR;
|
---|
329 | list = c_list();
|
---|
330 | musthave(DONE, 0);
|
---|
331 | return(list);
|
---|
332 | }
|
---|
333 |
|
---|
334 | static struct op *
|
---|
335 | thenpart()
|
---|
336 | {
|
---|
337 | register int c;
|
---|
338 | register struct op *t;
|
---|
339 |
|
---|
340 | if ((c = yylex(0)) != THEN) {
|
---|
341 | peeksym = c;
|
---|
342 | return((struct op *)NULL);
|
---|
343 | }
|
---|
344 | t = newtp();
|
---|
345 | t->type = 0;
|
---|
346 | t->left = c_list();
|
---|
347 | if (t->left == NULL)
|
---|
348 | SYNTAXERR;
|
---|
349 | t->right = elsepart();
|
---|
350 | return(t);
|
---|
351 | }
|
---|
352 |
|
---|
353 | static struct op *
|
---|
354 | elsepart()
|
---|
355 | {
|
---|
356 | register int c;
|
---|
357 | register struct op *t;
|
---|
358 |
|
---|
359 | switch (c = yylex(0)) {
|
---|
360 | case ELSE:
|
---|
361 | if ((t = c_list()) == NULL)
|
---|
362 | SYNTAXERR;
|
---|
363 | return(t);
|
---|
364 |
|
---|
365 | case ELIF:
|
---|
366 | t = newtp();
|
---|
367 | t->type = TELIF;
|
---|
368 | t->left = c_list();
|
---|
369 | t->right = thenpart();
|
---|
370 | return(t);
|
---|
371 |
|
---|
372 | default:
|
---|
373 | peeksym = c;
|
---|
374 | return((struct op *)NULL);
|
---|
375 | }
|
---|
376 | }
|
---|
377 |
|
---|
378 | static struct op *
|
---|
379 | caselist()
|
---|
380 | {
|
---|
381 | register struct op *t;
|
---|
382 |
|
---|
383 | t = NULL;
|
---|
384 | while ((peeksym = yylex(CONTIN)) != ESAC)
|
---|
385 | t = list(t, casepart());
|
---|
386 | return(t);
|
---|
387 | }
|
---|
388 |
|
---|
389 | static struct op *
|
---|
390 | casepart()
|
---|
391 | {
|
---|
392 | register struct op *t;
|
---|
393 |
|
---|
394 | t = newtp();
|
---|
395 | t->type = TPAT;
|
---|
396 | t->words = pattern();
|
---|
397 | musthave(')', 0);
|
---|
398 | t->left = c_list();
|
---|
399 | if ((peeksym = yylex(CONTIN)) != ESAC)
|
---|
400 | musthave(BREAK, CONTIN);
|
---|
401 | return(t);
|
---|
402 | }
|
---|
403 |
|
---|
404 | static char **
|
---|
405 | pattern()
|
---|
406 | {
|
---|
407 | register int c, cf;
|
---|
408 |
|
---|
409 | cf = CONTIN;
|
---|
410 | do {
|
---|
411 | musthave(WORD, cf);
|
---|
412 | word(yylval.cp);
|
---|
413 | cf = 0;
|
---|
414 | } while ((c = yylex(0)) == '|');
|
---|
415 | peeksym = c;
|
---|
416 | word(NOWORD);
|
---|
417 | return(copyw());
|
---|
418 | }
|
---|
419 |
|
---|
420 | static char **
|
---|
421 | wordlist()
|
---|
422 | {
|
---|
423 | register int c;
|
---|
424 |
|
---|
425 | if ((c = yylex(0)) != IN) {
|
---|
426 | peeksym = c;
|
---|
427 | return((char **)NULL);
|
---|
428 | }
|
---|
429 | startl = 0;
|
---|
430 | while ((c = yylex(0)) == WORD)
|
---|
431 | word(yylval.cp);
|
---|
432 | word(NOWORD);
|
---|
433 | peeksym = c;
|
---|
434 | return(copyw());
|
---|
435 | }
|
---|
436 |
|
---|
437 | /*
|
---|
438 | * supporting functions
|
---|
439 | */
|
---|
440 | static struct op *
|
---|
441 | list(t1, t2)
|
---|
442 | register struct op *t1, *t2;
|
---|
443 | {
|
---|
444 | if (t1 == NULL)
|
---|
445 | return(t2);
|
---|
446 | if (t2 == NULL)
|
---|
447 | return(t1);
|
---|
448 | return(block(TLIST, t1, t2, NOWORDS));
|
---|
449 | }
|
---|
450 |
|
---|
451 | static struct op *
|
---|
452 | block(type, t1, t2, wp)
|
---|
453 | int type;
|
---|
454 | struct op *t1, *t2;
|
---|
455 | char **wp;
|
---|
456 | {
|
---|
457 | register struct op *t;
|
---|
458 |
|
---|
459 | t = newtp();
|
---|
460 | t->type = type;
|
---|
461 | t->left = t1;
|
---|
462 | t->right = t2;
|
---|
463 | t->words = wp;
|
---|
464 | return(t);
|
---|
465 | }
|
---|
466 |
|
---|
467 | struct res {
|
---|
468 | char *r_name;
|
---|
469 | int r_val;
|
---|
470 | } restab[] = {
|
---|
471 | "for", FOR,
|
---|
472 | "case", CASE,
|
---|
473 | "esac", ESAC,
|
---|
474 | "while", WHILE,
|
---|
475 | "do", DO,
|
---|
476 | "done", DONE,
|
---|
477 | "if", IF,
|
---|
478 | "in", IN,
|
---|
479 | "then", THEN,
|
---|
480 | "else", ELSE,
|
---|
481 | "elif", ELIF,
|
---|
482 | "until", UNTIL,
|
---|
483 | "fi", FI,
|
---|
484 |
|
---|
485 | ";;", BREAK,
|
---|
486 | "||", LOGOR,
|
---|
487 | "&&", LOGAND,
|
---|
488 | "{", '{',
|
---|
489 | "}", '}',
|
---|
490 |
|
---|
491 | 0,
|
---|
492 | };
|
---|
493 |
|
---|
494 | int
|
---|
495 | rlookup(n)
|
---|
496 | register char *n;
|
---|
497 | {
|
---|
498 | register struct res *rp;
|
---|
499 |
|
---|
500 | for (rp = restab; rp->r_name; rp++)
|
---|
501 | if (strcmp(rp->r_name, n) == 0)
|
---|
502 | return(rp->r_val);
|
---|
503 | return(0);
|
---|
504 | }
|
---|
505 |
|
---|
506 | static struct op *
|
---|
507 | newtp()
|
---|
508 | {
|
---|
509 | register struct op *t;
|
---|
510 |
|
---|
511 | t = (struct op *)tree(sizeof(*t));
|
---|
512 | t->type = 0;
|
---|
513 | t->words = NULL;
|
---|
514 | t->ioact = NULL;
|
---|
515 | t->left = NULL;
|
---|
516 | t->right = NULL;
|
---|
517 | t->str = NULL;
|
---|
518 | return(t);
|
---|
519 | }
|
---|
520 |
|
---|
521 | static struct op *
|
---|
522 | namelist(t)
|
---|
523 | register struct op *t;
|
---|
524 | {
|
---|
525 | if (iolist) {
|
---|
526 | iolist = addword((char *)NULL, iolist);
|
---|
527 | t->ioact = copyio();
|
---|
528 | } else
|
---|
529 | t->ioact = NULL;
|
---|
530 | if (t->type != TCOM) {
|
---|
531 | if (t->type != TPAREN && t->ioact != NULL) {
|
---|
532 | t = block(TPAREN, t, NOBLOCK, NOWORDS);
|
---|
533 | t->ioact = t->left->ioact;
|
---|
534 | t->left->ioact = NULL;
|
---|
535 | }
|
---|
536 | return(t);
|
---|
537 | }
|
---|
538 | word(NOWORD);
|
---|
539 | t->words = copyw();
|
---|
540 | return(t);
|
---|
541 | }
|
---|
542 |
|
---|
543 | static char **
|
---|
544 | copyw()
|
---|
545 | {
|
---|
546 | register char **wd;
|
---|
547 |
|
---|
548 | wd = getwords(wdlist);
|
---|
549 | wdlist = 0;
|
---|
550 | return(wd);
|
---|
551 | }
|
---|
552 |
|
---|
553 | static void
|
---|
554 | word(cp)
|
---|
555 | char *cp;
|
---|
556 | {
|
---|
557 | wdlist = addword(cp, wdlist);
|
---|
558 | }
|
---|
559 |
|
---|
560 | static struct ioword **
|
---|
561 | copyio()
|
---|
562 | {
|
---|
563 | register struct ioword **iop;
|
---|
564 |
|
---|
565 | iop = (struct ioword **) getwords(iolist);
|
---|
566 | iolist = 0;
|
---|
567 | return(iop);
|
---|
568 | }
|
---|
569 |
|
---|
570 | static struct ioword *
|
---|
571 | io(u, f, cp)
|
---|
572 | int u;
|
---|
573 | int f;
|
---|
574 | char *cp;
|
---|
575 | {
|
---|
576 | register struct ioword *iop;
|
---|
577 |
|
---|
578 | iop = (struct ioword *) tree(sizeof(*iop));
|
---|
579 | iop->io_unit = u;
|
---|
580 | iop->io_flag = f;
|
---|
581 | iop->io_name = cp;
|
---|
582 | iolist = addword((char *)iop, iolist);
|
---|
583 | return(iop);
|
---|
584 | }
|
---|
585 |
|
---|
586 | static void
|
---|
587 | zzerr()
|
---|
588 | {
|
---|
589 | yyerror("syntax error");
|
---|
590 | }
|
---|
591 |
|
---|
592 | void
|
---|
593 | yyerror(s)
|
---|
594 | char *s;
|
---|
595 | {
|
---|
596 | yynerrs++;
|
---|
597 | if (talking && e.iop <= iostack) {
|
---|
598 | multiline = 0;
|
---|
599 | while (eofc() == 0 && yylex(0) != '\n')
|
---|
600 | ;
|
---|
601 | }
|
---|
602 | err(s);
|
---|
603 | fail();
|
---|
604 | }
|
---|
605 |
|
---|
606 | static int
|
---|
607 | yylex(cf)
|
---|
608 | int cf;
|
---|
609 | {
|
---|
610 | register int c, c1;
|
---|
611 | int atstart;
|
---|
612 |
|
---|
613 | if ((c = peeksym) > 0) {
|
---|
614 | peeksym = 0;
|
---|
615 | if (c == '\n')
|
---|
616 | startl = 1;
|
---|
617 | return(c);
|
---|
618 | }
|
---|
619 | nlseen = 0;
|
---|
620 | e.linep = line;
|
---|
621 | atstart = startl;
|
---|
622 | startl = 0;
|
---|
623 | yylval.i = 0;
|
---|
624 |
|
---|
625 | loop:
|
---|
626 | while ((c = getc(0)) == ' ' || c == '\t')
|
---|
627 | ;
|
---|
628 | switch (c) {
|
---|
629 | default:
|
---|
630 | if (any(c, "0123456789")) {
|
---|
631 | unget(c1 = getc(0));
|
---|
632 | if (c1 == '<' || c1 == '>') {
|
---|
633 | iounit = c - '0';
|
---|
634 | goto loop;
|
---|
635 | }
|
---|
636 | *e.linep++ = c;
|
---|
637 | c = c1;
|
---|
638 | }
|
---|
639 | break;
|
---|
640 |
|
---|
641 | case '#':
|
---|
642 | while ((c = getc(0)) != 0 && c != '\n')
|
---|
643 | ;
|
---|
644 | unget(c);
|
---|
645 | goto loop;
|
---|
646 |
|
---|
647 | case 0:
|
---|
648 | return(c);
|
---|
649 |
|
---|
650 | case '$':
|
---|
651 | *e.linep++ = c;
|
---|
652 | if ((c = getc(0)) == '{') {
|
---|
653 | if ((c = collect(c, '}')) != '\0')
|
---|
654 | return(c);
|
---|
655 | goto pack;
|
---|
656 | }
|
---|
657 | break;
|
---|
658 |
|
---|
659 | case '`':
|
---|
660 | case '\'':
|
---|
661 | case '"':
|
---|
662 | if ((c = collect(c, c)) != '\0')
|
---|
663 | return(c);
|
---|
664 | goto pack;
|
---|
665 |
|
---|
666 | case '|':
|
---|
667 | case '&':
|
---|
668 | case ';':
|
---|
669 | if ((c1 = dual(c)) != '\0') {
|
---|
670 | startl = 1;
|
---|
671 | return(c1);
|
---|
672 | }
|
---|
673 | startl = 1;
|
---|
674 | return(c);
|
---|
675 | case '^':
|
---|
676 | startl = 1;
|
---|
677 | return('|');
|
---|
678 | case '>':
|
---|
679 | case '<':
|
---|
680 | diag(c);
|
---|
681 | return(c);
|
---|
682 |
|
---|
683 | case '\n':
|
---|
684 | nlseen++;
|
---|
685 | gethere();
|
---|
686 | startl = 1;
|
---|
687 | if (multiline || cf & CONTIN) {
|
---|
688 | if (talking && e.iop <= iostack)
|
---|
689 | prs(cprompt->value);
|
---|
690 | if (cf & CONTIN)
|
---|
691 | goto loop;
|
---|
692 | }
|
---|
693 | return(c);
|
---|
694 |
|
---|
695 | case '(':
|
---|
696 | case ')':
|
---|
697 | startl = 1;
|
---|
698 | return(c);
|
---|
699 | }
|
---|
700 |
|
---|
701 | unget(c);
|
---|
702 |
|
---|
703 | pack:
|
---|
704 | while ((c = getc(0)) != 0 && !any(c, "`$ '\"\t;&<>()|^\n"))
|
---|
705 | if (e.linep >= elinep)
|
---|
706 | err("word too long");
|
---|
707 | else
|
---|
708 | *e.linep++ = c;
|
---|
709 | unget(c);
|
---|
710 | if(any(c, "\"'`$"))
|
---|
711 | goto loop;
|
---|
712 | *e.linep++ = '\0';
|
---|
713 | if (atstart && (c = rlookup(line))!=0) {
|
---|
714 | startl = 1;
|
---|
715 | return(c);
|
---|
716 | }
|
---|
717 | yylval.cp = strsave(line, areanum);
|
---|
718 | return(WORD);
|
---|
719 | }
|
---|
720 |
|
---|
721 | int
|
---|
722 | collect(c, c1)
|
---|
723 | register c, c1;
|
---|
724 | {
|
---|
725 | char s[2];
|
---|
726 |
|
---|
727 | *e.linep++ = c;
|
---|
728 | while ((c = getc(c1)) != c1) {
|
---|
729 | if (c == 0) {
|
---|
730 | unget(c);
|
---|
731 | s[0] = c1;
|
---|
732 | s[1] = 0;
|
---|
733 | prs("no closing "); yyerror(s);
|
---|
734 | return(YYERRCODE);
|
---|
735 | }
|
---|
736 | if (talking && c == '\n' && e.iop <= iostack)
|
---|
737 | prs(cprompt->value);
|
---|
738 | *e.linep++ = c;
|
---|
739 | }
|
---|
740 | *e.linep++ = c;
|
---|
741 | return(0);
|
---|
742 | }
|
---|
743 |
|
---|
744 | int
|
---|
745 | dual(c)
|
---|
746 | register c;
|
---|
747 | {
|
---|
748 | char s[3];
|
---|
749 | register char *cp = s;
|
---|
750 |
|
---|
751 | *cp++ = c;
|
---|
752 | *cp++ = getc(0);
|
---|
753 | *cp = 0;
|
---|
754 | if ((c = rlookup(s)) == 0)
|
---|
755 | unget(*--cp);
|
---|
756 | return(c);
|
---|
757 | }
|
---|
758 |
|
---|
759 | static void
|
---|
760 | diag(ec)
|
---|
761 | register int ec;
|
---|
762 | {
|
---|
763 | register int c;
|
---|
764 |
|
---|
765 | c = getc(0);
|
---|
766 | if (c == '>' || c == '<') {
|
---|
767 | if (c != ec)
|
---|
768 | zzerr();
|
---|
769 | yylval.i = ec == '>'? IOWRITE|IOCAT: IOHERE;
|
---|
770 | c = getc(0);
|
---|
771 | } else
|
---|
772 | yylval.i = ec == '>'? IOWRITE: IOREAD;
|
---|
773 | if (c != '&' || yylval.i == IOHERE)
|
---|
774 | unget(c);
|
---|
775 | else
|
---|
776 | yylval.i |= IODUP;
|
---|
777 | }
|
---|
778 |
|
---|
779 | static char *
|
---|
780 | tree(size)
|
---|
781 | unsigned size;
|
---|
782 | {
|
---|
783 | register char *t;
|
---|
784 |
|
---|
785 | if ((t = getcell(size)) == NULL) {
|
---|
786 | prs("command line too complicated\n");
|
---|
787 | fail();
|
---|
788 | /* NOTREACHED */
|
---|
789 | }
|
---|
790 | return(t);
|
---|
791 | }
|
---|
792 |
|
---|
793 | /* VARARGS1 */
|
---|
794 | /* ARGSUSED */
|
---|
795 | void
|
---|
796 | printf(s) /* yyparse calls it */
|
---|
797 | char *s;
|
---|
798 | {
|
---|
799 | }
|
---|
800 |
|
---|