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