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*d6b882a9SNobutomo Nakano * Copyright 2009 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 307c478bd9Sstevel@tonic-gate /* 317c478bd9Sstevel@tonic-gate * UNIX shell 327c478bd9Sstevel@tonic-gate */ 337c478bd9Sstevel@tonic-gate 347c478bd9Sstevel@tonic-gate #include "defs.h" 357c478bd9Sstevel@tonic-gate #include "sym.h" 367c478bd9Sstevel@tonic-gate 377c478bd9Sstevel@tonic-gate static struct ionod * inout(); 38965005c8Schin static void chkword(void); 39965005c8Schin static void chksym(int); 407c478bd9Sstevel@tonic-gate static struct trenod * term(); 417c478bd9Sstevel@tonic-gate static struct trenod * makelist(); 427c478bd9Sstevel@tonic-gate static struct trenod * list(); 437c478bd9Sstevel@tonic-gate static struct regnod * syncase(); 447c478bd9Sstevel@tonic-gate static struct trenod * item(); 457c478bd9Sstevel@tonic-gate static int skipnl(); 46965005c8Schin static void prsym(int); 47965005c8Schin static void synbad(void); 487c478bd9Sstevel@tonic-gate 497c478bd9Sstevel@tonic-gate 507c478bd9Sstevel@tonic-gate /* ======== storage allocation for functions ======== */ 517c478bd9Sstevel@tonic-gate 527c478bd9Sstevel@tonic-gate unsigned char * 537c478bd9Sstevel@tonic-gate getstor(asize) 547c478bd9Sstevel@tonic-gate int asize; 557c478bd9Sstevel@tonic-gate { 567c478bd9Sstevel@tonic-gate if (fndef) 577c478bd9Sstevel@tonic-gate return((unsigned char *)alloc(asize)); 587c478bd9Sstevel@tonic-gate else 597c478bd9Sstevel@tonic-gate return(getstak(asize)); 607c478bd9Sstevel@tonic-gate } 617c478bd9Sstevel@tonic-gate 627c478bd9Sstevel@tonic-gate 637c478bd9Sstevel@tonic-gate /* ======== command line decoding ========*/ 647c478bd9Sstevel@tonic-gate 657c478bd9Sstevel@tonic-gate 667c478bd9Sstevel@tonic-gate 677c478bd9Sstevel@tonic-gate 687c478bd9Sstevel@tonic-gate struct trenod * 697c478bd9Sstevel@tonic-gate makefork(flgs, i) 707c478bd9Sstevel@tonic-gate int flgs; 717c478bd9Sstevel@tonic-gate struct trenod *i; 727c478bd9Sstevel@tonic-gate { 73965005c8Schin struct forknod *t; 747c478bd9Sstevel@tonic-gate 757c478bd9Sstevel@tonic-gate t = (struct forknod *)getstor(sizeof(struct forknod)); 767c478bd9Sstevel@tonic-gate t->forktyp = flgs|TFORK; 777c478bd9Sstevel@tonic-gate t->forktre = i; 787c478bd9Sstevel@tonic-gate t->forkio = 0; 797c478bd9Sstevel@tonic-gate return((struct trenod *)t); 807c478bd9Sstevel@tonic-gate } 817c478bd9Sstevel@tonic-gate 827c478bd9Sstevel@tonic-gate static struct trenod * 837c478bd9Sstevel@tonic-gate makelist(type, i, r) 847c478bd9Sstevel@tonic-gate int type; 857c478bd9Sstevel@tonic-gate struct trenod *i, *r; 867c478bd9Sstevel@tonic-gate { 87965005c8Schin struct lstnod *t; 887c478bd9Sstevel@tonic-gate 897c478bd9Sstevel@tonic-gate if (i == 0 || r == 0) 907c478bd9Sstevel@tonic-gate synbad(); 917c478bd9Sstevel@tonic-gate else 927c478bd9Sstevel@tonic-gate { 937c478bd9Sstevel@tonic-gate t = (struct lstnod *)getstor(sizeof(struct lstnod)); 947c478bd9Sstevel@tonic-gate t->lsttyp = type; 957c478bd9Sstevel@tonic-gate t->lstlef = i; 967c478bd9Sstevel@tonic-gate t->lstrit = r; 977c478bd9Sstevel@tonic-gate } 987c478bd9Sstevel@tonic-gate return((struct trenod *)t); 997c478bd9Sstevel@tonic-gate } 1007c478bd9Sstevel@tonic-gate 1017c478bd9Sstevel@tonic-gate /* 1027c478bd9Sstevel@tonic-gate * cmd 1037c478bd9Sstevel@tonic-gate * empty 1047c478bd9Sstevel@tonic-gate * list 1057c478bd9Sstevel@tonic-gate * list & [ cmd ] 1067c478bd9Sstevel@tonic-gate * list [ ; cmd ] 1077c478bd9Sstevel@tonic-gate */ 1087c478bd9Sstevel@tonic-gate struct trenod * 1097c478bd9Sstevel@tonic-gate cmd(sym, flg) 110965005c8Schin int sym; 1117c478bd9Sstevel@tonic-gate int flg; 1127c478bd9Sstevel@tonic-gate { 113965005c8Schin struct trenod *i, *e; 1147c478bd9Sstevel@tonic-gate i = list(flg); 1157c478bd9Sstevel@tonic-gate if (wdval == NL) 1167c478bd9Sstevel@tonic-gate { 1177c478bd9Sstevel@tonic-gate if (flg & NLFLG) 1187c478bd9Sstevel@tonic-gate { 1197c478bd9Sstevel@tonic-gate wdval = ';'; 1207c478bd9Sstevel@tonic-gate chkpr(); 1217c478bd9Sstevel@tonic-gate } 1227c478bd9Sstevel@tonic-gate } 1237c478bd9Sstevel@tonic-gate else if (i == 0 && (flg & MTFLG) == 0) 1247c478bd9Sstevel@tonic-gate synbad(); 1257c478bd9Sstevel@tonic-gate 1267c478bd9Sstevel@tonic-gate switch (wdval) 1277c478bd9Sstevel@tonic-gate { 1287c478bd9Sstevel@tonic-gate case '&': 1297c478bd9Sstevel@tonic-gate if (i) 1307c478bd9Sstevel@tonic-gate i = makefork(FAMP, i); 1317c478bd9Sstevel@tonic-gate else 1327c478bd9Sstevel@tonic-gate synbad(); 1337c478bd9Sstevel@tonic-gate 1347c478bd9Sstevel@tonic-gate case ';': 1357c478bd9Sstevel@tonic-gate if (e = cmd(sym, flg | MTFLG)) 1367c478bd9Sstevel@tonic-gate i = makelist(TLST, i, e); 1377c478bd9Sstevel@tonic-gate else if (i == 0) 1387c478bd9Sstevel@tonic-gate synbad(); 1397c478bd9Sstevel@tonic-gate break; 1407c478bd9Sstevel@tonic-gate 1417c478bd9Sstevel@tonic-gate case EOFSYM: 1427c478bd9Sstevel@tonic-gate if (sym == NL) 1437c478bd9Sstevel@tonic-gate break; 1447c478bd9Sstevel@tonic-gate 1457c478bd9Sstevel@tonic-gate default: 1467c478bd9Sstevel@tonic-gate if (sym) 1477c478bd9Sstevel@tonic-gate chksym(sym); 1487c478bd9Sstevel@tonic-gate } 1497c478bd9Sstevel@tonic-gate return(i); 1507c478bd9Sstevel@tonic-gate } 1517c478bd9Sstevel@tonic-gate 1527c478bd9Sstevel@tonic-gate /* 1537c478bd9Sstevel@tonic-gate * list 1547c478bd9Sstevel@tonic-gate * term 1557c478bd9Sstevel@tonic-gate * list && term 1567c478bd9Sstevel@tonic-gate * list || term 1577c478bd9Sstevel@tonic-gate */ 1587c478bd9Sstevel@tonic-gate static struct trenod * 1597c478bd9Sstevel@tonic-gate list(flg) 1607c478bd9Sstevel@tonic-gate { 161965005c8Schin struct trenod *r; 162965005c8Schin int b; 1637c478bd9Sstevel@tonic-gate r = term(flg); 1647c478bd9Sstevel@tonic-gate while (r && ((b = (wdval == ANDFSYM)) || wdval == ORFSYM)) 1657c478bd9Sstevel@tonic-gate r = makelist((b ? TAND : TORF), r, term(NLFLG)); 1667c478bd9Sstevel@tonic-gate return(r); 1677c478bd9Sstevel@tonic-gate } 1687c478bd9Sstevel@tonic-gate 1697c478bd9Sstevel@tonic-gate /* 1707c478bd9Sstevel@tonic-gate * term 1717c478bd9Sstevel@tonic-gate * item 1727c478bd9Sstevel@tonic-gate * item |^ term 1737c478bd9Sstevel@tonic-gate */ 1747c478bd9Sstevel@tonic-gate static struct trenod * 1757c478bd9Sstevel@tonic-gate term(flg) 1767c478bd9Sstevel@tonic-gate { 177965005c8Schin struct trenod *t; 1787c478bd9Sstevel@tonic-gate 1797c478bd9Sstevel@tonic-gate reserv++; 1807c478bd9Sstevel@tonic-gate if (flg & NLFLG) 1817c478bd9Sstevel@tonic-gate skipnl(); 1827c478bd9Sstevel@tonic-gate else 1837c478bd9Sstevel@tonic-gate word(); 1847c478bd9Sstevel@tonic-gate if ((t = item(TRUE)) && (wdval == '^' || wdval == '|')) 1857c478bd9Sstevel@tonic-gate { 1867c478bd9Sstevel@tonic-gate struct trenod *left; 1877c478bd9Sstevel@tonic-gate struct trenod *right; 1887c478bd9Sstevel@tonic-gate 1897c478bd9Sstevel@tonic-gate left = makefork(FPOU, t); 1907c478bd9Sstevel@tonic-gate right = makefork(FPIN, term(NLFLG)); 1917c478bd9Sstevel@tonic-gate return(makefork(0, makelist(TFIL, left, right))); 1927c478bd9Sstevel@tonic-gate } 1937c478bd9Sstevel@tonic-gate else 1947c478bd9Sstevel@tonic-gate return(t); 1957c478bd9Sstevel@tonic-gate } 1967c478bd9Sstevel@tonic-gate 1977c478bd9Sstevel@tonic-gate 1987c478bd9Sstevel@tonic-gate static struct regnod * 1997c478bd9Sstevel@tonic-gate syncase(esym) 200965005c8Schin int esym; 2017c478bd9Sstevel@tonic-gate { 2027c478bd9Sstevel@tonic-gate skipnl(); 2037c478bd9Sstevel@tonic-gate if (wdval == esym) 2047c478bd9Sstevel@tonic-gate return(0); 2057c478bd9Sstevel@tonic-gate else 2067c478bd9Sstevel@tonic-gate { 207965005c8Schin struct regnod *r = 208965005c8Schin (struct regnod *)getstor(sizeof (struct regnod)); 209965005c8Schin struct argnod *argp; 2107c478bd9Sstevel@tonic-gate 2117c478bd9Sstevel@tonic-gate r->regptr = 0; 2127c478bd9Sstevel@tonic-gate for (;;) 2137c478bd9Sstevel@tonic-gate { 2147c478bd9Sstevel@tonic-gate if (fndef) 2157c478bd9Sstevel@tonic-gate { 2167c478bd9Sstevel@tonic-gate argp= wdarg; 2177c478bd9Sstevel@tonic-gate wdarg = (struct argnod *)alloc(length(argp->argval) + BYTESPERWORD); 2187c478bd9Sstevel@tonic-gate movstr(argp->argval, wdarg->argval); 2197c478bd9Sstevel@tonic-gate } 2207c478bd9Sstevel@tonic-gate 2217c478bd9Sstevel@tonic-gate wdarg->argnxt = r->regptr; 2227c478bd9Sstevel@tonic-gate r->regptr = wdarg; 2237c478bd9Sstevel@tonic-gate 2247c478bd9Sstevel@tonic-gate /* 'in' is not a reserved word in this case */ 2257c478bd9Sstevel@tonic-gate if (wdval == INSYM){ 2267c478bd9Sstevel@tonic-gate wdval = 0; 2277c478bd9Sstevel@tonic-gate } 2287c478bd9Sstevel@tonic-gate if (wdval || (word() != ')' && wdval != '|')) 2297c478bd9Sstevel@tonic-gate synbad(); 2307c478bd9Sstevel@tonic-gate if (wdval == '|') 2317c478bd9Sstevel@tonic-gate word(); 2327c478bd9Sstevel@tonic-gate else 2337c478bd9Sstevel@tonic-gate break; 2347c478bd9Sstevel@tonic-gate } 2357c478bd9Sstevel@tonic-gate r->regcom = cmd(0, NLFLG | MTFLG); 2367c478bd9Sstevel@tonic-gate if (wdval == ECSYM) 2377c478bd9Sstevel@tonic-gate r->regnxt = syncase(esym); 2387c478bd9Sstevel@tonic-gate else 2397c478bd9Sstevel@tonic-gate { 2407c478bd9Sstevel@tonic-gate chksym(esym); 2417c478bd9Sstevel@tonic-gate r->regnxt = 0; 2427c478bd9Sstevel@tonic-gate } 2437c478bd9Sstevel@tonic-gate return(r); 2447c478bd9Sstevel@tonic-gate } 2457c478bd9Sstevel@tonic-gate } 2467c478bd9Sstevel@tonic-gate 2477c478bd9Sstevel@tonic-gate /* 2487c478bd9Sstevel@tonic-gate * item 2497c478bd9Sstevel@tonic-gate * 2507c478bd9Sstevel@tonic-gate * ( cmd ) [ < in ] [ > out ] 2517c478bd9Sstevel@tonic-gate * word word* [ < in ] [ > out ] 2527c478bd9Sstevel@tonic-gate * if ... then ... else ... fi 2537c478bd9Sstevel@tonic-gate * for ... while ... do ... done 2547c478bd9Sstevel@tonic-gate * case ... in ... esac 2557c478bd9Sstevel@tonic-gate * begin ... end 2567c478bd9Sstevel@tonic-gate */ 2577c478bd9Sstevel@tonic-gate static struct trenod * 2587c478bd9Sstevel@tonic-gate item(flag) 2597c478bd9Sstevel@tonic-gate BOOL flag; 2607c478bd9Sstevel@tonic-gate { 261965005c8Schin struct trenod *r; 262965005c8Schin struct ionod *io; 2637c478bd9Sstevel@tonic-gate 2647c478bd9Sstevel@tonic-gate if (flag) 2657c478bd9Sstevel@tonic-gate io = inout((struct ionod *)0); 2667c478bd9Sstevel@tonic-gate else 2677c478bd9Sstevel@tonic-gate io = 0; 2687c478bd9Sstevel@tonic-gate switch (wdval) 2697c478bd9Sstevel@tonic-gate { 2707c478bd9Sstevel@tonic-gate case CASYM: 2717c478bd9Sstevel@tonic-gate { 272965005c8Schin struct swnod *t; 2737c478bd9Sstevel@tonic-gate 2747c478bd9Sstevel@tonic-gate t = (struct swnod *)getstor(sizeof(struct swnod)); 2757c478bd9Sstevel@tonic-gate r = (struct trenod *)t; 2767c478bd9Sstevel@tonic-gate 2777c478bd9Sstevel@tonic-gate chkword(); 2787c478bd9Sstevel@tonic-gate if (fndef) 2797c478bd9Sstevel@tonic-gate t->swarg = make(wdarg->argval); 2807c478bd9Sstevel@tonic-gate else 2817c478bd9Sstevel@tonic-gate t->swarg = wdarg->argval; 2827c478bd9Sstevel@tonic-gate skipnl(); 2837c478bd9Sstevel@tonic-gate chksym(INSYM | BRSYM); 2847c478bd9Sstevel@tonic-gate t->swlst = syncase(wdval == INSYM ? ESSYM : KTSYM); 2857c478bd9Sstevel@tonic-gate t->swtyp = TSW; 2867c478bd9Sstevel@tonic-gate break; 2877c478bd9Sstevel@tonic-gate } 2887c478bd9Sstevel@tonic-gate 2897c478bd9Sstevel@tonic-gate case IFSYM: 2907c478bd9Sstevel@tonic-gate { 291965005c8Schin int w; 292965005c8Schin struct ifnod *t; 2937c478bd9Sstevel@tonic-gate 2947c478bd9Sstevel@tonic-gate t = (struct ifnod *)getstor(sizeof(struct ifnod)); 2957c478bd9Sstevel@tonic-gate r = (struct trenod *)t; 2967c478bd9Sstevel@tonic-gate 2977c478bd9Sstevel@tonic-gate t->iftyp = TIF; 2987c478bd9Sstevel@tonic-gate t->iftre = cmd(THSYM, NLFLG); 2997c478bd9Sstevel@tonic-gate t->thtre = cmd(ELSYM | FISYM | EFSYM, NLFLG); 3007c478bd9Sstevel@tonic-gate t->eltre = ((w = wdval) == ELSYM ? cmd(FISYM, NLFLG) : (w == EFSYM ? (wdval = IFSYM, item(0)) : 0)); 3017c478bd9Sstevel@tonic-gate if (w == EFSYM) 3027c478bd9Sstevel@tonic-gate return(r); 3037c478bd9Sstevel@tonic-gate break; 3047c478bd9Sstevel@tonic-gate } 3057c478bd9Sstevel@tonic-gate 3067c478bd9Sstevel@tonic-gate case FORSYM: 3077c478bd9Sstevel@tonic-gate { 308965005c8Schin struct fornod *t; 3097c478bd9Sstevel@tonic-gate 3107c478bd9Sstevel@tonic-gate t = (struct fornod *)getstor(sizeof(struct fornod)); 3117c478bd9Sstevel@tonic-gate r = (struct trenod *)t; 3127c478bd9Sstevel@tonic-gate 3137c478bd9Sstevel@tonic-gate t->fortyp = TFOR; 3147c478bd9Sstevel@tonic-gate t->forlst = 0; 3157c478bd9Sstevel@tonic-gate chkword(); 3167c478bd9Sstevel@tonic-gate if (fndef) 3177c478bd9Sstevel@tonic-gate t->fornam = make(wdarg->argval); 3187c478bd9Sstevel@tonic-gate else 3197c478bd9Sstevel@tonic-gate t->fornam = wdarg->argval; 3207c478bd9Sstevel@tonic-gate if (skipnl() == INSYM) 3217c478bd9Sstevel@tonic-gate { 3227c478bd9Sstevel@tonic-gate chkword(); 3237c478bd9Sstevel@tonic-gate 3247c478bd9Sstevel@tonic-gate nohash++; 3257c478bd9Sstevel@tonic-gate t->forlst = (struct comnod *)item(0); 3267c478bd9Sstevel@tonic-gate nohash--; 3277c478bd9Sstevel@tonic-gate 3287c478bd9Sstevel@tonic-gate if (wdval != NL && wdval != ';') 3297c478bd9Sstevel@tonic-gate synbad(); 3307c478bd9Sstevel@tonic-gate if (wdval == NL) 3317c478bd9Sstevel@tonic-gate chkpr(); 3327c478bd9Sstevel@tonic-gate skipnl(); 3337c478bd9Sstevel@tonic-gate } 3347c478bd9Sstevel@tonic-gate chksym(DOSYM | BRSYM); 3357c478bd9Sstevel@tonic-gate t->fortre = cmd(wdval == DOSYM ? ODSYM : KTSYM, NLFLG); 3367c478bd9Sstevel@tonic-gate break; 3377c478bd9Sstevel@tonic-gate } 3387c478bd9Sstevel@tonic-gate 3397c478bd9Sstevel@tonic-gate case WHSYM: 3407c478bd9Sstevel@tonic-gate case UNSYM: 3417c478bd9Sstevel@tonic-gate { 342965005c8Schin struct whnod *t; 3437c478bd9Sstevel@tonic-gate 3447c478bd9Sstevel@tonic-gate t = (struct whnod *)getstor(sizeof(struct whnod)); 3457c478bd9Sstevel@tonic-gate r = (struct trenod *)t; 3467c478bd9Sstevel@tonic-gate 3477c478bd9Sstevel@tonic-gate t->whtyp = (wdval == WHSYM ? TWH : TUN); 3487c478bd9Sstevel@tonic-gate t->whtre = cmd(DOSYM, NLFLG); 3497c478bd9Sstevel@tonic-gate t->dotre = cmd(ODSYM, NLFLG); 3507c478bd9Sstevel@tonic-gate break; 3517c478bd9Sstevel@tonic-gate } 3527c478bd9Sstevel@tonic-gate 3537c478bd9Sstevel@tonic-gate case BRSYM: 3547c478bd9Sstevel@tonic-gate r = cmd(KTSYM, NLFLG); 3557c478bd9Sstevel@tonic-gate break; 3567c478bd9Sstevel@tonic-gate 3577c478bd9Sstevel@tonic-gate case '(': 3587c478bd9Sstevel@tonic-gate { 359965005c8Schin struct parnod *p; 3607c478bd9Sstevel@tonic-gate 3617c478bd9Sstevel@tonic-gate p = (struct parnod *)getstor(sizeof(struct parnod)); 3627c478bd9Sstevel@tonic-gate p->partre = cmd(')', NLFLG); 3637c478bd9Sstevel@tonic-gate p->partyp = TPAR; 3647c478bd9Sstevel@tonic-gate r = makefork(0, p); 3657c478bd9Sstevel@tonic-gate break; 3667c478bd9Sstevel@tonic-gate } 3677c478bd9Sstevel@tonic-gate 3687c478bd9Sstevel@tonic-gate default: 3697c478bd9Sstevel@tonic-gate if (io == 0) 3707c478bd9Sstevel@tonic-gate return(0); 3717c478bd9Sstevel@tonic-gate 3727c478bd9Sstevel@tonic-gate case 0: 3737c478bd9Sstevel@tonic-gate { 374965005c8Schin struct comnod *t; 375965005c8Schin struct argnod *argp; 376965005c8Schin struct argnod **argtail; 377965005c8Schin struct argnod **argset = 0; 3787c478bd9Sstevel@tonic-gate int keywd = 1; 3797c478bd9Sstevel@tonic-gate unsigned char *com; 3807c478bd9Sstevel@tonic-gate 3817c478bd9Sstevel@tonic-gate if ((wdval != NL) && ((peekn = skipwc()) == '(')) 3827c478bd9Sstevel@tonic-gate { 3837c478bd9Sstevel@tonic-gate struct fndnod *f; 3847c478bd9Sstevel@tonic-gate struct ionod *saveio; 3857c478bd9Sstevel@tonic-gate 3867c478bd9Sstevel@tonic-gate saveio = iotemp; 3877c478bd9Sstevel@tonic-gate peekn = 0; 3887c478bd9Sstevel@tonic-gate if (skipwc() != ')') 3897c478bd9Sstevel@tonic-gate synbad(); 3907c478bd9Sstevel@tonic-gate 391*d6b882a9SNobutomo Nakano /* 392*d6b882a9SNobutomo Nakano * We increase fndef before calling getstor(), 393*d6b882a9SNobutomo Nakano * so that getstor() uses malloc to allocate 394*d6b882a9SNobutomo Nakano * memory instead of stack. This is necessary 395*d6b882a9SNobutomo Nakano * since fndnod will be hung on np->namenv, 396*d6b882a9SNobutomo Nakano * which persists over command executions. 397*d6b882a9SNobutomo Nakano */ 398*d6b882a9SNobutomo Nakano fndef++; 3997c478bd9Sstevel@tonic-gate f = (struct fndnod *)getstor(sizeof(struct fndnod)); 4007c478bd9Sstevel@tonic-gate r = (struct trenod *)f; 4017c478bd9Sstevel@tonic-gate 4027c478bd9Sstevel@tonic-gate f->fndtyp = TFND; 4037c478bd9Sstevel@tonic-gate f->fndnam = make(wdarg->argval); 404*d6b882a9SNobutomo Nakano f->fndref = 0; 4057c478bd9Sstevel@tonic-gate reserv++; 4067c478bd9Sstevel@tonic-gate skipnl(); 4077c478bd9Sstevel@tonic-gate f->fndval = (struct trenod *)item(0); 4087c478bd9Sstevel@tonic-gate fndef--; 4097c478bd9Sstevel@tonic-gate 4107c478bd9Sstevel@tonic-gate if (iotemp != saveio) 4117c478bd9Sstevel@tonic-gate { 4127c478bd9Sstevel@tonic-gate struct ionod *ioptr = iotemp; 4137c478bd9Sstevel@tonic-gate 4147c478bd9Sstevel@tonic-gate while (ioptr->iolst != saveio) 4157c478bd9Sstevel@tonic-gate ioptr = ioptr->iolst; 4167c478bd9Sstevel@tonic-gate 4177c478bd9Sstevel@tonic-gate ioptr->iolst = fiotemp; 4187c478bd9Sstevel@tonic-gate fiotemp = iotemp; 4197c478bd9Sstevel@tonic-gate iotemp = saveio; 4207c478bd9Sstevel@tonic-gate } 4217c478bd9Sstevel@tonic-gate return(r); 4227c478bd9Sstevel@tonic-gate } 4237c478bd9Sstevel@tonic-gate else 4247c478bd9Sstevel@tonic-gate { 4257c478bd9Sstevel@tonic-gate t = (struct comnod *)getstor(sizeof(struct comnod)); 4267c478bd9Sstevel@tonic-gate r = (struct trenod *)t; 4277c478bd9Sstevel@tonic-gate 4287c478bd9Sstevel@tonic-gate t->comio = io; /*initial io chain*/ 4297c478bd9Sstevel@tonic-gate argtail = &(t->comarg); 4307c478bd9Sstevel@tonic-gate 4317c478bd9Sstevel@tonic-gate while (wdval == 0) 4327c478bd9Sstevel@tonic-gate { 4337c478bd9Sstevel@tonic-gate if (fndef) 4347c478bd9Sstevel@tonic-gate { 4357c478bd9Sstevel@tonic-gate argp = wdarg; 4367c478bd9Sstevel@tonic-gate wdarg = (struct argnod *)alloc(length(argp->argval) + BYTESPERWORD); 4377c478bd9Sstevel@tonic-gate movstr(argp->argval, wdarg->argval); 4387c478bd9Sstevel@tonic-gate } 4397c478bd9Sstevel@tonic-gate 4407c478bd9Sstevel@tonic-gate argp = wdarg; 4417c478bd9Sstevel@tonic-gate if (wdset && keywd) 4427c478bd9Sstevel@tonic-gate { 4437c478bd9Sstevel@tonic-gate argp->argnxt = (struct argnod *)argset; 4447c478bd9Sstevel@tonic-gate argset = (struct argnod **)argp; 4457c478bd9Sstevel@tonic-gate } 4467c478bd9Sstevel@tonic-gate else 4477c478bd9Sstevel@tonic-gate { 4487c478bd9Sstevel@tonic-gate *argtail = argp; 4497c478bd9Sstevel@tonic-gate argtail = &(argp->argnxt); 4507c478bd9Sstevel@tonic-gate keywd = flags & keyflg; 4517c478bd9Sstevel@tonic-gate } 4527c478bd9Sstevel@tonic-gate word(); 4537c478bd9Sstevel@tonic-gate if (flag) 4547c478bd9Sstevel@tonic-gate { 4557c478bd9Sstevel@tonic-gate if (io) 4567c478bd9Sstevel@tonic-gate { 4577c478bd9Sstevel@tonic-gate while(io->ionxt) 4587c478bd9Sstevel@tonic-gate io = io->ionxt; 4597c478bd9Sstevel@tonic-gate io->ionxt = inout((struct ionod *)0); 4607c478bd9Sstevel@tonic-gate } 4617c478bd9Sstevel@tonic-gate else 4627c478bd9Sstevel@tonic-gate t->comio = io = inout((struct ionod *)0); 4637c478bd9Sstevel@tonic-gate } 4647c478bd9Sstevel@tonic-gate } 4657c478bd9Sstevel@tonic-gate 4667c478bd9Sstevel@tonic-gate t->comtyp = TCOM; 4677c478bd9Sstevel@tonic-gate t->comset = (struct argnod *)argset; 4687c478bd9Sstevel@tonic-gate *argtail = 0; 4697c478bd9Sstevel@tonic-gate 4707c478bd9Sstevel@tonic-gate if (nohash == 0 && (fndef == 0 || (flags & hashflg))) 4717c478bd9Sstevel@tonic-gate { 4727c478bd9Sstevel@tonic-gate if (t->comarg) 4737c478bd9Sstevel@tonic-gate { 4747c478bd9Sstevel@tonic-gate com = t->comarg->argval; 4757c478bd9Sstevel@tonic-gate if (*com && *com != DOLLAR) 4767c478bd9Sstevel@tonic-gate pathlook(com, 0, t->comset); 4777c478bd9Sstevel@tonic-gate } 4787c478bd9Sstevel@tonic-gate } 4797c478bd9Sstevel@tonic-gate 4807c478bd9Sstevel@tonic-gate return(r); 4817c478bd9Sstevel@tonic-gate } 4827c478bd9Sstevel@tonic-gate } 4837c478bd9Sstevel@tonic-gate 4847c478bd9Sstevel@tonic-gate } 4857c478bd9Sstevel@tonic-gate reserv++; 4867c478bd9Sstevel@tonic-gate word(); 4877c478bd9Sstevel@tonic-gate if (io = inout(io)) 4887c478bd9Sstevel@tonic-gate { 4897c478bd9Sstevel@tonic-gate r = makefork(0,r); 4907c478bd9Sstevel@tonic-gate r->treio = io; 4917c478bd9Sstevel@tonic-gate } 4927c478bd9Sstevel@tonic-gate return(r); 4937c478bd9Sstevel@tonic-gate } 4947c478bd9Sstevel@tonic-gate 4957c478bd9Sstevel@tonic-gate 4967c478bd9Sstevel@tonic-gate static int 4977c478bd9Sstevel@tonic-gate skipnl() 4987c478bd9Sstevel@tonic-gate { 4997c478bd9Sstevel@tonic-gate while ((reserv++, word() == NL)) 5007c478bd9Sstevel@tonic-gate chkpr(); 5017c478bd9Sstevel@tonic-gate return(wdval); 5027c478bd9Sstevel@tonic-gate } 5037c478bd9Sstevel@tonic-gate 5047c478bd9Sstevel@tonic-gate static struct ionod * 5057c478bd9Sstevel@tonic-gate inout(lastio) 5067c478bd9Sstevel@tonic-gate struct ionod *lastio; 5077c478bd9Sstevel@tonic-gate { 508965005c8Schin int iof; 509965005c8Schin struct ionod *iop; 510965005c8Schin unsigned int c; 5117c478bd9Sstevel@tonic-gate 5127c478bd9Sstevel@tonic-gate iof = wdnum; 5137c478bd9Sstevel@tonic-gate switch (wdval) 5147c478bd9Sstevel@tonic-gate { 5157c478bd9Sstevel@tonic-gate case DOCSYM: /* << */ 5161573d361Snakanon iof |= IODOC|IODOC_SUBST; 5177c478bd9Sstevel@tonic-gate break; 5187c478bd9Sstevel@tonic-gate 5197c478bd9Sstevel@tonic-gate case APPSYM: /* >> */ 5207c478bd9Sstevel@tonic-gate case '>': 5217c478bd9Sstevel@tonic-gate if (wdnum == 0) 5227c478bd9Sstevel@tonic-gate iof |= 1; 5237c478bd9Sstevel@tonic-gate iof |= IOPUT; 5247c478bd9Sstevel@tonic-gate if (wdval == APPSYM) 5257c478bd9Sstevel@tonic-gate { 5267c478bd9Sstevel@tonic-gate iof |= IOAPP; 5277c478bd9Sstevel@tonic-gate break; 5287c478bd9Sstevel@tonic-gate } 5297c478bd9Sstevel@tonic-gate 5307c478bd9Sstevel@tonic-gate case '<': 5317c478bd9Sstevel@tonic-gate if ((c = nextwc()) == '&') 5327c478bd9Sstevel@tonic-gate iof |= IOMOV; 5337c478bd9Sstevel@tonic-gate else if (c == '>') 5347c478bd9Sstevel@tonic-gate iof |= IORDW; 5357c478bd9Sstevel@tonic-gate else 5367c478bd9Sstevel@tonic-gate peekn = c | MARK; 5377c478bd9Sstevel@tonic-gate break; 5387c478bd9Sstevel@tonic-gate 5397c478bd9Sstevel@tonic-gate default: 5407c478bd9Sstevel@tonic-gate return(lastio); 5417c478bd9Sstevel@tonic-gate } 5427c478bd9Sstevel@tonic-gate 5437c478bd9Sstevel@tonic-gate chkword(); 5447c478bd9Sstevel@tonic-gate iop = (struct ionod *)getstor(sizeof(struct ionod)); 5457c478bd9Sstevel@tonic-gate 5467c478bd9Sstevel@tonic-gate if (fndef) 5477c478bd9Sstevel@tonic-gate iop->ioname = (char *) make(wdarg->argval); 5487c478bd9Sstevel@tonic-gate else 5497c478bd9Sstevel@tonic-gate iop->ioname = (char *) (wdarg->argval); 5507c478bd9Sstevel@tonic-gate 5517c478bd9Sstevel@tonic-gate iop->iolink = 0; 5527c478bd9Sstevel@tonic-gate iop->iofile = iof; 5537c478bd9Sstevel@tonic-gate if (iof & IODOC) 5547c478bd9Sstevel@tonic-gate { 5557c478bd9Sstevel@tonic-gate iop->iolst = iopend; 5567c478bd9Sstevel@tonic-gate iopend = iop; 5577c478bd9Sstevel@tonic-gate } 5587c478bd9Sstevel@tonic-gate word(); 5597c478bd9Sstevel@tonic-gate iop->ionxt = inout(lastio); 5607c478bd9Sstevel@tonic-gate return(iop); 5617c478bd9Sstevel@tonic-gate } 5627c478bd9Sstevel@tonic-gate 563965005c8Schin static void 564965005c8Schin chkword(void) 5657c478bd9Sstevel@tonic-gate { 5667c478bd9Sstevel@tonic-gate if (word()) 5677c478bd9Sstevel@tonic-gate synbad(); 5687c478bd9Sstevel@tonic-gate } 5697c478bd9Sstevel@tonic-gate 570965005c8Schin static void 571965005c8Schin chksym(int sym) 5727c478bd9Sstevel@tonic-gate { 573965005c8Schin int x = sym & wdval; 5747c478bd9Sstevel@tonic-gate 5757c478bd9Sstevel@tonic-gate if (((x & SYMFLG) ? x : sym) != wdval) 5767c478bd9Sstevel@tonic-gate synbad(); 5777c478bd9Sstevel@tonic-gate } 5787c478bd9Sstevel@tonic-gate 579965005c8Schin static void 580965005c8Schin prsym(int sym) 5817c478bd9Sstevel@tonic-gate { 5827c478bd9Sstevel@tonic-gate if (sym & SYMFLG) 5837c478bd9Sstevel@tonic-gate { 584965005c8Schin const struct sysnod *sp = reserved; 5857c478bd9Sstevel@tonic-gate 5867c478bd9Sstevel@tonic-gate while (sp->sysval && sp->sysval != sym) 5877c478bd9Sstevel@tonic-gate sp++; 5887c478bd9Sstevel@tonic-gate prs(sp->sysnam); 5897c478bd9Sstevel@tonic-gate } 5907c478bd9Sstevel@tonic-gate else if (sym == EOFSYM) 59139e7390aSna195498 prs(_gettext(endoffile)); 5927c478bd9Sstevel@tonic-gate else 5937c478bd9Sstevel@tonic-gate { 5947c478bd9Sstevel@tonic-gate if (sym & SYMREP) 5957c478bd9Sstevel@tonic-gate prc(sym); 5967c478bd9Sstevel@tonic-gate if (sym == NL) 59739e7390aSna195498 prs(_gettext(nlorsemi)); 5987c478bd9Sstevel@tonic-gate else 5997c478bd9Sstevel@tonic-gate prc(sym); 6007c478bd9Sstevel@tonic-gate } 6017c478bd9Sstevel@tonic-gate } 6027c478bd9Sstevel@tonic-gate 603965005c8Schin static void 604965005c8Schin synbad(void) 6057c478bd9Sstevel@tonic-gate { 6067c478bd9Sstevel@tonic-gate prp(); 60739e7390aSna195498 prs(_gettext(synmsg)); 6087c478bd9Sstevel@tonic-gate if ((flags & ttyflg) == 0) 6097c478bd9Sstevel@tonic-gate { 61039e7390aSna195498 prs(_gettext(atline)); 6117c478bd9Sstevel@tonic-gate prn(standin->flin); 6127c478bd9Sstevel@tonic-gate } 6137c478bd9Sstevel@tonic-gate prs(colon); 6147c478bd9Sstevel@tonic-gate prc(LQ); 6157c478bd9Sstevel@tonic-gate if (wdval) 6167c478bd9Sstevel@tonic-gate prsym(wdval); 6177c478bd9Sstevel@tonic-gate else 6187c478bd9Sstevel@tonic-gate prs_cntl(wdarg->argval); 6197c478bd9Sstevel@tonic-gate prc(RQ); 62039e7390aSna195498 prs(_gettext(unexpected)); 6217c478bd9Sstevel@tonic-gate newline(); 6227c478bd9Sstevel@tonic-gate exitsh(SYNBAD); 6237c478bd9Sstevel@tonic-gate } 624