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