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