summaryrefslogtreecommitdiff
path: root/usr/src/lib/libshell/common/sh/name.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib/libshell/common/sh/name.c')
-rw-r--r--usr/src/lib/libshell/common/sh/name.c156
1 files changed, 125 insertions, 31 deletions
diff --git a/usr/src/lib/libshell/common/sh/name.c b/usr/src/lib/libshell/common/sh/name.c
index bbdeeb83dd..2189a3a42a 100644
--- a/usr/src/lib/libshell/common/sh/name.c
+++ b/usr/src/lib/libshell/common/sh/name.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 *
@@ -26,7 +26,6 @@
#define putenv ___putenv
#include "defs.h"
-#include <ctype.h>
#include "variables.h"
#include "path.h"
#include "lexstates.h"
@@ -88,6 +87,7 @@ struct adata
struct Cache_entry
{
Dt_t *root;
+ Dt_t *last_root;
char *name;
Namval_t *np;
Namval_t *last_table;
@@ -283,7 +283,7 @@ struct argnod *nv_onlist(struct argnod *arg, const char *name)
* Perform parameter assignment for a linked list of parameters
* <flags> contains attributes for the parameters
*/
-void nv_setlist(register struct argnod *arg,register int flags)
+void nv_setlist(register struct argnod *arg,register int flags, Namval_t *typ)
{
Shell_t *shp = &sh;
register char *cp;
@@ -340,6 +340,8 @@ void nv_setlist(register struct argnod *arg,register int flags)
else
cp = fp->fornam;
error_info.line = fp->fortyp-shp->st.firstline;
+ if(!array && tp->tre.tretyp!=TLST && tp->com.comset && !tp->com.comarg && tp->com.comset->argval[0]==0 && tp->com.comset->argval[1]=='[')
+ array |= (tp->com.comset->argflag&ARG_MESSAGE)?NV_IARRAY:NV_ARRAY;
if(shp->fn_depth && (Namval_t*)tp->com.comnamp==SYSTYPESET)
flag |= NV_NOSCOPE;
if(prefix && tp->com.comset && *cp=='[')
@@ -359,13 +361,15 @@ void nv_setlist(register struct argnod *arg,register int flags)
}
}
np = nv_open(cp,shp->var_tree,flag|NV_ASSIGN);
+ if(typ && !array && (nv_isnull(np) || nv_isarray(np)))
+ nv_settype(np,typ,0);
if((flags&NV_STATIC) && !nv_isnull(np))
#if SHOPT_TYPEDEF
goto check_type;
#else
continue;
#endif /* SHOPT_TYPEDEF */
- if(array)
+ if(array && (!(ap=nv_arrayptr(np)) || !ap->hdr.type))
{
if(!(arg->argflag&ARG_APPEND))
nv_unset(np);
@@ -377,7 +381,9 @@ void nv_setlist(register struct argnod *arg,register int flags)
{
nv_onattr(np,NV_ARRAY);
}
- if(tp->tre.tretyp!=TLST && !tp->com.comset && !tp->com.comarg)
+ }
+ if(array && tp->tre.tretyp!=TLST && !tp->com.comset && !tp->com.comarg)
+ {
#if SHOPT_TYPEDEF
goto check_type;
#else
@@ -444,7 +450,7 @@ void nv_setlist(register struct argnod *arg,register int flags)
if(!(array&NV_IARRAY) && !(tp->com.comset->argflag&ARG_MESSAGE))
nv_setarray(np,nv_associative);
}
- nv_setlist(tp->com.comset,flags);
+ nv_setlist(tp->com.comset,flags,0);
shp->prefix = prefix;
if(tp->com.comset->argval[1]!='[')
nv_setvtree(np);
@@ -496,17 +502,25 @@ void nv_setlist(register struct argnod *arg,register int flags)
else
shp->prefix = cp;
shp->last_table = 0;
- memset(&nr,0,sizeof(nr));
- memcpy(&node,L_ARGNOD,sizeof(node));
- L_ARGNOD->nvalue.nrp = &nr;
- nr.np = np;
- nr.root = shp->last_root;
- nr.table = shp->last_table;
- L_ARGNOD->nvflag = NV_REF|NV_NOFREE;
- L_ARGNOD->nvfun = 0;
+ if(shp->prefix)
+ {
+ if(*shp->prefix=='_' && shp->prefix[1]=='.' && nv_isref(L_ARGNOD))
+ {
+ sfprintf(stkstd,"%s%s",nv_name(L_ARGNOD->nvalue.nrp->np),shp->prefix+1);
+ shp->prefix = stkfreeze(stkstd,1);
+ }
+ memset(&nr,0,sizeof(nr));
+ memcpy(&node,L_ARGNOD,sizeof(node));
+ L_ARGNOD->nvalue.nrp = &nr;
+ nr.np = np;
+ nr.root = shp->last_root;
+ nr.table = shp->last_table;
+ L_ARGNOD->nvflag = NV_REF|NV_NOFREE;
+ L_ARGNOD->nvfun = 0;
+ }
sh_exec(tp,sh_isstate(SH_ERREXIT));
#if SHOPT_TYPEDEF
- if(!maketype)
+ if(shp->prefix)
#endif
{
L_ARGNOD->nvalue.nrp = node.nvalue.nrp;
@@ -523,7 +537,7 @@ void nv_setlist(register struct argnod *arg,register int flags)
tp = tp->lst.lstrit;
}
- if(!nv_isarray(np) && (tp->com.comarg || !tp->com.comset || tp->com.comset->argval[0]!='['))
+ if(!nv_isarray(np) && !typ && (tp->com.comarg || !tp->com.comset || tp->com.comset->argval[0]!='['))
nv_setvtree(np);
#if SHOPT_TYPEDEF
goto check_type;
@@ -776,7 +790,10 @@ Namval_t *nv_create(const char *name, Dt_t *root, int flags, Namfun_t *dp)
if(top)
{
if(nq==np)
+ {
flags &= ~NV_NOSCOPE;
+ root = shp->var_base;
+ }
else if(nq)
{
if(nv_isnull(np) && c!='.' && (np->nvfun=nv_cover(nq)))
@@ -798,7 +815,7 @@ Namval_t *nv_create(const char *name, Dt_t *root, int flags, Namfun_t *dp)
#endif
if(c=='.') /* don't optimize */
shp->argaddr = 0;
- else if((flags&NV_NOREF) && (c!='[' || *cp!='.'))
+ else if((flags&NV_NOREF) && (c!='[' && *cp!='.'))
{
if(c && !(flags&NV_NOADD))
nv_unref(np);
@@ -835,6 +852,9 @@ Namval_t *nv_create(const char *name, Dt_t *root, int flags, Namfun_t *dp)
flags &= ~NV_NOSCOPE;
}
flags |= NV_NOREF;
+ if(nv_isnull(np))
+ nv_onattr(np,NV_NOFREE);
+
}
shp->last_root = root;
if(cp[1]=='.')
@@ -867,8 +887,13 @@ Namval_t *nv_create(const char *name, Dt_t *root, int flags, Namfun_t *dp)
{
char *sub=0;
int n = 0;
+ mode &= ~HASH_NOSCOPE;
if(c=='[')
{
+#if 0
+ Namarr_t *ap = nv_arrayptr(np);
+ int scan = ap?(ap->nelem&ARRAY_SCAN):0;
+#endif
n = mode|nv_isarray(np);
if(!mode && (flags&NV_ARRAY) && ((c=sp[1])=='*' || c=='@') && sp[2]==']')
{
@@ -881,6 +906,10 @@ Namval_t *nv_create(const char *name, Dt_t *root, int flags, Namfun_t *dp)
if(flags&NV_ASSIGN)
n |= NV_ADD;
cp = nv_endsubscript(np,sp,n|(flags&NV_ASSIGN));
+#if 0
+ if(scan)
+ nv_putsub(np,NIL(char*),ARRAY_SCAN);
+#endif
}
else
cp = sp;
@@ -1000,6 +1029,7 @@ Namval_t *nv_create(const char *name, Dt_t *root, int flags, Namfun_t *dp)
if((nq = (*fp->disc->createf)(np,cp+1,flags,fp)) == np)
{
add = NV_ADD;
+ shp->last_table = 0;
break;
}
else if(np=nq)
@@ -1075,6 +1105,7 @@ void nv_delete(Namval_t* np, Dt_t *root, int flags)
* If <flags> & NV_NOREF then don't follow reference
* If <flags> & NV_NOFAIL then don't generate an error message on failure
* If <flags> & NV_STATIC then unset before an assignment
+ * If <flags> & NV_UNJUST then unset attributes before assignment
* SH_INIT is only set while initializing the environment
*/
Namval_t *nv_open(const char *name, Dt_t *root, int flags)
@@ -1175,6 +1206,7 @@ Namval_t *nv_open(const char *name, Dt_t *root, int flags)
if(nv_isarray(np))
nv_putsub(np,NIL(char*),ARRAY_UNDEF);
shp->last_table = xp->last_table;
+ shp->last_root = xp->last_root;
goto nocache;
}
}
@@ -1209,6 +1241,7 @@ Namval_t *nv_open(const char *name, Dt_t *root, int flags)
xp->root = root;
xp->np = np;
xp->last_table = shp->last_table;
+ xp->last_root = shp->last_root;
xp->flags = (flags&(NV_ARRAY|NV_NOSCOPE));
nvcache.index = (nvcache.index+1)&(NVCACHE-1);
}
@@ -1241,7 +1274,6 @@ skip:
if(np && shp->mktype)
np = nv_addnode(np,0);
#endif /* SHOPT_TYPEDEF */
-
if(c=='=' && np && (flags&NV_ASSIGN))
{
cp++;
@@ -1259,7 +1291,10 @@ skip:
if((flags&NV_STATIC) && !shp->mktype)
{
if(!nv_isnull(np))
+ {
+ shp->prefix = prefix;
return(np);
+ }
}
isref = nv_isref(np);
if(sh_isoption(SH_XTRACE) && nv_isarray(np))
@@ -1267,9 +1302,18 @@ skip:
c = msg==e_aliname? 0: (append | (flags&NV_EXPORT));
if(isref)
nv_offattr(np,NV_REF);
+ if(!append && (flags&NV_UNJUST))
+ {
+ nv_offattr(np,NV_LJUST|NV_RJUST|NV_ZFILL);
+ np->nvsize = 0;
+ }
nv_putval(np, cp, c);
if(isref)
+ {
+ if(nv_search((char*)np,shp->var_base,HASH_BUCKET))
+ shp->last_root = shp->var_base;
nv_setref(np,(Dt_t*)0,NV_VARNAME);
+ }
savesub = sub;
shp->prefix = prefix;
}
@@ -1325,7 +1369,7 @@ void nv_putval(register Namval_t *np, const char *string, int flags)
sh.argaddr = 0;
if(sh.subshell && !nv_local)
np = sh_assignok(np,1);
- if(np->nvfun && np->nvfun->disc && !(flags&NV_NODISC) && !nv_isattr(np,NV_REF))
+ if(np->nvfun && np->nvfun->disc && !(flags&NV_NODISC) && !nv_isref(np))
{
/* This function contains disc */
if(!nv_local)
@@ -1387,7 +1431,7 @@ void nv_putval(register Namval_t *np, const char *string, int flags)
up->ldp = new_of(Sfdouble_t,0);
else if(flags&NV_APPEND)
old = *(up->ldp);
- *(up->ldp) = ld+old;
+ *(up->ldp) = old?ld+old:ld;
}
else
{
@@ -1407,7 +1451,7 @@ void nv_putval(register Namval_t *np, const char *string, int flags)
up->dp = new_of(double,0);
else if(flags&NV_APPEND)
od = *(up->dp);
- *(up->dp) = d+od;
+ *(up->dp) = od?d+od:d;
}
}
else
@@ -1957,7 +2001,7 @@ static int scanfilter(Dt_t *dict, void *arg, void *data)
register struct adata *tp = (struct adata*)sp->scandata;
NOT_USED(dict);
#if SHOPT_TYPEDEF
- if(tp && tp->tp && nv_type(np)!=tp->tp)
+ if(tp && !is_abuiltin(np) && tp && tp->tp && nv_type(np)!=tp->tp)
return(0);
#endif /*SHOPT_TYPEDEF */
if(sp->scanmask?(k&sp->scanmask)==sp->scanflags:(!sp->scanflags || (k&sp->scanflags)))
@@ -2014,7 +2058,7 @@ void sh_scope(Shell_t *shp, struct argnod *envlist, int fun)
{
dtview(newscope,(Dt_t*)shp->var_tree);
shp->var_tree = newscope;
- nv_setlist(envlist,NV_EXPORT|NV_NOSCOPE|NV_IDENT|NV_ASSIGN);
+ nv_setlist(envlist,NV_EXPORT|NV_NOSCOPE|NV_IDENT|NV_ASSIGN,0);
if(!fun)
return;
shp->var_tree = dtview(newscope,0);
@@ -2039,6 +2083,10 @@ void sh_envnolocal (register Namval_t *np, void *data)
{
char *cp=0;
NOT_USED(data);
+ if(np==VERSIONNOD && nv_isref(np))
+ return;
+ if(np==L_ARGNOD)
+ return;
if(nv_isattr(np,NV_EXPORT) && nv_isarray(np))
{
nv_putsub(np,NIL(char*),0);
@@ -2047,7 +2095,7 @@ void sh_envnolocal (register Namval_t *np, void *data)
}
if(nv_isattr(np,NV_EXPORT|NV_NOFREE))
{
- if(nv_isref(np))
+ if(nv_isref(np) && np!=VERSIONNOD)
{
nv_offattr(np,NV_NOFREE|NV_REF);
free((void*)np->nvalue.nrp);
@@ -2082,7 +2130,11 @@ static void table_unset(Shell_t *shp, register Dt_t *root, int flags, Dt_t *oroo
for(np=(Namval_t*)dtfirst(root);np;np=npnext)
{
if(nv_isref(np))
- nv_unref(np);
+ {
+ free((void*)np->nvalue.nrp);
+ np->nvalue.cp = 0;
+ np->nvflag = 0;
+ }
if(nq=dtsearch(oroot,np))
{
if(nv_cover(nq))
@@ -2094,6 +2146,8 @@ static void table_unset(Shell_t *shp, register Dt_t *root, int flags, Dt_t *oroo
Sfdouble_t d = nv_getnum(nq);
nv_putval(nq,(char*)&d,NV_LDOUBLE);
}
+ else if(shp->test&4)
+ nv_putval(nq, strdup(nv_getval(nq)), NV_RDONLY);
else
nv_putval(nq, nv_getval(nq), NV_RDONLY);
shp->subshell = subshell;
@@ -2200,6 +2254,11 @@ void _nv_unset(register Namval_t *np,int flags)
/* called from disc, assign the actual value */
nv_local=0;
}
+ if(nv_isattr(np,NV_INT16P) == NV_INT16)
+ {
+ np->nvalue.cp = nv_isarray(np)?Empty:0;
+ goto done;
+ }
if(nv_isarray(np) && np->nvalue.cp!=Empty && np->nvfun)
up = np->nvalue.up;
else
@@ -2604,6 +2663,7 @@ void nv_newattr (register Namval_t *np, unsigned newatts, int size)
Namarr_t *ap = 0;
int oldsize,oldatts;
Namfun_t *fp= (newatts&NV_NODISC)?np->nvfun:0;
+ char *prefix = sh.prefix;
newatts &= ~NV_NODISC;
/* check for restrictions */
@@ -2623,7 +2683,8 @@ void nv_newattr (register Namval_t *np, unsigned newatts, int size)
sh_envput(sh.env,np);
}
#endif
- if((size==0||(n&NV_INTEGER)) && ((n^newatts)&~NV_NOCHANGE)==0)
+ oldsize = nv_size(np);
+ if((size==oldsize|| (n&NV_INTEGER)) && ((n^newatts)&~NV_NOCHANGE)==0)
{
if(size)
nv_setsize(np,size);
@@ -2684,6 +2745,7 @@ void nv_newattr (register Namval_t *np, unsigned newatts, int size)
np->nvfun = fp;
if(ap)
ap->nelem--;
+ sh.prefix = prefix;
return;
}
@@ -2800,11 +2862,20 @@ static char *lastdot(register char *cp, int eq)
while(c= *cp++)
{
if(c=='[')
- cp = nv_endsubscript((Namval_t*)0,ep=cp,0);
+ {
+ if(*cp==']')
+ cp++;
+ else
+ cp = nv_endsubscript((Namval_t*)0,ep=cp,0);
+ }
else if(c=='.')
{
if(*cp=='[')
- cp = nv_endsubscript((Namval_t*)0,cp,0);
+ {
+ cp = nv_endsubscript((Namval_t*)0,ep=cp,0);
+ if((ep=sh_checkid(ep+1,cp)) < cp)
+ cp=strcpy(ep,cp);
+ }
ep = 0;
}
else if(eq && c == '=')
@@ -2822,6 +2893,7 @@ int nv_rename(register Namval_t *np, int flags)
Namval_t *last_table = shp->last_table;
Dt_t *last_root = shp->last_root;
Dt_t *hp = 0;
+ char *prefix=shp->prefix,*nvenv = 0;
if(nv_isattr(np,NV_PARAM) && shp->st.prevst)
{
if(!(hp=(Dt_t*)shp->st.prevst->save_tree))
@@ -2837,6 +2909,7 @@ int nv_rename(register Namval_t *np, int flags)
errormsg(SH_DICT,ERROR_exit(1),e_varname,nv_name(np));
if(nv_isarray(np) && !(mp=nv_opensub(np)))
index=nv_aindex(np);
+ shp->prefix = 0;
if(!hp)
hp = shp->var_tree;
if(!(nr = nv_open(cp, hp, flags|NV_ARRAY|NV_NOREF|NV_NOSCOPE|NV_NOADD|NV_NOFAIL)))
@@ -2845,6 +2918,7 @@ int nv_rename(register Namval_t *np, int flags)
hp = shp->last_root;
if(!nr)
nr= nv_open(cp, hp, flags|NV_NOREF|((flags&NV_MOVE)?0:NV_NOFAIL));
+ shp->prefix = prefix;
if(!nr)
{
if(!nv_isvtree(np))
@@ -2859,7 +2933,10 @@ int nv_rename(register Namval_t *np, int flags)
mp->nvenv = (void*)np;
}
if(mp)
+ {
+ nvenv = (char*)np;
np = mp;
+ }
if(nr==np)
{
if(index<0)
@@ -2868,6 +2945,8 @@ int nv_rename(register Namval_t *np, int flags)
cp = strdup(cp);
}
_nv_unset(np,0);
+ if(!nv_isattr(np,NV_MINIMAL))
+ np->nvenv = nvenv;
if(nr==np)
{
nv_putsub(np,(char*)0, index);
@@ -2892,7 +2971,9 @@ void nv_setref(register Namval_t *np, Dt_t *hp, int flags)
{
Shell_t *shp = &sh;
register Namval_t *nq, *nr=0;
- register char *ep,*cp;
+ register char *ep,*cp;
+ Dt_t *root = shp->last_root;
+ Namarr_t *ap;
if(nv_isref(np))
return;
if(nv_isarray(np))
@@ -2908,13 +2989,22 @@ void nv_setref(register Namval_t *np, Dt_t *hp, int flags)
if(!hp)
hp = shp->var_tree;
if(!(nr = nq = nv_open(cp, hp, flags|NV_NOSCOPE|NV_NOADD|NV_NOFAIL)))
- hp = shp->var_base;
+ hp = shp->last_root==shp->var_tree?shp->var_tree:shp->var_base;
else if(shp->last_root)
hp = shp->last_root;
if(nq && ep && nv_isarray(nq) && !nv_getsub(nq))
nv_endsubscript(nq,ep-1,NV_ADD);
if(!nr)
+ {
nr= nq = nv_open(cp, hp, flags);
+ hp = shp->last_root;
+ }
+ if(shp->last_root == shp->var_tree && root!=shp->var_tree)
+ {
+ _nv_unset(np,NV_RDONLY);
+ nv_onattr(np,NV_REF);
+ errormsg(SH_DICT,ERROR_exit(1),e_globalref,nv_name(np));
+ }
if(nr==np)
{
if(shp->namespace && nv_dict(shp->namespace)==hp)
@@ -2923,6 +3013,8 @@ void nv_setref(register Namval_t *np, Dt_t *hp, int flags)
if(!(hp=dtvnext(hp)) || (nq=nv_search((char*)np,hp,NV_ADD|HASH_BUCKET))==np)
errormsg(SH_DICT,ERROR_exit(1),e_selfref,nv_name(np));
}
+ if(nq && !ep && (ap=nv_arrayptr(nq)) && !(ap->nelem&(ARRAY_UNDEF|ARRAY_SCAN)))
+ ep = nv_getsub(nq);
if(ep)
{
/* cause subscript evaluation and return result */
@@ -3017,8 +3109,10 @@ void nv_unref(register Namval_t *np)
Namval_t *nq;
if(!nv_isref(np))
return;
- nq = nv_refnode(np);
nv_offattr(np,NV_NOFREE|NV_REF);
+ if(!np->nvalue.nrp)
+ return;
+ nq = nv_refnode(np);
free((void*)np->nvalue.nrp);
np->nvalue.cp = strdup(nv_name(nq));
#if SHOPT_OPTIMIZE