summaryrefslogtreecommitdiff
path: root/usr/src/lib/libshell/common/sh/parse.c
diff options
context:
space:
mode:
authorApril Chin <April.Chin@Sun.COM>2008-12-27 14:59:38 -0800
committerApril Chin <April.Chin@Sun.COM>2008-12-27 14:59:38 -0800
commit7c2fbfb345896881c631598ee3852ce9ce33fb07 (patch)
tree4b173b5657508562dfc0aa05f7d056d1e9add505 /usr/src/lib/libshell/common/sh/parse.c
parent6071ac1de68fed78e1e10052045bbb5f1732a263 (diff)
downloadillumos-gate-7c2fbfb345896881c631598ee3852ce9ce33fb07.tar.gz
PSARC/2008/094 ksh93 Update 1
PSARC/2008/344 ksh93 Integration Update 1 Amendments 1 PSARC/2008/589 Remove /usr/bin/printf from PSARC case 2008 094 6619428 *ksh93* RFE: Update ksh93 in Solaris to ast-ksh.2008-11-04 6788659 RFE: Update libpp in Solaris to ast-open.2008-07-25 6561901 RFE: Add "shcomp" (shell script compiler) + kernel module to exec binary sh code 6599668 RFE: Move consumers of alias.sh over to ksh93 6595183 *ksh93* RFE: Update ksh93-integration demo code 6775901 *ksh93* no C message catalogs are generated for ksh93 6451262 *sleep* RFE: /usr/bin/sleep should support floating-point values 6687139 *ksh93* command substitution, exec, and stdout redirection cause allocation loop 6703761 *ksh93* crashes in script containing uncommon output redirections 6715496 *ksh93* SEGVs on array reinitialization 6713682 *ksh93* Creating a compound variable in a subshell "bleeds through" to the calling subshell 6672350 *ksh93* causes parent shell to die when child shell is suspended 6745015 *ksh93* VARIABLE=`command substitution` assignment is not reliable on OpenSolaris 6710205 *ksh93* problem with command substitution (within back quotes) containing \$' 6737600 *ksh93* exits debugger when user presses ctrl-c 6748645 *ksh93* fc -l -e - is mis-parsed, outputs wrong error message "-e - requires single argument" 6754020 *ksh93* does weird '[' expansion 6753538 *ksh93* umask modification leaks out of a ksh93 subshell 6766246 *ksh93* bug in pattern matching 6763594 *ksh93* executes command after "command" builtin twice on failure 6762665 *ksh93* Difficult-to-reproduce SIGSEGV in ksh93
Diffstat (limited to 'usr/src/lib/libshell/common/sh/parse.c')
-rw-r--r--usr/src/lib/libshell/common/sh/parse.c1046
1 files changed, 605 insertions, 441 deletions
diff --git a/usr/src/lib/libshell/common/sh/parse.c b/usr/src/lib/libshell/common/sh/parse.c
index 1cacd79e57..bccbd49d50 100644
--- a/usr/src/lib/libshell/common/sh/parse.c
+++ b/usr/src/lib/libshell/common/sh/parse.c
@@ -1,10 +1,10 @@
/***********************************************************************
* *
* This software is part of the ast package *
-* Copyright (c) 1982-2007 AT&T Knowledge Ventures *
+* Copyright (c) 1982-2008 AT&T Intellectual Property *
* and is licensed under the *
* Common Public License, Version 1.0 *
-* by AT&T Knowledge Ventures *
+* by AT&T Intellectual Property *
* *
* A copy of the License is available at *
* http://www.opensource.org/licenses/cpl1.0.txt *
@@ -48,23 +48,23 @@
/* These routines are local to this module */
-static Shnode_t *makeparent(int, Shnode_t*);
-static Shnode_t *makelist(int, Shnode_t*, Shnode_t*);
+static Shnode_t *makeparent(Lex_t*, int, Shnode_t*);
+static Shnode_t *makelist(Lex_t*, int, Shnode_t*, Shnode_t*);
static struct argnod *qscan(struct comnod*, int);
-static struct ionod *inout(struct ionod*, int);
-static Shnode_t *sh_cmd(int,int);
-static Shnode_t *term(int);
-static Shnode_t *list(int);
-static struct regnod *syncase(int);
-static Shnode_t *item(int);
-static Shnode_t *simple(int, struct ionod*);
-static int skipnl(int);
-static Shnode_t *test_expr(int);
-static Shnode_t *test_and(void);
-static Shnode_t *test_or(void);
-static Shnode_t *test_primary(void);
+static struct ionod *inout(Lex_t*,struct ionod*, int);
+static Shnode_t *sh_cmd(Lex_t*,int,int);
+static Shnode_t *term(Lex_t*,int);
+static Shnode_t *list(Lex_t*,int);
+static struct regnod *syncase(Lex_t*,int);
+static Shnode_t *item(Lex_t*,int);
+static Shnode_t *simple(Lex_t*,int, struct ionod*);
+static int skipnl(Lex_t*,int);
+static Shnode_t *test_expr(Lex_t*,int);
+static Shnode_t *test_and(Lex_t*);
+static Shnode_t *test_or(Lex_t*);
+static Shnode_t *test_primary(Lex_t*);
-#define sh_getlineno() (shlex.lastline)
+#define sh_getlineno(lp) (lp->lastline)
#ifndef NIL
# define NIL(type) ((type)0)
@@ -80,6 +80,7 @@ static struct stdata
} st;
#endif
+static int opt_get;
static int loop_level;
static struct argnod *label_list;
static struct argnod *label_last;
@@ -92,7 +93,7 @@ static struct argnod *label_last;
* write out entities for each item in the list
* type=='V' for variable assignment lists
* Otherwise type is determined by the command */
-static unsigned long writedefs(struct argnod *arglist, int line, int type, struct argnod *cmd)
+static unsigned long writedefs(Lex_t *lexp,struct argnod *arglist, int line, int type, struct argnod *cmd)
{
register struct argnod *argp = arglist;
register char *cp;
@@ -102,10 +103,10 @@ static unsigned long writedefs(struct argnod *arglist, int line, int type, struc
static char atbuff[20];
int justify=0;
char *attribute = atbuff;
- unsigned long parent=shlex.script;
+ unsigned long parent=lexp->script;
if(type==0)
{
- parent = shlex.current;
+ parent = lexp->current;
type = 'v';
switch(*argp->argval)
{
@@ -140,7 +141,7 @@ static unsigned long writedefs(struct argnod *arglist, int line, int type, struc
}
}
else if(cmd)
- parent=kiaentity(sh_argstr(cmd),-1,'p',-1,-1,shlex.unknown,'b',0,"");
+ parent=kiaentity(lexp,sh_argstr(cmd),-1,'p',-1,-1,lexp->unknown,'b',0,"");
*attribute = 0;
while(argp)
{
@@ -148,32 +149,109 @@ static unsigned long writedefs(struct argnod *arglist, int line, int type, struc
n = cp-argp->argval;
else
n = strlen(argp->argval);
- eline = sh.inlineno-(shlex.token==NL);
- r=kiaentity(argp->argval,n,type,line,eline,parent,justify,width,atbuff);
- sfprintf(shlex.kiatmp,"p;%..64d;v;%..64d;%d;%d;s;\n",shlex.current,r,line,eline);
+ eline = lexp->sh->inlineno-(lexp->token==NL);
+ r=kiaentity(lexp,argp->argval,n,type,line,eline,parent,justify,width,atbuff);
+ sfprintf(lexp->kiatmp,"p;%..64d;v;%..64d;%d;%d;s;\n",lexp->current,r,line,eline);
argp = argp->argnxt.ap;
}
return(r);
}
#endif /* SHOPT_KIA */
+
+static void typeset_order(const char *str,int line)
+{
+ register int c,n=0;
+ unsigned const char *cp=(unsigned char*)str;
+ static unsigned char *table;
+ if(*cp!='+' && *cp!='-')
+ return;
+ if(!table)
+ {
+ table = calloc(1,256);
+ for(cp=(unsigned char*)"bflmnprstuxACHS";c = *cp; cp++)
+ table[c] = 1;
+ for(cp=(unsigned char*)"aiEFLRXhTZ";c = *cp; cp++)
+ table[c] = 2;
+ for(c='0'; c <='9'; c++)
+ table[c] = 3;
+ }
+ for(cp=(unsigned char*)str; c= *cp++; n=table[c])
+ {
+ if(table[c] < n)
+ errormsg(SH_DICT,ERROR_warn(0),e_lextypeset,line,str);
+ }
+}
+
+/*
+ * add type definitions when compiling with -n
+ */
+static void check_typedef(struct comnod *tp)
+{
+ char *cp=0;
+ if(tp->comtyp&COMSCAN)
+ {
+ struct argnod *ap = tp->comarg;
+ while(ap = ap->argnxt.ap)
+ {
+ if(!(ap->argflag&ARG_RAW) || memcmp(ap->argval,"--",2))
+ break;
+ if(sh_isoption(SH_NOEXEC))
+ typeset_order(ap->argval,tp->comline);
+ if(memcmp(ap->argval,"-T",2)==0)
+ {
+ if(ap->argval[2])
+ cp = ap->argval+2;
+ else if((ap->argnxt.ap)->argflag&ARG_RAW)
+ cp = (ap->argnxt.ap)->argval;
+ if(cp)
+ break;
+ }
+ }
+ }
+ else
+ {
+ struct dolnod *dp = (struct dolnod*)tp->comarg;
+ char **argv = dp->dolval + dp->dolbot+1;
+ while((cp= *argv++) && memcmp(cp,"--",2))
+ {
+ if(sh_isoption(SH_NOEXEC))
+ typeset_order(cp,tp->comline);
+ if(memcmp(cp,"-T",2)==0)
+ {
+ if(cp[2])
+ cp = cp+2;
+ else
+ cp = *argv;
+ break;
+ }
+ }
+ }
+ if(cp)
+ {
+ Namval_t *mp=(Namval_t*)tp->comnamp ,*bp;
+ bp = sh_addbuiltin(cp,mp->nvalue.bfp, (void*)0);
+ nv_onattr(bp,nv_isattr(mp,NV_PUBLIC));
+ }
+}
+
/*
* Make a parent node for fork() or io-redirection
*/
-static Shnode_t *makeparent(int flag, Shnode_t *child)
+static Shnode_t *makeparent(Lex_t *lp, int flag, Shnode_t *child)
{
register Shnode_t *par = getnode(forknod);
par->fork.forktyp = flag;
par->fork.forktre = child;
par->fork.forkio = 0;
- par->fork.forkline = sh_getlineno()-1;
+ par->fork.forkline = sh_getlineno(lp)-1;
return(par);
}
-static Shnode_t *getanode(struct argnod *ap)
+static Shnode_t *getanode(Lex_t *lp, struct argnod *ap)
{
register Shnode_t *t = getnode(arithnod);
t->ar.artyp = TARITH;
- t->ar.arline = sh_getlineno();
+ t->ar.arline = sh_getlineno(lp);
t->ar.arexpr = ap;
if(ap->argflag&ARG_RAW)
t->ar.arcomp = sh_arithcomp(ap->argval);
@@ -185,11 +263,11 @@ static Shnode_t *getanode(struct argnod *ap)
/*
* Make a node corresponding to a command list
*/
-static Shnode_t *makelist(int type, Shnode_t *l, Shnode_t *r)
+static Shnode_t *makelist(Lex_t *lexp, int type, Shnode_t *l, Shnode_t *r)
{
register Shnode_t *t;
if(!l || !r)
- sh_syntax();
+ sh_syntax(lexp);
else
{
if((type&COMMSK) == TTST)
@@ -211,16 +289,17 @@ static Shnode_t *makelist(int type, Shnode_t *l, Shnode_t *r)
void *sh_parse(Shell_t *shp, Sfio_t *iop, int flag)
{
register Shnode_t *t;
+ Lex_t *lexp = (Lex_t*)shp->lex_context;
Fcin_t sav_input;
- struct argnod *sav_arg = shlex.arg;
+ struct argnod *sav_arg = lexp->arg;
int sav_prompt = shp->nextprompt;
if(shp->binscript && sffileno(iop)==shp->infd)
- return((void*)sh_trestore(iop));
+ return((void*)sh_trestore(shp,iop));
fcsave(&sav_input);
shp->st.staklist = 0;
- shlex.heredoc = 0;
- shlex.inlineno = shp->inlineno;
- shlex.firstline = shp->st.firstline;
+ lexp->heredoc = 0;
+ lexp->inlineno = shp->inlineno;
+ lexp->firstline = shp->st.firstline;
shp->nextprompt = 1;
loop_level = 0;
label_list = label_last = 0;
@@ -228,7 +307,7 @@ void *sh_parse(Shell_t *shp, Sfio_t *iop, int flag)
sh_onstate(SH_INTERACTIVE);
if(sh_isoption(SH_VERBOSE))
sh_onstate(SH_VERBOSE);
- sh_lexopen((Lex_t*)shp->lex_context,shp,0);
+ sh_lexopen(lexp,shp,0);
if(fcfopen(iop) < 0)
return(NIL(void*));
if(fcfile())
@@ -241,13 +320,13 @@ void *sh_parse(Shell_t *shp, Sfio_t *iop, int flag)
fcgetc(version);
fcclose();
fcrestore(&sav_input);
- shlex.arg = sav_arg;
+ lexp->arg = sav_arg;
if(version > 3)
errormsg(SH_DICT,ERROR_exit(1),e_lexversion);
if(sffileno(iop)==shp->infd)
shp->binscript = 1;
sfgetc(iop);
- return((void*)sh_trestore(iop));
+ return((void*)sh_trestore(shp,iop));
}
}
if((flag&SH_NL) && (shp->inlineno=error_info.line+shp->st.firstline)==0)
@@ -255,10 +334,10 @@ void *sh_parse(Shell_t *shp, Sfio_t *iop, int flag)
#if KSHELL
shp->nextprompt = 2;
#endif
- t = sh_cmd((flag&SH_EOF)?EOFSYM:'\n',SH_SEMI|SH_EMPTY|(flag&SH_NL));
+ t = sh_cmd(lexp,(flag&SH_EOF)?EOFSYM:'\n',SH_SEMI|SH_EMPTY|(flag&SH_NL));
fcclose();
fcrestore(&sav_input);
- shlex.arg = sav_arg;
+ lexp->arg = sav_arg;
/* unstack any completed alias expansions */
if((sfset(iop,0,0)&SF_STRING) && !sfreserve(iop,0,-1))
{
@@ -269,10 +348,10 @@ void *sh_parse(Shell_t *shp, Sfio_t *iop, int flag)
shp->nextprompt = sav_prompt;
if(flag&SH_NL)
{
- shp->st.firstline = shlex.firstline;
- shp->inlineno = shlex.inlineno;
+ shp->st.firstline = lexp->firstline;
+ shp->inlineno = lexp->inlineno;
}
- stakseek(0);
+ stkseek(shp->stk,0);
return((void*)t);
}
@@ -280,26 +359,28 @@ void *sh_parse(Shell_t *shp, Sfio_t *iop, int flag)
* This routine parses up the matching right parenthesis and returns
* the parse tree
*/
-Shnode_t *sh_dolparen(void)
+Shnode_t *sh_dolparen(Lex_t* lp)
{
register Shnode_t *t=0;
- register Lex_t *lp = (Lex_t*)sh.lex_context;
Sfio_t *sp = fcfile();
- int line = sh.inlineno;
- sh.inlineno = error_info.line+sh.st.firstline;
- sh_lexopen(lp,&sh,1);
- shlex.comsub = 1;
- switch(sh_lex())
+ int line = lp->sh->inlineno;
+ lp->sh->inlineno = error_info.line+lp->sh->st.firstline;
+ sh_lexopen(lp,lp->sh,1);
+ lp->comsub = 1;
+ switch(sh_lex(lp))
{
/* ((...)) arithmetic expression */
case EXPRSYM:
- t = getanode(shlex.arg);
+ t = getanode(lp,lp->arg);
break;
case LPAREN:
- t = sh_cmd(RPAREN,SH_NL|SH_EMPTY);
+ t = sh_cmd(lp,RPAREN,SH_NL|SH_EMPTY);
+ break;
+ case LBRACE:
+ t = sh_cmd(lp,RBRACE,SH_NL|SH_EMPTY);
break;
}
- shlex.comsub = 0;
+ lp->comsub = 0;
if(!sp && (sp=fcfile()))
{
/*
@@ -315,7 +396,7 @@ Shnode_t *sh_dolparen(void)
fcsopen(cp);
sfclose(sp);
}
- sh.inlineno = line;
+ lp->sh->inlineno = line;
return(t);
}
@@ -323,11 +404,11 @@ Shnode_t *sh_dolparen(void)
* remove temporary files and stacks
*/
-void sh_freeup(void)
+void sh_freeup(Shell_t *shp)
{
- if(sh.st.staklist)
- sh_funstaks(sh.st.staklist,-1);
- sh.st.staklist = 0;
+ if(shp->st.staklist)
+ sh_funstaks(shp->st.staklist,-1);
+ shp->st.staklist = 0;
}
/*
@@ -358,21 +439,21 @@ void sh_funstaks(register struct slnod *slp,int flag)
* list [ ; cmd ]
*/
-static Shnode_t *sh_cmd(register int sym, int flag)
+static Shnode_t *sh_cmd(Lex_t *lexp, register int sym, int flag)
{
register Shnode_t *left, *right;
register int type = FINT|FAMP;
if(sym==NL)
- shlex.lasttok = 0;
- left = list(flag);
- if(shlex.token==NL)
+ lexp->lasttok = 0;
+ left = list(lexp,flag);
+ if(lexp->token==NL)
{
if(flag&SH_NL)
- shlex.token=';';
+ lexp->token=';';
}
else if(!left && !(flag&SH_EMPTY))
- sh_syntax();
- switch(shlex.token)
+ sh_syntax(lexp);
+ switch(lexp->token)
{
case COOPSYM: /* set up a cooperating process */
type |= (FPIN|FPOU|FPCL|FCOOP);
@@ -383,23 +464,23 @@ static Shnode_t *sh_cmd(register int sym, int flag)
/* (...)& -> {...;} & */
if(left->tre.tretyp==TPAR)
left = left->par.partre;
- left = makeparent(TFORK|type, left);
+ left = makeparent(lexp,TFORK|type, left);
}
/* FALL THRU */
case ';':
if(!left)
- sh_syntax();
- if(right=sh_cmd(sym,flag|SH_EMPTY))
- left=makelist(TLST, left, right);
+ sh_syntax(lexp);
+ if(right=sh_cmd(lexp,sym,flag|SH_EMPTY))
+ left=makelist(lexp,TLST, left, right);
break;
case EOFSYM:
if(sym==NL)
break;
default:
- if(sym && sym!=shlex.token)
+ if(sym && sym!=lexp->token)
{
- if(sym!=ELSESYM || (shlex.token!=ELIFSYM && shlex.token!=FISYM))
- sh_syntax();
+ if(sym!=ELSESYM || (lexp->token!=ELIFSYM && lexp->token!=FISYM))
+ sh_syntax(lexp);
}
}
return(left);
@@ -412,12 +493,12 @@ static Shnode_t *sh_cmd(register int sym, int flag)
* list || term
* unfortunately, these are equal precedence
*/
-static Shnode_t *list(register int flag)
+static Shnode_t *list(Lex_t *lexp, register int flag)
{
- register Shnode_t *t = term(flag);
+ register Shnode_t *t = term(lexp,flag);
register int token;
- while(t && ((token=shlex.token)==ANDFSYM || token==ORFSYM))
- t = makelist((token==ANDFSYM?TAND:TORF), t, term(SH_NL|SH_SEMI));
+ while(t && ((token=lexp->token)==ANDFSYM || token==ORFSYM))
+ t = makelist(lexp,(token==ANDFSYM?TAND:TORF), t, term(lexp,SH_NL|SH_SEMI));
return(t);
}
@@ -426,29 +507,29 @@ static Shnode_t *list(register int flag)
* item
* item | term
*/
-static Shnode_t *term(register int flag)
+static Shnode_t *term(Lex_t *lexp,register int flag)
{
register Shnode_t *t;
register int token;
if(flag&SH_NL)
- token = skipnl(flag);
+ token = skipnl(lexp,flag);
else
- token = sh_lex();
+ token = sh_lex(lexp);
/* check to see if pipeline is to be timed */
if(token==TIMESYM || token==NOTSYM)
{
t = getnode(parnod);
t->par.partyp=TTIME;
- if(shlex.token==NOTSYM)
+ if(lexp->token==NOTSYM)
t->par.partyp |= COMSCAN;
- t->par.partre = term(0);
+ t->par.partre = term(lexp,0);
}
- else if((t=item(SH_NL|SH_EMPTY|(flag&SH_SEMI))) && shlex.token=='|')
+ else if((t=item(lexp,SH_NL|SH_EMPTY|(flag&SH_SEMI))) && lexp->token=='|')
{
register Shnode_t *tt;
int showme = t->tre.tretyp&FSHOWME;
- t = makeparent(TFORK|FPOU,t);
- if(tt=term(SH_NL))
+ t = makeparent(lexp,TFORK|FPOU,t);
+ if(tt=term(lexp,SH_NL))
{
switch(tt->tre.tretyp&COMMSK)
{
@@ -459,13 +540,13 @@ static Shnode_t *term(register int flag)
tt->lst.lstlef->tre.tretyp |= FPIN|FPCL;
break;
default:
- tt= makeparent(TSETIO|FPIN|FPCL,tt);
+ tt= makeparent(lexp,TSETIO|FPIN|FPCL,tt);
}
- t=makelist(TFIL,t,tt);
+ t=makelist(lexp,TFIL,t,tt);
t->tre.tretyp |= showme;
}
- else if(shlex.token)
- sh_syntax();
+ else if(lexp->token)
+ sh_syntax(lexp);
}
return(t);
}
@@ -473,9 +554,9 @@ static Shnode_t *term(register int flag)
/*
* case statement
*/
-static struct regnod* syncase(register int esym)
+static struct regnod* syncase(Lex_t *lexp,register int esym)
{
- register int tok = skipnl(0);
+ register int tok = skipnl(lexp,0);
register struct regnod *r;
if(tok==esym)
return(NIL(struct regnod*));
@@ -483,35 +564,35 @@ static struct regnod* syncase(register int esym)
r->regptr=0;
r->regflag=0;
if(tok==LPAREN)
- skipnl(0);
+ skipnl(lexp,0);
while(1)
{
- if(!shlex.arg)
- sh_syntax();
- shlex.arg->argnxt.ap=r->regptr;
- r->regptr = shlex.arg;
- if((tok=sh_lex())==RPAREN)
+ if(!lexp->arg)
+ sh_syntax(lexp);
+ lexp->arg->argnxt.ap=r->regptr;
+ r->regptr = lexp->arg;
+ if((tok=sh_lex(lexp))==RPAREN)
break;
else if(tok=='|')
- sh_lex();
+ sh_lex(lexp);
else
- sh_syntax();
+ sh_syntax(lexp);
}
- r->regcom=sh_cmd(0,SH_NL|SH_EMPTY|SH_SEMI);
- if((tok=shlex.token)==BREAKCASESYM)
- r->regnxt=syncase(esym);
+ r->regcom=sh_cmd(lexp,0,SH_NL|SH_EMPTY|SH_SEMI);
+ if((tok=lexp->token)==BREAKCASESYM)
+ r->regnxt=syncase(lexp,esym);
else if(tok==FALLTHRUSYM)
{
r->regflag++;
- r->regnxt=syncase(esym);
+ r->regnxt=syncase(lexp,esym);
}
else
{
if(tok!=esym && tok!=EOFSYM)
- sh_syntax();
+ sh_syntax(lexp);
r->regnxt=0;
}
- if(shlex.token==EOFSYM)
+ if(lexp->token==EOFSYM)
return(NIL(struct regnod*));
return(r);
}
@@ -523,46 +604,47 @@ static struct regnod* syncase(register int esym)
* Otherise a list containing an arithmetic command and a while
* is returned.
*/
-static Shnode_t *arithfor(register Shnode_t *tf)
+static Shnode_t *arithfor(Lex_t *lexp,register Shnode_t *tf)
{
register Shnode_t *t, *tw = tf;
register int offset;
register struct argnod *argp;
register int n;
- int argflag = shlex.arg->argflag;
+ Stk_t *stkp = lexp->sh->stk;
+ int argflag = lexp->arg->argflag;
/* save current input */
Fcin_t sav_input;
fcsave(&sav_input);
- fcsopen(shlex.arg->argval);
+ fcsopen(lexp->arg->argval);
/* split ((...)) into three expressions */
for(n=0; ; n++)
{
register int c;
- argp = (struct argnod*)stakseek(ARGVAL);
+ argp = (struct argnod*)stkseek(stkp,ARGVAL);
argp->argnxt.ap = 0;
argp->argchn.cp = 0;
argp->argflag = argflag;
if(n==2)
break;
/* copy up to ; onto the stack */
- sh_lexskip(';',1,ST_NESTED);
- offset = staktell()-1;
+ sh_lexskip(lexp,';',1,ST_NESTED);
+ offset = stktell(stkp)-1;
if((c=fcpeek(-1))!=';')
break;
/* remove trailing white space */
- while(offset>ARGVAL && ((c= *stakptr(offset-1)),isspace(c)))
+ while(offset>ARGVAL && ((c= *stkptr(stkp,offset-1)),isspace(c)))
offset--;
/* check for empty initialization expression */
if(offset==ARGVAL && n==0)
continue;
- stakseek(offset);
+ stkseek(stkp,offset);
/* check for empty condition and treat as while((1)) */
if(offset==ARGVAL)
- stakputc('1');
- argp = (struct argnod*)stakfreeze(1);
- t = getanode(argp);
+ sfputc(stkp,'1');
+ argp = (struct argnod*)stkfreeze(stkp,1);
+ t = getanode(lexp,argp);
if(n==0)
- tf = makelist(TLST,t,tw);
+ tf = makelist(lexp,TLST,t,tw);
else
tw->wh.whtre = t;
}
@@ -573,53 +655,58 @@ static Shnode_t *arithfor(register Shnode_t *tf)
fcrestore(&sav_input);
if(n<2)
{
- shlex.token = RPAREN|SYMREP;
- sh_syntax();
+ lexp->token = RPAREN|SYMREP;
+ sh_syntax(lexp);
}
/* check whether the increment is present */
if(*argp->argval)
{
- t = getanode(argp);
+ t = getanode(lexp,argp);
tw->wh.whinc = (struct arithnod*)t;
}
else
tw->wh.whinc = 0;
- sh_lexopen((Lex_t*)sh.lex_context, &sh,1);
- if((n=sh_lex())==NL)
- n = skipnl(0);
+ sh_lexopen(lexp, lexp->sh,1);
+ if((n=sh_lex(lexp))==NL)
+ n = skipnl(lexp,0);
else if(n==';')
- n = sh_lex();
+ n = sh_lex(lexp);
if(n!=DOSYM && n!=LBRACE)
- sh_syntax();
- tw->wh.dotre = sh_cmd(n==DOSYM?DONESYM:RBRACE,SH_NL);
+ sh_syntax(lexp);
+ tw->wh.dotre = sh_cmd(lexp,n==DOSYM?DONESYM:RBRACE,SH_NL);
tw->wh.whtyp = TWH;
return(tf);
}
-static Shnode_t *funct(void)
+static Shnode_t *funct(Lex_t *lexp)
{
+ Shell_t *shp = lexp->sh;
register Shnode_t *t;
register int flag;
struct slnod *volatile slp=0;
Stak_t *savstak;
Sfoff_t first, last;
- struct functnod *fp;
+ struct functnod *volatile fp;
Sfio_t *iop;
#if SHOPT_KIA
- unsigned long current = shlex.current;
+ unsigned long current = lexp->current;
#endif /* SHOPT_KIA */
int jmpval, saveloop=loop_level;
struct argnod *savelabel = label_last;
struct checkpt buff;
+ int save_optget = opt_get;
+ void *in_mktype = shp->mktype;
+ shp->mktype = 0;
+ opt_get = 0;
t = getnode(functnod);
- t->funct.functline = sh.inlineno;
+ t->funct.functline = shp->inlineno;
t->funct.functtyp=TFUN;
t->funct.functargs = 0;
- if(!(flag = (shlex.token==FUNCTSYM)))
+ if(!(flag = (lexp->token==FUNCTSYM)))
t->funct.functtyp |= FPOSIX;
- else if(sh_lex())
- sh_syntax();
+ else if(sh_lex(lexp))
+ sh_syntax(lexp);
if(!(iop=fcfile()))
{
iop = sfopen(NIL(Sfio_t*),fcseek(0),"s");
@@ -627,53 +714,53 @@ static Shnode_t *funct(void)
fcfopen(iop);
}
t->funct.functloc = first = fctell();
- if(!sh.st.filename || sffileno(iop)<0)
+ if(!shp->st.filename || sffileno(iop)<0)
{
if(fcfill() >= 0)
fcseek(-1);
if(sh_isstate(SH_HISTORY))
- t->funct.functloc = sfseek(sh.hist_ptr->histfp,(off_t)0,SEEK_CUR);
+ t->funct.functloc = sfseek(shp->hist_ptr->histfp,(off_t)0,SEEK_CUR);
else
{
/* copy source to temporary file */
t->funct.functloc = 0;
- if(shlex.sh->heredocs)
- t->funct.functloc = sfseek(shlex.sh->heredocs,(Sfoff_t)0, SEEK_END);
+ if(lexp->sh->heredocs)
+ t->funct.functloc = sfseek(lexp->sh->heredocs,(Sfoff_t)0, SEEK_END);
else
- shlex.sh->heredocs = sftmp(HERE_MEM);
- shlex.sh->funlog = shlex.sh->heredocs;
+ lexp->sh->heredocs = sftmp(HERE_MEM);
+ lexp->sh->funlog = lexp->sh->heredocs;
t->funct.functtyp |= FPIN;
}
}
- t->funct.functnam= (char*)shlex.arg->argval;
+ t->funct.functnam= (char*)lexp->arg->argval;
#if SHOPT_KIA
- if(shlex.kiafile)
- shlex.current = kiaentity(t->funct.functnam,-1,'p',-1,-1,shlex.script,'p',0,"");
+ if(lexp->kiafile)
+ lexp->current = kiaentity(lexp,t->funct.functnam,-1,'p',-1,-1,lexp->script,'p',0,"");
#endif /* SHOPT_KIA */
if(flag)
{
- shlex.token = sh_lex();
+ lexp->token = sh_lex(lexp);
#if SHOPT_BASH
- if(shlex.token == LPAREN)
+ if(lexp->token == LPAREN)
{
- if((shlex.token = sh_lex()) == RPAREN)
+ if((lexp->token = sh_lex(lexp)) == RPAREN)
t->funct.functtyp |= FPOSIX;
else
- sh_syntax();
+ sh_syntax(lexp);
}
#endif
}
if(t->funct.functtyp&FPOSIX)
- skipnl(0);
+ skipnl(lexp,0);
else
{
- if(shlex.token==0)
- t->funct.functargs = (struct comnod*)simple(SH_NOIO|SH_FUNDEF,NIL(struct ionod*));
- while(shlex.token==NL)
- shlex.token = sh_lex();
+ if(lexp->token==0)
+ t->funct.functargs = (struct comnod*)simple(lexp,SH_NOIO|SH_FUNDEF,NIL(struct ionod*));
+ while(lexp->token==NL)
+ lexp->token = sh_lex(lexp);
}
- if((flag && shlex.token!=LBRACE) || shlex.token==EOFSYM)
- sh_syntax();
+ if((flag && lexp->token!=LBRACE) || lexp->token==EOFSYM)
+ sh_syntax(lexp);
sh_pushcontext(&buff,1);
jmpval = sigsetjmp(buff.buff,0);
if(jmpval == 0)
@@ -683,8 +770,8 @@ static Shnode_t *funct(void)
savstak = stakinstall(savstak, 0);
slp = (struct slnod*)stakalloc(sizeof(struct slnod)+sizeof(struct functnod));
slp->slchild = 0;
- slp->slnext = sh.st.staklist;
- sh.st.staklist = 0;
+ slp->slnext = shp->st.staklist;
+ shp->st.staklist = 0;
t->funct.functstak = (struct slnod*)slp;
/*
* store the pathname of function definition file on stack
@@ -694,20 +781,20 @@ static Shnode_t *funct(void)
fp->functtyp = TFUN|FAMP;
fp->functnam = 0;
fp->functline = t->funct.functline;
- if(sh.st.filename)
- fp->functnam = stakcopy(sh.st.filename);
+ if(shp->st.filename)
+ fp->functnam = stakcopy(shp->st.filename);
loop_level = 0;
label_last = label_list;
- if(!flag && shlex.token==0)
+ if(!flag && lexp->token==0)
{
/* copy current word token to current stak frame */
struct argnod *ap;
- flag = ARGVAL + strlen(shlex.arg->argval);
+ flag = ARGVAL + strlen(lexp->arg->argval);
ap = (struct argnod*)stakalloc(flag);
- memcpy(ap,shlex.arg,flag);
- shlex.arg = ap;
+ memcpy(ap,lexp->arg,flag);
+ lexp->arg = ap;
}
- t->funct.functtre = item(SH_NOIO);
+ t->funct.functtre = item(lexp,SH_NOIO);
}
sh_popcontext(&buff);
loop_level = saveloop;
@@ -716,50 +803,54 @@ static Shnode_t *funct(void)
if(slp)
{
slp->slptr = stakinstall(savstak,0);
- slp->slchild = sh.st.staklist;
+ slp->slchild = shp->st.staklist;
}
#if SHOPT_KIA
- shlex.current = current;
+ lexp->current = current;
#endif /* SHOPT_KIA */
if(jmpval)
{
if(slp && slp->slptr)
{
- sh.st.staklist = slp->slnext;
+ shp->st.staklist = slp->slnext;
stakdelete(slp->slptr);
}
- siglongjmp(*sh.jmplist,jmpval);
+ siglongjmp(*shp->jmplist,jmpval);
}
- sh.st.staklist = (struct slnod*)slp;
+ shp->st.staklist = (struct slnod*)slp;
last = fctell();
fp->functline = (last-first);
fp->functtre = t;
- if(shlex.sh->funlog)
+ shp->mktype = in_mktype;
+ if(lexp->sh->funlog)
{
if(fcfill()>0)
fcseek(-1);
- shlex.sh->funlog = 0;
+ lexp->sh->funlog = 0;
}
#if SHOPT_KIA
- if(shlex.kiafile)
- kiaentity(t->funct.functnam,-1,'p',t->funct.functline,sh.inlineno-1,shlex.current,'p',0,"");
+ if(lexp->kiafile)
+ kiaentity(lexp,t->funct.functnam,-1,'p',t->funct.functline,shp->inlineno-1,lexp->current,'p',0,"");
#endif /* SHOPT_KIA */
+ t->funct.functtyp |= opt_get;
+ opt_get = save_optget;
return(t);
}
/*
* Compound assignment
*/
-static struct argnod *assign(register struct argnod *ap)
+static struct argnod *assign(Lex_t *lexp, register struct argnod *ap, int tdef)
{
register int n;
register Shnode_t *t, **tp;
register struct comnod *ac;
+ Stk_t *stkp = lexp->sh->stk;
int array=0;
Namval_t *np;
n = strlen(ap->argval)-1;
if(ap->argval[n]!='=')
- sh_syntax();
+ sh_syntax(lexp);
if(ap->argval[n-1]=='+')
{
ap->argval[n--]=0;
@@ -774,81 +865,110 @@ static struct argnod *assign(register struct argnod *ap)
*ap->argval=0;
t = getnode(fornod);
t->for_.fornam = (char*)(ap->argval+1);
- t->for_.fortyp = sh_getlineno();
+ t->for_.fortyp = sh_getlineno(lexp);
tp = &t->for_.fortre;
ap->argchn.ap = (struct argnod*)t;
ap->argflag &= ARG_QUOTED;
ap->argflag |= array;
- shlex.assignok = SH_ASSIGN;
+ lexp->assignok = SH_ASSIGN;
+ lexp->aliasok = 1;
array=0;
- if((n=skipnl(0))==RPAREN || n==LPAREN)
+ if((n=skipnl(lexp,0))==RPAREN || n==LPAREN)
{
int index= 0;
struct argnod **settail;
ac = (struct comnod*)getnode(comnod);
settail= &ac->comset;
memset((void*)ac,0,sizeof(*ac));
- ac->comline = sh_getlineno();
+ ac->comline = sh_getlineno(lexp);
while(n==LPAREN)
{
struct argnod *ap;
- ap = (struct argnod*)stakseek(ARGVAL);
+ ap = (struct argnod*)stkseek(stkp,ARGVAL);
ap->argflag= ARG_ASSIGN;
- sfprintf(stkstd,"[%d]=",index++);
- ap = (struct argnod*)stakfreeze(1);
+ sfprintf(stkp,"[%d]=",index++);
+ ap = (struct argnod*)stkfreeze(stkp,1);
ap->argnxt.ap = 0;
- ap = assign(ap);
+ ap = assign(lexp,ap,0);
ap->argflag |= ARG_MESSAGE;
*settail = ap;
settail = &(ap->argnxt.ap);
- n = skipnl(0);
+ while((n = skipnl(lexp,0))==0)
+ {
+ ap = (struct argnod*)stkseek(stkp,ARGVAL);
+ ap->argflag= ARG_ASSIGN;
+ sfprintf(stkp,"[%d]=",index++);
+ stakputs(lexp->arg->argval);
+ ap = (struct argnod*)stkfreeze(stkp,1);
+ ap->argnxt.ap = 0;
+ ap->argflag = lexp->arg->argflag;
+ *settail = ap;
+ settail = &(ap->argnxt.ap);
+ }
}
}
- else if(n)
- sh_syntax();
- else if(!(shlex.arg->argflag&ARG_ASSIGN) && !((np=nv_search(shlex.arg->argval,sh.fun_tree,0)) && nv_isattr(np,BLT_DCL)))
+ else if(n && n!=FUNCTSYM)
+ sh_syntax(lexp);
+ 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)))
+ {
array=SH_ARRAY;
+ if(fcgetc(n)==LPAREN)
+ {
+ int c;
+ if(fcgetc(c)==RPAREN)
+ {
+ lexp->token = SYMRES;
+ array = 0;
+ }
+ else
+ fcseek(-2);
+ }
+ else if(n>0)
+ fcseek(-1);
+ if(array && tdef)
+ sh_syntax(lexp);
+ }
while(1)
{
- if((n=shlex.token)==RPAREN)
+ if((n=lexp->token)==RPAREN)
break;
if(n==FUNCTSYM || n==SYMRES)
- ac = (struct comnod*)funct();
+ ac = (struct comnod*)funct(lexp);
else
- ac = (struct comnod*)simple(SH_NOIO|SH_ASSIGN|array,NIL(struct ionod*));
- if((n=shlex.token)==RPAREN)
+ ac = (struct comnod*)simple(lexp,SH_NOIO|SH_ASSIGN|array,NIL(struct ionod*));
+ if((n=lexp->token)==RPAREN)
break;
if(n!=NL && n!=';')
- sh_syntax();
- shlex.assignok = SH_ASSIGN;
- if((n=skipnl(0)) || array)
+ sh_syntax(lexp);
+ lexp->assignok = SH_ASSIGN;
+ if((n=skipnl(lexp,0)) || array)
{
if(n==RPAREN)
break;
if(array || n!=FUNCTSYM)
- sh_syntax();
+ sh_syntax(lexp);
}
- if((n!=FUNCTSYM) && !(shlex.arg->argflag&ARG_ASSIGN) && !((np=nv_search(shlex.arg->argval,sh.fun_tree,0)) && nv_isattr(np,BLT_DCL)))
+ 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)))
{
- struct argnod *arg = shlex.arg;
+ struct argnod *arg = lexp->arg;
if(n!=0)
- sh_syntax();
+ sh_syntax(lexp);
/* check for sys5 style function */
- if(sh_lex()!=LPAREN || sh_lex()!=RPAREN)
+ if(sh_lex(lexp)!=LPAREN || sh_lex(lexp)!=RPAREN)
{
- shlex.arg = arg;
- shlex.token = 0;
- sh_syntax();
+ lexp->arg = arg;
+ lexp->token = 0;
+ sh_syntax(lexp);
}
- shlex.arg = arg;
- shlex.token = SYMRES;
+ lexp->arg = arg;
+ lexp->token = SYMRES;
}
- t = makelist(TLST,(Shnode_t*)ac,t);
+ t = makelist(lexp,TLST,(Shnode_t*)ac,t);
*tp = t;
tp = &t->lst.lstrit;
}
*tp = (Shnode_t*)ac;
- shlex.assignok = 0;
+ lexp->assignok = 0;
return(ap);
}
@@ -863,56 +983,56 @@ static struct argnod *assign(register struct argnod *ap)
* begin ... end
*/
-static Shnode_t *item(int flag)
+static Shnode_t *item(Lex_t *lexp,int flag)
{
register Shnode_t *t;
register struct ionod *io;
- register int tok = (shlex.token&0xff);
- int savwdval = shlex.lasttok;
- int savline = shlex.lastline;
- int showme=0;
- if(!(flag&SH_NOIO) && (tok=='<' || tok=='>'))
- io=inout(NIL(struct ionod*),1);
+ register int tok = (lexp->token&0xff);
+ int savwdval = lexp->lasttok;
+ int savline = lexp->lastline;
+ int showme=0, comsub;
+ if(!(flag&SH_NOIO) && (tok=='<' || tok=='>' || lexp->token==IOVNAME))
+ io=inout(lexp,NIL(struct ionod*),1);
else
io=0;
- if((tok=shlex.token) && tok!=EOFSYM && tok!=FUNCTSYM)
+ if((tok=lexp->token) && tok!=EOFSYM && tok!=FUNCTSYM)
{
- shlex.lastline = sh_getlineno();
- shlex.lasttok = shlex.token;
+ lexp->lastline = sh_getlineno(lexp);
+ lexp->lasttok = lexp->token;
}
switch(tok)
{
/* [[ ... ]] test expression */
case BTESTSYM:
- t = test_expr(ETESTSYM);
+ t = test_expr(lexp,ETESTSYM);
t->tre.tretyp &= ~TTEST;
break;
/* ((...)) arithmetic expression */
case EXPRSYM:
- t = getanode(shlex.arg);
- sh_lex();
+ t = getanode(lexp,lexp->arg);
+ sh_lex(lexp);
goto done;
/* case statement */
case CASESYM:
{
- int savetok = shlex.lasttok;
- int saveline = shlex.lastline;
+ int savetok = lexp->lasttok;
+ int saveline = lexp->lastline;
t = getnode(swnod);
- if(sh_lex())
- sh_syntax();
- t->sw.swarg=shlex.arg;
+ if(sh_lex(lexp))
+ sh_syntax(lexp);
+ t->sw.swarg=lexp->arg;
t->sw.swtyp=TSW;
t->sw.swio = 0;
t->sw.swtyp |= FLINENO;
- t->sw.swline = sh.inlineno;
- if((tok=skipnl(0))!=INSYM && tok!=LBRACE)
- sh_syntax();
- if(!(t->sw.swlst=syncase(tok==INSYM?ESACSYM:RBRACE)) && shlex.token==EOFSYM)
+ t->sw.swline = lexp->sh->inlineno;
+ if((tok=skipnl(lexp,0))!=INSYM && tok!=LBRACE)
+ sh_syntax(lexp);
+ if(!(t->sw.swlst=syncase(lexp,tok==INSYM?ESACSYM:RBRACE)) && lexp->token==EOFSYM)
{
- shlex.lasttok = savetok;
- shlex.lastline = saveline;
- sh_syntax();
+ lexp->lasttok = savetok;
+ lexp->lastline = saveline;
+ sh_syntax(lexp);
}
break;
}
@@ -923,11 +1043,11 @@ static Shnode_t *item(int flag)
register Shnode_t *tt;
t = getnode(ifnod);
t->if_.iftyp=TIF;
- t->if_.iftre=sh_cmd(THENSYM,SH_NL);
- t->if_.thtre=sh_cmd(ELSESYM,SH_NL|SH_SEMI);
- tok = shlex.token;
- t->if_.eltre=(tok==ELSESYM?sh_cmd(FISYM,SH_NL|SH_SEMI):
- (tok==ELIFSYM?(shlex.token=IFSYM, tt=item(SH_NOIO)):0));
+ t->if_.iftre=sh_cmd(lexp,THENSYM,SH_NL);
+ t->if_.thtre=sh_cmd(lexp,ELSESYM,SH_NL|SH_SEMI);
+ tok = lexp->token;
+ t->if_.eltre=(tok==ELSESYM?sh_cmd(lexp,FISYM,SH_NL|SH_SEMI):
+ (tok==ELIFSYM?(lexp->token=IFSYM, tt=item(lexp,SH_NOIO)):0));
if(tok==ELIFSYM)
{
if(!tt || tt->tre.tretyp!=TSETIO)
@@ -945,33 +1065,33 @@ static Shnode_t *item(int flag)
case SELECTSYM:
{
t = getnode(fornod);
- t->for_.fortyp=(shlex.token==FORSYM?TFOR:TSELECT);
+ t->for_.fortyp=(lexp->token==FORSYM?TFOR:TSELECT);
t->for_.forlst=0;
- t->for_.forline = sh.inlineno;
- if(sh_lex())
+ t->for_.forline = lexp->sh->inlineno;
+ if(sh_lex(lexp))
{
- if(shlex.token!=EXPRSYM || t->for_.fortyp!=TFOR)
- sh_syntax();
+ if(lexp->token!=EXPRSYM || t->for_.fortyp!=TFOR)
+ sh_syntax(lexp);
/* arithmetic for */
- t = arithfor(t);
+ t = arithfor(lexp,t);
break;
}
- t->for_.fornam=(char*) shlex.arg->argval;
+ t->for_.fornam=(char*) lexp->arg->argval;
t->for_.fortyp |= FLINENO;
#if SHOPT_KIA
- if(shlex.kiafile)
- writedefs(shlex.arg,sh.inlineno,'v',NIL(struct argnod*));
+ if(lexp->kiafile)
+ writedefs(lexp,lexp->arg,lexp->sh->inlineno,'v',NIL(struct argnod*));
#endif /* SHOPT_KIA */
- while((tok=sh_lex())==NL);
+ while((tok=sh_lex(lexp))==NL);
if(tok==INSYM)
{
- if(sh_lex())
+ if(sh_lex(lexp))
{
- if(shlex.token != NL && shlex.token !=';')
- sh_syntax();
+ if(lexp->token != NL && lexp->token !=';')
+ sh_syntax(lexp);
/* some Linux scripts assume this */
if(sh_isoption(SH_NOEXEC))
- errormsg(SH_DICT,ERROR_warn(0),e_lexemptyfor,sh.inlineno-(shlex.token=='\n'));
+ errormsg(SH_DICT,ERROR_warn(0),e_lexemptyfor,lexp->sh->inlineno-(lexp->token=='\n'));
t->for_.forlst = (struct comnod*)getnode(comnod);
(t->for_.forlst)->comarg = 0;
(t->for_.forlst)->comset = 0;
@@ -982,18 +1102,18 @@ static Shnode_t *item(int flag)
(t->for_.forlst)->comtyp = 0;
}
else
- t->for_.forlst=(struct comnod*)simple(SH_NOIO,NIL(struct ionod*));
- if(shlex.token != NL && shlex.token !=';')
- sh_syntax();
- tok = skipnl(0);
+ t->for_.forlst=(struct comnod*)simple(lexp,SH_NOIO,NIL(struct ionod*));
+ if(lexp->token != NL && lexp->token !=';')
+ sh_syntax(lexp);
+ tok = skipnl(lexp,0);
}
/* 'for i;do cmd' is valid syntax */
else if(tok==';')
- tok=sh_lex();
+ tok=sh_lex(lexp);
if(tok!=DOSYM && tok!=LBRACE)
- sh_syntax();
+ sh_syntax(lexp);
loop_level++;
- t->for_.fortre=sh_cmd(tok==DOSYM?DONESYM:RBRACE,SH_NL|SH_SEMI);
+ t->for_.fortre=sh_cmd(lexp,tok==DOSYM?DONESYM:RBRACE,SH_NL|SH_SEMI);
if(--loop_level==0)
label_last = label_list;
break;
@@ -1001,20 +1121,20 @@ static Shnode_t *item(int flag)
/* This is the code for parsing function definitions */
case FUNCTSYM:
- return(funct());
+ return(funct(lexp));
#if SHOPT_NAMESPACE
case NSPACESYM:
t = getnode(fornod);
t->for_.fortyp=TNSPACE;
t->for_.forlst=0;
- if(sh_lex())
- sh_syntax();
- t->for_.fornam=(char*) shlex.arg->argval;
- while((tok=sh_lex())==NL);
+ if(sh_lex(lexp))
+ sh_syntax(lexp);
+ t->for_.fornam=(char*) lexp->arg->argval;
+ while((tok=sh_lex(lexp))==NL);
if(tok!=LBRACE)
- sh_syntax();
- t->for_.fortre = sh_cmd(RBRACE,SH_NL);
+ sh_syntax(lexp);
+ t->for_.fortre = sh_cmd(lexp,RBRACE,SH_NL);
break;
#endif /* SHOPT_NAMESPACE */
@@ -1022,10 +1142,10 @@ static Shnode_t *item(int flag)
case WHILESYM:
case UNTILSYM:
t = getnode(whnod);
- t->wh.whtyp=(shlex.token==WHILESYM ? TWH : TUN);
+ t->wh.whtyp=(lexp->token==WHILESYM ? TWH : TUN);
loop_level++;
- t->wh.whtre = sh_cmd(DOSYM,SH_NL);
- t->wh.dotre = sh_cmd(DONESYM,SH_NL|SH_SEMI);
+ t->wh.whtre = sh_cmd(lexp,DOSYM,SH_NL);
+ t->wh.dotre = sh_cmd(lexp,DONESYM,SH_NL|SH_SEMI);
if(--loop_level==0)
label_last = label_list;
t->wh.whinc = 0;
@@ -1036,17 +1156,17 @@ static Shnode_t *item(int flag)
register struct argnod *argp = label_list;
while(argp)
{
- if(strcmp(argp->argval,shlex.arg->argval)==0)
- errormsg(SH_DICT,ERROR_exit(3),e_lexsyntax3,sh.inlineno,argp->argval);
+ if(strcmp(argp->argval,lexp->arg->argval)==0)
+ errormsg(SH_DICT,ERROR_exit(3),e_lexsyntax3,lexp->sh->inlineno,argp->argval);
argp = argp->argnxt.ap;
}
- shlex.arg->argnxt.ap = label_list;
- label_list = shlex.arg;
- label_list->argchn.len = sh_getlineno();
+ lexp->arg->argnxt.ap = label_list;
+ label_list = lexp->arg;
+ label_list->argchn.len = sh_getlineno(lexp);
label_list->argflag = loop_level;
- skipnl(flag);
- if(!(t = item(SH_NL)))
- sh_syntax();
+ skipnl(lexp,flag);
+ if(!(t = item(lexp,SH_NL)))
+ sh_syntax(lexp);
tok = (t->tre.tretyp&(COMSCAN|COMSCAN-1));
if(sh_isoption(SH_NOEXEC) && tok!=TWH && tok!=TUN && tok!=TFOR && tok!=TSELECT)
errormsg(SH_DICT,ERROR_warn(0),e_lexlabignore,label_list->argchn.len,label_list->argval);
@@ -1055,12 +1175,15 @@ static Shnode_t *item(int flag)
/* command group with {...} */
case LBRACE:
- t = sh_cmd(RBRACE,SH_NL);
+ comsub = lexp->comsub;
+ lexp->comsub = 0;
+ t = sh_cmd(lexp,RBRACE,SH_NL);
+ lexp->comsub = comsub;
break;
case LPAREN:
t = getnode(parnod);
- t->par.partre=sh_cmd(RPAREN,SH_NL);
+ t->par.partre=sh_cmd(lexp,RPAREN,SH_NL);
t->par.partyp=TPAR;
break;
@@ -1073,45 +1196,51 @@ static Shnode_t *item(int flag)
{
if(!(flag&SH_SEMI))
return(0);
- if(sh_lex()==';')
- sh_syntax();
+ if(sh_lex(lexp)==';')
+ sh_syntax(lexp);
showme = FSHOWME;
}
/* simple command */
case 0:
- t = (Shnode_t*)simple(flag,io);
+ t = (Shnode_t*)simple(lexp,flag,io);
+ if(t->com.comarg && lexp->intypeset && (lexp->sh->shcomp || sh_isoption(SH_NOEXEC) || sh.dot_depth))
+ check_typedef(&t->com);
+ lexp->intypeset = 0;
+ lexp->inexec = 0;
t->tre.tretyp |= showme;
return(t);
}
- sh_lex();
- if(io=inout(io,0))
+ sh_lex(lexp);
+ if(io=inout(lexp,io,0))
{
if((tok=t->tre.tretyp&COMMSK) != TFORK)
tok = TSETIO;
- t=makeparent(tok,t);
+ t=makeparent(lexp,tok,t);
t->tre.treio=io;
}
done:
- shlex.lasttok = savwdval;
- shlex.lastline = savline;
+ lexp->lasttok = savwdval;
+ lexp->lastline = savline;
return(t);
}
/*
* This is for a simple command, for list, or compound assignment
*/
-static Shnode_t *simple(int flag, struct ionod *io)
+static Shnode_t *simple(Lex_t *lexp,int flag, struct ionod *io)
{
register struct comnod *t;
register struct argnod *argp;
register int tok;
+ Stk_t *stkp = lexp->sh->stk;
struct argnod **argtail;
struct argnod **settail;
- int argno = 0;
+ int cmdarg=0;
+ int argno = 0, argmax=0;
int assignment = 0;
int key_on = (!(flag&SH_NOIO) && sh_isoption(SH_KEYWORD));
int associative=0;
- if((argp=shlex.arg) && (argp->argflag&ARG_ASSIGN) && argp->argval[0]=='[')
+ if((argp=lexp->arg) && (argp->argflag&ARG_ASSIGN) && argp->argval[0]=='[')
{
flag |= SH_ARRAY;
associative = 1;
@@ -1119,29 +1248,29 @@ static Shnode_t *simple(int flag, struct ionod *io)
t = (struct comnod*)getnode(comnod);
t->comio=io; /*initial io chain*/
/* set command line number for error messages */
- t->comline = sh_getlineno();
+ t->comline = sh_getlineno(lexp);
argtail = &(t->comarg);
t->comset = 0;
t->comnamp = 0;
t->comnamq = 0;
t->comstate = 0;
settail = &(t->comset);
- while(shlex.token==0)
+ while(lexp->token==0)
{
- argp = shlex.arg;
+ argp = lexp->arg;
if(*argp->argval==LBRACE && (flag&SH_FUNDEF) && argp->argval[1]==0)
{
- shlex.token = LBRACE;
+ lexp->token = LBRACE;
break;
}
if(associative && argp->argval[0]!='[')
- sh_syntax();
+ sh_syntax(lexp);
/* check for assignment argument */
if((argp->argflag&ARG_ASSIGN) && assignment!=2)
{
*settail = argp;
settail = &(argp->argnxt.ap);
- shlex.assignok = (flag&SH_ASSIGN)?SH_ASSIGN:1;
+ lexp->assignok = (flag&SH_ASSIGN)?SH_ASSIGN:1;
if(assignment)
{
struct argnod *ap=argp;
@@ -1151,9 +1280,9 @@ static Shnode_t *simple(int flag, struct ionod *io)
last = strchr(argp->argval,'=');
if((cp=strchr(argp->argval,'[')) && (cp < last))
last = cp;
- stakseek(ARGVAL);
- stakwrite(argp->argval,last-argp->argval);
- ap=(struct argnod*)stakfreeze(1);
+ stkseek(stkp,ARGVAL);
+ sfwrite(stkp,argp->argval,last-argp->argval);
+ ap=(struct argnod*)stkfreeze(stkp,1);
ap->argflag = ARG_RAW;
ap->argchn.ap = 0;
}
@@ -1163,43 +1292,62 @@ static Shnode_t *simple(int flag, struct ionod *io)
argno++;
}
else /* alias substitutions allowed */
- shlex.aliasok = 1;
+ lexp->aliasok = 1;
}
else
{
if(!(argp->argflag&ARG_RAW))
+ {
+ if(argno>0)
+ argmax = argno;
argno = -1;
- if(argno>=0 && argno++==0 && !(flag&SH_ARRAY) && *argp->argval!='/')
+ }
+ if(argno>=0 && argno++==cmdarg && !(flag&SH_ARRAY) && *argp->argval!='/')
{
/* check for builtin command */
- Namval_t *np=nv_bfsearch(argp->argval,sh.fun_tree, (Namval_t**)&t->comnamq,(char**)0);
- if((t->comnamp=(void*)np) && is_abuiltin(np) &&
- nv_isattr(np,BLT_DCL))
+ Namval_t *np=nv_bfsearch(argp->argval,lexp->sh->fun_tree, (Namval_t**)&t->comnamq,(char**)0);
+ if(cmdarg==0)
+ t->comnamp = (void*)np;
+ if(np && is_abuiltin(np))
{
- assignment = 1+(*argp->argval=='a');
- key_on = 1;
+ if(nv_isattr(np,BLT_DCL))
+ {
+ assignment = 1+(*argp->argval=='a');
+ if(np==SYSTYPESET)
+ lexp->intypeset = 1;
+ key_on = 1;
+ }
+ else if(np==SYSCOMMAND)
+ cmdarg++;
+ else if(np==SYSEXEC)
+ lexp->inexec = 1;
+ else if(np->nvalue.bfp==b_getopts)
+ opt_get |= FOPTGET;
}
}
*argtail = argp;
argtail = &(argp->argnxt.ap);
- if(!(shlex.assignok=key_on) && !(flag&SH_NOIO))
- shlex.assignok = SH_COMPASSIGN;
- shlex.aliasok = 0;
+ if(!(lexp->assignok=key_on) && !(flag&SH_NOIO) && sh_isoption(SH_NOEXEC))
+ lexp->assignok = SH_COMPASSIGN;
+ lexp->aliasok = 0;
}
retry:
- tok = sh_lex();
+ tok = sh_lex(lexp);
+ if(tok==LABLSYM && (flag&SH_ASSIGN))
+ lexp->token = tok = 0;
#if SHOPT_DEVFD
if((tok==IPROCSYM || tok==OPROCSYM))
{
Shnode_t *t;
int mode = (tok==OPROCSYM);
- t = sh_cmd(RPAREN,SH_NL);
- argp = (struct argnod*)stakalloc(sizeof(struct argnod));
+ t = sh_cmd(lexp,RPAREN,SH_NL);
+ argp = (struct argnod*)stkalloc(stkp,sizeof(struct argnod));
*argp->argval = 0;
+ argmax = 0;
argno = -1;
*argtail = argp;
argtail = &(argp->argnxt.ap);
- argp->argchn.ap = (struct argnod*)makeparent(mode?TFORK|FPIN|FAMP|FPCL:TFORK|FPOU,t);
+ argp->argchn.ap = (struct argnod*)makeparent(lexp,mode?TFORK|FPIN|FAMP|FPCL:TFORK|FPOU,t);
argp->argflag = (ARG_EXP|mode);
goto retry;
}
@@ -1208,20 +1356,26 @@ static Shnode_t *simple(int flag, struct ionod *io)
{
if(argp->argflag&ARG_ASSIGN)
{
- argp = assign(argp);
+ int intypeset = lexp->intypeset;
+ int tdef = 0;
+ lexp->intypeset = 0;
+ if(t->comnamp==SYSTYPESET && t->comarg->argnxt.ap && strcmp(t->comarg->argnxt.ap->argval,"-T")==0)
+ tdef = 1;
+ argp = assign(lexp,argp,tdef);
+ lexp->intypeset = intypeset;
if(associative)
- shlex.assignok |= SH_ASSIGN;
+ lexp->assignok |= SH_ASSIGN;
goto retry;
}
else if(argno==1 && !t->comset)
{
/* SVR2 style function */
- if(sh_lex() == RPAREN)
+ if(sh_lex(lexp) == RPAREN)
{
- shlex.arg = argp;
- return(funct());
+ lexp->arg = argp;
+ return(funct(lexp));
}
- shlex.token = LPAREN;
+ lexp->token = LPAREN;
}
}
else if(flag&SH_ASSIGN)
@@ -1229,7 +1383,11 @@ static Shnode_t *simple(int flag, struct ionod *io)
if(tok==RPAREN)
break;
else if(tok==NL && (flag&SH_ARRAY))
+ {
+ lexp->comp_assign = 2;
goto retry;
+ }
+
}
if(!(flag&SH_NOIO))
{
@@ -1237,41 +1395,43 @@ static Shnode_t *simple(int flag, struct ionod *io)
{
while(io->ionxt)
io = io->ionxt;
- io->ionxt = inout((struct ionod*)0,0);
+ io->ionxt = inout(lexp,(struct ionod*)0,0);
}
else
- t->comio = io = inout((struct ionod*)0,0);
+ t->comio = io = inout(lexp,(struct ionod*)0,0);
}
}
*argtail = 0;
- t->comtyp = TCOM;
+ if(argno>0)
+ argmax = argno;
+ t->comtyp = TCOM | (argmax<<(COMBITS+2));
#if SHOPT_KIA
- if(shlex.kiafile && !(flag&SH_NOIO))
+ if(lexp->kiafile && !(flag&SH_NOIO))
{
register Namval_t *np=(Namval_t*)t->comnamp;
unsigned long r=0;
int line = t->comline;
argp = t->comarg;
if(np)
- r = kiaentity(nv_name(np),-1,'p',-1,0,shlex.unknown,'b',0,"");
+ r = kiaentity(lexp,nv_name(np),-1,'p',-1,0,lexp->unknown,'b',0,"");
else if(argp)
- r = kiaentity(sh_argstr(argp),-1,'p',-1,0,shlex.unknown,'c',0,"");
+ r = kiaentity(lexp,sh_argstr(argp),-1,'p',-1,0,lexp->unknown,'c',0,"");
if(r>0)
- sfprintf(shlex.kiatmp,"p;%..64d;p;%..64d;%d;%d;c;\n",shlex.current,r,line,line);
+ sfprintf(lexp->kiatmp,"p;%..64d;p;%..64d;%d;%d;c;\n",lexp->current,r,line,line);
if(t->comset && argno==0)
- writedefs(t->comset,line,'v',t->comarg);
+ writedefs(lexp,t->comset,line,'v',t->comarg);
else if(np && nv_isattr(np,BLT_DCL))
- writedefs(argp,line,0,NIL(struct argnod*));
+ writedefs(lexp,argp,line,0,NIL(struct argnod*));
else if(argp && strcmp(argp->argval,"read")==0)
- writedefs(argp,line,0,NIL(struct argnod*));
+ writedefs(lexp,argp,line,0,NIL(struct argnod*));
#if 0
else if(argp && strcmp(argp->argval,"unset")==0)
- writedefs(argp,line,'u',NIL(struct argnod*));
+ writedefs(lexp,argp,line,'u',NIL(struct argnod*));
#endif
else if(argp && *argp->argval=='.' && argp->argval[1]==0 && (argp=argp->argnxt.ap))
{
- r = kiaentity(sh_argstr(argp),-1,'p',0,0,shlex.script,'d',0,"");
- sfprintf(shlex.kiatmp,"p;%..64d;p;%..64d;%d;%d;d;\n",shlex.current,r,line,line);
+ r = kiaentity(lexp,sh_argstr(argp),-1,'p',0,0,lexp->script,'d',0,"");
+ sfprintf(lexp->kiatmp,"p;%..64d;p;%..64d;%d;%d;d;\n",lexp->current,r,line,line);
}
}
#endif /* SHOPT_KIA */
@@ -1304,30 +1464,30 @@ static Shnode_t *simple(int flag, struct ionod *io)
break;
}
if(sh_isoption(SH_NOEXEC) && tok==0)
- errormsg(SH_DICT,ERROR_warn(0),e_lexlabunknown,sh.inlineno-(shlex.token=='\n'),cp);
+ errormsg(SH_DICT,ERROR_warn(0),e_lexlabunknown,lexp->sh->inlineno-(lexp->token=='\n'),cp);
}
else if(sh_isoption(SH_NOEXEC) && np==SYSSET && ((tok= *argp->argval)=='-'||tok=='+') &&
(argp->argval[1]==0||strchr(argp->argval,'k')))
- errormsg(SH_DICT,ERROR_warn(0),e_lexobsolete5,sh.inlineno-(shlex.token=='\n'),argp->argval);
+ errormsg(SH_DICT,ERROR_warn(0),e_lexobsolete5,lexp->sh->inlineno-(lexp->token=='\n'),argp->argval);
}
/* expand argument list if possible */
if(argno>0)
t->comarg = qscan(t,argno);
else if(t->comarg)
t->comtyp |= COMSCAN;
- shlex.aliasok = 0;
+ lexp->aliasok = 0;
return((Shnode_t*)t);
}
/*
* skip past newlines but issue prompt if interactive
*/
-static int skipnl(int flag)
+static int skipnl(Lex_t *lexp,int flag)
{
register int token;
- while((token=sh_lex())==NL);
+ while((token=sh_lex(lexp))==NL);
if(token==';' && !(flag&SH_SEMI))
- sh_syntax();
+ sh_syntax(lexp);
return(token);
}
@@ -1336,18 +1496,19 @@ static int skipnl(int flag)
* if flag>0 then an alias can be in the next word
* if flag<0 only one redirection will be processed
*/
-static struct ionod *inout(struct ionod *lastio,int flag)
+static struct ionod *inout(Lex_t *lexp,struct ionod *lastio,int flag)
{
- register int iof = shlex.digits, token=shlex.token;
+ register int iof = lexp->digits, token=lexp->token;
register struct ionod *iop;
+ Stk_t *stkp = lexp->sh->stk;
char *iovname=0;
#if SHOPT_BASH
register int errout=0;
#endif
if(token==IOVNAME)
{
- iovname=shlex.arg->argval+1;
- token= sh_lex();
+ iovname=lexp->arg->argval+1;
+ token= sh_lex(lexp);
iof = 0;
}
switch(token&0xff)
@@ -1387,83 +1548,85 @@ static struct ionod *inout(struct ionod *lastio,int flag)
iof |= IOCLOB;
else if((token&SYMSHARP) == SYMSHARP)
iof |= IOLSEEK;
+ else if((token&SYMSEMI) == SYMSEMI)
+ iof |= IOREWRITE;
break;
default:
return(lastio);
}
- shlex.digits=0;
- iop=(struct ionod*) stakalloc(sizeof(struct ionod));
+ lexp->digits=0;
+ iop=(struct ionod*) stkalloc(stkp,sizeof(struct ionod));
iop->iodelim = 0;
- if(token=sh_lex())
+ if(token=sh_lex(lexp))
{
- if(token==RPAREN && (iof&IOLSEEK) && shlex.comsub)
+ if(token==RPAREN && (iof&IOLSEEK) && lexp->comsub)
{
- shlex.arg = (struct argnod*)stakalloc(sizeof(struct argnod)+3);
- strcpy(shlex.arg->argval,"CUR");
- shlex.arg->argflag = ARG_RAW;
+ lexp->arg = (struct argnod*)stkalloc(stkp,sizeof(struct argnod)+3);
+ strcpy(lexp->arg->argval,"CUR");
+ lexp->arg->argflag = ARG_RAW;
iof |= IOARITH;
fcseek(-1);
}
else if(token==EXPRSYM && (iof&IOLSEEK))
iof |= IOARITH;
else
- sh_syntax();
+ sh_syntax(lexp);
}
- iop->ioname=shlex.arg->argval;
+ iop->ioname=lexp->arg->argval;
iop->iovname = iovname;
if(iof&IODOC)
{
- if(shlex.digits==2)
+ if(lexp->digits==2)
{
iof |= IOSTRG;
- if(!(shlex.arg->argflag&ARG_RAW))
+ if(!(lexp->arg->argflag&ARG_RAW))
iof &= ~IORAW;
}
else
{
- if(!shlex.sh->heredocs)
- shlex.sh->heredocs = sftmp(HERE_MEM);
- iop->iolst=shlex.heredoc;
- shlex.heredoc=iop;
- if(shlex.arg->argflag&ARG_QUOTED)
+ if(!lexp->sh->heredocs)
+ lexp->sh->heredocs = sftmp(HERE_MEM);
+ iop->iolst=lexp->heredoc;
+ lexp->heredoc=iop;
+ if(lexp->arg->argflag&ARG_QUOTED)
iof |= IOQUOTE;
- if(shlex.digits==3)
+ if(lexp->digits==3)
iof |= IOLSEEK;
- if(shlex.digits)
+ if(lexp->digits)
iof |= IOSTRIP;
}
}
else
{
iop->iolst = 0;
- if(shlex.arg->argflag&ARG_RAW)
+ if(lexp->arg->argflag&ARG_RAW)
iof |= IORAW;
}
iop->iofile=iof;
if(flag>0)
/* allow alias substitutions and parameter assignments */
- shlex.aliasok = shlex.assignok = 1;
+ lexp->aliasok = lexp->assignok = 1;
#if SHOPT_KIA
- if(shlex.kiafile)
+ if(lexp->kiafile)
{
- int n = sh.inlineno-(shlex.token=='\n');
+ int n = lexp->sh->inlineno-(lexp->token=='\n');
if(!(iof&IOMOV))
{
- unsigned long r=kiaentity((iof&IORAW)?sh_fmtq(iop->ioname):iop->ioname,-1,'f',0,0,shlex.script,'f',0,"");
- sfprintf(shlex.kiatmp,"p;%..64d;f;%..64d;%d;%d;%c;%d\n",shlex.current,r,n,n,(iof&IOPUT)?((iof&IOAPP)?'a':'w'):((iof&IODOC)?'h':'r'),iof&IOUFD);
+ unsigned long r=kiaentity(lexp,(iof&IORAW)?sh_fmtq(iop->ioname):iop->ioname,-1,'f',0,0,lexp->script,'f',0,"");
+ 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);
}
}
#endif /* SHOPT_KIA */
if(flag>=0)
{
struct ionod *ioq=iop;
- sh_lex();
+ sh_lex(lexp);
#if SHOPT_BASH
if(errout)
{
/* redirect standard output to standard error */
- ioq = (struct ionod*)stakalloc(sizeof(struct ionod));
+ ioq = (struct ionod*)stkalloc(stkp,sizeof(struct ionod));
ioq->ioname = "1";
ioq->iolst = 0;
ioq->iodelim = 0;
@@ -1471,7 +1634,7 @@ static struct ionod *inout(struct ionod *lastio,int flag)
iop->ionxt=ioq;
}
#endif
- ioq->ionxt=inout(lastio,flag);
+ ioq->ionxt=inout(lexp,lastio,flag);
}
else
iop->ionxt=0;
@@ -1540,27 +1703,27 @@ static struct argnod *qscan(struct comnod *ac,int argn)
return((struct argnod*)dp);
}
-static Shnode_t *test_expr(int sym)
+static Shnode_t *test_expr(Lex_t *lp,int sym)
{
- register Shnode_t *t = test_or();
- if(shlex.token!=sym)
- sh_syntax();
+ register Shnode_t *t = test_or(lp);
+ if(lp->token!=sym)
+ sh_syntax(lp);
return(t);
}
-static Shnode_t *test_or(void)
+static Shnode_t *test_or(Lex_t *lp)
{
- register Shnode_t *t = test_and();
- while(shlex.token==ORFSYM)
- t = makelist(TORF|TTEST,t,test_and());
+ register Shnode_t *t = test_and(lp);
+ while(lp->token==ORFSYM)
+ t = makelist(lp,TORF|TTEST,t,test_and(lp));
return(t);
}
-static Shnode_t *test_and(void)
+static Shnode_t *test_and(Lex_t *lp)
{
- register Shnode_t *t = test_primary();
- while(shlex.token==ANDFSYM)
- t = makelist(TAND|TTEST,t,test_primary());
+ register Shnode_t *t = test_primary(lp);
+ while(lp->token==ANDFSYM)
+ t = makelist(lp,TAND|TTEST,t,test_primary(lp));
return(t);
}
@@ -1581,46 +1744,46 @@ static void ere_match(void)
fcfopen(base);
}
-static Shnode_t *test_primary(void)
+static Shnode_t *test_primary(Lex_t *lexp)
{
register struct argnod *arg;
register Shnode_t *t;
register int num,token;
- token = skipnl(0);
- num = shlex.digits;
+ token = skipnl(lexp,0);
+ num = lexp->digits;
switch(token)
{
case '(':
- t = test_expr(')');
- t = makelist(TTST|TTEST|TPAREN ,t, (Shnode_t*)pointerof(sh.inlineno));
+ t = test_expr(lexp,')');
+ t = makelist(lexp,TTST|TTEST|TPAREN ,t, (Shnode_t*)pointerof(lexp->sh->inlineno));
break;
case '!':
- if(!(t = test_primary()))
- sh_syntax();
+ if(!(t = test_primary(lexp)))
+ sh_syntax(lexp);
t->tre.tretyp |= TNEGATE;
return(t);
case TESTUNOP:
- if(sh_lex())
- sh_syntax();
+ if(sh_lex(lexp))
+ sh_syntax(lexp);
#if SHOPT_KIA
- if(shlex.kiafile && !strchr("sntzoOG",num))
+ if(lexp->kiafile && !strchr("sntzoOG",num))
{
- int line = sh.inlineno- (shlex.token==NL);
+ int line = lexp->sh->inlineno- (lexp->token==NL);
unsigned long r;
- r=kiaentity(sh_argstr(shlex.arg),-1,'f',0,0,shlex.script,'t',0,"");
- sfprintf(shlex.kiatmp,"p;%..64d;f;%..64d;%d;%d;t;\n",shlex.current,r,line,line);
+ r=kiaentity(lexp,sh_argstr(lexp->arg),-1,'f',0,0,lexp->script,'t',0,"");
+ sfprintf(lexp->kiatmp,"p;%..64d;f;%..64d;%d;%d;t;\n",lexp->current,r,line,line);
}
#endif /* SHOPT_KIA */
- t = makelist(TTST|TTEST|TUNARY|(num<<TSHIFT),
- (Shnode_t*)shlex.arg,(Shnode_t*)shlex.arg);
- t->tst.tstline = sh.inlineno;
+ t = makelist(lexp,TTST|TTEST|TUNARY|(num<<TSHIFT),
+ (Shnode_t*)lexp->arg,(Shnode_t*)lexp->arg);
+ t->tst.tstline = lexp->sh->inlineno;
break;
/* binary test operators */
case 0:
- arg = shlex.arg;
- if((token=sh_lex())==TESTBINOP)
+ arg = lexp->arg;
+ if((token=sh_lex(lexp))==TESTBINOP)
{
- num = shlex.digits;
+ num = lexp->digits;
if(num==TEST_REP)
{
ere_match();
@@ -1633,48 +1796,48 @@ static Shnode_t *test_primary(void)
num = TEST_SGT;
else if(token==ANDFSYM||token==ORFSYM||token==ETESTSYM||token==RPAREN)
{
- t = makelist(TTST|TTEST|TUNARY|('n'<<TSHIFT),
+ t = makelist(lexp,TTST|TTEST|TUNARY|('n'<<TSHIFT),
(Shnode_t*)arg,(Shnode_t*)arg);
- t->tst.tstline = sh.inlineno;
+ t->tst.tstline = lexp->sh->inlineno;
return(t);
}
else
- sh_syntax();
+ sh_syntax(lexp);
#if SHOPT_KIA
- if(shlex.kiafile && (num==TEST_EF||num==TEST_NT||num==TEST_OT))
+ if(lexp->kiafile && (num==TEST_EF||num==TEST_NT||num==TEST_OT))
{
- int line = sh.inlineno- (shlex.token==NL);
+ int line = lexp->sh->inlineno- (lexp->token==NL);
unsigned long r;
- r=kiaentity(sh_argstr(shlex.arg),-1,'f',0,0,shlex.current,'t',0,"");
- sfprintf(shlex.kiatmp,"p;%..64d;f;%..64d;%d;%d;t;\n",shlex.current,r,line,line);
+ r=kiaentity(lexp,sh_argstr(lexp->arg),-1,'f',0,0,lexp->current,'t',0,"");
+ sfprintf(lexp->kiatmp,"p;%..64d;f;%..64d;%d;%d;t;\n",lexp->current,r,line,line);
}
#endif /* SHOPT_KIA */
- if(sh_lex())
- sh_syntax();
+ if(sh_lex(lexp))
+ sh_syntax(lexp);
if(num&TEST_PATTERN)
{
- if(shlex.arg->argflag&(ARG_EXP|ARG_MAC))
+ if(lexp->arg->argflag&(ARG_EXP|ARG_MAC))
num &= ~TEST_PATTERN;
}
t = getnode(tstnod);
t->lst.lsttyp = TTST|TTEST|TBINARY|(num<<TSHIFT);
t->lst.lstlef = (Shnode_t*)arg;
- t->lst.lstrit = (Shnode_t*)shlex.arg;
- t->tst.tstline = sh.inlineno;
+ t->lst.lstrit = (Shnode_t*)lexp->arg;
+ t->tst.tstline = lexp->sh->inlineno;
#if SHOPT_KIA
- if(shlex.kiafile && (num==TEST_EF||num==TEST_NT||num==TEST_OT))
+ if(lexp->kiafile && (num==TEST_EF||num==TEST_NT||num==TEST_OT))
{
- int line = sh.inlineno-(shlex.token==NL);
+ int line = lexp->sh->inlineno-(lexp->token==NL);
unsigned long r;
- r=kiaentity(sh_argstr(shlex.arg),-1,'f',0,0,shlex.current,'t',0,"");
- sfprintf(shlex.kiatmp,"p;%..64d;f;%..64d;%d;%d;t;\n",shlex.current,r,line,line);
+ r=kiaentity(lexp,sh_argstr(lexp->arg),-1,'f',0,0,lexp->current,'t',0,"");
+ sfprintf(lexp->kiatmp,"p;%..64d;f;%..64d;%d;%d;t;\n",lexp->current,r,line,line);
}
#endif /* SHOPT_KIA */
break;
default:
return(0);
}
- skipnl(0);
+ skipnl(lexp,0);
return(t);
}
@@ -1683,23 +1846,23 @@ static Shnode_t *test_primary(void)
* return an entity checksum
* The entity is created if it doesn't exist
*/
-unsigned long kiaentity(const char *name,int len,int type,int first,int last,unsigned long parent, int pkind, int width, const char *attr)
+unsigned 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)
{
+ Stk_t *stkp = lexp->sh->stk;
Namval_t *np;
- long offset = staktell();
- stakputc(type);
+ long offset = stktell(stkp);
+ sfputc(stkp,type);
if(len>0)
- stakwrite(name,len);
+ sfwrite(stkp,name,len);
else
{
if(type=='p')
- stakputs(path_basename(name));
+ sfputr(stkp,path_basename(name),0);
else
- stakputs(name);
+ sfputr(stkp,name,0);
}
- stakputc(0);
- np = nv_search(stakptr(offset),shlex.entity_tree,NV_ADD);
- stakseek(offset);
+ np = nv_search(stakptr(offset),lexp->entity_tree,NV_ADD);
+ stkseek(stkp,offset);
np->nvalue.i = pkind;
nv_setsize(np,width);
if(!nv_isattr(np,NV_TAGGED) && first>=0)
@@ -1708,9 +1871,9 @@ unsigned long kiaentity(const char *name,int len,int type,int first,int last,uns
if(!pkind)
pkind = '0';
if(len>0)
- sfprintf(shlex.kiafile,"%..64d;%c;%.*s;%d;%d;%..64d;%..64d;%c;%d;%s\n",np->hash,type,len,name,first,last,parent,shlex.fscript,pkind,width,attr);
+ 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);
else
- sfprintf(shlex.kiafile,"%..64d;%c;%s;%d;%d;%..64d;%..64d;%c;%d;%s\n",np->hash,type,name,first,last,parent,shlex.fscript,pkind,width,attr);
+ 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);
}
return(np->hash);
}
@@ -1718,40 +1881,41 @@ unsigned long kiaentity(const char *name,int len,int type,int first,int last,uns
static void kia_add(register Namval_t *np, void *data)
{
char *name = nv_name(np);
+ Lex_t *lp = (Lex_t*)data;
NOT_USED(data);
- kiaentity(name+1,-1,*name,0,-1,(*name=='p'?shlex.unknown:shlex.script),np->nvalue.i,nv_size(np),"");
+ kiaentity(lp,name+1,-1,*name,0,-1,(*name=='p'?lp->unknown:lp->script),np->nvalue.i,nv_size(np),"");
}
-int kiaclose(void)
+int kiaclose(Lex_t *lexp)
{
register off_t off1,off2;
register int n;
- if(shlex.kiafile)
+ if(lexp->kiafile)
{
- unsigned long r = kiaentity(shlex.scriptname,-1,'p',-1,sh.inlineno-1,0,'s',0,"");
- kiaentity(shlex.scriptname,-1,'p',1,sh.inlineno-1,r,'s',0,"");
- kiaentity(shlex.scriptname,-1,'f',1,sh.inlineno-1,r,'s',0,"");
- nv_scan(shlex.entity_tree,kia_add,(void*)0,NV_TAGGED,0);
- off1 = sfseek(shlex.kiafile,(off_t)0,SEEK_END);
- sfseek(shlex.kiatmp,(off_t)0,SEEK_SET);
- sfmove(shlex.kiatmp,shlex.kiafile,SF_UNBOUND,-1);
- off2 = sfseek(shlex.kiafile,(off_t)0,SEEK_END);
+ unsigned long r = kiaentity(lexp,lexp->scriptname,-1,'p',-1,lexp->sh->inlineno-1,0,'s',0,"");
+ kiaentity(lexp,lexp->scriptname,-1,'p',1,lexp->sh->inlineno-1,r,'s',0,"");
+ kiaentity(lexp,lexp->scriptname,-1,'f',1,lexp->sh->inlineno-1,r,'s',0,"");
+ nv_scan(lexp->entity_tree,kia_add,(void*)lexp,NV_TAGGED,0);
+ off1 = sfseek(lexp->kiafile,(off_t)0,SEEK_END);
+ sfseek(lexp->kiatmp,(off_t)0,SEEK_SET);
+ sfmove(lexp->kiatmp,lexp->kiafile,SF_UNBOUND,-1);
+ off2 = sfseek(lexp->kiafile,(off_t)0,SEEK_END);
#ifdef SF_BUFCONST
if(off2==off1)
- n= sfprintf(shlex.kiafile,"DIRECTORY\nENTITY;%lld;%d\nDIRECTORY;",(Sflong_t)shlex.kiabegin,(size_t)(off1-shlex.kiabegin));
+ n= sfprintf(lexp->kiafile,"DIRECTORY\nENTITY;%lld;%d\nDIRECTORY;",(Sflong_t)lexp->kiabegin,(size_t)(off1-lexp->kiabegin));
else
- n= sfprintf(shlex.kiafile,"DIRECTORY\nENTITY;%lld;%d\nRELATIONSHIP;%lld;%d\nDIRECTORY;",(Sflong_t)shlex.kiabegin,(size_t)(off1-shlex.kiabegin),(Sflong_t)off1,(size_t)(off2-off1));
+ 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));
if(off2 >= INT_MAX)
off2 = -(n+12);
- sfprintf(shlex.kiafile,"%010.10lld;%010d\n",(Sflong_t)off2+10, n+12);
+ sfprintf(lexp->kiafile,"%010.10lld;%010d\n",(Sflong_t)off2+10, n+12);
#else
if(off2==off1)
- n= sfprintf(shlex.kiafile,"DIRECTORY\nENTITY;%d;%d\nDIRECTORY;",shlex.kiabegin,off1-shlex.kiabegin);
+ n= sfprintf(lexp->kiafile,"DIRECTORY\nENTITY;%d;%d\nDIRECTORY;",lexp->kiabegin,off1-lexp->kiabegin);
else
- n= sfprintf(shlex.kiafile,"DIRECTORY\nENTITY;%d;%d\nRELATIONSHIP;%d;%d\nDIRECTORY;",shlex.kiabegin,off1-shlex.kiabegin,off1,off2-off1);
- sfprintf(shlex.kiafile,"%010d;%010d\n",off2+10, n+12);
+ n= sfprintf(lexp->kiafile,"DIRECTORY\nENTITY;%d;%d\nRELATIONSHIP;%d;%d\nDIRECTORY;",lexp->kiabegin,off1-lexp->kiabegin,off1,off2-off1);
+ sfprintf(lexp->kiafile,"%010d;%010d\n",off2+10, n+12);
#endif
}
- return(sfclose(shlex.kiafile));
+ return(sfclose(lexp->kiafile));
}
#endif /* SHOPT_KIA */