summaryrefslogtreecommitdiff
path: root/usr/src/lib/libshell/common/sh/macro.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib/libshell/common/sh/macro.c')
-rw-r--r--usr/src/lib/libshell/common/sh/macro.c94
1 files changed, 71 insertions, 23 deletions
diff --git a/usr/src/lib/libshell/common/sh/macro.c b/usr/src/lib/libshell/common/sh/macro.c
index cb938764d6..684e2d0464 100644
--- a/usr/src/lib/libshell/common/sh/macro.c
+++ b/usr/src/lib/libshell/common/sh/macro.c
@@ -1,7 +1,7 @@
/***********************************************************************
* *
* This software is part of the ast package *
-* Copyright (c) 1982-2008 AT&T Intellectual Property *
+* Copyright (c) 1982-2009 AT&T Intellectual Property *
* and is licensed under the *
* Common Public License, Version 1.0 *
* by AT&T Intellectual Property *
@@ -38,6 +38,7 @@
#include "variables.h"
#include "shlex.h"
#include "io.h"
+#include "jobs.h"
#include "shnodes.h"
#include "path.h"
#include "national.h"
@@ -529,8 +530,13 @@ static void copyto(register Mac_t *mp,int endch, int newquote)
{
/* preserve \digit for pattern matching */
/* also \alpha for extended patterns */
- if(!mp->lit && !mp->quote && (n==S_DIG || ((paren+ere) && sh_lexstates[ST_DOL][*(unsigned char*)cp]==S_ALP)))
- break;
+ if(!mp->lit && !mp->quote)
+ {
+ if((n==S_DIG || ((paren+ere) && sh_lexstates[ST_DOL][*(unsigned char*)cp]==S_ALP)))
+ break;
+ if(ere && mp->pattern==1 && strchr(".[()*+?{|^$&!",*cp))
+ break;
+ }
/* followed by file expansion */
if(!mp->lit && (n==S_ESC || (!mp->quote &&
(n==S_PAT||n==S_ENDCH||n==S_SLASH||n==S_BRACT||*cp=='-'))))
@@ -647,8 +653,14 @@ static void copyto(register Mac_t *mp,int endch, int newquote)
int offset=0,oldpat = mp->pattern;
int oldarith = mp->arith, oldsub=mp->subcopy;
sfwrite(stkp,first,++c);
- if((mp->assign&1) && first[c-2]=='.')
- offset = stktell(stkp);
+ if(mp->assign&1)
+ {
+ if(first[c-2]=='.')
+ offset = stktell(stkp);
+ if(isastchar(*cp) && cp[1]==']')
+ errormsg(SH_DICT,ERROR_exit(1),
+e_badsubscript,*cp);
+ }
first = fcseek(c);
mp->pattern = 4;
mp->arith = 0;
@@ -678,7 +690,7 @@ static void copyto(register Mac_t *mp,int endch, int newquote)
{
char *p = cp;
while((c=mbchar(p)) && c!=RPAREN && c!='E');
- ere = c=='E';
+ ere = (c=='E'||c=='A');
}
}
else if(n==RPAREN)
@@ -892,7 +904,7 @@ static char *getdolarg(Shell_t *shp, int n, int *size)
static char *prefix(Shell_t *shp, char *id)
{
Namval_t *np;
- register char *cp = strchr(id,'.');
+ register char *sub=0, *cp = strchr(id,'.');
if(cp)
{
*cp = 0;
@@ -905,11 +917,23 @@ static char *prefix(Shell_t *shp, char *id)
int n;
char *sp;
shp->argaddr = 0;
- while(nv_isref(np))
+ while(nv_isref(np) && np->nvalue.cp)
+ {
+ sub = nv_refsub(np);
np = nv_refnode(np);
- id = (char*)malloc(strlen(cp)+1+(n=strlen(sp=nv_name(np)))+1);
- strcpy(&id[n],cp);
+ if(sub)
+ nv_putsub(np,sub,0L);
+ }
+ id = (char*)malloc(strlen(cp)+1+(n=strlen(sp=nv_name(np)))+ (sub?strlen(sub)+3:1));
memcpy(id,sp,n);
+ if(sub)
+ {
+ id[n++] = '[';
+ strcpy(&id[n],sub);
+ n+= strlen(sub)+1;
+ id[n-1] = ']';
+ }
+ strcpy(&id[n],cp);
return(id);
}
}
@@ -961,7 +985,7 @@ int sh_macfun(Shell_t *shp, const char *name, int offset)
tp = (Shnode_t*)&node;
tp->com.comarg = (struct argnod*)dp;
tp->com.comline = shp->inlineno;
- dp->dolnum = 2;
+ dp->dolnum = 1;
dp->dolval[0] = strdup(name);
stkseek(shp->stk,offset);
comsubst((Mac_t*)shp->mac_context,tp,2);
@@ -1009,14 +1033,14 @@ static int varsub(Mac_t *mp)
Namarr_t *ap=0;
int dolmax=0, vsize= -1, offset= -1, nulflg, replen=0, bysub=0;
char idbuff[3], *id = idbuff, *pattern=0, *repstr, *arrmax=0;
- int addsub=0,oldpat=mp->pattern,idnum=0,flag=0,d;
+ int var=1,addsub=0,oldpat=mp->pattern,idnum=0,flag=0,d;
Stk_t *stkp = mp->shp->stk;
retry1:
mp->zeros = 0;
idbuff[0] = 0;
idbuff[1] = 0;
c = fcget();
- switch(c>0x7f?S_ALP:sh_lexstates[ST_DOL][c])
+ switch(isascii(c)?sh_lexstates[ST_DOL][c]:S_ALP)
{
case S_RBRA:
if(type<M_SIZE)
@@ -1053,6 +1077,7 @@ retry1:
}
/* FALL THRU */
case S_SPC2:
+ var = 0;
*id = c;
v = special(mp->shp,c);
if(isastchar(c))
@@ -1081,6 +1106,7 @@ retry1:
comsubst(mp,(Shnode_t*)0,1);
return(1);
case S_DIG:
+ var = 0;
c -= '0';
mp->shp->argaddr = 0;
if(type)
@@ -1117,7 +1143,7 @@ retry1:
np = 0;
do
sfputc(stkp,c);
- while(((c=fcget()),(c>0x7f||isaname(c)))||type && c=='.');
+ while(((c=fcget()),(!isascii(c)||isaname(c)))||type && c=='.');
while(c==LBRACT && (type||mp->arrayok))
{
mp->shp->argaddr=0;
@@ -1204,10 +1230,14 @@ retry1:
}
else
#endif /* SHOPT_FILESCAN */
- if(mp->shp->argaddr)
- flag &= ~NV_NOADD;
- np = nv_open(id,mp->shp->var_tree,flag|NV_NOFAIL);
- if((!np || nv_isnull(np)) && type==M_BRACE && c==RBRACE && !(flag&NV_ARRAY))
+ {
+ if(mp->shp->argaddr)
+ flag &= ~NV_NOADD;
+ np = nv_open(id,mp->shp->var_tree,flag|NV_NOFAIL);
+ }
+ if(isastchar(mode))
+ var = 0;
+ if((!np || nv_isnull(np)) && type==M_BRACE && c==RBRACE && !(flag&NV_ARRAY) && strchr(id,'.'))
{
if(sh_macfun(mp->shp,id,offset))
{
@@ -1215,6 +1245,13 @@ retry1:
return(1);
}
}
+ if(np && (flag&NV_NOADD) && nv_isnull(np))
+ {
+ if(nv_isattr(np,NV_NOFREE))
+ nv_offattr(np,NV_NOFREE);
+ else
+ np = 0;
+ }
ap = np?nv_arrayptr(np):0;
if(type)
{
@@ -1299,7 +1336,15 @@ retry1:
v = nv_getvtree(np,(Namfun_t*)0);
else
{
- v = nv_getval(np);
+ if(type && fcpeek(0)=='+')
+ {
+ if(ap)
+ v = nv_arrayisset(np,ap)?(char*)"x":0;
+ else
+ v = nv_isnull(np)?0:(char*)"x";
+ }
+ else
+ v = nv_getval(np);
/* special case --- ignore leading zeros */
if( (mp->arith||mp->let) && (np->nvfun || nv_isattr(np,(NV_LJUST|NV_RJUST|NV_ZFILL))) && (offset==0 || !isalnum(c)))
mp->zeros = 1;
@@ -1345,6 +1390,7 @@ retry1:
mac_error(np);
if(type==M_NAMESCAN || type==M_NAMECOUNT)
{
+ mp->shp->last_root = mp->shp->var_tree;
id = prefix(mp->shp,id);
stkseek(stkp,offset);
if(type==M_NAMECOUNT)
@@ -1432,6 +1478,7 @@ retry1:
int quoted = mp->quoted;
int arith = mp->arith;
int zeros = mp->zeros;
+ int assign = mp->assign;
if(newops)
{
type = fcget();
@@ -1446,6 +1493,7 @@ retry1:
mp->pattern = 1+(c=='/');
mp->split = 0;
mp->quoted = 0;
+ mp->assign &= ~1;
mp->arith = mp->zeros = 0;
newquote = 0;
}
@@ -1459,6 +1507,7 @@ retry1:
mp->quoted = quoted;
mp->arith = arith;
mp->zeros = zeros;
+ mp->assign = assign;
/* add null byte */
sfputc(stkp,0);
stkseek(stkp,stktell(stkp)-1);
@@ -1803,7 +1852,7 @@ retry2:
mac_error(np);
}
}
- else if(sh_isoption(SH_NOUNSET) && (!np || nv_isnull(np) || (nv_isarray(np) && !np->nvalue.cp)))
+ else if(var && sh_isoption(SH_NOUNSET) && (!np || nv_isnull(np) || (nv_isarray(np) && !np->nvalue.cp)))
{
if(np)
{
@@ -2467,7 +2516,6 @@ static char *sh_tilde(Shell_t *shp,register const char *string)
*/
static char *special(Shell_t *shp,register int c)
{
- register Namval_t *np;
if(c!='$')
shp->argaddr = 0;
switch(c)
@@ -2497,10 +2545,10 @@ static char *special(Shell_t *shp,register int c)
case '?':
return(ltos(shp->savexit));
case 0:
- if(sh_isstate(SH_PROFILE) || !error_info.id || ((np=nv_search(error_info.id,shp->bltin_tree,0)) && nv_isattr(np,BLT_SPC)))
+ if(sh_isstate(SH_PROFILE) || shp->fn_depth==0 || !shp->st.cmdname)
return(shp->shname);
else
- return(error_info.id);
+ return(shp->st.cmdname);
}
return(NIL(char*));
}