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.1 (Berkeley) 06/04/85"; 9 #endif not lint 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 t = (struct command *) calloc(1, sizeof (*t)); 229 t->t_dtyp = TPAR; 230 t->t_dflg = FAND|FINT; 231 t->t_dspr = t1; 232 t1 = t; 233 } else 234 t1->t_dflg |= FAND|FINT; 235 t = (struct command *) calloc(1, sizeof (*t)); 236 t->t_dtyp = TLST; 237 t->t_dflg = 0; 238 t->t_dcar = t1; 239 t->t_dcdr = syntax(p, p2, flags); 240 return(t); 241 } 242 if (l == 0) 243 return (syn1(p1, p2, flags)); 244 seterr("Too many ('s"); 245 return (0); 246 } 247 248 /* 249 * syn1 250 * syn1a 251 * syn1a ; syntax 252 */ 253 struct command * 254 syn1(p1, p2, flags) 255 struct wordent *p1, *p2; 256 int flags; 257 { 258 register struct wordent *p; 259 register struct command *t; 260 int l; 261 262 l = 0; 263 for (p = p1; p != p2; p = p->next) 264 switch (p->word[0]) { 265 266 case '(': 267 l++; 268 continue; 269 270 case ')': 271 l--; 272 continue; 273 274 case ';': 275 case '\n': 276 if (l != 0) 277 break; 278 t = (struct command *) calloc(1, sizeof (*t)); 279 t->t_dtyp = TLST; 280 t->t_dcar = syn1a(p1, p, flags); 281 t->t_dcdr = syntax(p->next, p2, flags); 282 if (t->t_dcdr == 0) 283 t->t_dcdr = t->t_dcar, t->t_dcar = 0; 284 return (t); 285 } 286 return (syn1a(p1, p2, flags)); 287 } 288 289 /* 290 * syn1a 291 * syn1b 292 * syn1b || syn1a 293 */ 294 struct command * 295 syn1a(p1, p2, flags) 296 struct wordent *p1, *p2; 297 int flags; 298 { 299 register struct wordent *p; 300 register struct command *t; 301 register int l = 0; 302 303 for (p = p1; p != p2; p = p->next) 304 switch (p->word[0]) { 305 306 case '(': 307 l++; 308 continue; 309 310 case ')': 311 l--; 312 continue; 313 314 case '|': 315 if (p->word[1] != '|') 316 continue; 317 if (l == 0) { 318 t = (struct command *) calloc(1, sizeof (*t)); 319 t->t_dtyp = TOR; 320 t->t_dcar = syn1b(p1, p, flags); 321 t->t_dcdr = syn1a(p->next, p2, flags); 322 t->t_dflg = 0; 323 return (t); 324 } 325 continue; 326 } 327 return (syn1b(p1, p2, flags)); 328 } 329 330 /* 331 * syn1b 332 * syn2 333 * syn2 && syn1b 334 */ 335 struct command * 336 syn1b(p1, p2, flags) 337 struct wordent *p1, *p2; 338 int flags; 339 { 340 register struct wordent *p; 341 register struct command *t; 342 register int l = 0; 343 344 l = 0; 345 for (p = p1; p != p2; p = p->next) 346 switch (p->word[0]) { 347 348 case '(': 349 l++; 350 continue; 351 352 case ')': 353 l--; 354 continue; 355 356 case '&': 357 if (p->word[1] == '&' && l == 0) { 358 t = (struct command *) calloc(1, sizeof (*t)); 359 t->t_dtyp = TAND; 360 t->t_dcar = syn2(p1, p, flags); 361 t->t_dcdr = syn1b(p->next, p2, flags); 362 t->t_dflg = 0; 363 return (t); 364 } 365 continue; 366 } 367 return (syn2(p1, p2, flags)); 368 } 369 370 /* 371 * syn2 372 * syn3 373 * syn3 | syn2 374 * syn3 |& syn2 375 */ 376 struct command * 377 syn2(p1, p2, flags) 378 struct wordent *p1, *p2; 379 int flags; 380 { 381 register struct wordent *p, *pn; 382 register struct command *t; 383 register int l = 0; 384 int f; 385 386 for (p = p1; p != p2; p = p->next) 387 switch (p->word[0]) { 388 389 case '(': 390 l++; 391 continue; 392 393 case ')': 394 l--; 395 continue; 396 397 case '|': 398 if (l != 0) 399 continue; 400 t = (struct command *) calloc(1, sizeof (*t)); 401 f = flags | POUT; 402 pn = p->next; 403 if (pn != p2 && pn->word[0] == '&') { 404 f |= PDIAG; 405 t->t_dflg |= FDIAG; 406 } 407 t->t_dtyp = TFIL; 408 t->t_dcar = syn3(p1, p, f); 409 if (pn != p2 && pn->word[0] == '&') 410 p = pn; 411 t->t_dcdr = syn2(p->next, p2, flags | PIN); 412 return (t); 413 } 414 return (syn3(p1, p2, flags)); 415 } 416 417 char *RELPAR = "<>()"; 418 419 /* 420 * syn3 421 * ( syn0 ) [ < in ] [ > out ] 422 * word word* [ < in ] [ > out ] 423 * KEYWORD ( word* ) word* [ < in ] [ > out ] 424 * 425 * KEYWORD = (@ exit foreach if set switch test while) 426 */ 427 struct command * 428 syn3(p1, p2, flags) 429 struct wordent *p1, *p2; 430 int flags; 431 { 432 register struct wordent *p; 433 struct wordent *lp, *rp; 434 register struct command *t; 435 register int l; 436 char **av; 437 int n, c; 438 bool specp = 0; 439 440 if (p1 != p2) { 441 p = p1; 442 again: 443 switch (srchx(p->word)) { 444 445 case ZELSE: 446 p = p->next; 447 if (p != p2) 448 goto again; 449 break; 450 451 case ZEXIT: 452 case ZFOREACH: 453 case ZIF: 454 case ZLET: 455 case ZSET: 456 case ZSWITCH: 457 case ZWHILE: 458 specp = 1; 459 break; 460 } 461 } 462 n = 0; 463 l = 0; 464 for (p = p1; p != p2; p = p->next) 465 switch (p->word[0]) { 466 467 case '(': 468 if (specp) 469 n++; 470 l++; 471 continue; 472 473 case ')': 474 if (specp) 475 n++; 476 l--; 477 continue; 478 479 case '>': 480 case '<': 481 if (l != 0) { 482 if (specp) 483 n++; 484 continue; 485 } 486 if (p->next == p2) 487 continue; 488 if (any(p->next->word[0], RELPAR)) 489 continue; 490 n--; 491 continue; 492 493 default: 494 if (!specp && l != 0) 495 continue; 496 n++; 497 continue; 498 } 499 if (n < 0) 500 n = 0; 501 t = (struct command *) calloc(1, sizeof (*t)); 502 av = (char **) calloc((unsigned) (n + 1), sizeof (char **)); 503 t->t_dcom = av; 504 n = 0; 505 if (p2->word[0] == ')') 506 t->t_dflg = FPAR; 507 lp = 0; 508 rp = 0; 509 l = 0; 510 for (p = p1; p != p2; p = p->next) { 511 c = p->word[0]; 512 switch (c) { 513 514 case '(': 515 if (l == 0) { 516 if (lp != 0 && !specp) 517 seterr("Badly placed ("); 518 lp = p->next; 519 } 520 l++; 521 goto savep; 522 523 case ')': 524 l--; 525 if (l == 0) 526 rp = p; 527 goto savep; 528 529 case '>': 530 if (l != 0) 531 goto savep; 532 if (p->word[1] == '>') 533 t->t_dflg |= FCAT; 534 if (p->next != p2 && eq(p->next->word, "&")) { 535 t->t_dflg |= FDIAG, p = p->next; 536 if (flags & (POUT|PDIAG)) 537 goto badout; 538 } 539 if (p->next != p2 && eq(p->next->word, "!")) 540 t->t_dflg |= FANY, p = p->next; 541 if (p->next == p2) { 542 missfile: 543 seterr("Missing name for redirect"); 544 continue; 545 } 546 p = p->next; 547 if (any(p->word[0], RELPAR)) 548 goto missfile; 549 if ((flags & POUT) && (flags & PDIAG) == 0 || t->t_drit) 550 badout: 551 seterr("Ambiguous output redirect"); 552 else 553 t->t_drit = savestr(p->word); 554 continue; 555 556 case '<': 557 if (l != 0) 558 goto savep; 559 if (p->word[1] == '<') 560 t->t_dflg |= FHERE; 561 if (p->next == p2) 562 goto missfile; 563 p = p->next; 564 if (any(p->word[0], RELPAR)) 565 goto missfile; 566 if ((flags & PHERE) && (t->t_dflg & FHERE)) 567 seterr("Can't << within ()'s"); 568 else if ((flags & PIN) || t->t_dlef) 569 seterr("Ambiguous input redirect"); 570 else 571 t->t_dlef = savestr(p->word); 572 continue; 573 574 savep: 575 if (!specp) 576 continue; 577 default: 578 if (l != 0 && !specp) 579 continue; 580 if (err == 0) 581 av[n] = savestr(p->word); 582 n++; 583 continue; 584 } 585 } 586 if (lp != 0 && !specp) { 587 if (n != 0) 588 seterr("Badly placed ()'s"); 589 t->t_dtyp = TPAR; 590 t->t_dspr = syn0(lp, rp, PHERE); 591 } else { 592 if (n == 0) 593 seterr("Invalid null command"); 594 t->t_dtyp = TCOM; 595 } 596 return (t); 597 } 598 599 freesyn(t) 600 register struct command *t; 601 { 602 register char **v; 603 604 if (t == 0) 605 return; 606 switch (t->t_dtyp) { 607 608 case TCOM: 609 for (v = t->t_dcom; *v; v++) 610 XFREE(*v) 611 XFREE((char *)t->t_dcom) 612 goto lr; 613 614 case TPAR: 615 freesyn(t->t_dspr); 616 /* fall into ... */ 617 618 lr: 619 XFREE(t->t_dlef) 620 XFREE(t->t_drit) 621 break; 622 623 case TAND: 624 case TOR: 625 case TFIL: 626 case TLST: 627 freesyn(t->t_dcar), freesyn(t->t_dcdr); 628 break; 629 } 630 XFREE((char *)t) 631 } 632