1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 23*7c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 24*7c478bd9Sstevel@tonic-gate 25*7c478bd9Sstevel@tonic-gate 26*7c478bd9Sstevel@tonic-gate /* 27*7c478bd9Sstevel@tonic-gate * Copyright (c) 1996, by Sun Microsystems, Inc. 28*7c478bd9Sstevel@tonic-gate * All rights reserved. 29*7c478bd9Sstevel@tonic-gate */ 30*7c478bd9Sstevel@tonic-gate 31*7c478bd9Sstevel@tonic-gate #ident "%Z%%M% %I% %E% SMI" /* SVr4.0 1.12.1.4 */ 32*7c478bd9Sstevel@tonic-gate /* 33*7c478bd9Sstevel@tonic-gate * UNIX shell 34*7c478bd9Sstevel@tonic-gate */ 35*7c478bd9Sstevel@tonic-gate 36*7c478bd9Sstevel@tonic-gate #include "defs.h" 37*7c478bd9Sstevel@tonic-gate #include "sym.h" 38*7c478bd9Sstevel@tonic-gate 39*7c478bd9Sstevel@tonic-gate static struct ionod * inout(); 40*7c478bd9Sstevel@tonic-gate static int chkword(); 41*7c478bd9Sstevel@tonic-gate static int chksym(); 42*7c478bd9Sstevel@tonic-gate static struct trenod * term(); 43*7c478bd9Sstevel@tonic-gate static struct trenod * makelist(); 44*7c478bd9Sstevel@tonic-gate static struct trenod * list(); 45*7c478bd9Sstevel@tonic-gate static struct regnod * syncase(); 46*7c478bd9Sstevel@tonic-gate static struct trenod * item(); 47*7c478bd9Sstevel@tonic-gate static int skipnl(); 48*7c478bd9Sstevel@tonic-gate static int prsym(); 49*7c478bd9Sstevel@tonic-gate static int synbad(); 50*7c478bd9Sstevel@tonic-gate 51*7c478bd9Sstevel@tonic-gate 52*7c478bd9Sstevel@tonic-gate /* ======== storage allocation for functions ======== */ 53*7c478bd9Sstevel@tonic-gate 54*7c478bd9Sstevel@tonic-gate unsigned char * 55*7c478bd9Sstevel@tonic-gate getstor(asize) 56*7c478bd9Sstevel@tonic-gate int asize; 57*7c478bd9Sstevel@tonic-gate { 58*7c478bd9Sstevel@tonic-gate if (fndef) 59*7c478bd9Sstevel@tonic-gate return((unsigned char *)alloc(asize)); 60*7c478bd9Sstevel@tonic-gate else 61*7c478bd9Sstevel@tonic-gate return(getstak(asize)); 62*7c478bd9Sstevel@tonic-gate } 63*7c478bd9Sstevel@tonic-gate 64*7c478bd9Sstevel@tonic-gate 65*7c478bd9Sstevel@tonic-gate /* ======== command line decoding ========*/ 66*7c478bd9Sstevel@tonic-gate 67*7c478bd9Sstevel@tonic-gate 68*7c478bd9Sstevel@tonic-gate 69*7c478bd9Sstevel@tonic-gate 70*7c478bd9Sstevel@tonic-gate struct trenod * 71*7c478bd9Sstevel@tonic-gate makefork(flgs, i) 72*7c478bd9Sstevel@tonic-gate int flgs; 73*7c478bd9Sstevel@tonic-gate struct trenod *i; 74*7c478bd9Sstevel@tonic-gate { 75*7c478bd9Sstevel@tonic-gate register struct forknod *t; 76*7c478bd9Sstevel@tonic-gate 77*7c478bd9Sstevel@tonic-gate t = (struct forknod *)getstor(sizeof(struct forknod)); 78*7c478bd9Sstevel@tonic-gate t->forktyp = flgs|TFORK; 79*7c478bd9Sstevel@tonic-gate t->forktre = i; 80*7c478bd9Sstevel@tonic-gate t->forkio = 0; 81*7c478bd9Sstevel@tonic-gate return((struct trenod *)t); 82*7c478bd9Sstevel@tonic-gate } 83*7c478bd9Sstevel@tonic-gate 84*7c478bd9Sstevel@tonic-gate static struct trenod * 85*7c478bd9Sstevel@tonic-gate makelist(type, i, r) 86*7c478bd9Sstevel@tonic-gate int type; 87*7c478bd9Sstevel@tonic-gate struct trenod *i, *r; 88*7c478bd9Sstevel@tonic-gate { 89*7c478bd9Sstevel@tonic-gate register struct lstnod *t; 90*7c478bd9Sstevel@tonic-gate 91*7c478bd9Sstevel@tonic-gate if (i == 0 || r == 0) 92*7c478bd9Sstevel@tonic-gate synbad(); 93*7c478bd9Sstevel@tonic-gate else 94*7c478bd9Sstevel@tonic-gate { 95*7c478bd9Sstevel@tonic-gate t = (struct lstnod *)getstor(sizeof(struct lstnod)); 96*7c478bd9Sstevel@tonic-gate t->lsttyp = type; 97*7c478bd9Sstevel@tonic-gate t->lstlef = i; 98*7c478bd9Sstevel@tonic-gate t->lstrit = r; 99*7c478bd9Sstevel@tonic-gate } 100*7c478bd9Sstevel@tonic-gate return((struct trenod *)t); 101*7c478bd9Sstevel@tonic-gate } 102*7c478bd9Sstevel@tonic-gate 103*7c478bd9Sstevel@tonic-gate /* 104*7c478bd9Sstevel@tonic-gate * cmd 105*7c478bd9Sstevel@tonic-gate * empty 106*7c478bd9Sstevel@tonic-gate * list 107*7c478bd9Sstevel@tonic-gate * list & [ cmd ] 108*7c478bd9Sstevel@tonic-gate * list [ ; cmd ] 109*7c478bd9Sstevel@tonic-gate */ 110*7c478bd9Sstevel@tonic-gate struct trenod * 111*7c478bd9Sstevel@tonic-gate cmd(sym, flg) 112*7c478bd9Sstevel@tonic-gate register int sym; 113*7c478bd9Sstevel@tonic-gate int flg; 114*7c478bd9Sstevel@tonic-gate { 115*7c478bd9Sstevel@tonic-gate register struct trenod *i, *e; 116*7c478bd9Sstevel@tonic-gate i = list(flg); 117*7c478bd9Sstevel@tonic-gate if (wdval == NL) 118*7c478bd9Sstevel@tonic-gate { 119*7c478bd9Sstevel@tonic-gate if (flg & NLFLG) 120*7c478bd9Sstevel@tonic-gate { 121*7c478bd9Sstevel@tonic-gate wdval = ';'; 122*7c478bd9Sstevel@tonic-gate chkpr(); 123*7c478bd9Sstevel@tonic-gate } 124*7c478bd9Sstevel@tonic-gate } 125*7c478bd9Sstevel@tonic-gate else if (i == 0 && (flg & MTFLG) == 0) 126*7c478bd9Sstevel@tonic-gate synbad(); 127*7c478bd9Sstevel@tonic-gate 128*7c478bd9Sstevel@tonic-gate switch (wdval) 129*7c478bd9Sstevel@tonic-gate { 130*7c478bd9Sstevel@tonic-gate case '&': 131*7c478bd9Sstevel@tonic-gate if (i) 132*7c478bd9Sstevel@tonic-gate i = makefork(FAMP, i); 133*7c478bd9Sstevel@tonic-gate else 134*7c478bd9Sstevel@tonic-gate synbad(); 135*7c478bd9Sstevel@tonic-gate 136*7c478bd9Sstevel@tonic-gate case ';': 137*7c478bd9Sstevel@tonic-gate if (e = cmd(sym, flg | MTFLG)) 138*7c478bd9Sstevel@tonic-gate i = makelist(TLST, i, e); 139*7c478bd9Sstevel@tonic-gate else if (i == 0) 140*7c478bd9Sstevel@tonic-gate synbad(); 141*7c478bd9Sstevel@tonic-gate break; 142*7c478bd9Sstevel@tonic-gate 143*7c478bd9Sstevel@tonic-gate case EOFSYM: 144*7c478bd9Sstevel@tonic-gate if (sym == NL) 145*7c478bd9Sstevel@tonic-gate break; 146*7c478bd9Sstevel@tonic-gate 147*7c478bd9Sstevel@tonic-gate default: 148*7c478bd9Sstevel@tonic-gate if (sym) 149*7c478bd9Sstevel@tonic-gate chksym(sym); 150*7c478bd9Sstevel@tonic-gate } 151*7c478bd9Sstevel@tonic-gate return(i); 152*7c478bd9Sstevel@tonic-gate } 153*7c478bd9Sstevel@tonic-gate 154*7c478bd9Sstevel@tonic-gate /* 155*7c478bd9Sstevel@tonic-gate * list 156*7c478bd9Sstevel@tonic-gate * term 157*7c478bd9Sstevel@tonic-gate * list && term 158*7c478bd9Sstevel@tonic-gate * list || term 159*7c478bd9Sstevel@tonic-gate */ 160*7c478bd9Sstevel@tonic-gate static struct trenod * 161*7c478bd9Sstevel@tonic-gate list(flg) 162*7c478bd9Sstevel@tonic-gate { 163*7c478bd9Sstevel@tonic-gate register struct trenod *r; 164*7c478bd9Sstevel@tonic-gate register int b; 165*7c478bd9Sstevel@tonic-gate r = term(flg); 166*7c478bd9Sstevel@tonic-gate while (r && ((b = (wdval == ANDFSYM)) || wdval == ORFSYM)) 167*7c478bd9Sstevel@tonic-gate r = makelist((b ? TAND : TORF), r, term(NLFLG)); 168*7c478bd9Sstevel@tonic-gate return(r); 169*7c478bd9Sstevel@tonic-gate } 170*7c478bd9Sstevel@tonic-gate 171*7c478bd9Sstevel@tonic-gate /* 172*7c478bd9Sstevel@tonic-gate * term 173*7c478bd9Sstevel@tonic-gate * item 174*7c478bd9Sstevel@tonic-gate * item |^ term 175*7c478bd9Sstevel@tonic-gate */ 176*7c478bd9Sstevel@tonic-gate static struct trenod * 177*7c478bd9Sstevel@tonic-gate term(flg) 178*7c478bd9Sstevel@tonic-gate { 179*7c478bd9Sstevel@tonic-gate register struct trenod *t; 180*7c478bd9Sstevel@tonic-gate 181*7c478bd9Sstevel@tonic-gate reserv++; 182*7c478bd9Sstevel@tonic-gate if (flg & NLFLG) 183*7c478bd9Sstevel@tonic-gate skipnl(); 184*7c478bd9Sstevel@tonic-gate else 185*7c478bd9Sstevel@tonic-gate word(); 186*7c478bd9Sstevel@tonic-gate if ((t = item(TRUE)) && (wdval == '^' || wdval == '|')) 187*7c478bd9Sstevel@tonic-gate { 188*7c478bd9Sstevel@tonic-gate struct trenod *left; 189*7c478bd9Sstevel@tonic-gate struct trenod *right; 190*7c478bd9Sstevel@tonic-gate 191*7c478bd9Sstevel@tonic-gate left = makefork(FPOU, t); 192*7c478bd9Sstevel@tonic-gate right = makefork(FPIN, term(NLFLG)); 193*7c478bd9Sstevel@tonic-gate return(makefork(0, makelist(TFIL, left, right))); 194*7c478bd9Sstevel@tonic-gate } 195*7c478bd9Sstevel@tonic-gate else 196*7c478bd9Sstevel@tonic-gate return(t); 197*7c478bd9Sstevel@tonic-gate } 198*7c478bd9Sstevel@tonic-gate 199*7c478bd9Sstevel@tonic-gate 200*7c478bd9Sstevel@tonic-gate static struct regnod * 201*7c478bd9Sstevel@tonic-gate syncase(esym) 202*7c478bd9Sstevel@tonic-gate register int esym; 203*7c478bd9Sstevel@tonic-gate { 204*7c478bd9Sstevel@tonic-gate skipnl(); 205*7c478bd9Sstevel@tonic-gate if (wdval == esym) 206*7c478bd9Sstevel@tonic-gate return(0); 207*7c478bd9Sstevel@tonic-gate else 208*7c478bd9Sstevel@tonic-gate { 209*7c478bd9Sstevel@tonic-gate register struct regnod *r = (struct regnod *)getstor(sizeof(struct regnod)); 210*7c478bd9Sstevel@tonic-gate register struct argnod *argp; 211*7c478bd9Sstevel@tonic-gate 212*7c478bd9Sstevel@tonic-gate r->regptr = 0; 213*7c478bd9Sstevel@tonic-gate for (;;) 214*7c478bd9Sstevel@tonic-gate { 215*7c478bd9Sstevel@tonic-gate if (fndef) 216*7c478bd9Sstevel@tonic-gate { 217*7c478bd9Sstevel@tonic-gate argp= wdarg; 218*7c478bd9Sstevel@tonic-gate wdarg = (struct argnod *)alloc(length(argp->argval) + BYTESPERWORD); 219*7c478bd9Sstevel@tonic-gate movstr(argp->argval, wdarg->argval); 220*7c478bd9Sstevel@tonic-gate } 221*7c478bd9Sstevel@tonic-gate 222*7c478bd9Sstevel@tonic-gate wdarg->argnxt = r->regptr; 223*7c478bd9Sstevel@tonic-gate r->regptr = wdarg; 224*7c478bd9Sstevel@tonic-gate 225*7c478bd9Sstevel@tonic-gate /* 'in' is not a reserved word in this case */ 226*7c478bd9Sstevel@tonic-gate if (wdval == INSYM){ 227*7c478bd9Sstevel@tonic-gate wdval = 0; 228*7c478bd9Sstevel@tonic-gate } 229*7c478bd9Sstevel@tonic-gate if (wdval || (word() != ')' && wdval != '|')) 230*7c478bd9Sstevel@tonic-gate synbad(); 231*7c478bd9Sstevel@tonic-gate if (wdval == '|') 232*7c478bd9Sstevel@tonic-gate word(); 233*7c478bd9Sstevel@tonic-gate else 234*7c478bd9Sstevel@tonic-gate break; 235*7c478bd9Sstevel@tonic-gate } 236*7c478bd9Sstevel@tonic-gate r->regcom = cmd(0, NLFLG | MTFLG); 237*7c478bd9Sstevel@tonic-gate if (wdval == ECSYM) 238*7c478bd9Sstevel@tonic-gate r->regnxt = syncase(esym); 239*7c478bd9Sstevel@tonic-gate else 240*7c478bd9Sstevel@tonic-gate { 241*7c478bd9Sstevel@tonic-gate chksym(esym); 242*7c478bd9Sstevel@tonic-gate r->regnxt = 0; 243*7c478bd9Sstevel@tonic-gate } 244*7c478bd9Sstevel@tonic-gate return(r); 245*7c478bd9Sstevel@tonic-gate } 246*7c478bd9Sstevel@tonic-gate } 247*7c478bd9Sstevel@tonic-gate 248*7c478bd9Sstevel@tonic-gate /* 249*7c478bd9Sstevel@tonic-gate * item 250*7c478bd9Sstevel@tonic-gate * 251*7c478bd9Sstevel@tonic-gate * ( cmd ) [ < in ] [ > out ] 252*7c478bd9Sstevel@tonic-gate * word word* [ < in ] [ > out ] 253*7c478bd9Sstevel@tonic-gate * if ... then ... else ... fi 254*7c478bd9Sstevel@tonic-gate * for ... while ... do ... done 255*7c478bd9Sstevel@tonic-gate * case ... in ... esac 256*7c478bd9Sstevel@tonic-gate * begin ... end 257*7c478bd9Sstevel@tonic-gate */ 258*7c478bd9Sstevel@tonic-gate static struct trenod * 259*7c478bd9Sstevel@tonic-gate item(flag) 260*7c478bd9Sstevel@tonic-gate BOOL flag; 261*7c478bd9Sstevel@tonic-gate { 262*7c478bd9Sstevel@tonic-gate register struct trenod *r; 263*7c478bd9Sstevel@tonic-gate register struct ionod *io; 264*7c478bd9Sstevel@tonic-gate 265*7c478bd9Sstevel@tonic-gate if (flag) 266*7c478bd9Sstevel@tonic-gate io = inout((struct ionod *)0); 267*7c478bd9Sstevel@tonic-gate else 268*7c478bd9Sstevel@tonic-gate io = 0; 269*7c478bd9Sstevel@tonic-gate switch (wdval) 270*7c478bd9Sstevel@tonic-gate { 271*7c478bd9Sstevel@tonic-gate case CASYM: 272*7c478bd9Sstevel@tonic-gate { 273*7c478bd9Sstevel@tonic-gate register struct swnod *t; 274*7c478bd9Sstevel@tonic-gate 275*7c478bd9Sstevel@tonic-gate t = (struct swnod *)getstor(sizeof(struct swnod)); 276*7c478bd9Sstevel@tonic-gate r = (struct trenod *)t; 277*7c478bd9Sstevel@tonic-gate 278*7c478bd9Sstevel@tonic-gate chkword(); 279*7c478bd9Sstevel@tonic-gate if (fndef) 280*7c478bd9Sstevel@tonic-gate t->swarg = make(wdarg->argval); 281*7c478bd9Sstevel@tonic-gate else 282*7c478bd9Sstevel@tonic-gate t->swarg = wdarg->argval; 283*7c478bd9Sstevel@tonic-gate skipnl(); 284*7c478bd9Sstevel@tonic-gate chksym(INSYM | BRSYM); 285*7c478bd9Sstevel@tonic-gate t->swlst = syncase(wdval == INSYM ? ESSYM : KTSYM); 286*7c478bd9Sstevel@tonic-gate t->swtyp = TSW; 287*7c478bd9Sstevel@tonic-gate break; 288*7c478bd9Sstevel@tonic-gate } 289*7c478bd9Sstevel@tonic-gate 290*7c478bd9Sstevel@tonic-gate case IFSYM: 291*7c478bd9Sstevel@tonic-gate { 292*7c478bd9Sstevel@tonic-gate register int w; 293*7c478bd9Sstevel@tonic-gate register struct ifnod *t; 294*7c478bd9Sstevel@tonic-gate 295*7c478bd9Sstevel@tonic-gate t = (struct ifnod *)getstor(sizeof(struct ifnod)); 296*7c478bd9Sstevel@tonic-gate r = (struct trenod *)t; 297*7c478bd9Sstevel@tonic-gate 298*7c478bd9Sstevel@tonic-gate t->iftyp = TIF; 299*7c478bd9Sstevel@tonic-gate t->iftre = cmd(THSYM, NLFLG); 300*7c478bd9Sstevel@tonic-gate t->thtre = cmd(ELSYM | FISYM | EFSYM, NLFLG); 301*7c478bd9Sstevel@tonic-gate t->eltre = ((w = wdval) == ELSYM ? cmd(FISYM, NLFLG) : (w == EFSYM ? (wdval = IFSYM, item(0)) : 0)); 302*7c478bd9Sstevel@tonic-gate if (w == EFSYM) 303*7c478bd9Sstevel@tonic-gate return(r); 304*7c478bd9Sstevel@tonic-gate break; 305*7c478bd9Sstevel@tonic-gate } 306*7c478bd9Sstevel@tonic-gate 307*7c478bd9Sstevel@tonic-gate case FORSYM: 308*7c478bd9Sstevel@tonic-gate { 309*7c478bd9Sstevel@tonic-gate register struct fornod *t; 310*7c478bd9Sstevel@tonic-gate 311*7c478bd9Sstevel@tonic-gate t = (struct fornod *)getstor(sizeof(struct fornod)); 312*7c478bd9Sstevel@tonic-gate r = (struct trenod *)t; 313*7c478bd9Sstevel@tonic-gate 314*7c478bd9Sstevel@tonic-gate t->fortyp = TFOR; 315*7c478bd9Sstevel@tonic-gate t->forlst = 0; 316*7c478bd9Sstevel@tonic-gate chkword(); 317*7c478bd9Sstevel@tonic-gate if (fndef) 318*7c478bd9Sstevel@tonic-gate t->fornam = make(wdarg->argval); 319*7c478bd9Sstevel@tonic-gate else 320*7c478bd9Sstevel@tonic-gate t->fornam = wdarg->argval; 321*7c478bd9Sstevel@tonic-gate if (skipnl() == INSYM) 322*7c478bd9Sstevel@tonic-gate { 323*7c478bd9Sstevel@tonic-gate chkword(); 324*7c478bd9Sstevel@tonic-gate 325*7c478bd9Sstevel@tonic-gate nohash++; 326*7c478bd9Sstevel@tonic-gate t->forlst = (struct comnod *)item(0); 327*7c478bd9Sstevel@tonic-gate nohash--; 328*7c478bd9Sstevel@tonic-gate 329*7c478bd9Sstevel@tonic-gate if (wdval != NL && wdval != ';') 330*7c478bd9Sstevel@tonic-gate synbad(); 331*7c478bd9Sstevel@tonic-gate if (wdval == NL) 332*7c478bd9Sstevel@tonic-gate chkpr(); 333*7c478bd9Sstevel@tonic-gate skipnl(); 334*7c478bd9Sstevel@tonic-gate } 335*7c478bd9Sstevel@tonic-gate chksym(DOSYM | BRSYM); 336*7c478bd9Sstevel@tonic-gate t->fortre = cmd(wdval == DOSYM ? ODSYM : KTSYM, NLFLG); 337*7c478bd9Sstevel@tonic-gate break; 338*7c478bd9Sstevel@tonic-gate } 339*7c478bd9Sstevel@tonic-gate 340*7c478bd9Sstevel@tonic-gate case WHSYM: 341*7c478bd9Sstevel@tonic-gate case UNSYM: 342*7c478bd9Sstevel@tonic-gate { 343*7c478bd9Sstevel@tonic-gate register struct whnod *t; 344*7c478bd9Sstevel@tonic-gate 345*7c478bd9Sstevel@tonic-gate t = (struct whnod *)getstor(sizeof(struct whnod)); 346*7c478bd9Sstevel@tonic-gate r = (struct trenod *)t; 347*7c478bd9Sstevel@tonic-gate 348*7c478bd9Sstevel@tonic-gate t->whtyp = (wdval == WHSYM ? TWH : TUN); 349*7c478bd9Sstevel@tonic-gate t->whtre = cmd(DOSYM, NLFLG); 350*7c478bd9Sstevel@tonic-gate t->dotre = cmd(ODSYM, NLFLG); 351*7c478bd9Sstevel@tonic-gate break; 352*7c478bd9Sstevel@tonic-gate } 353*7c478bd9Sstevel@tonic-gate 354*7c478bd9Sstevel@tonic-gate case BRSYM: 355*7c478bd9Sstevel@tonic-gate r = cmd(KTSYM, NLFLG); 356*7c478bd9Sstevel@tonic-gate break; 357*7c478bd9Sstevel@tonic-gate 358*7c478bd9Sstevel@tonic-gate case '(': 359*7c478bd9Sstevel@tonic-gate { 360*7c478bd9Sstevel@tonic-gate register struct parnod *p; 361*7c478bd9Sstevel@tonic-gate 362*7c478bd9Sstevel@tonic-gate p = (struct parnod *)getstor(sizeof(struct parnod)); 363*7c478bd9Sstevel@tonic-gate p->partre = cmd(')', NLFLG); 364*7c478bd9Sstevel@tonic-gate p->partyp = TPAR; 365*7c478bd9Sstevel@tonic-gate r = makefork(0, p); 366*7c478bd9Sstevel@tonic-gate break; 367*7c478bd9Sstevel@tonic-gate } 368*7c478bd9Sstevel@tonic-gate 369*7c478bd9Sstevel@tonic-gate default: 370*7c478bd9Sstevel@tonic-gate if (io == 0) 371*7c478bd9Sstevel@tonic-gate return(0); 372*7c478bd9Sstevel@tonic-gate 373*7c478bd9Sstevel@tonic-gate case 0: 374*7c478bd9Sstevel@tonic-gate { 375*7c478bd9Sstevel@tonic-gate register struct comnod *t; 376*7c478bd9Sstevel@tonic-gate register struct argnod *argp; 377*7c478bd9Sstevel@tonic-gate register struct argnod **argtail; 378*7c478bd9Sstevel@tonic-gate register struct argnod **argset = 0; 379*7c478bd9Sstevel@tonic-gate int keywd = 1; 380*7c478bd9Sstevel@tonic-gate unsigned char *com; 381*7c478bd9Sstevel@tonic-gate 382*7c478bd9Sstevel@tonic-gate if ((wdval != NL) && ((peekn = skipwc()) == '(')) 383*7c478bd9Sstevel@tonic-gate { 384*7c478bd9Sstevel@tonic-gate struct fndnod *f; 385*7c478bd9Sstevel@tonic-gate struct ionod *saveio; 386*7c478bd9Sstevel@tonic-gate 387*7c478bd9Sstevel@tonic-gate saveio = iotemp; 388*7c478bd9Sstevel@tonic-gate peekn = 0; 389*7c478bd9Sstevel@tonic-gate if (skipwc() != ')') 390*7c478bd9Sstevel@tonic-gate synbad(); 391*7c478bd9Sstevel@tonic-gate 392*7c478bd9Sstevel@tonic-gate f = (struct fndnod *)getstor(sizeof(struct fndnod)); 393*7c478bd9Sstevel@tonic-gate r = (struct trenod *)f; 394*7c478bd9Sstevel@tonic-gate 395*7c478bd9Sstevel@tonic-gate f->fndtyp = TFND; 396*7c478bd9Sstevel@tonic-gate if (fndef) 397*7c478bd9Sstevel@tonic-gate f->fndnam = make(wdarg->argval); 398*7c478bd9Sstevel@tonic-gate else 399*7c478bd9Sstevel@tonic-gate f->fndnam = wdarg->argval; 400*7c478bd9Sstevel@tonic-gate reserv++; 401*7c478bd9Sstevel@tonic-gate fndef++; 402*7c478bd9Sstevel@tonic-gate skipnl(); 403*7c478bd9Sstevel@tonic-gate f->fndval = (struct trenod *)item(0); 404*7c478bd9Sstevel@tonic-gate fndef--; 405*7c478bd9Sstevel@tonic-gate 406*7c478bd9Sstevel@tonic-gate if (iotemp != saveio) 407*7c478bd9Sstevel@tonic-gate { 408*7c478bd9Sstevel@tonic-gate struct ionod *ioptr = iotemp; 409*7c478bd9Sstevel@tonic-gate 410*7c478bd9Sstevel@tonic-gate while (ioptr->iolst != saveio) 411*7c478bd9Sstevel@tonic-gate ioptr = ioptr->iolst; 412*7c478bd9Sstevel@tonic-gate 413*7c478bd9Sstevel@tonic-gate ioptr->iolst = fiotemp; 414*7c478bd9Sstevel@tonic-gate fiotemp = iotemp; 415*7c478bd9Sstevel@tonic-gate iotemp = saveio; 416*7c478bd9Sstevel@tonic-gate } 417*7c478bd9Sstevel@tonic-gate return(r); 418*7c478bd9Sstevel@tonic-gate } 419*7c478bd9Sstevel@tonic-gate else 420*7c478bd9Sstevel@tonic-gate { 421*7c478bd9Sstevel@tonic-gate t = (struct comnod *)getstor(sizeof(struct comnod)); 422*7c478bd9Sstevel@tonic-gate r = (struct trenod *)t; 423*7c478bd9Sstevel@tonic-gate 424*7c478bd9Sstevel@tonic-gate t->comio = io; /*initial io chain*/ 425*7c478bd9Sstevel@tonic-gate argtail = &(t->comarg); 426*7c478bd9Sstevel@tonic-gate 427*7c478bd9Sstevel@tonic-gate while (wdval == 0) 428*7c478bd9Sstevel@tonic-gate { 429*7c478bd9Sstevel@tonic-gate if (fndef) 430*7c478bd9Sstevel@tonic-gate { 431*7c478bd9Sstevel@tonic-gate argp = wdarg; 432*7c478bd9Sstevel@tonic-gate wdarg = (struct argnod *)alloc(length(argp->argval) + BYTESPERWORD); 433*7c478bd9Sstevel@tonic-gate movstr(argp->argval, wdarg->argval); 434*7c478bd9Sstevel@tonic-gate } 435*7c478bd9Sstevel@tonic-gate 436*7c478bd9Sstevel@tonic-gate argp = wdarg; 437*7c478bd9Sstevel@tonic-gate if (wdset && keywd) 438*7c478bd9Sstevel@tonic-gate { 439*7c478bd9Sstevel@tonic-gate argp->argnxt = (struct argnod *)argset; 440*7c478bd9Sstevel@tonic-gate argset = (struct argnod **)argp; 441*7c478bd9Sstevel@tonic-gate } 442*7c478bd9Sstevel@tonic-gate else 443*7c478bd9Sstevel@tonic-gate { 444*7c478bd9Sstevel@tonic-gate *argtail = argp; 445*7c478bd9Sstevel@tonic-gate argtail = &(argp->argnxt); 446*7c478bd9Sstevel@tonic-gate keywd = flags & keyflg; 447*7c478bd9Sstevel@tonic-gate } 448*7c478bd9Sstevel@tonic-gate word(); 449*7c478bd9Sstevel@tonic-gate if (flag) 450*7c478bd9Sstevel@tonic-gate { 451*7c478bd9Sstevel@tonic-gate if (io) 452*7c478bd9Sstevel@tonic-gate { 453*7c478bd9Sstevel@tonic-gate while(io->ionxt) 454*7c478bd9Sstevel@tonic-gate io = io->ionxt; 455*7c478bd9Sstevel@tonic-gate io->ionxt = inout((struct ionod *)0); 456*7c478bd9Sstevel@tonic-gate } 457*7c478bd9Sstevel@tonic-gate else 458*7c478bd9Sstevel@tonic-gate t->comio = io = inout((struct ionod *)0); 459*7c478bd9Sstevel@tonic-gate } 460*7c478bd9Sstevel@tonic-gate } 461*7c478bd9Sstevel@tonic-gate 462*7c478bd9Sstevel@tonic-gate t->comtyp = TCOM; 463*7c478bd9Sstevel@tonic-gate t->comset = (struct argnod *)argset; 464*7c478bd9Sstevel@tonic-gate *argtail = 0; 465*7c478bd9Sstevel@tonic-gate 466*7c478bd9Sstevel@tonic-gate if (nohash == 0 && (fndef == 0 || (flags & hashflg))) 467*7c478bd9Sstevel@tonic-gate { 468*7c478bd9Sstevel@tonic-gate if (t->comarg) 469*7c478bd9Sstevel@tonic-gate { 470*7c478bd9Sstevel@tonic-gate com = t->comarg->argval; 471*7c478bd9Sstevel@tonic-gate if (*com && *com != DOLLAR) 472*7c478bd9Sstevel@tonic-gate pathlook(com, 0, t->comset); 473*7c478bd9Sstevel@tonic-gate } 474*7c478bd9Sstevel@tonic-gate } 475*7c478bd9Sstevel@tonic-gate 476*7c478bd9Sstevel@tonic-gate return(r); 477*7c478bd9Sstevel@tonic-gate } 478*7c478bd9Sstevel@tonic-gate } 479*7c478bd9Sstevel@tonic-gate 480*7c478bd9Sstevel@tonic-gate } 481*7c478bd9Sstevel@tonic-gate reserv++; 482*7c478bd9Sstevel@tonic-gate word(); 483*7c478bd9Sstevel@tonic-gate if (io = inout(io)) 484*7c478bd9Sstevel@tonic-gate { 485*7c478bd9Sstevel@tonic-gate r = makefork(0,r); 486*7c478bd9Sstevel@tonic-gate r->treio = io; 487*7c478bd9Sstevel@tonic-gate } 488*7c478bd9Sstevel@tonic-gate return(r); 489*7c478bd9Sstevel@tonic-gate } 490*7c478bd9Sstevel@tonic-gate 491*7c478bd9Sstevel@tonic-gate 492*7c478bd9Sstevel@tonic-gate static int 493*7c478bd9Sstevel@tonic-gate skipnl() 494*7c478bd9Sstevel@tonic-gate { 495*7c478bd9Sstevel@tonic-gate while ((reserv++, word() == NL)) 496*7c478bd9Sstevel@tonic-gate chkpr(); 497*7c478bd9Sstevel@tonic-gate return(wdval); 498*7c478bd9Sstevel@tonic-gate } 499*7c478bd9Sstevel@tonic-gate 500*7c478bd9Sstevel@tonic-gate static struct ionod * 501*7c478bd9Sstevel@tonic-gate inout(lastio) 502*7c478bd9Sstevel@tonic-gate struct ionod *lastio; 503*7c478bd9Sstevel@tonic-gate { 504*7c478bd9Sstevel@tonic-gate register int iof; 505*7c478bd9Sstevel@tonic-gate register struct ionod *iop; 506*7c478bd9Sstevel@tonic-gate register unsigned int c; 507*7c478bd9Sstevel@tonic-gate 508*7c478bd9Sstevel@tonic-gate iof = wdnum; 509*7c478bd9Sstevel@tonic-gate switch (wdval) 510*7c478bd9Sstevel@tonic-gate { 511*7c478bd9Sstevel@tonic-gate case DOCSYM: /* << */ 512*7c478bd9Sstevel@tonic-gate iof |= IODOC; 513*7c478bd9Sstevel@tonic-gate break; 514*7c478bd9Sstevel@tonic-gate 515*7c478bd9Sstevel@tonic-gate case APPSYM: /* >> */ 516*7c478bd9Sstevel@tonic-gate case '>': 517*7c478bd9Sstevel@tonic-gate if (wdnum == 0) 518*7c478bd9Sstevel@tonic-gate iof |= 1; 519*7c478bd9Sstevel@tonic-gate iof |= IOPUT; 520*7c478bd9Sstevel@tonic-gate if (wdval == APPSYM) 521*7c478bd9Sstevel@tonic-gate { 522*7c478bd9Sstevel@tonic-gate iof |= IOAPP; 523*7c478bd9Sstevel@tonic-gate break; 524*7c478bd9Sstevel@tonic-gate } 525*7c478bd9Sstevel@tonic-gate 526*7c478bd9Sstevel@tonic-gate case '<': 527*7c478bd9Sstevel@tonic-gate if ((c = nextwc()) == '&') 528*7c478bd9Sstevel@tonic-gate iof |= IOMOV; 529*7c478bd9Sstevel@tonic-gate else if (c == '>') 530*7c478bd9Sstevel@tonic-gate iof |= IORDW; 531*7c478bd9Sstevel@tonic-gate else 532*7c478bd9Sstevel@tonic-gate peekn = c | MARK; 533*7c478bd9Sstevel@tonic-gate break; 534*7c478bd9Sstevel@tonic-gate 535*7c478bd9Sstevel@tonic-gate default: 536*7c478bd9Sstevel@tonic-gate return(lastio); 537*7c478bd9Sstevel@tonic-gate } 538*7c478bd9Sstevel@tonic-gate 539*7c478bd9Sstevel@tonic-gate chkword(); 540*7c478bd9Sstevel@tonic-gate iop = (struct ionod *)getstor(sizeof(struct ionod)); 541*7c478bd9Sstevel@tonic-gate 542*7c478bd9Sstevel@tonic-gate if (fndef) 543*7c478bd9Sstevel@tonic-gate iop->ioname = (char *) make(wdarg->argval); 544*7c478bd9Sstevel@tonic-gate else 545*7c478bd9Sstevel@tonic-gate iop->ioname = (char *) (wdarg->argval); 546*7c478bd9Sstevel@tonic-gate 547*7c478bd9Sstevel@tonic-gate iop->iolink = 0; 548*7c478bd9Sstevel@tonic-gate iop->iofile = iof; 549*7c478bd9Sstevel@tonic-gate if (iof & IODOC) 550*7c478bd9Sstevel@tonic-gate { 551*7c478bd9Sstevel@tonic-gate iop->iolst = iopend; 552*7c478bd9Sstevel@tonic-gate iopend = iop; 553*7c478bd9Sstevel@tonic-gate } 554*7c478bd9Sstevel@tonic-gate word(); 555*7c478bd9Sstevel@tonic-gate iop->ionxt = inout(lastio); 556*7c478bd9Sstevel@tonic-gate return(iop); 557*7c478bd9Sstevel@tonic-gate } 558*7c478bd9Sstevel@tonic-gate 559*7c478bd9Sstevel@tonic-gate static int 560*7c478bd9Sstevel@tonic-gate chkword() 561*7c478bd9Sstevel@tonic-gate { 562*7c478bd9Sstevel@tonic-gate if (word()) 563*7c478bd9Sstevel@tonic-gate synbad(); 564*7c478bd9Sstevel@tonic-gate } 565*7c478bd9Sstevel@tonic-gate 566*7c478bd9Sstevel@tonic-gate static int 567*7c478bd9Sstevel@tonic-gate chksym(sym) 568*7c478bd9Sstevel@tonic-gate { 569*7c478bd9Sstevel@tonic-gate register int x = sym & wdval; 570*7c478bd9Sstevel@tonic-gate 571*7c478bd9Sstevel@tonic-gate if (((x & SYMFLG) ? x : sym) != wdval) 572*7c478bd9Sstevel@tonic-gate synbad(); 573*7c478bd9Sstevel@tonic-gate } 574*7c478bd9Sstevel@tonic-gate 575*7c478bd9Sstevel@tonic-gate static int 576*7c478bd9Sstevel@tonic-gate prsym(sym) 577*7c478bd9Sstevel@tonic-gate { 578*7c478bd9Sstevel@tonic-gate if (sym & SYMFLG) 579*7c478bd9Sstevel@tonic-gate { 580*7c478bd9Sstevel@tonic-gate register const struct sysnod *sp = reserved; 581*7c478bd9Sstevel@tonic-gate 582*7c478bd9Sstevel@tonic-gate while (sp->sysval && sp->sysval != sym) 583*7c478bd9Sstevel@tonic-gate sp++; 584*7c478bd9Sstevel@tonic-gate prs(sp->sysnam); 585*7c478bd9Sstevel@tonic-gate } 586*7c478bd9Sstevel@tonic-gate else if (sym == EOFSYM) 587*7c478bd9Sstevel@tonic-gate prs(endoffile); 588*7c478bd9Sstevel@tonic-gate else 589*7c478bd9Sstevel@tonic-gate { 590*7c478bd9Sstevel@tonic-gate if (sym & SYMREP) 591*7c478bd9Sstevel@tonic-gate prc(sym); 592*7c478bd9Sstevel@tonic-gate if (sym == NL) 593*7c478bd9Sstevel@tonic-gate prs("newline or ;"); 594*7c478bd9Sstevel@tonic-gate else 595*7c478bd9Sstevel@tonic-gate prc(sym); 596*7c478bd9Sstevel@tonic-gate } 597*7c478bd9Sstevel@tonic-gate } 598*7c478bd9Sstevel@tonic-gate 599*7c478bd9Sstevel@tonic-gate static int 600*7c478bd9Sstevel@tonic-gate synbad() 601*7c478bd9Sstevel@tonic-gate { 602*7c478bd9Sstevel@tonic-gate prp(); 603*7c478bd9Sstevel@tonic-gate prs(synmsg); 604*7c478bd9Sstevel@tonic-gate if ((flags & ttyflg) == 0) 605*7c478bd9Sstevel@tonic-gate { 606*7c478bd9Sstevel@tonic-gate prs(atline); 607*7c478bd9Sstevel@tonic-gate prn(standin->flin); 608*7c478bd9Sstevel@tonic-gate } 609*7c478bd9Sstevel@tonic-gate prs(colon); 610*7c478bd9Sstevel@tonic-gate prc(LQ); 611*7c478bd9Sstevel@tonic-gate if (wdval) 612*7c478bd9Sstevel@tonic-gate prsym(wdval); 613*7c478bd9Sstevel@tonic-gate else 614*7c478bd9Sstevel@tonic-gate prs_cntl(wdarg->argval); 615*7c478bd9Sstevel@tonic-gate prc(RQ); 616*7c478bd9Sstevel@tonic-gate prs(unexpected); 617*7c478bd9Sstevel@tonic-gate newline(); 618*7c478bd9Sstevel@tonic-gate exitsh(SYNBAD); 619*7c478bd9Sstevel@tonic-gate } 620