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