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