da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/***********************************************************************
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* This software is part of the ast package *
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner* Copyright (c) 1982-2010 AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* and is licensed under the *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Common Public License, Version 1.0 *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* by AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* A copy of the License is available at *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* http://www.opensource.org/licenses/cpl1.0.txt *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Information and Software Systems Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* AT&T Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Florham Park NJ *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* David Korn <dgk@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin***********************************************************************/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#pragma prototyped
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * UNIX shell
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * S. R. Bourne
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Rewritten by David Korn
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * AT&T Labs
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * This is the parser for a shell language
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if KSHELL
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "defs.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <shell.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <ctype.h>
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <fcin.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <error.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "shlex.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "history.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "builtins.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "test.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "history.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define HERE_MEM 1024 /* size of here-docs kept in memory */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define hash nvlink.hl._hash
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/* These routines are local to this module */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic Shnode_t *makeparent(Lex_t*, int, Shnode_t*);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic Shnode_t *makelist(Lex_t*, int, Shnode_t*, Shnode_t*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic struct argnod *qscan(struct comnod*, int);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic struct ionod *inout(Lex_t*,struct ionod*, int);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic Shnode_t *sh_cmd(Lex_t*,int,int);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic Shnode_t *term(Lex_t*,int);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic Shnode_t *list(Lex_t*,int);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic struct regnod *syncase(Lex_t*,int);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic Shnode_t *item(Lex_t*,int);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic Shnode_t *simple(Lex_t*,int, struct ionod*);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic int skipnl(Lex_t*,int);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic Shnode_t *test_expr(Lex_t*,int);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic Shnode_t *test_and(Lex_t*);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic Shnode_t *test_or(Lex_t*);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic Shnode_t *test_primary(Lex_t*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#define sh_getlineno(lp) (lp->lastline)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifndef NIL
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define NIL(type) ((type)0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* NIL */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define CNTL(x) ((x)&037)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if !KSHELL
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic struct stdata
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct slnod *staklist;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int cmdline;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin} st;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic int opt_get;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int loop_level;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic struct argnod *label_list;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic struct argnod *label_last;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define getnode(type) ((Shnode_t*)stakalloc(sizeof(struct type)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_KIA
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "path.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * write out entities for each item in the list
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * type=='V' for variable assignment lists
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Otherwise type is determined by the command */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic unsigned long writedefs(Lex_t *lexp,struct argnod *arglist, int line, int type, struct argnod *cmd)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register struct argnod *argp = arglist;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int n,eline;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int width=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned long r=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static char atbuff[20];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int justify=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *attribute = atbuff;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin unsigned long parent=lexp->script;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(type==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin parent = lexp->current;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin type = 'v';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch(*argp->argval)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'a':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin type='p';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin justify = 'a';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'e':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *attribute++ = 'x';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'r':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *attribute++ = 'r';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'l':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(argp = argp->argnxt.ap)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((n= *(cp=argp->argval))!='-' && n!='+')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(cp[1]==n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while((n= *++cp))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(isdigit(n))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin width = 10*width + n-'0';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(n=='L' || n=='R' || n =='Z')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin justify=n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *attribute++ = n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(cmd)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin parent=kiaentity(lexp,sh_argstr(cmd),-1,'p',-1,-1,lexp->unknown,'b',0,"");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *attribute = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(argp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((cp=strchr(argp->argval,'='))||(cp=strchr(argp->argval,'?')))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = cp-argp->argval;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = strlen(argp->argval);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin eline = lexp->sh->inlineno-(lexp->token==NL);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin r=kiaentity(lexp,argp->argval,n,type,line,eline,parent,justify,width,atbuff);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfprintf(lexp->kiatmp,"p;%..64d;v;%..64d;%d;%d;s;\n",lexp->current,r,line,eline);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argp = argp->argnxt.ap;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(r);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_KIA */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic void typeset_order(const char *str,int line)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register int c,n=0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin unsigned const char *cp=(unsigned char*)str;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin static unsigned char *table;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(*cp!='+' && *cp!='-')
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!table)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin table = calloc(1,256);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin for(cp=(unsigned char*)"bflmnprstuxACHS";c = *cp; cp++)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin table[c] = 1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin for(cp=(unsigned char*)"aiEFLRXhTZ";c = *cp; cp++)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin table[c] = 2;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin for(c='0'; c <='9'; c++)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin table[c] = 3;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin for(cp=(unsigned char*)str; c= *cp++; n=table[c])
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(table[c] < n)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin errormsg(SH_DICT,ERROR_warn(0),e_lextypeset,line,str);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin}
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin/*
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * add type definitions when compiling with -n
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic void check_typedef(struct comnod *tp)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin char *cp=0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(tp->comtyp&COMSCAN)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin struct argnod *ap = tp->comarg;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin while(ap = ap->argnxt.ap)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!(ap->argflag&ARG_RAW) || memcmp(ap->argval,"--",2))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin break;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(sh_isoption(SH_NOEXEC))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin typeset_order(ap->argval,tp->comline);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(memcmp(ap->argval,"-T",2)==0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(ap->argval[2])
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin cp = ap->argval+2;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if((ap->argnxt.ap)->argflag&ARG_RAW)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin cp = (ap->argnxt.ap)->argval;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(cp)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin break;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin struct dolnod *dp = (struct dolnod*)tp->comarg;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin char **argv = dp->dolval + dp->dolbot+1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin while((cp= *argv++) && memcmp(cp,"--",2))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(sh_isoption(SH_NOEXEC))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin typeset_order(cp,tp->comline);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(memcmp(cp,"-T",2)==0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(cp[2])
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin cp = cp+2;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin cp = *argv;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin break;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(cp)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Namval_t *mp=(Namval_t*)tp->comnamp ,*bp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin bp = sh_addbuiltin(cp,mp->nvalue.bfp, (void*)0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_onattr(bp,nv_isattr(mp,NV_PUBLIC));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin}
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Make a parent node for fork() or io-redirection
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic Shnode_t *makeparent(Lex_t *lp, int flag, Shnode_t *child)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Shnode_t *par = getnode(forknod);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin par->fork.forktyp = flag;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin par->fork.forktre = child;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin par->fork.forkio = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin par->fork.forkline = sh_getlineno(lp)-1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(par);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulknerstatic int paramsub(const char *str)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner{
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner register int c,sub=0,lit=0;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner while(c= *str++)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner {
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if(c=='$' && !lit)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner {
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if(*str=='(')
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner return(0);
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if(sub)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner continue;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if(*str=='{')
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner str++;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if(!isdigit(*str) && strchr("?#@*!$ ",*str)==0)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner return(1);
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner }
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner else if(c=='`')
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner return(0);
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner else if(c=='[' && !lit)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner sub++;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner else if(c==']' && !lit)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner sub--;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner else if(c=='\'')
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner lit = !lit;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner }
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner return(0);
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner}
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic Shnode_t *getanode(Lex_t *lp, struct argnod *ap)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Shnode_t *t = getnode(arithnod);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t->ar.artyp = TARITH;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin t->ar.arline = sh_getlineno(lp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t->ar.arexpr = ap;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ap->argflag&ARG_RAW)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t->ar.arcomp = sh_arithcomp(ap->argval);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner {
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if(sh_isoption(SH_NOEXEC) && (ap->argflag&ARG_MAC) && paramsub(ap->argval))
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner errormsg(SH_DICT,ERROR_warn(0),"%d: parameter substitution requires unnecessary string to number conversion",lp->sh->inlineno-(lp->token=='\n'));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t->ar.arcomp = 0;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(t);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Make a node corresponding to a command list
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic Shnode_t *makelist(Lex_t *lexp, int type, Shnode_t *l, Shnode_t *r)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Shnode_t *t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!l || !r)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_syntax(lexp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((type&COMMSK) == TTST)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t = getnode(tstnod);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t = getnode(lstnod);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t->lst.lsttyp = type;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t->lst.lstlef = l;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t->lst.lstrit = r;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(t);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * entry to shell parser
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Flag can be the union of SH_EOF|SH_NL
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvoid *sh_parse(Shell_t *shp, Sfio_t *iop, int flag)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Shnode_t *t;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Lex_t *lexp = (Lex_t*)shp->lex_context;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Fcin_t sav_input;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin struct argnod *sav_arg = lexp->arg;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int sav_prompt = shp->nextprompt;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(shp->binscript && (sffileno(iop)==shp->infd || (flag&SH_FUNEVAL)))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return((void*)sh_trestore(shp,iop));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcsave(&sav_input);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin shp->st.staklist = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lexp->heredoc = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lexp->inlineno = shp->inlineno;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lexp->firstline = shp->st.firstline;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin shp->nextprompt = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin loop_level = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin label_list = label_last = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh_isoption(SH_INTERACTIVE))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_onstate(SH_INTERACTIVE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh_isoption(SH_VERBOSE))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_onstate(SH_VERBOSE);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_lexopen(lexp,shp,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fcfopen(iop) < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(NIL(void*));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fcfile())
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *cp = fcfirst();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if( cp[0]==CNTL('k') && cp[1]==CNTL('s') && cp[2]==CNTL('h') && cp[3]==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int version;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcseek(4);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcgetc(version);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcclose();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcrestore(&sav_input);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lexp->arg = sav_arg;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(version > 3)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_exit(1),e_lexversion);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(sffileno(iop)==shp->infd || (flag&SH_FUNEVAL))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin shp->binscript = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfgetc(iop);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return((void*)sh_trestore(shp,iop));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz flag &= ~SH_FUNEVAL;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((flag&SH_NL) && (shp->inlineno=error_info.line+shp->st.firstline)==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin shp->inlineno=1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if KSHELL
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin shp->nextprompt = 2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin t = sh_cmd(lexp,(flag&SH_EOF)?EOFSYM:'\n',SH_SEMI|SH_EMPTY|(flag&SH_NL));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcclose();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcrestore(&sav_input);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lexp->arg = sav_arg;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* unstack any completed alias expansions */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((sfset(iop,0,0)&SF_STRING) && !sfreserve(iop,0,-1))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfio_t *sp = sfstack(iop,NULL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfclose(sp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin shp->nextprompt = sav_prompt;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flag&SH_NL)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->st.firstline = lexp->firstline;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->inlineno = lexp->inlineno;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin stkseek(shp->stk,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return((void*)t);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * This routine parses up the matching right parenthesis and returns
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * the parse tree
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April ChinShnode_t *sh_dolparen(Lex_t* lp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Shnode_t *t=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfio_t *sp = fcfile();
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int line = lp->sh->inlineno;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->sh->inlineno = error_info.line+lp->sh->st.firstline;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_lexopen(lp,lp->sh,1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->comsub = 1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin switch(sh_lex(lp))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* ((...)) arithmetic expression */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case EXPRSYM:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin t = getanode(lp,lp->arg);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case LPAREN:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin t = sh_cmd(lp,RPAREN,SH_NL|SH_EMPTY);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin break;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin case LBRACE:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin t = sh_cmd(lp,RBRACE,SH_NL|SH_EMPTY);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->comsub = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!sp && (sp=fcfile()))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * This code handles the case where string has been converted
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * to a file by an alias setup
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fcgetc(c) > 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcseek(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = fcseek(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcclose();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcsopen(cp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfclose(sp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp->sh->inlineno = line;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(t);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * remove temporary files and stacks
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinvoid sh_freeup(Shell_t *shp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->st.staklist)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_funstaks(shp->st.staklist,-1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->st.staklist = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * increase reference count for each stack in function list when flag>0
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * decrease reference count for each stack in function list when flag<=0
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * stack is freed when reference count is zero
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvoid sh_funstaks(register struct slnod *slp,int flag)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register struct slnod *slpold;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(slpold=slp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(slp->slchild)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_funstaks(slp->slchild,flag);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin slp = slp->slnext;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flag<=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakdelete(slpold->slptr);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin staklink(slpold->slptr);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * cmd
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * empty
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * list
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * list & [ cmd ]
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * list [ ; cmd ]
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic Shnode_t *sh_cmd(Lex_t *lexp, register int sym, int flag)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Shnode_t *left, *right;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int type = FINT|FAMP;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sym==NL)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lexp->lasttok = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin left = list(lexp,flag);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lexp->token==NL)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flag&SH_NL)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lexp->token=';';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(!left && !(flag&SH_EMPTY))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_syntax(lexp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin switch(lexp->token)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case COOPSYM: /* set up a cooperating process */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin type |= (FPIN|FPOU|FPCL|FCOOP);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* FALL THRU */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '&':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(left)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* (...)& -> {...;} & */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(left->tre.tretyp==TPAR)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin left = left->par.partre;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin left = makeparent(lexp,TFORK|type, left);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* FALL THRU */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case ';':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!left)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_syntax(lexp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(right=sh_cmd(lexp,sym,flag|SH_EMPTY))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin left=makelist(lexp,TLST, left, right);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case EOFSYM:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sym==NL)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(sym && sym!=lexp->token)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(sym!=ELSESYM || (lexp->token!=ELIFSYM && lexp->token!=FISYM))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_syntax(lexp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(left);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * list
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * term
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * list && term
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * list || term
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * unfortunately, these are equal precedence
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic Shnode_t *list(Lex_t *lexp, register int flag)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register Shnode_t *t = term(lexp,flag);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int token;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin while(t && ((token=lexp->token)==ANDFSYM || token==ORFSYM))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin t = makelist(lexp,(token==ANDFSYM?TAND:TORF), t, term(lexp,SH_NL|SH_SEMI));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(t);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * term
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * item
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * item | term
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic Shnode_t *term(Lex_t *lexp,register int flag)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Shnode_t *t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int token;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flag&SH_NL)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin token = skipnl(lexp,flag);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin token = sh_lex(lexp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* check to see if pipeline is to be timed */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(token==TIMESYM || token==NOTSYM)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t = getnode(parnod);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t->par.partyp=TTIME;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lexp->token==NOTSYM)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t->par.partyp |= COMSCAN;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin t->par.partre = term(lexp,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if((t=item(lexp,SH_NL|SH_EMPTY|(flag&SH_SEMI))) && lexp->token=='|')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Shnode_t *tt;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int showme = t->tre.tretyp&FSHOWME;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin t = makeparent(lexp,TFORK|FPOU,t);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(tt=term(lexp,SH_NL))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch(tt->tre.tretyp&COMMSK)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case TFORK:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tt->tre.tretyp |= FPIN|FPCL;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case TFIL:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tt->lst.lstlef->tre.tretyp |= FPIN|FPCL;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin tt= makeparent(lexp,TSETIO|FPIN|FPCL,tt);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin t=makelist(lexp,TFIL,t,tt);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t->tre.tretyp |= showme;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(lexp->token)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_syntax(lexp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(t);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * case statement
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic struct regnod* syncase(Lex_t *lexp,register int esym)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register int tok = skipnl(lexp,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register struct regnod *r;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(tok==esym)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(NIL(struct regnod*));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin r = (struct regnod*)stakalloc(sizeof(struct regnod));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin r->regptr=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin r->regflag=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(tok==LPAREN)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin skipnl(lexp,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!lexp->arg)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_syntax(lexp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lexp->arg->argnxt.ap=r->regptr;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin r->regptr = lexp->arg;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((tok=sh_lex(lexp))==RPAREN)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(tok=='|')
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_lex(lexp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_syntax(lexp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin r->regcom=sh_cmd(lexp,0,SH_NL|SH_EMPTY|SH_SEMI);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((tok=lexp->token)==BREAKCASESYM)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin r->regnxt=syncase(lexp,esym);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(tok==FALLTHRUSYM)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin r->regflag++;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin r->regnxt=syncase(lexp,esym);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(tok!=esym && tok!=EOFSYM)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_syntax(lexp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin r->regnxt=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lexp->token==EOFSYM)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(NIL(struct regnod*));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(r);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * This routine creates the parse tree for the arithmetic for
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * When called, shlex.arg contains the string inside ((...))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * When the first argument is missing, a while node is returned
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Otherise a list containing an arithmetic command and a while
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * is returned.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic Shnode_t *arithfor(Lex_t *lexp,register Shnode_t *tf)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Shnode_t *t, *tw = tf;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int offset;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register struct argnod *argp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int n;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Stk_t *stkp = lexp->sh->stk;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int argflag = lexp->arg->argflag;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* save current input */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Fcin_t sav_input;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcsave(&sav_input);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin fcsopen(lexp->arg->argval);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* split ((...)) into three expressions */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(n=0; ; n++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin argp = (struct argnod*)stkseek(stkp,ARGVAL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argp->argnxt.ap = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argp->argchn.cp = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argp->argflag = argflag;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n==2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* copy up to ; onto the stack */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_lexskip(lexp,';',1,ST_NESTED);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin offset = stktell(stkp)-1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((c=fcpeek(-1))!=';')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* remove trailing white space */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin while(offset>ARGVAL && ((c= *stkptr(stkp,offset-1)),isspace(c)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin offset--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* check for empty initialization expression */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(offset==ARGVAL && n==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin stkseek(stkp,offset);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* check for empty condition and treat as while((1)) */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(offset==ARGVAL)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfputc(stkp,'1');
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin argp = (struct argnod*)stkfreeze(stkp,1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin t = getanode(lexp,argp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n==0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin tf = makelist(lexp,TLST,t,tw);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tw->wh.whtre = t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while((offset=fcpeek(0)) && isspace(offset))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcseek(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputs(fcseek(0));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argp = (struct argnod*)stakfreeze(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcrestore(&sav_input);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n<2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lexp->token = RPAREN|SYMREP;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_syntax(lexp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* check whether the increment is present */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*argp->argval)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin t = getanode(lexp,argp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tw->wh.whinc = (struct arithnod*)t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tw->wh.whinc = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_lexopen(lexp, lexp->sh,1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((n=sh_lex(lexp))==NL)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin n = skipnl(lexp,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(n==';')
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin n = sh_lex(lexp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n!=DOSYM && n!=LBRACE)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_syntax(lexp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin tw->wh.dotre = sh_cmd(lexp,n==DOSYM?DONESYM:RBRACE,SH_NL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tw->wh.whtyp = TWH;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(tf);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic Shnode_t *funct(Lex_t *lexp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Shell_t *shp = lexp->sh;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Shnode_t *t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int flag;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct slnod *volatile slp=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Stak_t *savstak;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfoff_t first, last;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin struct functnod *volatile fp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfio_t *iop;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_KIA
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin unsigned long current = lexp->current;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_KIA */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int jmpval, saveloop=loop_level;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct argnod *savelabel = label_last;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct checkpt buff;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int save_optget = opt_get;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin void *in_mktype = shp->mktype;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->mktype = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin opt_get = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t = getnode(functnod);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin t->funct.functline = shp->inlineno;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t->funct.functtyp=TFUN;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t->funct.functargs = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!(flag = (lexp->token==FUNCTSYM)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t->funct.functtyp |= FPOSIX;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(sh_lex(lexp))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_syntax(lexp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(iop=fcfile()))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin iop = sfopen(NIL(Sfio_t*),fcseek(0),"s");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcclose();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcfopen(iop);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t->funct.functloc = first = fctell();
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!shp->st.filename || sffileno(iop)<0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fcfill() >= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcseek(-1);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(sh_isstate(SH_HISTORY) && shp->hist_ptr)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin t->funct.functloc = sfseek(shp->hist_ptr->histfp,(off_t)0,SEEK_CUR);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* copy source to temporary file */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t->funct.functloc = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lexp->sh->heredocs)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin t->funct.functloc = sfseek(lexp->sh->heredocs,(Sfoff_t)0, SEEK_END);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lexp->sh->heredocs = sftmp(HERE_MEM);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lexp->sh->funlog = lexp->sh->heredocs;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t->funct.functtyp |= FPIN;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin t->funct.functnam= (char*)lexp->arg->argval;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_KIA
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lexp->kiafile)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lexp->current = kiaentity(lexp,t->funct.functnam,-1,'p',-1,-1,lexp->script,'p',0,"");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_KIA */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flag)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lexp->token = sh_lex(lexp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_BASH
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lexp->token == LPAREN)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((lexp->token = sh_lex(lexp)) == RPAREN)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t->funct.functtyp |= FPOSIX;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_syntax(lexp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(t->funct.functtyp&FPOSIX)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin skipnl(lexp,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lexp->token==0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin t->funct.functargs = (struct comnod*)simple(lexp,SH_NOIO|SH_FUNDEF,NIL(struct ionod*));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin while(lexp->token==NL)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lexp->token = sh_lex(lexp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((flag && lexp->token!=LBRACE) || lexp->token==EOFSYM)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_syntax(lexp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_pushcontext(&buff,1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin jmpval = sigsetjmp(buff.buff,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(jmpval == 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* create a new stak frame to compile the command */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin savstak = stakcreate(STAK_SMALL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin savstak = stakinstall(savstak, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin slp = (struct slnod*)stakalloc(sizeof(struct slnod)+sizeof(struct functnod));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin slp->slchild = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin slp->slnext = shp->st.staklist;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->st.staklist = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t->funct.functstak = (struct slnod*)slp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * store the pathname of function definition file on stack
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * in name field of fake for node
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp = (struct functnod*)(slp+1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->functtyp = TFUN|FAMP;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->functnam = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->functline = t->funct.functline;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->st.filename)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin fp->functnam = stakcopy(shp->st.filename);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin loop_level = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin label_last = label_list;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!flag && lexp->token==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* copy current word token to current stak frame */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct argnod *ap;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin flag = ARGVAL + strlen(lexp->arg->argval);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ap = (struct argnod*)stakalloc(flag);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin memcpy(ap,lexp->arg,flag);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lexp->arg = ap;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin t->funct.functtre = item(lexp,SH_NOIO);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner else if(shp->shcomp)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner exit(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_popcontext(&buff);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin loop_level = saveloop;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin label_last = savelabel;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* restore the old stack */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(slp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin slp->slptr = stakinstall(savstak,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin slp->slchild = shp->st.staklist;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_KIA
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lexp->current = current;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_KIA */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(jmpval)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(slp && slp->slptr)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->st.staklist = slp->slnext;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakdelete(slp->slptr);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin siglongjmp(*shp->jmplist,jmpval);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->st.staklist = (struct slnod*)slp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin last = fctell();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->functline = (last-first);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->functtre = t;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->mktype = in_mktype;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lexp->sh->funlog)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fcfill()>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcseek(-1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lexp->sh->funlog = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_KIA
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lexp->kiafile)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin kiaentity(lexp,t->funct.functnam,-1,'p',t->funct.functline,shp->inlineno-1,lexp->current,'p',0,"");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_KIA */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin t->funct.functtyp |= opt_get;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin opt_get = save_optget;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(t);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Compound assignment
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic struct argnod *assign(Lex_t *lexp, register struct argnod *ap, int tdef)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Shnode_t *t, **tp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register struct comnod *ac;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Stk_t *stkp = lexp->sh->stk;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int array=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Namval_t *np;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = strlen(ap->argval)-1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ap->argval[n]!='=')
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_syntax(lexp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(ap->argval[n-1]=='+')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ap->argval[n--]=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin array = ARG_APPEND;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* shift right */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(n > 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ap->argval[n] = ap->argval[n-1];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *ap->argval=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t = getnode(fornod);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t->for_.fornam = (char*)(ap->argval+1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin t->for_.fortyp = sh_getlineno(lexp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tp = &t->for_.fortre;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ap->argchn.ap = (struct argnod*)t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ap->argflag &= ARG_QUOTED;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ap->argflag |= array;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lexp->assignok = SH_ASSIGN;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lexp->aliasok = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin array=0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((n=skipnl(lexp,0))==RPAREN || n==LPAREN)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int index= 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct argnod **settail;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ac = (struct comnod*)getnode(comnod);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin settail= &ac->comset;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memset((void*)ac,0,sizeof(*ac));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ac->comline = sh_getlineno(lexp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(n==LPAREN)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct argnod *ap;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ap = (struct argnod*)stkseek(stkp,ARGVAL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ap->argflag= ARG_ASSIGN;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfprintf(stkp,"[%d]=",index++);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ap = (struct argnod*)stkfreeze(stkp,1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ap->argnxt.ap = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ap = assign(lexp,ap,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ap->argflag |= ARG_MESSAGE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *settail = ap;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin settail = &(ap->argnxt.ap);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin while((n = skipnl(lexp,0))==0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ap = (struct argnod*)stkseek(stkp,ARGVAL);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ap->argflag= ARG_ASSIGN;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfprintf(stkp,"[%d]=",index++);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin stakputs(lexp->arg->argval);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ap = (struct argnod*)stkfreeze(stkp,1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ap->argnxt.ap = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ap->argflag = lexp->arg->argflag;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin *settail = ap;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin settail = &(ap->argnxt.ap);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(n && n!=FUNCTSYM)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_syntax(lexp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(n!=FUNCTSYM && !(lexp->arg->argflag&ARG_ASSIGN) && !((np=nv_search(lexp->arg->argval,lexp->sh->fun_tree,0)) && (nv_isattr(np,BLT_DCL)|| np==SYSDOT)))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin array=SH_ARRAY;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(fcgetc(n)==LPAREN)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int c;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(fcgetc(c)==RPAREN)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lexp->token = SYMRES;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin array = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin fcseek(-2);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(n>0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin fcseek(-1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(array && tdef)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_syntax(lexp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((n=lexp->token)==RPAREN)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n==FUNCTSYM || n==SYMRES)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ac = (struct comnod*)funct(lexp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ac = (struct comnod*)simple(lexp,SH_NOIO|SH_ASSIGN|array,NIL(struct ionod*));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((n=lexp->token)==RPAREN)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n!=NL && n!=';')
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_syntax(lexp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lexp->assignok = SH_ASSIGN;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((n=skipnl(lexp,0)) || array)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n==RPAREN)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(array || n!=FUNCTSYM)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_syntax(lexp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((n!=FUNCTSYM) && !(lexp->arg->argflag&ARG_ASSIGN) && !((np=nv_search(lexp->arg->argval,lexp->sh->fun_tree,0)) && (nv_isattr(np,BLT_DCL)||np==SYSDOT)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin struct argnod *arg = lexp->arg;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n!=0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_syntax(lexp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* check for sys5 style function */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(sh_lex(lexp)!=LPAREN || sh_lex(lexp)!=RPAREN)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lexp->arg = arg;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lexp->token = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_syntax(lexp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lexp->arg = arg;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lexp->token = SYMRES;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin t = makelist(lexp,TLST,(Shnode_t*)ac,t);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *tp = t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tp = &t->lst.lstrit;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *tp = (Shnode_t*)ac;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lexp->assignok = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(ap);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * item
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * ( cmd ) [ < in ] [ > out ]
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * word word* [ < in ] [ > out ]
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * if ... then ... else ... fi
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * for ... while ... do ... done
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * case ... in ... esac
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * begin ... end
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic Shnode_t *item(Lex_t *lexp,int flag)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Shnode_t *t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register struct ionod *io;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register int tok = (lexp->token&0xff);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int savwdval = lexp->lasttok;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int savline = lexp->lastline;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int showme=0, comsub;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!(flag&SH_NOIO) && (tok=='<' || tok=='>' || lexp->token==IOVNAME))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin io=inout(lexp,NIL(struct ionod*),1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin io=0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((tok=lexp->token) && tok!=EOFSYM && tok!=FUNCTSYM)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lexp->lastline = sh_getlineno(lexp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lexp->lasttok = lexp->token;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch(tok)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* [[ ... ]] test expression */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case BTESTSYM:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin t = test_expr(lexp,ETESTSYM);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t->tre.tretyp &= ~TTEST;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* ((...)) arithmetic expression */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case EXPRSYM:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin t = getanode(lexp,lexp->arg);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_lex(lexp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto done;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* case statement */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case CASESYM:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int savetok = lexp->lasttok;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int saveline = lexp->lastline;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t = getnode(swnod);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(sh_lex(lexp))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_syntax(lexp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin t->sw.swarg=lexp->arg;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t->sw.swtyp=TSW;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t->sw.swio = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t->sw.swtyp |= FLINENO;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin t->sw.swline = lexp->sh->inlineno;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((tok=skipnl(lexp,0))!=INSYM && tok!=LBRACE)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_syntax(lexp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!(t->sw.swlst=syncase(lexp,tok==INSYM?ESACSYM:RBRACE)) && lexp->token==EOFSYM)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lexp->lasttok = savetok;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lexp->lastline = saveline;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_syntax(lexp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* if statement */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case IFSYM:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Shnode_t *tt;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t = getnode(ifnod);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t->if_.iftyp=TIF;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin t->if_.iftre=sh_cmd(lexp,THENSYM,SH_NL);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin t->if_.thtre=sh_cmd(lexp,ELSESYM,SH_NL|SH_SEMI);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin tok = lexp->token;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin t->if_.eltre=(tok==ELSESYM?sh_cmd(lexp,FISYM,SH_NL|SH_SEMI):
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin (tok==ELIFSYM?(lexp->token=IFSYM, tt=item(lexp,SH_NOIO)):0));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(tok==ELIFSYM)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!tt || tt->tre.tretyp!=TSETIO)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto done;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t->if_.eltre = tt->fork.forktre;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tt->fork.forktre = t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t = tt;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto done;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* for and select statement */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case FORSYM:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case SELECTSYM:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t = getnode(fornod);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin t->for_.fortyp=(lexp->token==FORSYM?TFOR:TSELECT);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t->for_.forlst=0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin t->for_.forline = lexp->sh->inlineno;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(sh_lex(lexp))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lexp->token!=EXPRSYM || t->for_.fortyp!=TFOR)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_syntax(lexp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* arithmetic for */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin t = arithfor(lexp,t);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin t->for_.fornam=(char*) lexp->arg->argval;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t->for_.fortyp |= FLINENO;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_KIA
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lexp->kiafile)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin writedefs(lexp,lexp->arg,lexp->sh->inlineno,'v',NIL(struct argnod*));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_KIA */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin while((tok=sh_lex(lexp))==NL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(tok==INSYM)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(sh_lex(lexp))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lexp->token != NL && lexp->token !=';')
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_syntax(lexp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* some Linux scripts assume this */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh_isoption(SH_NOEXEC))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin errormsg(SH_DICT,ERROR_warn(0),e_lexemptyfor,lexp->sh->inlineno-(lexp->token=='\n'));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t->for_.forlst = (struct comnod*)getnode(comnod);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (t->for_.forlst)->comarg = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (t->for_.forlst)->comset = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (t->for_.forlst)->comnamp = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (t->for_.forlst)->comnamq = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (t->for_.forlst)->comstate = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (t->for_.forlst)->comio = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (t->for_.forlst)->comtyp = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin t->for_.forlst=(struct comnod*)simple(lexp,SH_NOIO,NIL(struct ionod*));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lexp->token != NL && lexp->token !=';')
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_syntax(lexp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin tok = skipnl(lexp,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* 'for i;do cmd' is valid syntax */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(tok==';')
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin tok=sh_lex(lexp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(tok!=DOSYM && tok!=LBRACE)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_syntax(lexp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin loop_level++;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin t->for_.fortre=sh_cmd(lexp,tok==DOSYM?DONESYM:RBRACE,SH_NL|SH_SEMI);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(--loop_level==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin label_last = label_list;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* This is the code for parsing function definitions */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case FUNCTSYM:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(funct(lexp));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_NAMESPACE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case NSPACESYM:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t = getnode(fornod);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t->for_.fortyp=TNSPACE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t->for_.forlst=0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(sh_lex(lexp))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_syntax(lexp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin t->for_.fornam=(char*) lexp->arg->argval;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin while((tok=sh_lex(lexp))==NL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(tok!=LBRACE)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_syntax(lexp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin t->for_.fortre = sh_cmd(lexp,RBRACE,SH_NL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_NAMESPACE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* while and until */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case WHILESYM:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case UNTILSYM:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t = getnode(whnod);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin t->wh.whtyp=(lexp->token==WHILESYM ? TWH : TUN);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin loop_level++;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin t->wh.whtre = sh_cmd(lexp,DOSYM,SH_NL);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin t->wh.dotre = sh_cmd(lexp,DONESYM,SH_NL|SH_SEMI);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(--loop_level==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin label_last = label_list;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t->wh.whinc = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case LABLSYM:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register struct argnod *argp = label_list;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(argp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(strcmp(argp->argval,lexp->arg->argval)==0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin errormsg(SH_DICT,ERROR_exit(3),e_lexsyntax3,lexp->sh->inlineno,argp->argval);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argp = argp->argnxt.ap;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lexp->arg->argnxt.ap = label_list;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin label_list = lexp->arg;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin label_list->argchn.len = sh_getlineno(lexp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin label_list->argflag = loop_level;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin skipnl(lexp,flag);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!(t = item(lexp,SH_NL)))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_syntax(lexp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tok = (t->tre.tretyp&(COMSCAN|COMSCAN-1));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh_isoption(SH_NOEXEC) && tok!=TWH && tok!=TUN && tok!=TFOR && tok!=TSELECT)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_warn(0),e_lexlabignore,label_list->argchn.len,label_list->argval);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(t);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* command group with {...} */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case LBRACE:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin comsub = lexp->comsub;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lexp->comsub = 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz t = sh_cmd(lexp,RBRACE,SH_NL|SH_SEMI);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lexp->comsub = comsub;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case LPAREN:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t = getnode(parnod);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz t->par.partre=sh_cmd(lexp,RPAREN,SH_NL|SH_SEMI);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t->par.partyp=TPAR;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(io==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case ';':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(io==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(flag&SH_SEMI))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(sh_lex(lexp)==';')
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_syntax(lexp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin showme = FSHOWME;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* simple command */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 0:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin t = (Shnode_t*)simple(lexp,flag,io);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(t->com.comarg && lexp->intypeset && (lexp->sh->shcomp || sh_isoption(SH_NOEXEC) || sh.dot_depth))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin check_typedef(&t->com);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lexp->intypeset = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lexp->inexec = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t->tre.tretyp |= showme;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(t);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_lex(lexp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(io=inout(lexp,io,0))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((tok=t->tre.tretyp&COMMSK) != TFORK)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tok = TSETIO;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin t=makeparent(lexp,tok,t);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t->tre.treio=io;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chindone:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lexp->lasttok = savwdval;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lexp->lastline = savline;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(t);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzstatic struct argnod *process_sub(Lex_t *lexp,int tok)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz{
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz struct argnod *argp;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz Shnode_t *t;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz int mode = (tok==OPROCSYM);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz t = sh_cmd(lexp,RPAREN,SH_NL);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz argp = (struct argnod*)stkalloc(lexp->sh->stk,sizeof(struct argnod));
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz *argp->argval = 0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz argp->argchn.ap = (struct argnod*)makeparent(lexp,mode?TFORK|FPIN|FAMP|FPCL:TFORK|FPOU,t);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz argp->argflag = (ARG_EXP|mode);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz return(argp);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz}
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * This is for a simple command, for list, or compound assignment
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic Shnode_t *simple(Lex_t *lexp,int flag, struct ionod *io)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register struct comnod *t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register struct argnod *argp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int tok;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Stk_t *stkp = lexp->sh->stk;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct argnod **argtail;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct argnod **settail;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int cmdarg=0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int argno = 0, argmax=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int assignment = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int key_on = (!(flag&SH_NOIO) && sh_isoption(SH_KEYWORD));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int associative=0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((argp=lexp->arg) && (argp->argflag&ARG_ASSIGN) && argp->argval[0]=='[')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flag |= SH_ARRAY;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin associative = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t = (struct comnod*)getnode(comnod);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t->comio=io; /*initial io chain*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* set command line number for error messages */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin t->comline = sh_getlineno(lexp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argtail = &(t->comarg);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t->comset = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t->comnamp = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t->comnamq = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t->comstate = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin settail = &(t->comset);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin while(lexp->token==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin argp = lexp->arg;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*argp->argval==LBRACE && (flag&SH_FUNDEF) && argp->argval[1]==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lexp->token = LBRACE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(associative && argp->argval[0]!='[')
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_syntax(lexp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* check for assignment argument */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((argp->argflag&ARG_ASSIGN) && assignment!=2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *settail = argp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin settail = &(argp->argnxt.ap);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lexp->assignok = (flag&SH_ASSIGN)?SH_ASSIGN:1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(assignment)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct argnod *ap=argp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *last, *cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(assignment==1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin last = strchr(argp->argval,'=');
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(last && (last[-1]==']'|| (last[-1]=='+' && last[-2]==']')) && (cp=strchr(argp->argval,'[')) && (cp < last))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin last = cp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin stkseek(stkp,ARGVAL);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfwrite(stkp,argp->argval,last-argp->argval);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ap=(struct argnod*)stkfreeze(stkp,1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ap->argflag = ARG_RAW;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ap->argchn.ap = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *argtail = ap;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argtail = &(ap->argnxt.ap);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(argno>=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argno++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else /* alias substitutions allowed */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lexp->aliasok = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(argp->argflag&ARG_RAW))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(argno>0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin argmax = argno;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argno = -1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(argno>=0 && argno++==cmdarg && !(flag&SH_ARRAY) && *argp->argval!='/')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* check for builtin command */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Namval_t *np=nv_bfsearch(argp->argval,lexp->sh->fun_tree, (Namval_t**)&t->comnamq,(char**)0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(cmdarg==0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin t->comnamp = (void*)np;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(np && is_abuiltin(np))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(nv_isattr(np,BLT_DCL))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin assignment = 1+(*argp->argval=='a');
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(np==SYSTYPESET)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lexp->intypeset = 1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin key_on = 1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(np==SYSCOMMAND)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin cmdarg++;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(np==SYSEXEC)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lexp->inexec = 1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(np->nvalue.bfp==b_getopts)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin opt_get |= FOPTGET;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *argtail = argp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argtail = &(argp->argnxt.ap);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!(lexp->assignok=key_on) && !(flag&SH_NOIO) && sh_isoption(SH_NOEXEC))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lexp->assignok = SH_COMPASSIGN;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lexp->aliasok = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin retry:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin tok = sh_lex(lexp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(tok==LABLSYM && (flag&SH_ASSIGN))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lexp->token = tok = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_DEVFD
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((tok==IPROCSYM || tok==OPROCSYM))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz argp = process_sub(lexp,tok);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin argmax = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argno = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *argtail = argp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argtail = &(argp->argnxt.ap);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto retry;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_DEVFD */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(tok==LPAREN)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(argp->argflag&ARG_ASSIGN)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int intypeset = lexp->intypeset;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int tdef = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lexp->intypeset = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(t->comnamp==SYSTYPESET && t->comarg->argnxt.ap && strcmp(t->comarg->argnxt.ap->argval,"-T")==0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin tdef = 1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin argp = assign(lexp,argp,tdef);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lexp->intypeset = intypeset;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(associative)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lexp->assignok |= SH_ASSIGN;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto retry;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(argno==1 && !t->comset)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* SVR2 style function */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(sh_lex(lexp) == RPAREN)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lexp->arg = argp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(funct(lexp));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lexp->token = LPAREN;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(flag&SH_ASSIGN)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(tok==RPAREN)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(tok==NL && (flag&SH_ARRAY))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lexp->comp_assign = 2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto retry;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(flag&SH_NOIO))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(io)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(io->ionxt)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin io = io->ionxt;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin io->ionxt = inout(lexp,(struct ionod*)0,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin t->comio = io = inout(lexp,(struct ionod*)0,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *argtail = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(argno>0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin argmax = argno;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner t->comtyp = TCOM;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_KIA
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lexp->kiafile && !(flag&SH_NOIO))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Namval_t *np=(Namval_t*)t->comnamp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned long r=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int line = t->comline;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argp = t->comarg;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(np)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin r = kiaentity(lexp,nv_name(np),-1,'p',-1,0,lexp->unknown,'b',0,"");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(argp)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin r = kiaentity(lexp,sh_argstr(argp),-1,'p',-1,0,lexp->unknown,'c',0,"");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(r>0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfprintf(lexp->kiatmp,"p;%..64d;p;%..64d;%d;%d;c;\n",lexp->current,r,line,line);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(t->comset && argno==0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin writedefs(lexp,t->comset,line,'v',t->comarg);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(np && nv_isattr(np,BLT_DCL))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin writedefs(lexp,argp,line,0,NIL(struct argnod*));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(argp && strcmp(argp->argval,"read")==0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin writedefs(lexp,argp,line,0,NIL(struct argnod*));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if 0
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(argp && strcmp(argp->argval,"unset")==0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin writedefs(lexp,argp,line,'u',NIL(struct argnod*));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(argp && *argp->argval=='.' && argp->argval[1]==0 && (argp=argp->argnxt.ap))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin r = kiaentity(lexp,sh_argstr(argp),-1,'p',0,0,lexp->script,'d',0,"");
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfprintf(lexp->kiatmp,"p;%..64d;p;%..64d;%d;%d;d;\n",lexp->current,r,line,line);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_KIA */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(t->comnamp && (argp=t->comarg->argnxt.ap))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Namval_t *np=(Namval_t*)t->comnamp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((np==SYSBREAK || np==SYSCONT) && (argp->argflag&ARG_RAW) && !isdigit(*argp->argval))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *cp = argp->argval;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* convert break/continue labels to numbers */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tok = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(argp=label_list;argp!=label_last;argp=argp->argnxt.ap)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(strcmp(cp,argp->argval))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tok = loop_level-argp->argflag;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(tok>=1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argp = t->comarg->argnxt.ap;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(tok>9)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argp->argval[1] = '0'+tok%10;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argp->argval[2] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tok /= 10;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argp->argval[1] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *argp->argval = '0'+tok;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh_isoption(SH_NOEXEC) && tok==0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin errormsg(SH_DICT,ERROR_warn(0),e_lexlabunknown,lexp->sh->inlineno-(lexp->token=='\n'),cp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(sh_isoption(SH_NOEXEC) && np==SYSSET && ((tok= *argp->argval)=='-'||tok=='+') &&
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (argp->argval[1]==0||strchr(argp->argval,'k')))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin errormsg(SH_DICT,ERROR_warn(0),e_lexobsolete5,lexp->sh->inlineno-(lexp->token=='\n'),argp->argval);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* expand argument list if possible */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(argno>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t->comarg = qscan(t,argno);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(t->comarg)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t->comtyp |= COMSCAN;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lexp->aliasok = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return((Shnode_t*)t);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * skip past newlines but issue prompt if interactive
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic int skipnl(Lex_t *lexp,int flag)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int token;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin while((token=sh_lex(lexp))==NL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(token==';' && !(flag&SH_SEMI))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_syntax(lexp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(token);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * check for and process and i/o redirections
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * if flag>0 then an alias can be in the next word
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * if flag<0 only one redirection will be processed
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic struct ionod *inout(Lex_t *lexp,struct ionod *lastio,int flag)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register int iof = lexp->digits, token=lexp->token;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register struct ionod *iop;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Stk_t *stkp = lexp->sh->stk;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *iovname=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int errout=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(token==IOVNAME)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin iovname=lexp->arg->argval+1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin token= sh_lex(lexp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin iof = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch(token&0xff)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '<':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(token==IODOCSYM)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin iof |= (IODOC|IORAW);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(token==IOMOV0SYM)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin iof |= IOMOV;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else if(token==IORDWRSYMT)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz iof |= IORDW|IOREWRITE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(token==IORDWRSYM)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin iof |= IORDW;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if((token&SYMSHARP) == SYMSHARP)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin iof |= IOLSEEK;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fcgetc(n)=='#')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin iof |= IOCOPY;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(n>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcseek(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '>':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(iof<0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errout = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin iof = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin iof |= IOPUT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(token==IOAPPSYM)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin iof |= IOAPP;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(token==IOMOV1SYM)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin iof |= IOMOV;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(token==IOCLOBSYM)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin iof |= IOCLOB;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if((token&SYMSHARP) == SYMSHARP)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin iof |= IOLSEEK;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if((token&SYMSEMI) == SYMSEMI)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin iof |= IOREWRITE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(lastio);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lexp->digits=0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin iop=(struct ionod*) stkalloc(stkp,sizeof(struct ionod));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin iop->iodelim = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(token=sh_lex(lexp))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(token==RPAREN && (iof&IOLSEEK) && lexp->comsub)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lexp->arg = (struct argnod*)stkalloc(stkp,sizeof(struct argnod)+3);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin strcpy(lexp->arg->argval,"CUR");
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lexp->arg->argflag = ARG_RAW;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin iof |= IOARITH;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcseek(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(token==EXPRSYM && (iof&IOLSEEK))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin iof |= IOARITH;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else if(((token==IPROCSYM && !(iof&IOPUT)) || (token==OPROCSYM && (iof&IOPUT))) && !(iof&(IOLSEEK|IOREWRITE|IOMOV|IODOC)))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz lexp->arg = process_sub(lexp,token);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz iof |= IOPROCSUB;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_syntax(lexp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if( (iof&IOPROCSUB) && !(iof&IOLSEEK))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz iop->ioname= (char*)lexp->arg->argchn.ap;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz iop->ioname=lexp->arg->argval;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin iop->iovname = iovname;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(iof&IODOC)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lexp->digits==2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin iof |= IOSTRG;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!(lexp->arg->argflag&ARG_RAW))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin iof &= ~IORAW;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!lexp->sh->heredocs)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lexp->sh->heredocs = sftmp(HERE_MEM);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin iop->iolst=lexp->heredoc;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lexp->heredoc=iop;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lexp->arg->argflag&ARG_QUOTED)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin iof |= IOQUOTE;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lexp->digits==3)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin iof |= IOLSEEK;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lexp->digits)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin iof |= IOSTRIP;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin iop->iolst = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lexp->arg->argflag&ARG_RAW)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin iof |= IORAW;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin iop->iofile=iof;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flag>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* allow alias substitutions and parameter assignments */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lexp->aliasok = lexp->assignok = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_KIA
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lexp->kiafile)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int n = lexp->sh->inlineno-(lexp->token=='\n');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(iof&IOMOV))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin unsigned long r=kiaentity(lexp,(iof&IORAW)?sh_fmtq(iop->ioname):iop->ioname,-1,'f',0,0,lexp->script,'f',0,"");
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfprintf(lexp->kiatmp,"p;%..64d;f;%..64d;%d;%d;%c;%d\n",lexp->current,r,n,n,(iof&IOPUT)?((iof&IOAPP)?'a':'w'):((iof&IODOC)?'h':'r'),iof&IOUFD);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_KIA */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flag>=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct ionod *ioq=iop;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_lex(lexp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(errout)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* redirect standard output to standard error */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ioq = (struct ionod*)stkalloc(stkp,sizeof(struct ionod));
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz memset(ioq,0,sizeof(*ioq));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ioq->ioname = "1";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ioq->iolst = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ioq->iodelim = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ioq->iofile = IORAW|IOPUT|IOMOV|2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin iop->ionxt=ioq;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ioq->ionxt=inout(lexp,lastio,flag);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin iop->ionxt=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(iop);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * convert argument chain to argument list when no special arguments
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic struct argnod *qscan(struct comnod *ac,int argn)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char **cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register struct argnod *ap;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register struct dolnod* dp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int special=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* special hack for test -t compatibility */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((Namval_t*)ac->comnamp==SYSTEST)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin special = 2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(*(ac->comarg->argval)=='[' && ac->comarg->argval[1]==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin special = 3;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(special)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ap = ac->comarg->argnxt.ap;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(argn==(special+1) && ap->argval[1]==0 && *ap->argval=='!')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ap = ap->argnxt.ap;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(argn!=special)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin special=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(special)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin const char *message;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(strcmp(ap->argval,"-t"))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin message = "line %d: Invariant test";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin special=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin message = "line %d: -t requires argument";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin argn++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh_isoption(SH_NOEXEC))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_warn(0),message,ac->comline);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* leave space for an extra argument at the front */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp = (struct dolnod*)stakalloc((unsigned)sizeof(struct dolnod) + ARG_SPARE*sizeof(char*) + argn*sizeof(char*));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = dp->dolval+ARG_SPARE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp->dolnum = argn;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp->dolbot = ARG_SPARE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ap = ac->comarg;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(ap)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *cp++ = ap->argval;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ap = ap->argnxt.ap;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(special==3)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp[0] = cp[-1];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp[-1] = "1";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(special)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *cp++ = "1";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *cp = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return((struct argnod*)dp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic Shnode_t *test_expr(Lex_t *lp,int sym)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register Shnode_t *t = test_or(lp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lp->token!=sym)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_syntax(lp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(t);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic Shnode_t *test_or(Lex_t *lp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register Shnode_t *t = test_and(lp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin while(lp->token==ORFSYM)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin t = makelist(lp,TORF|TTEST,t,test_and(lp));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(t);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic Shnode_t *test_and(Lex_t *lp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register Shnode_t *t = test_primary(lp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin while(lp->token==ANDFSYM)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin t = makelist(lp,TAND|TTEST,t,test_primary(lp));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(t);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * convert =~ into == ~(E)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void ere_match(void)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfio_t *base, *iop = sfopen((Sfio_t*)0," ~(E)","s");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while( fcgetc(c),(c==' ' || c=='\t'));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcseek(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(base=fcfile()))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin base = sfopen(NIL(Sfio_t*),fcseek(0),"s");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcclose();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfstack(base,iop);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcfopen(base);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic Shnode_t *test_primary(Lex_t *lexp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register struct argnod *arg;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Shnode_t *t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int num,token;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin token = skipnl(lexp,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin num = lexp->digits;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch(token)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '(':
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin t = test_expr(lexp,')');
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin t = makelist(lexp,TTST|TTEST|TPAREN ,t, (Shnode_t*)pointerof(lexp->sh->inlineno));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case '!':
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!(t = test_primary(lexp)))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_syntax(lexp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t->tre.tretyp |= TNEGATE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(t);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case TESTUNOP:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(sh_lex(lexp))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_syntax(lexp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_KIA
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lexp->kiafile && !strchr("sntzoOG",num))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int line = lexp->sh->inlineno- (lexp->token==NL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned long r;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin r=kiaentity(lexp,sh_argstr(lexp->arg),-1,'f',0,0,lexp->script,'t',0,"");
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfprintf(lexp->kiatmp,"p;%..64d;f;%..64d;%d;%d;t;\n",lexp->current,r,line,line);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_KIA */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin t = makelist(lexp,TTST|TTEST|TUNARY|(num<<TSHIFT),
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin (Shnode_t*)lexp->arg,(Shnode_t*)lexp->arg);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin t->tst.tstline = lexp->sh->inlineno;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* binary test operators */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 0:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin arg = lexp->arg;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((token=sh_lex(lexp))==TESTBINOP)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin num = lexp->digits;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(num==TEST_REP)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ere_match();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin num = TEST_PEQ;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(token=='<')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin num = TEST_SLT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(token=='>')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin num = TEST_SGT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(token==ANDFSYM||token==ORFSYM||token==ETESTSYM||token==RPAREN)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin t = makelist(lexp,TTST|TTEST|TUNARY|('n'<<TSHIFT),
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (Shnode_t*)arg,(Shnode_t*)arg);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin t->tst.tstline = lexp->sh->inlineno;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(t);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_syntax(lexp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_KIA
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lexp->kiafile && (num==TEST_EF||num==TEST_NT||num==TEST_OT))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int line = lexp->sh->inlineno- (lexp->token==NL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned long r;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin r=kiaentity(lexp,sh_argstr(lexp->arg),-1,'f',0,0,lexp->current,'t',0,"");
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfprintf(lexp->kiatmp,"p;%..64d;f;%..64d;%d;%d;t;\n",lexp->current,r,line,line);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_KIA */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(sh_lex(lexp))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_syntax(lexp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(num&TEST_PATTERN)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lexp->arg->argflag&(ARG_EXP|ARG_MAC))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin num &= ~TEST_PATTERN;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t = getnode(tstnod);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t->lst.lsttyp = TTST|TTEST|TBINARY|(num<<TSHIFT);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin t->lst.lstlef = (Shnode_t*)arg;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin t->lst.lstrit = (Shnode_t*)lexp->arg;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin t->tst.tstline = lexp->sh->inlineno;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_KIA
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lexp->kiafile && (num==TEST_EF||num==TEST_NT||num==TEST_OT))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int line = lexp->sh->inlineno-(lexp->token==NL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned long r;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin r=kiaentity(lexp,sh_argstr(lexp->arg),-1,'f',0,0,lexp->current,'t',0,"");
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfprintf(lexp->kiatmp,"p;%..64d;f;%..64d;%d;%d;t;\n",lexp->current,r,line,line);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_KIA */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin skipnl(lexp,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(t);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_KIA
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * return an entity checksum
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * The entity is created if it doesn't exist
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinunsigned long kiaentity(Lex_t *lexp,const char *name,int len,int type,int first,int last,unsigned long parent, int pkind, int width, const char *attr)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Stk_t *stkp = lexp->sh->stk;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Namval_t *np;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin long offset = stktell(stkp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfputc(stkp,type);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(len>0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfwrite(stkp,name,len);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(type=='p')
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfputr(stkp,path_basename(name),0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfputr(stkp,name,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin np = nv_search(stakptr(offset),lexp->entity_tree,NV_ADD);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin stkseek(stkp,offset);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np->nvalue.i = pkind;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_setsize(np,width);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!nv_isattr(np,NV_TAGGED) && first>=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_onattr(np,NV_TAGGED);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!pkind)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pkind = '0';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(len>0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfprintf(lexp->kiafile,"%..64d;%c;%.*s;%d;%d;%..64d;%..64d;%c;%d;%s\n",np->hash,type,len,name,first,last,parent,lexp->fscript,pkind,width,attr);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfprintf(lexp->kiafile,"%..64d;%c;%s;%d;%d;%..64d;%..64d;%c;%d;%s\n",np->hash,type,name,first,last,parent,lexp->fscript,pkind,width,attr);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(np->hash);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void kia_add(register Namval_t *np, void *data)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *name = nv_name(np);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Lex_t *lp = (Lex_t*)data;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin NOT_USED(data);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin kiaentity(lp,name+1,-1,*name,0,-1,(*name=='p'?lp->unknown:lp->script),np->nvalue.i,nv_size(np),"");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinint kiaclose(Lex_t *lexp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register off_t off1,off2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int n;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(lexp->kiafile)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin unsigned long r = kiaentity(lexp,lexp->scriptname,-1,'p',-1,lexp->sh->inlineno-1,0,'s',0,"");
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin kiaentity(lexp,lexp->scriptname,-1,'p',1,lexp->sh->inlineno-1,r,'s',0,"");
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin kiaentity(lexp,lexp->scriptname,-1,'f',1,lexp->sh->inlineno-1,r,'s',0,"");
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_scan(lexp->entity_tree,kia_add,(void*)lexp,NV_TAGGED,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin off1 = sfseek(lexp->kiafile,(off_t)0,SEEK_END);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfseek(lexp->kiatmp,(off_t)0,SEEK_SET);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfmove(lexp->kiatmp,lexp->kiafile,SF_UNBOUND,-1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin off2 = sfseek(lexp->kiafile,(off_t)0,SEEK_END);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef SF_BUFCONST
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(off2==off1)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin n= sfprintf(lexp->kiafile,"DIRECTORY\nENTITY;%lld;%d\nDIRECTORY;",(Sflong_t)lexp->kiabegin,(size_t)(off1-lexp->kiabegin));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin n= sfprintf(lexp->kiafile,"DIRECTORY\nENTITY;%lld;%d\nRELATIONSHIP;%lld;%d\nDIRECTORY;",(Sflong_t)lexp->kiabegin,(size_t)(off1-lexp->kiabegin),(Sflong_t)off1,(size_t)(off2-off1));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(off2 >= INT_MAX)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin off2 = -(n+12);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfprintf(lexp->kiafile,"%010.10lld;%010d\n",(Sflong_t)off2+10, n+12);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(off2==off1)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin n= sfprintf(lexp->kiafile,"DIRECTORY\nENTITY;%d;%d\nDIRECTORY;",lexp->kiabegin,off1-lexp->kiabegin);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin n= sfprintf(lexp->kiafile,"DIRECTORY\nENTITY;%d;%d\nRELATIONSHIP;%d;%d\nDIRECTORY;",lexp->kiabegin,off1-lexp->kiabegin,off1,off2-off1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfprintf(lexp->kiafile,"%010d;%010d\n",off2+10, n+12);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(sfclose(lexp->kiafile));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_KIA */