17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 57c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 67c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 77c478bd9Sstevel@tonic-gate * with the License. 87c478bd9Sstevel@tonic-gate * 97c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 107c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 117c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 127c478bd9Sstevel@tonic-gate * and limitations under the License. 137c478bd9Sstevel@tonic-gate * 147c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 157c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 167c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 177c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 187c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 197c478bd9Sstevel@tonic-gate * 207c478bd9Sstevel@tonic-gate * CDDL HEADER END 217c478bd9Sstevel@tonic-gate */ 22*965005c8Schin 23*965005c8Schin /* 24*965005c8Schin * Copyright 1997 Sun Microsystems, Inc. All rights reserved. 25*965005c8Schin * Use is subject to license terms. 26*965005c8Schin */ 27*965005c8Schin 287c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 297c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 307c478bd9Sstevel@tonic-gate 31*965005c8Schin #pragma ident "%Z%%M% %I% %E% SMI" 327c478bd9Sstevel@tonic-gate /* 337c478bd9Sstevel@tonic-gate * UNIX shell 347c478bd9Sstevel@tonic-gate */ 357c478bd9Sstevel@tonic-gate 367c478bd9Sstevel@tonic-gate #include "defs.h" 377c478bd9Sstevel@tonic-gate #include "sym.h" 387c478bd9Sstevel@tonic-gate 397c478bd9Sstevel@tonic-gate static struct ionod * inout(); 40*965005c8Schin static void chkword(void); 41*965005c8Schin static void chksym(int); 427c478bd9Sstevel@tonic-gate static struct trenod * term(); 437c478bd9Sstevel@tonic-gate static struct trenod * makelist(); 447c478bd9Sstevel@tonic-gate static struct trenod * list(); 457c478bd9Sstevel@tonic-gate static struct regnod * syncase(); 467c478bd9Sstevel@tonic-gate static struct trenod * item(); 477c478bd9Sstevel@tonic-gate static int skipnl(); 48*965005c8Schin static void prsym(int); 49*965005c8Schin static void synbad(void); 507c478bd9Sstevel@tonic-gate 517c478bd9Sstevel@tonic-gate 527c478bd9Sstevel@tonic-gate /* ======== storage allocation for functions ======== */ 537c478bd9Sstevel@tonic-gate 547c478bd9Sstevel@tonic-gate unsigned char * 557c478bd9Sstevel@tonic-gate getstor(asize) 567c478bd9Sstevel@tonic-gate int asize; 577c478bd9Sstevel@tonic-gate { 587c478bd9Sstevel@tonic-gate if (fndef) 597c478bd9Sstevel@tonic-gate return((unsigned char *)alloc(asize)); 607c478bd9Sstevel@tonic-gate else 617c478bd9Sstevel@tonic-gate return(getstak(asize)); 627c478bd9Sstevel@tonic-gate } 637c478bd9Sstevel@tonic-gate 647c478bd9Sstevel@tonic-gate 657c478bd9Sstevel@tonic-gate /* ======== command line decoding ========*/ 667c478bd9Sstevel@tonic-gate 677c478bd9Sstevel@tonic-gate 687c478bd9Sstevel@tonic-gate 697c478bd9Sstevel@tonic-gate 707c478bd9Sstevel@tonic-gate struct trenod * 717c478bd9Sstevel@tonic-gate makefork(flgs, i) 727c478bd9Sstevel@tonic-gate int flgs; 737c478bd9Sstevel@tonic-gate struct trenod *i; 747c478bd9Sstevel@tonic-gate { 75*965005c8Schin struct forknod *t; 767c478bd9Sstevel@tonic-gate 777c478bd9Sstevel@tonic-gate t = (struct forknod *)getstor(sizeof(struct forknod)); 787c478bd9Sstevel@tonic-gate t->forktyp = flgs|TFORK; 797c478bd9Sstevel@tonic-gate t->forktre = i; 807c478bd9Sstevel@tonic-gate t->forkio = 0; 817c478bd9Sstevel@tonic-gate return((struct trenod *)t); 827c478bd9Sstevel@tonic-gate } 837c478bd9Sstevel@tonic-gate 847c478bd9Sstevel@tonic-gate static struct trenod * 857c478bd9Sstevel@tonic-gate makelist(type, i, r) 867c478bd9Sstevel@tonic-gate int type; 877c478bd9Sstevel@tonic-gate struct trenod *i, *r; 887c478bd9Sstevel@tonic-gate { 89*965005c8Schin struct lstnod *t; 907c478bd9Sstevel@tonic-gate 917c478bd9Sstevel@tonic-gate if (i == 0 || r == 0) 927c478bd9Sstevel@tonic-gate synbad(); 937c478bd9Sstevel@tonic-gate else 947c478bd9Sstevel@tonic-gate { 957c478bd9Sstevel@tonic-gate t = (struct lstnod *)getstor(sizeof(struct lstnod)); 967c478bd9Sstevel@tonic-gate t->lsttyp = type; 977c478bd9Sstevel@tonic-gate t->lstlef = i; 987c478bd9Sstevel@tonic-gate t->lstrit = r; 997c478bd9Sstevel@tonic-gate } 1007c478bd9Sstevel@tonic-gate return((struct trenod *)t); 1017c478bd9Sstevel@tonic-gate } 1027c478bd9Sstevel@tonic-gate 1037c478bd9Sstevel@tonic-gate /* 1047c478bd9Sstevel@tonic-gate * cmd 1057c478bd9Sstevel@tonic-gate * empty 1067c478bd9Sstevel@tonic-gate * list 1077c478bd9Sstevel@tonic-gate * list & [ cmd ] 1087c478bd9Sstevel@tonic-gate * list [ ; cmd ] 1097c478bd9Sstevel@tonic-gate */ 1107c478bd9Sstevel@tonic-gate struct trenod * 1117c478bd9Sstevel@tonic-gate cmd(sym, flg) 112*965005c8Schin int sym; 1137c478bd9Sstevel@tonic-gate int flg; 1147c478bd9Sstevel@tonic-gate { 115*965005c8Schin struct trenod *i, *e; 1167c478bd9Sstevel@tonic-gate i = list(flg); 1177c478bd9Sstevel@tonic-gate if (wdval == NL) 1187c478bd9Sstevel@tonic-gate { 1197c478bd9Sstevel@tonic-gate if (flg & NLFLG) 1207c478bd9Sstevel@tonic-gate { 1217c478bd9Sstevel@tonic-gate wdval = ';'; 1227c478bd9Sstevel@tonic-gate chkpr(); 1237c478bd9Sstevel@tonic-gate } 1247c478bd9Sstevel@tonic-gate } 1257c478bd9Sstevel@tonic-gate else if (i == 0 && (flg & MTFLG) == 0) 1267c478bd9Sstevel@tonic-gate synbad(); 1277c478bd9Sstevel@tonic-gate 1287c478bd9Sstevel@tonic-gate switch (wdval) 1297c478bd9Sstevel@tonic-gate { 1307c478bd9Sstevel@tonic-gate case '&': 1317c478bd9Sstevel@tonic-gate if (i) 1327c478bd9Sstevel@tonic-gate i = makefork(FAMP, i); 1337c478bd9Sstevel@tonic-gate else 1347c478bd9Sstevel@tonic-gate synbad(); 1357c478bd9Sstevel@tonic-gate 1367c478bd9Sstevel@tonic-gate case ';': 1377c478bd9Sstevel@tonic-gate if (e = cmd(sym, flg | MTFLG)) 1387c478bd9Sstevel@tonic-gate i = makelist(TLST, i, e); 1397c478bd9Sstevel@tonic-gate else if (i == 0) 1407c478bd9Sstevel@tonic-gate synbad(); 1417c478bd9Sstevel@tonic-gate break; 1427c478bd9Sstevel@tonic-gate 1437c478bd9Sstevel@tonic-gate case EOFSYM: 1447c478bd9Sstevel@tonic-gate if (sym == NL) 1457c478bd9Sstevel@tonic-gate break; 1467c478bd9Sstevel@tonic-gate 1477c478bd9Sstevel@tonic-gate default: 1487c478bd9Sstevel@tonic-gate if (sym) 1497c478bd9Sstevel@tonic-gate chksym(sym); 1507c478bd9Sstevel@tonic-gate } 1517c478bd9Sstevel@tonic-gate return(i); 1527c478bd9Sstevel@tonic-gate } 1537c478bd9Sstevel@tonic-gate 1547c478bd9Sstevel@tonic-gate /* 1557c478bd9Sstevel@tonic-gate * list 1567c478bd9Sstevel@tonic-gate * term 1577c478bd9Sstevel@tonic-gate * list && term 1587c478bd9Sstevel@tonic-gate * list || term 1597c478bd9Sstevel@tonic-gate */ 1607c478bd9Sstevel@tonic-gate static struct trenod * 1617c478bd9Sstevel@tonic-gate list(flg) 1627c478bd9Sstevel@tonic-gate { 163*965005c8Schin struct trenod *r; 164*965005c8Schin int b; 1657c478bd9Sstevel@tonic-gate r = term(flg); 1667c478bd9Sstevel@tonic-gate while (r && ((b = (wdval == ANDFSYM)) || wdval == ORFSYM)) 1677c478bd9Sstevel@tonic-gate r = makelist((b ? TAND : TORF), r, term(NLFLG)); 1687c478bd9Sstevel@tonic-gate return(r); 1697c478bd9Sstevel@tonic-gate } 1707c478bd9Sstevel@tonic-gate 1717c478bd9Sstevel@tonic-gate /* 1727c478bd9Sstevel@tonic-gate * term 1737c478bd9Sstevel@tonic-gate * item 1747c478bd9Sstevel@tonic-gate * item |^ term 1757c478bd9Sstevel@tonic-gate */ 1767c478bd9Sstevel@tonic-gate static struct trenod * 1777c478bd9Sstevel@tonic-gate term(flg) 1787c478bd9Sstevel@tonic-gate { 179*965005c8Schin struct trenod *t; 1807c478bd9Sstevel@tonic-gate 1817c478bd9Sstevel@tonic-gate reserv++; 1827c478bd9Sstevel@tonic-gate if (flg & NLFLG) 1837c478bd9Sstevel@tonic-gate skipnl(); 1847c478bd9Sstevel@tonic-gate else 1857c478bd9Sstevel@tonic-gate word(); 1867c478bd9Sstevel@tonic-gate if ((t = item(TRUE)) && (wdval == '^' || wdval == '|')) 1877c478bd9Sstevel@tonic-gate { 1887c478bd9Sstevel@tonic-gate struct trenod *left; 1897c478bd9Sstevel@tonic-gate struct trenod *right; 1907c478bd9Sstevel@tonic-gate 1917c478bd9Sstevel@tonic-gate left = makefork(FPOU, t); 1927c478bd9Sstevel@tonic-gate right = makefork(FPIN, term(NLFLG)); 1937c478bd9Sstevel@tonic-gate return(makefork(0, makelist(TFIL, left, right))); 1947c478bd9Sstevel@tonic-gate } 1957c478bd9Sstevel@tonic-gate else 1967c478bd9Sstevel@tonic-gate return(t); 1977c478bd9Sstevel@tonic-gate } 1987c478bd9Sstevel@tonic-gate 1997c478bd9Sstevel@tonic-gate 2007c478bd9Sstevel@tonic-gate static struct regnod * 2017c478bd9Sstevel@tonic-gate syncase(esym) 202*965005c8Schin int esym; 2037c478bd9Sstevel@tonic-gate { 2047c478bd9Sstevel@tonic-gate skipnl(); 2057c478bd9Sstevel@tonic-gate if (wdval == esym) 2067c478bd9Sstevel@tonic-gate return(0); 2077c478bd9Sstevel@tonic-gate else 2087c478bd9Sstevel@tonic-gate { 209*965005c8Schin struct regnod *r = 210*965005c8Schin (struct regnod *)getstor(sizeof (struct regnod)); 211*965005c8Schin struct argnod *argp; 2127c478bd9Sstevel@tonic-gate 2137c478bd9Sstevel@tonic-gate r->regptr = 0; 2147c478bd9Sstevel@tonic-gate for (;;) 2157c478bd9Sstevel@tonic-gate { 2167c478bd9Sstevel@tonic-gate if (fndef) 2177c478bd9Sstevel@tonic-gate { 2187c478bd9Sstevel@tonic-gate argp= wdarg; 2197c478bd9Sstevel@tonic-gate wdarg = (struct argnod *)alloc(length(argp->argval) + BYTESPERWORD); 2207c478bd9Sstevel@tonic-gate movstr(argp->argval, wdarg->argval); 2217c478bd9Sstevel@tonic-gate } 2227c478bd9Sstevel@tonic-gate 2237c478bd9Sstevel@tonic-gate wdarg->argnxt = r->regptr; 2247c478bd9Sstevel@tonic-gate r->regptr = wdarg; 2257c478bd9Sstevel@tonic-gate 2267c478bd9Sstevel@tonic-gate /* 'in' is not a reserved word in this case */ 2277c478bd9Sstevel@tonic-gate if (wdval == INSYM){ 2287c478bd9Sstevel@tonic-gate wdval = 0; 2297c478bd9Sstevel@tonic-gate } 2307c478bd9Sstevel@tonic-gate if (wdval || (word() != ')' && wdval != '|')) 2317c478bd9Sstevel@tonic-gate synbad(); 2327c478bd9Sstevel@tonic-gate if (wdval == '|') 2337c478bd9Sstevel@tonic-gate word(); 2347c478bd9Sstevel@tonic-gate else 2357c478bd9Sstevel@tonic-gate break; 2367c478bd9Sstevel@tonic-gate } 2377c478bd9Sstevel@tonic-gate r->regcom = cmd(0, NLFLG | MTFLG); 2387c478bd9Sstevel@tonic-gate if (wdval == ECSYM) 2397c478bd9Sstevel@tonic-gate r->regnxt = syncase(esym); 2407c478bd9Sstevel@tonic-gate else 2417c478bd9Sstevel@tonic-gate { 2427c478bd9Sstevel@tonic-gate chksym(esym); 2437c478bd9Sstevel@tonic-gate r->regnxt = 0; 2447c478bd9Sstevel@tonic-gate } 2457c478bd9Sstevel@tonic-gate return(r); 2467c478bd9Sstevel@tonic-gate } 2477c478bd9Sstevel@tonic-gate } 2487c478bd9Sstevel@tonic-gate 2497c478bd9Sstevel@tonic-gate /* 2507c478bd9Sstevel@tonic-gate * item 2517c478bd9Sstevel@tonic-gate * 2527c478bd9Sstevel@tonic-gate * ( cmd ) [ < in ] [ > out ] 2537c478bd9Sstevel@tonic-gate * word word* [ < in ] [ > out ] 2547c478bd9Sstevel@tonic-gate * if ... then ... else ... fi 2557c478bd9Sstevel@tonic-gate * for ... while ... do ... done 2567c478bd9Sstevel@tonic-gate * case ... in ... esac 2577c478bd9Sstevel@tonic-gate * begin ... end 2587c478bd9Sstevel@tonic-gate */ 2597c478bd9Sstevel@tonic-gate static struct trenod * 2607c478bd9Sstevel@tonic-gate item(flag) 2617c478bd9Sstevel@tonic-gate BOOL flag; 2627c478bd9Sstevel@tonic-gate { 263*965005c8Schin struct trenod *r; 264*965005c8Schin struct ionod *io; 2657c478bd9Sstevel@tonic-gate 2667c478bd9Sstevel@tonic-gate if (flag) 2677c478bd9Sstevel@tonic-gate io = inout((struct ionod *)0); 2687c478bd9Sstevel@tonic-gate else 2697c478bd9Sstevel@tonic-gate io = 0; 2707c478bd9Sstevel@tonic-gate switch (wdval) 2717c478bd9Sstevel@tonic-gate { 2727c478bd9Sstevel@tonic-gate case CASYM: 2737c478bd9Sstevel@tonic-gate { 274*965005c8Schin struct swnod *t; 2757c478bd9Sstevel@tonic-gate 2767c478bd9Sstevel@tonic-gate t = (struct swnod *)getstor(sizeof(struct swnod)); 2777c478bd9Sstevel@tonic-gate r = (struct trenod *)t; 2787c478bd9Sstevel@tonic-gate 2797c478bd9Sstevel@tonic-gate chkword(); 2807c478bd9Sstevel@tonic-gate if (fndef) 2817c478bd9Sstevel@tonic-gate t->swarg = make(wdarg->argval); 2827c478bd9Sstevel@tonic-gate else 2837c478bd9Sstevel@tonic-gate t->swarg = wdarg->argval; 2847c478bd9Sstevel@tonic-gate skipnl(); 2857c478bd9Sstevel@tonic-gate chksym(INSYM | BRSYM); 2867c478bd9Sstevel@tonic-gate t->swlst = syncase(wdval == INSYM ? ESSYM : KTSYM); 2877c478bd9Sstevel@tonic-gate t->swtyp = TSW; 2887c478bd9Sstevel@tonic-gate break; 2897c478bd9Sstevel@tonic-gate } 2907c478bd9Sstevel@tonic-gate 2917c478bd9Sstevel@tonic-gate case IFSYM: 2927c478bd9Sstevel@tonic-gate { 293*965005c8Schin int w; 294*965005c8Schin struct ifnod *t; 2957c478bd9Sstevel@tonic-gate 2967c478bd9Sstevel@tonic-gate t = (struct ifnod *)getstor(sizeof(struct ifnod)); 2977c478bd9Sstevel@tonic-gate r = (struct trenod *)t; 2987c478bd9Sstevel@tonic-gate 2997c478bd9Sstevel@tonic-gate t->iftyp = TIF; 3007c478bd9Sstevel@tonic-gate t->iftre = cmd(THSYM, NLFLG); 3017c478bd9Sstevel@tonic-gate t->thtre = cmd(ELSYM | FISYM | EFSYM, NLFLG); 3027c478bd9Sstevel@tonic-gate t->eltre = ((w = wdval) == ELSYM ? cmd(FISYM, NLFLG) : (w == EFSYM ? (wdval = IFSYM, item(0)) : 0)); 3037c478bd9Sstevel@tonic-gate if (w == EFSYM) 3047c478bd9Sstevel@tonic-gate return(r); 3057c478bd9Sstevel@tonic-gate break; 3067c478bd9Sstevel@tonic-gate } 3077c478bd9Sstevel@tonic-gate 3087c478bd9Sstevel@tonic-gate case FORSYM: 3097c478bd9Sstevel@tonic-gate { 310*965005c8Schin struct fornod *t; 3117c478bd9Sstevel@tonic-gate 3127c478bd9Sstevel@tonic-gate t = (struct fornod *)getstor(sizeof(struct fornod)); 3137c478bd9Sstevel@tonic-gate r = (struct trenod *)t; 3147c478bd9Sstevel@tonic-gate 3157c478bd9Sstevel@tonic-gate t->fortyp = TFOR; 3167c478bd9Sstevel@tonic-gate t->forlst = 0; 3177c478bd9Sstevel@tonic-gate chkword(); 3187c478bd9Sstevel@tonic-gate if (fndef) 3197c478bd9Sstevel@tonic-gate t->fornam = make(wdarg->argval); 3207c478bd9Sstevel@tonic-gate else 3217c478bd9Sstevel@tonic-gate t->fornam = wdarg->argval; 3227c478bd9Sstevel@tonic-gate if (skipnl() == INSYM) 3237c478bd9Sstevel@tonic-gate { 3247c478bd9Sstevel@tonic-gate chkword(); 3257c478bd9Sstevel@tonic-gate 3267c478bd9Sstevel@tonic-gate nohash++; 3277c478bd9Sstevel@tonic-gate t->forlst = (struct comnod *)item(0); 3287c478bd9Sstevel@tonic-gate nohash--; 3297c478bd9Sstevel@tonic-gate 3307c478bd9Sstevel@tonic-gate if (wdval != NL && wdval != ';') 3317c478bd9Sstevel@tonic-gate synbad(); 3327c478bd9Sstevel@tonic-gate if (wdval == NL) 3337c478bd9Sstevel@tonic-gate chkpr(); 3347c478bd9Sstevel@tonic-gate skipnl(); 3357c478bd9Sstevel@tonic-gate } 3367c478bd9Sstevel@tonic-gate chksym(DOSYM | BRSYM); 3377c478bd9Sstevel@tonic-gate t->fortre = cmd(wdval == DOSYM ? ODSYM : KTSYM, NLFLG); 3387c478bd9Sstevel@tonic-gate break; 3397c478bd9Sstevel@tonic-gate } 3407c478bd9Sstevel@tonic-gate 3417c478bd9Sstevel@tonic-gate case WHSYM: 3427c478bd9Sstevel@tonic-gate case UNSYM: 3437c478bd9Sstevel@tonic-gate { 344*965005c8Schin struct whnod *t; 3457c478bd9Sstevel@tonic-gate 3467c478bd9Sstevel@tonic-gate t = (struct whnod *)getstor(sizeof(struct whnod)); 3477c478bd9Sstevel@tonic-gate r = (struct trenod *)t; 3487c478bd9Sstevel@tonic-gate 3497c478bd9Sstevel@tonic-gate t->whtyp = (wdval == WHSYM ? TWH : TUN); 3507c478bd9Sstevel@tonic-gate t->whtre = cmd(DOSYM, NLFLG); 3517c478bd9Sstevel@tonic-gate t->dotre = cmd(ODSYM, NLFLG); 3527c478bd9Sstevel@tonic-gate break; 3537c478bd9Sstevel@tonic-gate } 3547c478bd9Sstevel@tonic-gate 3557c478bd9Sstevel@tonic-gate case BRSYM: 3567c478bd9Sstevel@tonic-gate r = cmd(KTSYM, NLFLG); 3577c478bd9Sstevel@tonic-gate break; 3587c478bd9Sstevel@tonic-gate 3597c478bd9Sstevel@tonic-gate case '(': 3607c478bd9Sstevel@tonic-gate { 361*965005c8Schin struct parnod *p; 3627c478bd9Sstevel@tonic-gate 3637c478bd9Sstevel@tonic-gate p = (struct parnod *)getstor(sizeof(struct parnod)); 3647c478bd9Sstevel@tonic-gate p->partre = cmd(')', NLFLG); 3657c478bd9Sstevel@tonic-gate p->partyp = TPAR; 3667c478bd9Sstevel@tonic-gate r = makefork(0, p); 3677c478bd9Sstevel@tonic-gate break; 3687c478bd9Sstevel@tonic-gate } 3697c478bd9Sstevel@tonic-gate 3707c478bd9Sstevel@tonic-gate default: 3717c478bd9Sstevel@tonic-gate if (io == 0) 3727c478bd9Sstevel@tonic-gate return(0); 3737c478bd9Sstevel@tonic-gate 3747c478bd9Sstevel@tonic-gate case 0: 3757c478bd9Sstevel@tonic-gate { 376*965005c8Schin struct comnod *t; 377*965005c8Schin struct argnod *argp; 378*965005c8Schin struct argnod **argtail; 379*965005c8Schin struct argnod **argset = 0; 3807c478bd9Sstevel@tonic-gate int keywd = 1; 3817c478bd9Sstevel@tonic-gate unsigned char *com; 3827c478bd9Sstevel@tonic-gate 3837c478bd9Sstevel@tonic-gate if ((wdval != NL) && ((peekn = skipwc()) == '(')) 3847c478bd9Sstevel@tonic-gate { 3857c478bd9Sstevel@tonic-gate struct fndnod *f; 3867c478bd9Sstevel@tonic-gate struct ionod *saveio; 3877c478bd9Sstevel@tonic-gate 3887c478bd9Sstevel@tonic-gate saveio = iotemp; 3897c478bd9Sstevel@tonic-gate peekn = 0; 3907c478bd9Sstevel@tonic-gate if (skipwc() != ')') 3917c478bd9Sstevel@tonic-gate synbad(); 3927c478bd9Sstevel@tonic-gate 3937c478bd9Sstevel@tonic-gate f = (struct fndnod *)getstor(sizeof(struct fndnod)); 3947c478bd9Sstevel@tonic-gate r = (struct trenod *)f; 3957c478bd9Sstevel@tonic-gate 3967c478bd9Sstevel@tonic-gate f->fndtyp = TFND; 3977c478bd9Sstevel@tonic-gate if (fndef) 3987c478bd9Sstevel@tonic-gate f->fndnam = make(wdarg->argval); 3997c478bd9Sstevel@tonic-gate else 4007c478bd9Sstevel@tonic-gate f->fndnam = wdarg->argval; 4017c478bd9Sstevel@tonic-gate reserv++; 4027c478bd9Sstevel@tonic-gate fndef++; 4037c478bd9Sstevel@tonic-gate skipnl(); 4047c478bd9Sstevel@tonic-gate f->fndval = (struct trenod *)item(0); 4057c478bd9Sstevel@tonic-gate fndef--; 4067c478bd9Sstevel@tonic-gate 4077c478bd9Sstevel@tonic-gate if (iotemp != saveio) 4087c478bd9Sstevel@tonic-gate { 4097c478bd9Sstevel@tonic-gate struct ionod *ioptr = iotemp; 4107c478bd9Sstevel@tonic-gate 4117c478bd9Sstevel@tonic-gate while (ioptr->iolst != saveio) 4127c478bd9Sstevel@tonic-gate ioptr = ioptr->iolst; 4137c478bd9Sstevel@tonic-gate 4147c478bd9Sstevel@tonic-gate ioptr->iolst = fiotemp; 4157c478bd9Sstevel@tonic-gate fiotemp = iotemp; 4167c478bd9Sstevel@tonic-gate iotemp = saveio; 4177c478bd9Sstevel@tonic-gate } 4187c478bd9Sstevel@tonic-gate return(r); 4197c478bd9Sstevel@tonic-gate } 4207c478bd9Sstevel@tonic-gate else 4217c478bd9Sstevel@tonic-gate { 4227c478bd9Sstevel@tonic-gate t = (struct comnod *)getstor(sizeof(struct comnod)); 4237c478bd9Sstevel@tonic-gate r = (struct trenod *)t; 4247c478bd9Sstevel@tonic-gate 4257c478bd9Sstevel@tonic-gate t->comio = io; /*initial io chain*/ 4267c478bd9Sstevel@tonic-gate argtail = &(t->comarg); 4277c478bd9Sstevel@tonic-gate 4287c478bd9Sstevel@tonic-gate while (wdval == 0) 4297c478bd9Sstevel@tonic-gate { 4307c478bd9Sstevel@tonic-gate if (fndef) 4317c478bd9Sstevel@tonic-gate { 4327c478bd9Sstevel@tonic-gate argp = wdarg; 4337c478bd9Sstevel@tonic-gate wdarg = (struct argnod *)alloc(length(argp->argval) + BYTESPERWORD); 4347c478bd9Sstevel@tonic-gate movstr(argp->argval, wdarg->argval); 4357c478bd9Sstevel@tonic-gate } 4367c478bd9Sstevel@tonic-gate 4377c478bd9Sstevel@tonic-gate argp = wdarg; 4387c478bd9Sstevel@tonic-gate if (wdset && keywd) 4397c478bd9Sstevel@tonic-gate { 4407c478bd9Sstevel@tonic-gate argp->argnxt = (struct argnod *)argset; 4417c478bd9Sstevel@tonic-gate argset = (struct argnod **)argp; 4427c478bd9Sstevel@tonic-gate } 4437c478bd9Sstevel@tonic-gate else 4447c478bd9Sstevel@tonic-gate { 4457c478bd9Sstevel@tonic-gate *argtail = argp; 4467c478bd9Sstevel@tonic-gate argtail = &(argp->argnxt); 4477c478bd9Sstevel@tonic-gate keywd = flags & keyflg; 4487c478bd9Sstevel@tonic-gate } 4497c478bd9Sstevel@tonic-gate word(); 4507c478bd9Sstevel@tonic-gate if (flag) 4517c478bd9Sstevel@tonic-gate { 4527c478bd9Sstevel@tonic-gate if (io) 4537c478bd9Sstevel@tonic-gate { 4547c478bd9Sstevel@tonic-gate while(io->ionxt) 4557c478bd9Sstevel@tonic-gate io = io->ionxt; 4567c478bd9Sstevel@tonic-gate io->ionxt = inout((struct ionod *)0); 4577c478bd9Sstevel@tonic-gate } 4587c478bd9Sstevel@tonic-gate else 4597c478bd9Sstevel@tonic-gate t->comio = io = inout((struct ionod *)0); 4607c478bd9Sstevel@tonic-gate } 4617c478bd9Sstevel@tonic-gate } 4627c478bd9Sstevel@tonic-gate 4637c478bd9Sstevel@tonic-gate t->comtyp = TCOM; 4647c478bd9Sstevel@tonic-gate t->comset = (struct argnod *)argset; 4657c478bd9Sstevel@tonic-gate *argtail = 0; 4667c478bd9Sstevel@tonic-gate 4677c478bd9Sstevel@tonic-gate if (nohash == 0 && (fndef == 0 || (flags & hashflg))) 4687c478bd9Sstevel@tonic-gate { 4697c478bd9Sstevel@tonic-gate if (t->comarg) 4707c478bd9Sstevel@tonic-gate { 4717c478bd9Sstevel@tonic-gate com = t->comarg->argval; 4727c478bd9Sstevel@tonic-gate if (*com && *com != DOLLAR) 4737c478bd9Sstevel@tonic-gate pathlook(com, 0, t->comset); 4747c478bd9Sstevel@tonic-gate } 4757c478bd9Sstevel@tonic-gate } 4767c478bd9Sstevel@tonic-gate 4777c478bd9Sstevel@tonic-gate return(r); 4787c478bd9Sstevel@tonic-gate } 4797c478bd9Sstevel@tonic-gate } 4807c478bd9Sstevel@tonic-gate 4817c478bd9Sstevel@tonic-gate } 4827c478bd9Sstevel@tonic-gate reserv++; 4837c478bd9Sstevel@tonic-gate word(); 4847c478bd9Sstevel@tonic-gate if (io = inout(io)) 4857c478bd9Sstevel@tonic-gate { 4867c478bd9Sstevel@tonic-gate r = makefork(0,r); 4877c478bd9Sstevel@tonic-gate r->treio = io; 4887c478bd9Sstevel@tonic-gate } 4897c478bd9Sstevel@tonic-gate return(r); 4907c478bd9Sstevel@tonic-gate } 4917c478bd9Sstevel@tonic-gate 4927c478bd9Sstevel@tonic-gate 4937c478bd9Sstevel@tonic-gate static int 4947c478bd9Sstevel@tonic-gate skipnl() 4957c478bd9Sstevel@tonic-gate { 4967c478bd9Sstevel@tonic-gate while ((reserv++, word() == NL)) 4977c478bd9Sstevel@tonic-gate chkpr(); 4987c478bd9Sstevel@tonic-gate return(wdval); 4997c478bd9Sstevel@tonic-gate } 5007c478bd9Sstevel@tonic-gate 5017c478bd9Sstevel@tonic-gate static struct ionod * 5027c478bd9Sstevel@tonic-gate inout(lastio) 5037c478bd9Sstevel@tonic-gate struct ionod *lastio; 5047c478bd9Sstevel@tonic-gate { 505*965005c8Schin int iof; 506*965005c8Schin struct ionod *iop; 507*965005c8Schin unsigned int c; 5087c478bd9Sstevel@tonic-gate 5097c478bd9Sstevel@tonic-gate iof = wdnum; 5107c478bd9Sstevel@tonic-gate switch (wdval) 5117c478bd9Sstevel@tonic-gate { 5127c478bd9Sstevel@tonic-gate case DOCSYM: /* << */ 5137c478bd9Sstevel@tonic-gate iof |= IODOC; 5147c478bd9Sstevel@tonic-gate break; 5157c478bd9Sstevel@tonic-gate 5167c478bd9Sstevel@tonic-gate case APPSYM: /* >> */ 5177c478bd9Sstevel@tonic-gate case '>': 5187c478bd9Sstevel@tonic-gate if (wdnum == 0) 5197c478bd9Sstevel@tonic-gate iof |= 1; 5207c478bd9Sstevel@tonic-gate iof |= IOPUT; 5217c478bd9Sstevel@tonic-gate if (wdval == APPSYM) 5227c478bd9Sstevel@tonic-gate { 5237c478bd9Sstevel@tonic-gate iof |= IOAPP; 5247c478bd9Sstevel@tonic-gate break; 5257c478bd9Sstevel@tonic-gate } 5267c478bd9Sstevel@tonic-gate 5277c478bd9Sstevel@tonic-gate case '<': 5287c478bd9Sstevel@tonic-gate if ((c = nextwc()) == '&') 5297c478bd9Sstevel@tonic-gate iof |= IOMOV; 5307c478bd9Sstevel@tonic-gate else if (c == '>') 5317c478bd9Sstevel@tonic-gate iof |= IORDW; 5327c478bd9Sstevel@tonic-gate else 5337c478bd9Sstevel@tonic-gate peekn = c | MARK; 5347c478bd9Sstevel@tonic-gate break; 5357c478bd9Sstevel@tonic-gate 5367c478bd9Sstevel@tonic-gate default: 5377c478bd9Sstevel@tonic-gate return(lastio); 5387c478bd9Sstevel@tonic-gate } 5397c478bd9Sstevel@tonic-gate 5407c478bd9Sstevel@tonic-gate chkword(); 5417c478bd9Sstevel@tonic-gate iop = (struct ionod *)getstor(sizeof(struct ionod)); 5427c478bd9Sstevel@tonic-gate 5437c478bd9Sstevel@tonic-gate if (fndef) 5447c478bd9Sstevel@tonic-gate iop->ioname = (char *) make(wdarg->argval); 5457c478bd9Sstevel@tonic-gate else 5467c478bd9Sstevel@tonic-gate iop->ioname = (char *) (wdarg->argval); 5477c478bd9Sstevel@tonic-gate 5487c478bd9Sstevel@tonic-gate iop->iolink = 0; 5497c478bd9Sstevel@tonic-gate iop->iofile = iof; 5507c478bd9Sstevel@tonic-gate if (iof & IODOC) 5517c478bd9Sstevel@tonic-gate { 5527c478bd9Sstevel@tonic-gate iop->iolst = iopend; 5537c478bd9Sstevel@tonic-gate iopend = iop; 5547c478bd9Sstevel@tonic-gate } 5557c478bd9Sstevel@tonic-gate word(); 5567c478bd9Sstevel@tonic-gate iop->ionxt = inout(lastio); 5577c478bd9Sstevel@tonic-gate return(iop); 5587c478bd9Sstevel@tonic-gate } 5597c478bd9Sstevel@tonic-gate 560*965005c8Schin static void 561*965005c8Schin chkword(void) 5627c478bd9Sstevel@tonic-gate { 5637c478bd9Sstevel@tonic-gate if (word()) 5647c478bd9Sstevel@tonic-gate synbad(); 5657c478bd9Sstevel@tonic-gate } 5667c478bd9Sstevel@tonic-gate 567*965005c8Schin static void 568*965005c8Schin chksym(int sym) 5697c478bd9Sstevel@tonic-gate { 570*965005c8Schin int x = sym & wdval; 5717c478bd9Sstevel@tonic-gate 5727c478bd9Sstevel@tonic-gate if (((x & SYMFLG) ? x : sym) != wdval) 5737c478bd9Sstevel@tonic-gate synbad(); 5747c478bd9Sstevel@tonic-gate } 5757c478bd9Sstevel@tonic-gate 576*965005c8Schin static void 577*965005c8Schin prsym(int sym) 5787c478bd9Sstevel@tonic-gate { 5797c478bd9Sstevel@tonic-gate if (sym & SYMFLG) 5807c478bd9Sstevel@tonic-gate { 581*965005c8Schin const struct sysnod *sp = reserved; 5827c478bd9Sstevel@tonic-gate 5837c478bd9Sstevel@tonic-gate while (sp->sysval && sp->sysval != sym) 5847c478bd9Sstevel@tonic-gate sp++; 5857c478bd9Sstevel@tonic-gate prs(sp->sysnam); 5867c478bd9Sstevel@tonic-gate } 5877c478bd9Sstevel@tonic-gate else if (sym == EOFSYM) 5887c478bd9Sstevel@tonic-gate prs(endoffile); 5897c478bd9Sstevel@tonic-gate else 5907c478bd9Sstevel@tonic-gate { 5917c478bd9Sstevel@tonic-gate if (sym & SYMREP) 5927c478bd9Sstevel@tonic-gate prc(sym); 5937c478bd9Sstevel@tonic-gate if (sym == NL) 5947c478bd9Sstevel@tonic-gate prs("newline or ;"); 5957c478bd9Sstevel@tonic-gate else 5967c478bd9Sstevel@tonic-gate prc(sym); 5977c478bd9Sstevel@tonic-gate } 5987c478bd9Sstevel@tonic-gate } 5997c478bd9Sstevel@tonic-gate 600*965005c8Schin static void 601*965005c8Schin synbad(void) 6027c478bd9Sstevel@tonic-gate { 6037c478bd9Sstevel@tonic-gate prp(); 6047c478bd9Sstevel@tonic-gate prs(synmsg); 6057c478bd9Sstevel@tonic-gate if ((flags & ttyflg) == 0) 6067c478bd9Sstevel@tonic-gate { 6077c478bd9Sstevel@tonic-gate prs(atline); 6087c478bd9Sstevel@tonic-gate prn(standin->flin); 6097c478bd9Sstevel@tonic-gate } 6107c478bd9Sstevel@tonic-gate prs(colon); 6117c478bd9Sstevel@tonic-gate prc(LQ); 6127c478bd9Sstevel@tonic-gate if (wdval) 6137c478bd9Sstevel@tonic-gate prsym(wdval); 6147c478bd9Sstevel@tonic-gate else 6157c478bd9Sstevel@tonic-gate prs_cntl(wdarg->argval); 6167c478bd9Sstevel@tonic-gate prc(RQ); 6177c478bd9Sstevel@tonic-gate prs(unexpected); 6187c478bd9Sstevel@tonic-gate newline(); 6197c478bd9Sstevel@tonic-gate exitsh(SYNBAD); 6207c478bd9Sstevel@tonic-gate } 621