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