1 /*- 2 * Copyright (c) 1980, 1991 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #ifndef lint 9 static char sccsid[] = "@(#)parse.c 5.10 (Berkeley) 06/08/91"; 10 #endif /* not lint */ 11 12 #include <sys/types.h> 13 #include <stdlib.h> 14 #include <string.h> 15 #include "csh.h" 16 #include "extern.h" 17 18 static void asyntax __P((struct wordent *, struct wordent *)); 19 static void asyn0 __P((struct wordent *, struct wordent *)); 20 static void asyn3 __P((struct wordent *, struct wordent *)); 21 static struct wordent 22 *freenod __P((struct wordent *, struct wordent *)); 23 static struct command 24 *syn0 __P((struct wordent *, struct wordent *, int)); 25 static struct command 26 *syn1 __P((struct wordent *, struct wordent *, int)); 27 static struct command 28 *syn1a __P((struct wordent *, struct wordent *, int)); 29 static struct command 30 *syn1b __P((struct wordent *, struct wordent *, int)); 31 static struct command 32 *syn2 __P((struct wordent *, struct wordent *, int)); 33 static struct command 34 *syn3 __P((struct wordent *, struct wordent *, int)); 35 36 #define ALEFT 21 /* max of 20 alias expansions */ 37 #define HLEFT 11 /* max of 10 history expansions */ 38 /* 39 * Perform aliasing on the word list lex 40 * Do a (very rudimentary) parse to separate into commands. 41 * If word 0 of a command has an alias, do it. 42 * Repeat a maximum of 20 times. 43 */ 44 static int aleft; 45 extern int hleft; 46 void 47 alias(lex) 48 register struct wordent *lex; 49 { 50 jmp_buf osetexit; 51 52 aleft = ALEFT; 53 hleft = HLEFT; 54 getexit(osetexit); 55 (void) setexit(); 56 if (haderr) { 57 resexit(osetexit); 58 reset(); 59 } 60 if (--aleft == 0) 61 stderror(ERR_ALIASLOOP); 62 asyntax(lex->next, lex); 63 resexit(osetexit); 64 } 65 66 static void 67 asyntax(p1, p2) 68 register struct wordent *p1, *p2; 69 { 70 while (p1 != p2) 71 if (any(";&\n", p1->word[0])) 72 p1 = p1->next; 73 else { 74 asyn0(p1, p2); 75 return; 76 } 77 } 78 79 static void 80 asyn0(p1, p2) 81 struct wordent *p1; 82 register struct wordent *p2; 83 { 84 register struct wordent *p; 85 register int l = 0; 86 87 for (p = p1; p != p2; p = p->next) 88 switch (p->word[0]) { 89 90 case '(': 91 l++; 92 continue; 93 94 case ')': 95 l--; 96 if (l < 0) 97 stderror(ERR_TOOMANYRP); 98 continue; 99 100 case '>': 101 if (p->next != p2 && eq(p->next->word, STRand)) 102 p = p->next; 103 continue; 104 105 case '&': 106 case '|': 107 case ';': 108 case '\n': 109 if (l != 0) 110 continue; 111 asyn3(p1, p); 112 asyntax(p->next, p2); 113 return; 114 } 115 if (l == 0) 116 asyn3(p1, p2); 117 } 118 119 static void 120 asyn3(p1, p2) 121 struct wordent *p1; 122 register struct wordent *p2; 123 { 124 register struct varent *ap; 125 struct wordent alout; 126 register bool redid; 127 128 if (p1 == p2) 129 return; 130 if (p1->word[0] == '(') { 131 for (p2 = p2->prev; p2->word[0] != ')'; p2 = p2->prev) 132 if (p2 == p1) 133 return; 134 if (p2 == p1->next) 135 return; 136 asyn0(p1->next, p2); 137 return; 138 } 139 ap = adrof1(p1->word, &aliases); 140 if (ap == 0) 141 return; 142 alhistp = p1->prev; 143 alhistt = p2; 144 alvec = ap->vec; 145 redid = lex(&alout); 146 alhistp = alhistt = 0; 147 alvec = 0; 148 if (seterr) { 149 freelex(&alout); 150 stderror(ERR_OLD); 151 } 152 if (p1->word[0] && eq(p1->word, alout.next->word)) { 153 Char *cp = alout.next->word; 154 155 alout.next->word = Strspl(STRQNULL, cp); 156 xfree((ptr_t) cp); 157 } 158 p1 = freenod(p1, redid ? p2 : p1->next); 159 if (alout.next != &alout) { 160 p1->next->prev = alout.prev->prev; 161 alout.prev->prev->next = p1->next; 162 alout.next->prev = p1; 163 p1->next = alout.next; 164 xfree((ptr_t) alout.prev->word); 165 xfree((ptr_t) (alout.prev)); 166 } 167 reset(); /* throw! */ 168 } 169 170 static struct wordent * 171 freenod(p1, p2) 172 register struct wordent *p1, *p2; 173 { 174 register struct wordent *retp = p1->prev; 175 176 while (p1 != p2) { 177 xfree((ptr_t) p1->word); 178 p1 = p1->next; 179 xfree((ptr_t) (p1->prev)); 180 } 181 retp->next = p2; 182 p2->prev = retp; 183 return (retp); 184 } 185 186 #define PHERE 1 187 #define PIN 2 188 #define POUT 4 189 #define PDIAG 8 190 191 /* 192 * syntax 193 * empty 194 * syn0 195 */ 196 struct command * 197 syntax(p1, p2, flags) 198 register struct wordent *p1, *p2; 199 int flags; 200 { 201 202 while (p1 != p2) 203 if (any(";&\n", p1->word[0])) 204 p1 = p1->next; 205 else 206 return (syn0(p1, p2, flags)); 207 return (0); 208 } 209 210 /* 211 * syn0 212 * syn1 213 * syn1 & syntax 214 */ 215 static struct command * 216 syn0(p1, p2, flags) 217 struct wordent *p1, *p2; 218 int flags; 219 { 220 register struct wordent *p; 221 register struct command *t, *t1; 222 int l; 223 224 l = 0; 225 for (p = p1; p != p2; p = p->next) 226 switch (p->word[0]) { 227 228 case '(': 229 l++; 230 continue; 231 232 case ')': 233 l--; 234 if (l < 0) 235 seterror(ERR_TOOMANYRP); 236 continue; 237 238 case '|': 239 if (p->word[1] == '|') 240 continue; 241 /* fall into ... */ 242 243 case '>': 244 if (p->next != p2 && eq(p->next->word, STRand)) 245 p = p->next; 246 continue; 247 248 case '&': 249 if (l != 0) 250 break; 251 if (p->word[1] == '&') 252 continue; 253 t1 = syn1(p1, p, flags); 254 if (t1->t_dtyp == NODE_LIST || 255 t1->t_dtyp == NODE_AND || 256 t1->t_dtyp == NODE_OR) { 257 t = (struct command *) xcalloc(1, sizeof(*t)); 258 t->t_dtyp = NODE_PAREN; 259 t->t_dflg = F_AMPERSAND | F_NOINTERRUPT; 260 t->t_dspr = t1; 261 t1 = t; 262 } 263 else 264 t1->t_dflg |= F_AMPERSAND | F_NOINTERRUPT; 265 t = (struct command *) xcalloc(1, sizeof(*t)); 266 t->t_dtyp = NODE_LIST; 267 t->t_dflg = 0; 268 t->t_dcar = t1; 269 t->t_dcdr = syntax(p, p2, flags); 270 return (t); 271 } 272 if (l == 0) 273 return (syn1(p1, p2, flags)); 274 seterror(ERR_TOOMANYLP); 275 return (0); 276 } 277 278 /* 279 * syn1 280 * syn1a 281 * syn1a ; syntax 282 */ 283 static struct command * 284 syn1(p1, p2, flags) 285 struct wordent *p1, *p2; 286 int flags; 287 { 288 register struct wordent *p; 289 register struct command *t; 290 int l; 291 292 l = 0; 293 for (p = p1; p != p2; p = p->next) 294 switch (p->word[0]) { 295 296 case '(': 297 l++; 298 continue; 299 300 case ')': 301 l--; 302 continue; 303 304 case ';': 305 case '\n': 306 if (l != 0) 307 break; 308 t = (struct command *) xcalloc(1, sizeof(*t)); 309 t->t_dtyp = NODE_LIST; 310 t->t_dcar = syn1a(p1, p, flags); 311 t->t_dcdr = syntax(p->next, p2, flags); 312 if (t->t_dcdr == 0) 313 t->t_dcdr = t->t_dcar, t->t_dcar = 0; 314 return (t); 315 } 316 return (syn1a(p1, p2, flags)); 317 } 318 319 /* 320 * syn1a 321 * syn1b 322 * syn1b || syn1a 323 */ 324 static struct command * 325 syn1a(p1, p2, flags) 326 struct wordent *p1, *p2; 327 int flags; 328 { 329 register struct wordent *p; 330 register struct command *t; 331 register int l = 0; 332 333 for (p = p1; p != p2; p = p->next) 334 switch (p->word[0]) { 335 336 case '(': 337 l++; 338 continue; 339 340 case ')': 341 l--; 342 continue; 343 344 case '|': 345 if (p->word[1] != '|') 346 continue; 347 if (l == 0) { 348 t = (struct command *) xcalloc(1, sizeof(*t)); 349 t->t_dtyp = NODE_OR; 350 t->t_dcar = syn1b(p1, p, flags); 351 t->t_dcdr = syn1a(p->next, p2, flags); 352 t->t_dflg = 0; 353 return (t); 354 } 355 continue; 356 } 357 return (syn1b(p1, p2, flags)); 358 } 359 360 /* 361 * syn1b 362 * syn2 363 * syn2 && syn1b 364 */ 365 static struct command * 366 syn1b(p1, p2, flags) 367 struct wordent *p1, *p2; 368 int flags; 369 { 370 register struct wordent *p; 371 register struct command *t; 372 register int l = 0; 373 374 for (p = p1; p != p2; p = p->next) 375 switch (p->word[0]) { 376 377 case '(': 378 l++; 379 continue; 380 381 case ')': 382 l--; 383 continue; 384 385 case '&': 386 if (p->word[1] == '&' && l == 0) { 387 t = (struct command *) xcalloc(1, sizeof(*t)); 388 t->t_dtyp = NODE_AND; 389 t->t_dcar = syn2(p1, p, flags); 390 t->t_dcdr = syn1b(p->next, p2, flags); 391 t->t_dflg = 0; 392 return (t); 393 } 394 continue; 395 } 396 return (syn2(p1, p2, flags)); 397 } 398 399 /* 400 * syn2 401 * syn3 402 * syn3 | syn2 403 * syn3 |& syn2 404 */ 405 static struct command * 406 syn2(p1, p2, flags) 407 struct wordent *p1, *p2; 408 int flags; 409 { 410 register struct wordent *p, *pn; 411 register struct command *t; 412 register int l = 0; 413 int f; 414 415 for (p = p1; p != p2; p = p->next) 416 switch (p->word[0]) { 417 418 case '(': 419 l++; 420 continue; 421 422 case ')': 423 l--; 424 continue; 425 426 case '|': 427 if (l != 0) 428 continue; 429 t = (struct command *) xcalloc(1, sizeof(*t)); 430 f = flags | POUT; 431 pn = p->next; 432 if (pn != p2 && pn->word[0] == '&') { 433 f |= PDIAG; 434 t->t_dflg |= F_STDERR; 435 } 436 t->t_dtyp = NODE_PIPE; 437 t->t_dcar = syn3(p1, p, f); 438 if (pn != p2 && pn->word[0] == '&') 439 p = pn; 440 t->t_dcdr = syn2(p->next, p2, flags | PIN); 441 return (t); 442 } 443 return (syn3(p1, p2, flags)); 444 } 445 446 static char RELPAR[] = {'<', '>', '(', ')', '\0'}; 447 448 /* 449 * syn3 450 * ( syn0 ) [ < in ] [ > out ] 451 * word word* [ < in ] [ > out ] 452 * KEYWORD ( word* ) word* [ < in ] [ > out ] 453 * 454 * KEYWORD = (@ exit foreach if set switch test while) 455 */ 456 static struct command * 457 syn3(p1, p2, flags) 458 struct wordent *p1, *p2; 459 int flags; 460 { 461 register struct wordent *p; 462 struct wordent *lp, *rp; 463 register struct command *t; 464 register int l; 465 Char **av; 466 int n, c; 467 bool specp = 0; 468 469 if (p1 != p2) { 470 p = p1; 471 again: 472 switch (srchx(p->word)) { 473 474 case T_ELSE: 475 p = p->next; 476 if (p != p2) 477 goto again; 478 break; 479 480 case T_EXIT: 481 case T_FOREACH: 482 case T_IF: 483 case T_LET: 484 case T_SET: 485 case T_SWITCH: 486 case T_WHILE: 487 specp = 1; 488 break; 489 } 490 } 491 n = 0; 492 l = 0; 493 for (p = p1; p != p2; p = p->next) 494 switch (p->word[0]) { 495 496 case '(': 497 if (specp) 498 n++; 499 l++; 500 continue; 501 502 case ')': 503 if (specp) 504 n++; 505 l--; 506 continue; 507 508 case '>': 509 case '<': 510 if (l != 0) { 511 if (specp) 512 n++; 513 continue; 514 } 515 if (p->next == p2) 516 continue; 517 if (any(RELPAR, p->next->word[0])) 518 continue; 519 n--; 520 continue; 521 522 default: 523 if (!specp && l != 0) 524 continue; 525 n++; 526 continue; 527 } 528 if (n < 0) 529 n = 0; 530 t = (struct command *) xcalloc(1, sizeof(*t)); 531 av = (Char **) xcalloc((size_t) (n + 1), sizeof(Char **)); 532 t->t_dcom = av; 533 n = 0; 534 if (p2->word[0] == ')') 535 t->t_dflg = F_NOFORK; 536 lp = 0; 537 rp = 0; 538 l = 0; 539 for (p = p1; p != p2; p = p->next) { 540 c = p->word[0]; 541 switch (c) { 542 543 case '(': 544 if (l == 0) { 545 if (lp != 0 && !specp) 546 seterror(ERR_BADPLP); 547 lp = p->next; 548 } 549 l++; 550 goto savep; 551 552 case ')': 553 l--; 554 if (l == 0) 555 rp = p; 556 goto savep; 557 558 case '>': 559 if (l != 0) 560 goto savep; 561 if (p->word[1] == '>') 562 t->t_dflg |= F_APPEND; 563 if (p->next != p2 && eq(p->next->word, STRand)) { 564 t->t_dflg |= F_STDERR, p = p->next; 565 if (flags & (POUT | PDIAG)) { 566 seterror(ERR_OUTRED); 567 continue; 568 } 569 } 570 if (p->next != p2 && eq(p->next->word, STRbang)) 571 t->t_dflg |= F_OVERWRITE, p = p->next; 572 if (p->next == p2) { 573 seterror(ERR_MISRED); 574 continue; 575 } 576 p = p->next; 577 if (any(RELPAR, p->word[0])) { 578 seterror(ERR_MISRED); 579 continue; 580 } 581 if ((flags & POUT) && (flags & PDIAG) == 0 || t->t_drit) 582 seterror(ERR_OUTRED); 583 else 584 t->t_drit = Strsave(p->word); 585 continue; 586 587 case '<': 588 if (l != 0) 589 goto savep; 590 if (p->word[1] == '<') 591 t->t_dflg |= F_READ; 592 if (p->next == p2) { 593 seterror(ERR_MISRED); 594 continue; 595 } 596 p = p->next; 597 if (any(RELPAR, p->word[0])) { 598 seterror(ERR_MISRED); 599 continue; 600 } 601 if ((flags & PHERE) && (t->t_dflg & F_READ)) 602 seterror(ERR_REDPAR); 603 else if ((flags & PIN) || t->t_dlef) 604 seterror(ERR_INRED); 605 else 606 t->t_dlef = Strsave(p->word); 607 continue; 608 609 savep: 610 if (!specp) 611 continue; 612 default: 613 if (l != 0 && !specp) 614 continue; 615 if (seterr == 0) 616 av[n] = Strsave(p->word); 617 n++; 618 continue; 619 } 620 } 621 if (lp != 0 && !specp) { 622 if (n != 0) 623 seterror(ERR_BADPLPS); 624 t->t_dtyp = NODE_PAREN; 625 t->t_dspr = syn0(lp, rp, PHERE); 626 } 627 else { 628 if (n == 0) 629 seterror(ERR_NULLCOM); 630 t->t_dtyp = NODE_COMMAND; 631 } 632 return (t); 633 } 634 635 void 636 freesyn(t) 637 register struct command *t; 638 { 639 register Char **v; 640 641 if (t == 0) 642 return; 643 switch (t->t_dtyp) { 644 645 case NODE_COMMAND: 646 for (v = t->t_dcom; *v; v++) 647 xfree((ptr_t) * v); 648 xfree((ptr_t) (t->t_dcom)); 649 xfree((ptr_t) t->t_dlef); 650 xfree((ptr_t) t->t_drit); 651 break; 652 case NODE_PAREN: 653 freesyn(t->t_dspr); 654 xfree((ptr_t) t->t_dlef); 655 xfree((ptr_t) t->t_drit); 656 break; 657 658 case NODE_AND: 659 case NODE_OR: 660 case NODE_PIPE: 661 case NODE_LIST: 662 freesyn(t->t_dcar), freesyn(t->t_dcdr); 663 break; 664 } 665 xfree((ptr_t) t); 666 } 667