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