10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
52256Sna195498 * Common Development and Distribution License (the "License").
62256Sna195498 * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate *
80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate * See the License for the specific language governing permissions
110Sstevel@tonic-gate * and limitations under the License.
120Sstevel@tonic-gate *
130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate *
190Sstevel@tonic-gate * CDDL HEADER END
200Sstevel@tonic-gate */
21527Schin
22527Schin /*
23*9369SNobutomo.Nakano@Sun.COM * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
24527Schin * Use is subject to license terms.
25527Schin */
26527Schin
270Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
280Sstevel@tonic-gate /* All Rights Reserved */
290Sstevel@tonic-gate
300Sstevel@tonic-gate /*
310Sstevel@tonic-gate * UNIX shell
320Sstevel@tonic-gate */
330Sstevel@tonic-gate
340Sstevel@tonic-gate #include "defs.h"
350Sstevel@tonic-gate #include "sym.h"
360Sstevel@tonic-gate
370Sstevel@tonic-gate static struct ionod * inout();
38527Schin static void chkword(void);
39527Schin static void chksym(int);
400Sstevel@tonic-gate static struct trenod * term();
410Sstevel@tonic-gate static struct trenod * makelist();
420Sstevel@tonic-gate static struct trenod * list();
430Sstevel@tonic-gate static struct regnod * syncase();
440Sstevel@tonic-gate static struct trenod * item();
450Sstevel@tonic-gate static int skipnl();
46527Schin static void prsym(int);
47527Schin static void synbad(void);
480Sstevel@tonic-gate
490Sstevel@tonic-gate
500Sstevel@tonic-gate /* ======== storage allocation for functions ======== */
510Sstevel@tonic-gate
520Sstevel@tonic-gate unsigned char *
getstor(asize)530Sstevel@tonic-gate getstor(asize)
540Sstevel@tonic-gate int asize;
550Sstevel@tonic-gate {
560Sstevel@tonic-gate if (fndef)
570Sstevel@tonic-gate return((unsigned char *)alloc(asize));
580Sstevel@tonic-gate else
590Sstevel@tonic-gate return(getstak(asize));
600Sstevel@tonic-gate }
610Sstevel@tonic-gate
620Sstevel@tonic-gate
630Sstevel@tonic-gate /* ======== command line decoding ========*/
640Sstevel@tonic-gate
650Sstevel@tonic-gate
660Sstevel@tonic-gate
670Sstevel@tonic-gate
680Sstevel@tonic-gate struct trenod *
makefork(flgs,i)690Sstevel@tonic-gate makefork(flgs, i)
700Sstevel@tonic-gate int flgs;
710Sstevel@tonic-gate struct trenod *i;
720Sstevel@tonic-gate {
73527Schin struct forknod *t;
740Sstevel@tonic-gate
750Sstevel@tonic-gate t = (struct forknod *)getstor(sizeof(struct forknod));
760Sstevel@tonic-gate t->forktyp = flgs|TFORK;
770Sstevel@tonic-gate t->forktre = i;
780Sstevel@tonic-gate t->forkio = 0;
790Sstevel@tonic-gate return((struct trenod *)t);
800Sstevel@tonic-gate }
810Sstevel@tonic-gate
820Sstevel@tonic-gate static struct trenod *
makelist(type,i,r)830Sstevel@tonic-gate makelist(type, i, r)
840Sstevel@tonic-gate int type;
850Sstevel@tonic-gate struct trenod *i, *r;
860Sstevel@tonic-gate {
87527Schin struct lstnod *t;
880Sstevel@tonic-gate
890Sstevel@tonic-gate if (i == 0 || r == 0)
900Sstevel@tonic-gate synbad();
910Sstevel@tonic-gate else
920Sstevel@tonic-gate {
930Sstevel@tonic-gate t = (struct lstnod *)getstor(sizeof(struct lstnod));
940Sstevel@tonic-gate t->lsttyp = type;
950Sstevel@tonic-gate t->lstlef = i;
960Sstevel@tonic-gate t->lstrit = r;
970Sstevel@tonic-gate }
980Sstevel@tonic-gate return((struct trenod *)t);
990Sstevel@tonic-gate }
1000Sstevel@tonic-gate
1010Sstevel@tonic-gate /*
1020Sstevel@tonic-gate * cmd
1030Sstevel@tonic-gate * empty
1040Sstevel@tonic-gate * list
1050Sstevel@tonic-gate * list & [ cmd ]
1060Sstevel@tonic-gate * list [ ; cmd ]
1070Sstevel@tonic-gate */
1080Sstevel@tonic-gate struct trenod *
cmd(sym,flg)1090Sstevel@tonic-gate cmd(sym, flg)
110527Schin int sym;
1110Sstevel@tonic-gate int flg;
1120Sstevel@tonic-gate {
113527Schin struct trenod *i, *e;
1140Sstevel@tonic-gate i = list(flg);
1150Sstevel@tonic-gate if (wdval == NL)
1160Sstevel@tonic-gate {
1170Sstevel@tonic-gate if (flg & NLFLG)
1180Sstevel@tonic-gate {
1190Sstevel@tonic-gate wdval = ';';
1200Sstevel@tonic-gate chkpr();
1210Sstevel@tonic-gate }
1220Sstevel@tonic-gate }
1230Sstevel@tonic-gate else if (i == 0 && (flg & MTFLG) == 0)
1240Sstevel@tonic-gate synbad();
1250Sstevel@tonic-gate
1260Sstevel@tonic-gate switch (wdval)
1270Sstevel@tonic-gate {
1280Sstevel@tonic-gate case '&':
1290Sstevel@tonic-gate if (i)
1300Sstevel@tonic-gate i = makefork(FAMP, i);
1310Sstevel@tonic-gate else
1320Sstevel@tonic-gate synbad();
1330Sstevel@tonic-gate
1340Sstevel@tonic-gate case ';':
1350Sstevel@tonic-gate if (e = cmd(sym, flg | MTFLG))
1360Sstevel@tonic-gate i = makelist(TLST, i, e);
1370Sstevel@tonic-gate else if (i == 0)
1380Sstevel@tonic-gate synbad();
1390Sstevel@tonic-gate break;
1400Sstevel@tonic-gate
1410Sstevel@tonic-gate case EOFSYM:
1420Sstevel@tonic-gate if (sym == NL)
1430Sstevel@tonic-gate break;
1440Sstevel@tonic-gate
1450Sstevel@tonic-gate default:
1460Sstevel@tonic-gate if (sym)
1470Sstevel@tonic-gate chksym(sym);
1480Sstevel@tonic-gate }
1490Sstevel@tonic-gate return(i);
1500Sstevel@tonic-gate }
1510Sstevel@tonic-gate
1520Sstevel@tonic-gate /*
1530Sstevel@tonic-gate * list
1540Sstevel@tonic-gate * term
1550Sstevel@tonic-gate * list && term
1560Sstevel@tonic-gate * list || term
1570Sstevel@tonic-gate */
1580Sstevel@tonic-gate static struct trenod *
list(flg)1590Sstevel@tonic-gate list(flg)
1600Sstevel@tonic-gate {
161527Schin struct trenod *r;
162527Schin int b;
1630Sstevel@tonic-gate r = term(flg);
1640Sstevel@tonic-gate while (r && ((b = (wdval == ANDFSYM)) || wdval == ORFSYM))
1650Sstevel@tonic-gate r = makelist((b ? TAND : TORF), r, term(NLFLG));
1660Sstevel@tonic-gate return(r);
1670Sstevel@tonic-gate }
1680Sstevel@tonic-gate
1690Sstevel@tonic-gate /*
1700Sstevel@tonic-gate * term
1710Sstevel@tonic-gate * item
1720Sstevel@tonic-gate * item |^ term
1730Sstevel@tonic-gate */
1740Sstevel@tonic-gate static struct trenod *
term(flg)1750Sstevel@tonic-gate term(flg)
1760Sstevel@tonic-gate {
177527Schin struct trenod *t;
1780Sstevel@tonic-gate
1790Sstevel@tonic-gate reserv++;
1800Sstevel@tonic-gate if (flg & NLFLG)
1810Sstevel@tonic-gate skipnl();
1820Sstevel@tonic-gate else
1830Sstevel@tonic-gate word();
1840Sstevel@tonic-gate if ((t = item(TRUE)) && (wdval == '^' || wdval == '|'))
1850Sstevel@tonic-gate {
1860Sstevel@tonic-gate struct trenod *left;
1870Sstevel@tonic-gate struct trenod *right;
1880Sstevel@tonic-gate
1890Sstevel@tonic-gate left = makefork(FPOU, t);
1900Sstevel@tonic-gate right = makefork(FPIN, term(NLFLG));
1910Sstevel@tonic-gate return(makefork(0, makelist(TFIL, left, right)));
1920Sstevel@tonic-gate }
1930Sstevel@tonic-gate else
1940Sstevel@tonic-gate return(t);
1950Sstevel@tonic-gate }
1960Sstevel@tonic-gate
1970Sstevel@tonic-gate
1980Sstevel@tonic-gate static struct regnod *
syncase(esym)1990Sstevel@tonic-gate syncase(esym)
200527Schin int esym;
2010Sstevel@tonic-gate {
2020Sstevel@tonic-gate skipnl();
2030Sstevel@tonic-gate if (wdval == esym)
2040Sstevel@tonic-gate return(0);
2050Sstevel@tonic-gate else
2060Sstevel@tonic-gate {
207527Schin struct regnod *r =
208527Schin (struct regnod *)getstor(sizeof (struct regnod));
209527Schin struct argnod *argp;
2100Sstevel@tonic-gate
2110Sstevel@tonic-gate r->regptr = 0;
2120Sstevel@tonic-gate for (;;)
2130Sstevel@tonic-gate {
2140Sstevel@tonic-gate if (fndef)
2150Sstevel@tonic-gate {
2160Sstevel@tonic-gate argp= wdarg;
2170Sstevel@tonic-gate wdarg = (struct argnod *)alloc(length(argp->argval) + BYTESPERWORD);
2180Sstevel@tonic-gate movstr(argp->argval, wdarg->argval);
2190Sstevel@tonic-gate }
2200Sstevel@tonic-gate
2210Sstevel@tonic-gate wdarg->argnxt = r->regptr;
2220Sstevel@tonic-gate r->regptr = wdarg;
2230Sstevel@tonic-gate
2240Sstevel@tonic-gate /* 'in' is not a reserved word in this case */
2250Sstevel@tonic-gate if (wdval == INSYM){
2260Sstevel@tonic-gate wdval = 0;
2270Sstevel@tonic-gate }
2280Sstevel@tonic-gate if (wdval || (word() != ')' && wdval != '|'))
2290Sstevel@tonic-gate synbad();
2300Sstevel@tonic-gate if (wdval == '|')
2310Sstevel@tonic-gate word();
2320Sstevel@tonic-gate else
2330Sstevel@tonic-gate break;
2340Sstevel@tonic-gate }
2350Sstevel@tonic-gate r->regcom = cmd(0, NLFLG | MTFLG);
2360Sstevel@tonic-gate if (wdval == ECSYM)
2370Sstevel@tonic-gate r->regnxt = syncase(esym);
2380Sstevel@tonic-gate else
2390Sstevel@tonic-gate {
2400Sstevel@tonic-gate chksym(esym);
2410Sstevel@tonic-gate r->regnxt = 0;
2420Sstevel@tonic-gate }
2430Sstevel@tonic-gate return(r);
2440Sstevel@tonic-gate }
2450Sstevel@tonic-gate }
2460Sstevel@tonic-gate
2470Sstevel@tonic-gate /*
2480Sstevel@tonic-gate * item
2490Sstevel@tonic-gate *
2500Sstevel@tonic-gate * ( cmd ) [ < in ] [ > out ]
2510Sstevel@tonic-gate * word word* [ < in ] [ > out ]
2520Sstevel@tonic-gate * if ... then ... else ... fi
2530Sstevel@tonic-gate * for ... while ... do ... done
2540Sstevel@tonic-gate * case ... in ... esac
2550Sstevel@tonic-gate * begin ... end
2560Sstevel@tonic-gate */
2570Sstevel@tonic-gate static struct trenod *
item(flag)2580Sstevel@tonic-gate item(flag)
2590Sstevel@tonic-gate BOOL flag;
2600Sstevel@tonic-gate {
261527Schin struct trenod *r;
262527Schin struct ionod *io;
2630Sstevel@tonic-gate
2640Sstevel@tonic-gate if (flag)
2650Sstevel@tonic-gate io = inout((struct ionod *)0);
2660Sstevel@tonic-gate else
2670Sstevel@tonic-gate io = 0;
2680Sstevel@tonic-gate switch (wdval)
2690Sstevel@tonic-gate {
2700Sstevel@tonic-gate case CASYM:
2710Sstevel@tonic-gate {
272527Schin struct swnod *t;
2730Sstevel@tonic-gate
2740Sstevel@tonic-gate t = (struct swnod *)getstor(sizeof(struct swnod));
2750Sstevel@tonic-gate r = (struct trenod *)t;
2760Sstevel@tonic-gate
2770Sstevel@tonic-gate chkword();
2780Sstevel@tonic-gate if (fndef)
2790Sstevel@tonic-gate t->swarg = make(wdarg->argval);
2800Sstevel@tonic-gate else
2810Sstevel@tonic-gate t->swarg = wdarg->argval;
2820Sstevel@tonic-gate skipnl();
2830Sstevel@tonic-gate chksym(INSYM | BRSYM);
2840Sstevel@tonic-gate t->swlst = syncase(wdval == INSYM ? ESSYM : KTSYM);
2850Sstevel@tonic-gate t->swtyp = TSW;
2860Sstevel@tonic-gate break;
2870Sstevel@tonic-gate }
2880Sstevel@tonic-gate
2890Sstevel@tonic-gate case IFSYM:
2900Sstevel@tonic-gate {
291527Schin int w;
292527Schin struct ifnod *t;
2930Sstevel@tonic-gate
2940Sstevel@tonic-gate t = (struct ifnod *)getstor(sizeof(struct ifnod));
2950Sstevel@tonic-gate r = (struct trenod *)t;
2960Sstevel@tonic-gate
2970Sstevel@tonic-gate t->iftyp = TIF;
2980Sstevel@tonic-gate t->iftre = cmd(THSYM, NLFLG);
2990Sstevel@tonic-gate t->thtre = cmd(ELSYM | FISYM | EFSYM, NLFLG);
3000Sstevel@tonic-gate t->eltre = ((w = wdval) == ELSYM ? cmd(FISYM, NLFLG) : (w == EFSYM ? (wdval = IFSYM, item(0)) : 0));
3010Sstevel@tonic-gate if (w == EFSYM)
3020Sstevel@tonic-gate return(r);
3030Sstevel@tonic-gate break;
3040Sstevel@tonic-gate }
3050Sstevel@tonic-gate
3060Sstevel@tonic-gate case FORSYM:
3070Sstevel@tonic-gate {
308527Schin struct fornod *t;
3090Sstevel@tonic-gate
3100Sstevel@tonic-gate t = (struct fornod *)getstor(sizeof(struct fornod));
3110Sstevel@tonic-gate r = (struct trenod *)t;
3120Sstevel@tonic-gate
3130Sstevel@tonic-gate t->fortyp = TFOR;
3140Sstevel@tonic-gate t->forlst = 0;
3150Sstevel@tonic-gate chkword();
3160Sstevel@tonic-gate if (fndef)
3170Sstevel@tonic-gate t->fornam = make(wdarg->argval);
3180Sstevel@tonic-gate else
3190Sstevel@tonic-gate t->fornam = wdarg->argval;
3200Sstevel@tonic-gate if (skipnl() == INSYM)
3210Sstevel@tonic-gate {
3220Sstevel@tonic-gate chkword();
3230Sstevel@tonic-gate
3240Sstevel@tonic-gate nohash++;
3250Sstevel@tonic-gate t->forlst = (struct comnod *)item(0);
3260Sstevel@tonic-gate nohash--;
3270Sstevel@tonic-gate
3280Sstevel@tonic-gate if (wdval != NL && wdval != ';')
3290Sstevel@tonic-gate synbad();
3300Sstevel@tonic-gate if (wdval == NL)
3310Sstevel@tonic-gate chkpr();
3320Sstevel@tonic-gate skipnl();
3330Sstevel@tonic-gate }
3340Sstevel@tonic-gate chksym(DOSYM | BRSYM);
3350Sstevel@tonic-gate t->fortre = cmd(wdval == DOSYM ? ODSYM : KTSYM, NLFLG);
3360Sstevel@tonic-gate break;
3370Sstevel@tonic-gate }
3380Sstevel@tonic-gate
3390Sstevel@tonic-gate case WHSYM:
3400Sstevel@tonic-gate case UNSYM:
3410Sstevel@tonic-gate {
342527Schin struct whnod *t;
3430Sstevel@tonic-gate
3440Sstevel@tonic-gate t = (struct whnod *)getstor(sizeof(struct whnod));
3450Sstevel@tonic-gate r = (struct trenod *)t;
3460Sstevel@tonic-gate
3470Sstevel@tonic-gate t->whtyp = (wdval == WHSYM ? TWH : TUN);
3480Sstevel@tonic-gate t->whtre = cmd(DOSYM, NLFLG);
3490Sstevel@tonic-gate t->dotre = cmd(ODSYM, NLFLG);
3500Sstevel@tonic-gate break;
3510Sstevel@tonic-gate }
3520Sstevel@tonic-gate
3530Sstevel@tonic-gate case BRSYM:
3540Sstevel@tonic-gate r = cmd(KTSYM, NLFLG);
3550Sstevel@tonic-gate break;
3560Sstevel@tonic-gate
3570Sstevel@tonic-gate case '(':
3580Sstevel@tonic-gate {
359527Schin struct parnod *p;
3600Sstevel@tonic-gate
3610Sstevel@tonic-gate p = (struct parnod *)getstor(sizeof(struct parnod));
3620Sstevel@tonic-gate p->partre = cmd(')', NLFLG);
3630Sstevel@tonic-gate p->partyp = TPAR;
3640Sstevel@tonic-gate r = makefork(0, p);
3650Sstevel@tonic-gate break;
3660Sstevel@tonic-gate }
3670Sstevel@tonic-gate
3680Sstevel@tonic-gate default:
3690Sstevel@tonic-gate if (io == 0)
3700Sstevel@tonic-gate return(0);
3710Sstevel@tonic-gate
3720Sstevel@tonic-gate case 0:
3730Sstevel@tonic-gate {
374527Schin struct comnod *t;
375527Schin struct argnod *argp;
376527Schin struct argnod **argtail;
377527Schin struct argnod **argset = 0;
3780Sstevel@tonic-gate int keywd = 1;
3790Sstevel@tonic-gate unsigned char *com;
3800Sstevel@tonic-gate
3810Sstevel@tonic-gate if ((wdval != NL) && ((peekn = skipwc()) == '('))
3820Sstevel@tonic-gate {
3830Sstevel@tonic-gate struct fndnod *f;
3840Sstevel@tonic-gate struct ionod *saveio;
3850Sstevel@tonic-gate
3860Sstevel@tonic-gate saveio = iotemp;
3870Sstevel@tonic-gate peekn = 0;
3880Sstevel@tonic-gate if (skipwc() != ')')
3890Sstevel@tonic-gate synbad();
3900Sstevel@tonic-gate
391*9369SNobutomo.Nakano@Sun.COM /*
392*9369SNobutomo.Nakano@Sun.COM * We increase fndef before calling getstor(),
393*9369SNobutomo.Nakano@Sun.COM * so that getstor() uses malloc to allocate
394*9369SNobutomo.Nakano@Sun.COM * memory instead of stack. This is necessary
395*9369SNobutomo.Nakano@Sun.COM * since fndnod will be hung on np->namenv,
396*9369SNobutomo.Nakano@Sun.COM * which persists over command executions.
397*9369SNobutomo.Nakano@Sun.COM */
398*9369SNobutomo.Nakano@Sun.COM fndef++;
3990Sstevel@tonic-gate f = (struct fndnod *)getstor(sizeof(struct fndnod));
4000Sstevel@tonic-gate r = (struct trenod *)f;
4010Sstevel@tonic-gate
4020Sstevel@tonic-gate f->fndtyp = TFND;
403*9369SNobutomo.Nakano@Sun.COM f->fndnam = make(wdarg->argval);
404*9369SNobutomo.Nakano@Sun.COM f->fndref = 0;
4050Sstevel@tonic-gate reserv++;
4060Sstevel@tonic-gate skipnl();
4070Sstevel@tonic-gate f->fndval = (struct trenod *)item(0);
4080Sstevel@tonic-gate fndef--;
4090Sstevel@tonic-gate
4100Sstevel@tonic-gate if (iotemp != saveio)
4110Sstevel@tonic-gate {
4120Sstevel@tonic-gate struct ionod *ioptr = iotemp;
4130Sstevel@tonic-gate
4140Sstevel@tonic-gate while (ioptr->iolst != saveio)
4150Sstevel@tonic-gate ioptr = ioptr->iolst;
4160Sstevel@tonic-gate
4170Sstevel@tonic-gate ioptr->iolst = fiotemp;
4180Sstevel@tonic-gate fiotemp = iotemp;
4190Sstevel@tonic-gate iotemp = saveio;
4200Sstevel@tonic-gate }
4210Sstevel@tonic-gate return(r);
4220Sstevel@tonic-gate }
4230Sstevel@tonic-gate else
4240Sstevel@tonic-gate {
4250Sstevel@tonic-gate t = (struct comnod *)getstor(sizeof(struct comnod));
4260Sstevel@tonic-gate r = (struct trenod *)t;
4270Sstevel@tonic-gate
4280Sstevel@tonic-gate t->comio = io; /*initial io chain*/
4290Sstevel@tonic-gate argtail = &(t->comarg);
4300Sstevel@tonic-gate
4310Sstevel@tonic-gate while (wdval == 0)
4320Sstevel@tonic-gate {
4330Sstevel@tonic-gate if (fndef)
4340Sstevel@tonic-gate {
4350Sstevel@tonic-gate argp = wdarg;
4360Sstevel@tonic-gate wdarg = (struct argnod *)alloc(length(argp->argval) + BYTESPERWORD);
4370Sstevel@tonic-gate movstr(argp->argval, wdarg->argval);
4380Sstevel@tonic-gate }
4390Sstevel@tonic-gate
4400Sstevel@tonic-gate argp = wdarg;
4410Sstevel@tonic-gate if (wdset && keywd)
4420Sstevel@tonic-gate {
4430Sstevel@tonic-gate argp->argnxt = (struct argnod *)argset;
4440Sstevel@tonic-gate argset = (struct argnod **)argp;
4450Sstevel@tonic-gate }
4460Sstevel@tonic-gate else
4470Sstevel@tonic-gate {
4480Sstevel@tonic-gate *argtail = argp;
4490Sstevel@tonic-gate argtail = &(argp->argnxt);
4500Sstevel@tonic-gate keywd = flags & keyflg;
4510Sstevel@tonic-gate }
4520Sstevel@tonic-gate word();
4530Sstevel@tonic-gate if (flag)
4540Sstevel@tonic-gate {
4550Sstevel@tonic-gate if (io)
4560Sstevel@tonic-gate {
4570Sstevel@tonic-gate while(io->ionxt)
4580Sstevel@tonic-gate io = io->ionxt;
4590Sstevel@tonic-gate io->ionxt = inout((struct ionod *)0);
4600Sstevel@tonic-gate }
4610Sstevel@tonic-gate else
4620Sstevel@tonic-gate t->comio = io = inout((struct ionod *)0);
4630Sstevel@tonic-gate }
4640Sstevel@tonic-gate }
4650Sstevel@tonic-gate
4660Sstevel@tonic-gate t->comtyp = TCOM;
4670Sstevel@tonic-gate t->comset = (struct argnod *)argset;
4680Sstevel@tonic-gate *argtail = 0;
4690Sstevel@tonic-gate
4700Sstevel@tonic-gate if (nohash == 0 && (fndef == 0 || (flags & hashflg)))
4710Sstevel@tonic-gate {
4720Sstevel@tonic-gate if (t->comarg)
4730Sstevel@tonic-gate {
4740Sstevel@tonic-gate com = t->comarg->argval;
4750Sstevel@tonic-gate if (*com && *com != DOLLAR)
4760Sstevel@tonic-gate pathlook(com, 0, t->comset);
4770Sstevel@tonic-gate }
4780Sstevel@tonic-gate }
4790Sstevel@tonic-gate
4800Sstevel@tonic-gate return(r);
4810Sstevel@tonic-gate }
4820Sstevel@tonic-gate }
4830Sstevel@tonic-gate
4840Sstevel@tonic-gate }
4850Sstevel@tonic-gate reserv++;
4860Sstevel@tonic-gate word();
4870Sstevel@tonic-gate if (io = inout(io))
4880Sstevel@tonic-gate {
4890Sstevel@tonic-gate r = makefork(0,r);
4900Sstevel@tonic-gate r->treio = io;
4910Sstevel@tonic-gate }
4920Sstevel@tonic-gate return(r);
4930Sstevel@tonic-gate }
4940Sstevel@tonic-gate
4950Sstevel@tonic-gate
4960Sstevel@tonic-gate static int
skipnl()4970Sstevel@tonic-gate skipnl()
4980Sstevel@tonic-gate {
4990Sstevel@tonic-gate while ((reserv++, word() == NL))
5000Sstevel@tonic-gate chkpr();
5010Sstevel@tonic-gate return(wdval);
5020Sstevel@tonic-gate }
5030Sstevel@tonic-gate
5040Sstevel@tonic-gate static struct ionod *
inout(lastio)5050Sstevel@tonic-gate inout(lastio)
5060Sstevel@tonic-gate struct ionod *lastio;
5070Sstevel@tonic-gate {
508527Schin int iof;
509527Schin struct ionod *iop;
510527Schin unsigned int c;
5110Sstevel@tonic-gate
5120Sstevel@tonic-gate iof = wdnum;
5130Sstevel@tonic-gate switch (wdval)
5140Sstevel@tonic-gate {
5150Sstevel@tonic-gate case DOCSYM: /* << */
5165976Snakanon iof |= IODOC|IODOC_SUBST;
5170Sstevel@tonic-gate break;
5180Sstevel@tonic-gate
5190Sstevel@tonic-gate case APPSYM: /* >> */
5200Sstevel@tonic-gate case '>':
5210Sstevel@tonic-gate if (wdnum == 0)
5220Sstevel@tonic-gate iof |= 1;
5230Sstevel@tonic-gate iof |= IOPUT;
5240Sstevel@tonic-gate if (wdval == APPSYM)
5250Sstevel@tonic-gate {
5260Sstevel@tonic-gate iof |= IOAPP;
5270Sstevel@tonic-gate break;
5280Sstevel@tonic-gate }
5290Sstevel@tonic-gate
5300Sstevel@tonic-gate case '<':
5310Sstevel@tonic-gate if ((c = nextwc()) == '&')
5320Sstevel@tonic-gate iof |= IOMOV;
5330Sstevel@tonic-gate else if (c == '>')
5340Sstevel@tonic-gate iof |= IORDW;
5350Sstevel@tonic-gate else
5360Sstevel@tonic-gate peekn = c | MARK;
5370Sstevel@tonic-gate break;
5380Sstevel@tonic-gate
5390Sstevel@tonic-gate default:
5400Sstevel@tonic-gate return(lastio);
5410Sstevel@tonic-gate }
5420Sstevel@tonic-gate
5430Sstevel@tonic-gate chkword();
5440Sstevel@tonic-gate iop = (struct ionod *)getstor(sizeof(struct ionod));
5450Sstevel@tonic-gate
5460Sstevel@tonic-gate if (fndef)
5470Sstevel@tonic-gate iop->ioname = (char *) make(wdarg->argval);
5480Sstevel@tonic-gate else
5490Sstevel@tonic-gate iop->ioname = (char *) (wdarg->argval);
5500Sstevel@tonic-gate
5510Sstevel@tonic-gate iop->iolink = 0;
5520Sstevel@tonic-gate iop->iofile = iof;
5530Sstevel@tonic-gate if (iof & IODOC)
5540Sstevel@tonic-gate {
5550Sstevel@tonic-gate iop->iolst = iopend;
5560Sstevel@tonic-gate iopend = iop;
5570Sstevel@tonic-gate }
5580Sstevel@tonic-gate word();
5590Sstevel@tonic-gate iop->ionxt = inout(lastio);
5600Sstevel@tonic-gate return(iop);
5610Sstevel@tonic-gate }
5620Sstevel@tonic-gate
563527Schin static void
chkword(void)564527Schin chkword(void)
5650Sstevel@tonic-gate {
5660Sstevel@tonic-gate if (word())
5670Sstevel@tonic-gate synbad();
5680Sstevel@tonic-gate }
5690Sstevel@tonic-gate
570527Schin static void
chksym(int sym)571527Schin chksym(int sym)
5720Sstevel@tonic-gate {
573527Schin int x = sym & wdval;
5740Sstevel@tonic-gate
5750Sstevel@tonic-gate if (((x & SYMFLG) ? x : sym) != wdval)
5760Sstevel@tonic-gate synbad();
5770Sstevel@tonic-gate }
5780Sstevel@tonic-gate
579527Schin static void
prsym(int sym)580527Schin prsym(int sym)
5810Sstevel@tonic-gate {
5820Sstevel@tonic-gate if (sym & SYMFLG)
5830Sstevel@tonic-gate {
584527Schin const struct sysnod *sp = reserved;
5850Sstevel@tonic-gate
5860Sstevel@tonic-gate while (sp->sysval && sp->sysval != sym)
5870Sstevel@tonic-gate sp++;
5880Sstevel@tonic-gate prs(sp->sysnam);
5890Sstevel@tonic-gate }
5900Sstevel@tonic-gate else if (sym == EOFSYM)
5912256Sna195498 prs(_gettext(endoffile));
5920Sstevel@tonic-gate else
5930Sstevel@tonic-gate {
5940Sstevel@tonic-gate if (sym & SYMREP)
5950Sstevel@tonic-gate prc(sym);
5960Sstevel@tonic-gate if (sym == NL)
5972256Sna195498 prs(_gettext(nlorsemi));
5980Sstevel@tonic-gate else
5990Sstevel@tonic-gate prc(sym);
6000Sstevel@tonic-gate }
6010Sstevel@tonic-gate }
6020Sstevel@tonic-gate
603527Schin static void
synbad(void)604527Schin synbad(void)
6050Sstevel@tonic-gate {
6060Sstevel@tonic-gate prp();
6072256Sna195498 prs(_gettext(synmsg));
6080Sstevel@tonic-gate if ((flags & ttyflg) == 0)
6090Sstevel@tonic-gate {
6102256Sna195498 prs(_gettext(atline));
6110Sstevel@tonic-gate prn(standin->flin);
6120Sstevel@tonic-gate }
6130Sstevel@tonic-gate prs(colon);
6140Sstevel@tonic-gate prc(LQ);
6150Sstevel@tonic-gate if (wdval)
6160Sstevel@tonic-gate prsym(wdval);
6170Sstevel@tonic-gate else
6180Sstevel@tonic-gate prs_cntl(wdarg->argval);
6190Sstevel@tonic-gate prc(RQ);
6202256Sna195498 prs(_gettext(unexpected));
6210Sstevel@tonic-gate newline();
6220Sstevel@tonic-gate exitsh(SYNBAD);
6230Sstevel@tonic-gate }
624