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