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* A copy of the License is available at *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Information and Software Systems Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* AT&T Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Florham Park NJ *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* David Korn <dgk@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin***********************************************************************/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * AT&T Labs
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern int uwin_path(const char*, char*, int);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* _lib_pathnative */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic void ltou(char*);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic void utol(char*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void rightjust(char*, int, int);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic char *lastdot(char*, int);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif /*SHOPT_TYPEDEF */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_MULTIBYTE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/* ======== name value pair routines ======== */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * output variable name in format for re-input
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin while(c= *sp++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c==']')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(c=='\\')
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register struct sh_type *sp = (struct sh_type*)sh.mktype;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register int i;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(sp->numnodes==0 && !nv_isnull(np) && sh.last_table)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* could be an redefine */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(sp->numnodes && memcmp(np->nvname,NV_CLASS,sizeof(NV_CLASS)-1))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* check for a redefine */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(name && np->nvname[i]=='.' && np->nvname[i+1]=='_' && np->nvname[i+2]==0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin errormsg(SH_DICT,ERROR_exit(1),e_redef,sp->nodes[0]->nvname);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sp->nodes = (Namval_t**)realloc(sp->nodes,sizeof(Namval_t*)*sp->maxnodes);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif /* SHOPT_TYPEDEF */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * given a list of assignments, determine <name> is on the list
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin returns a pointer to the argnod on the list or NULL
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstruct argnod *nv_onlist(struct argnod *arg, const char *name)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(*arg->argval==0 && arg->argchn.ap && !(arg->argflag&~(ARG_APPEND|ARG_QUOTED|ARG_MESSAGE)))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(memcmp(cp,name,len)==0 && (cp[len]==0 || cp[len]=='='))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Perform parameter assignment for a linked list of parameters
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * <flags> contains attributes for the parameters
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzvoid nv_setlist(register struct argnod *arg,register int flags, Namval_t *typ)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shtp.nodes =(Namval_t**)malloc(shtp.maxnodes*sizeof(Namval_t*));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif /* SHOPT_TYPEDEF*/
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin cp = sh_mactrim(shp,arg->argval,(flags&NV_NOREF)?-3:-1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(*arg->argval==0 && arg->argchn.ap && !(arg->argflag&~(ARG_APPEND|ARG_QUOTED|ARG_MESSAGE)))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(!array && tp->tre.tretyp!=TLST && tp->com.comset && !tp->com.comarg && tp->com.comset->argval[0]==0 && tp->com.comset->argval[1]=='[')
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz array |= (tp->com.comset->argflag&ARG_MESSAGE)?NV_IARRAY:NV_ARRAY;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->fn_depth && (Namval_t*)tp->com.comnamp==SYSTYPESET)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(typ && !array && (nv_isnull(np) || nv_isarray(np)))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif /* SHOPT_TYPEDEF */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(array && (!(ap=nv_arrayptr(np)) || !ap->hdr.type))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(array && tp->tre.tretyp!=TLST && !tp->com.comset && !tp->com.comarg)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif /* SHOPT_TYPEDEF */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* check for array assignment */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(tp->tre.tretyp!=TLST && tp->com.comarg && !tp->com.comset && !((mp=tp->com.comnamp) && nv_isattr(mp,BLT_DCL)))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->mktype && shp->dot_depth==0 && np==((struct sh_type*)shp->mktype)->nodes[0])
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin errormsg(SH_DICT,ERROR_exit(1),"%s: not a known type name",argv[0]);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif /* SHOPT_TYPEDEF */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!nv_isarray(np) || ((ap=nv_arrayptr(np)) && (ap->nelem&ARRAY_MASK)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int n = -1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_debug(shp,trap,name,(char*)0,argv,(arg->argflag&ARG_APPEND)|ARG_ASSIGN);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif /* SHOPT_TYPEDEF */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(tp->tre.tretyp==TLST || !tp->com.comset || tp->com.comset->argval[0]!='[')
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(tp->tre.tretyp!=TLST && !tp->com.comnamp && tp->com.comset && tp->com.comset->argval[0]==0 && tp->com.comset->argchn.ap)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((arg->argflag&ARG_APPEND) && (!nv_isarray(np) || (nv_aindex(np)>=0)))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!(array&NV_IARRAY) && !(tp->com.comset->argflag&ARG_MESSAGE))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif /* SHOPT_TYPEDEF */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin errormsg(SH_DICT,ERROR_exit(1),e_badappend,nv_name(np));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!nv_isnull(np) && np->nvalue.cp!=Empty && !nv_isvtree(np))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(np->nvalue.cp && np->nvalue.cp!=Empty && !nv_type(np))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!sh_isoption(SH_BASH) && !(array&NV_IARRAY) && !nv_isarray(np))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfprintf(stkstd,"%s[%d]",prefix?nv_name(np):cp,sub);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(*shp->prefix=='_' && shp->prefix[1]=='.' && nv_isref(L_ARGNOD))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sfprintf(stkstd,"%s%s",nv_name(L_ARGNOD->nvalue.nrp->np),shp->prefix+1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!tp->lst.lstlef || !tp->lst.lstlef->tre.tretyp==TCOM || tp->lst.lstlef->com.comarg || tp->lst.lstlef->com.comset && tp->lst.lstlef->com.comset->argval[0]!='[')
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(!nv_isarray(np) && !typ && (tp->com.comarg || !tp->com.comset || tp->com.comset->argval[0]!='['))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif /* SHOPT_TYPEDEF */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_open(shtp.nodes[0]->nvname,shp->var_tree,NV_ASSIGN|NV_VARNAME|NV_NOADD|NV_NOFAIL);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif /* SHOPT_TYPEDEF */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * copy the subscript onto the stack
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(c= *sub++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * construct a new name from a prefix and base name on the stack
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char *copystack(const char *prefix, register const char *name, const char *sub)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(*name!='[' && *name!='.' && *name!='=' && *name!='+')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * grow this stack string <name> by <n> bytes and move from cp-1 to end
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * right by <n>. Returns beginning of string on the stack
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char *stack_extend(const char *cname, char *cp, int n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(m-->0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return((char*)name);
7c2fbfb345896881c631598ee3852ce9ce33fb07April ChinNamval_t *nv_create(const char *name, Dt_t *root, int flags, Namfun_t *dp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((rp=shp->st.real_fun) && !rp->sdict && (flags&NV_STATIC))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nv_isnull(np) && c!='.' && (np->nvfun=nv_cover(nq)))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(add && nv_isnull(np) && c=='.' && cp[1]!='.')
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else if((flags&NV_NOREF) && (c!='[' && *cp!='.'))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(nv_isref(np) && (c=='[' || c=='.' || !(flags&NV_ASSIGN)))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin errormsg(SH_DICT,ERROR_exit(1),e_noref,nv_name(np));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sub && c==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(c)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(c=='.' && (cp[1]==0 || cp[1]=='=' || cp[1]=='+'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * for backward compatibility
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * evaluate subscript for
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * possible side effects
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int n = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c=='[')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!mode && (flags&NV_ARRAY) && ((c=sp[1])=='*' || c=='@') && sp[2]==']')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* not implemented yet */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((c = *cp)=='.' || (c=='[' && nv_isarray(np)) || (n&ARRAY_FILL) || (flags&NV_ARRAY))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(m && !(n&NV_ADD))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n <= m)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int r = n-m;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(n==0 && (c==0 || (c=='[' && !nv_isarray(np))))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* subscript must be 0*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nv_isarray(np) && (c=='[' || c=='.' || (flags&NV_ARRAY)))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(ap && ap->table && (nq=nv_search(sub,ap->table,n)))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* ignore [0] */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((nq = (*fp->disc->createf)(np,cp+1,flags,fp)) == np)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(c=='[');
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * delete the node <np> from the dictionary <root> and clear from the cache
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * if <root> is NULL, only the cache is cleared
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * if flags does not contain NV_NOFREE, the node is freed
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinvoid nv_delete(Namval_t* np, Dt_t *root, int flags)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register int c;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin for(c=0,xp=nvcache.entries ; c < NVCACHE; xp= &nvcache.entries[++c])
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!(flags&NV_NOFREE) && ((flags&NV_FUNCTION) || !nv_subsaved(np)))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfprintf(sfstderr,"%s not deleted\n",nv_name(np));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Put <arg> into associative memory.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * If <flags> & NV_ARRAY then follow array to next subscript
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * If <flags> & NV_NOARRAY then subscript is not allowed
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * If <flags> & NV_NOSCOPE then use the current scope only
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * If <flags> & NV_ASSIGN then assignment is allowed
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * If <flags> & NV_IDENT then name must be an identifier
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * If <flags> & NV_VARNAME then name must be a valid variable name
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * If <flags> & NV_NOADD then node will not be added if not found
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * If <flags> & NV_NOREF then don't follow reference
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * If <flags> & NV_NOFAIL then don't generate an error message on failure
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * If <flags> & NV_STATIC then unset before an assignment
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz * If <flags> & NV_UNJUST then unset attributes before assignment
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * SH_INIT is only set while initializing the environment
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinNamval_t *nv_open(const char *name, Dt_t *root, int flags)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin name = cp = copystack(np?nv_name(np):0,name,(const char*)0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin name = cp = copystack(shp->prefix,name,(const char*)0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = *(unsigned char*)cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while((c= *(unsigned char*)cp++) && (c!='=') && (c!='/') &&
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin (c>=0x200 || !(c=sh_lexstates[ST_NORM][c]) || c==S_EPAT || c==S_COLON));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(c=='.')
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin for(c=0,xp=nvcache.entries ; c < NVCACHE; xp= &nvcache.entries[++c])
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(*name==*xp->name && (flags&(NV_ARRAY|NV_NOSCOPE))==xp->flags && memcmp(xp->name,name,xp->len)==0 && (name[xp->len]==0 || name[xp->len]=='=' || name[xp->len]=='+'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = ((flags&NV_NOSCOPE)?HASH_NOSCOPE:0)|((flags&NV_NOADD)?0:NV_ADD);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif /* SHOPT_TYPEDEF */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(nv_search((char*)np,shp->var_base,HASH_BUCKET))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(c)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c=='.')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(c=='[')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static int ja_size(char*, int, int);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static void ja_restore(void);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_MULTIBYTE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * put value <string> into name-value node <np>.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * If <np> is an array, then the element given by the
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * current index is assigned to.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * If <flags> contains NV_RDONLY, readonly attribute is ignored
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * If <flags> contains NV_INTEGER, string is a pointer to a number
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * If <flags> contains NV_NOFREE, previous value is freed, and <string>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * becomes value of node and <flags> becomes attributes
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvoid nv_putval(register Namval_t *np, const char *string, int flags)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_exit(1),e_readonly, nv_name(np));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* The following could cause the shell to fork if assignment
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * would cause a side effect
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(np->nvfun && np->nvfun->disc && !(flags&NV_NODISC) && !nv_isref(np))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* This function contains disc */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sp && ((flags&NV_EXPORT) || nv_isattr(np,NV_EXPORT)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* called from disc, assign the actual value */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(np->nvalue.cp && np->nvalue.cp!=sp && !nv_isattr(np,NV_NOFREE))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(np->nvalue.up && nv_isarray(np) && nv_arrayptr(np))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nv_isattr(np, NV_LONG) && sizeof(double)<sizeof(Sfdouble_t))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin d = (double)(*(float*)sp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin d = *(double*)sp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nv_isattr(np, NV_LONG) && sizeof(int32_t)<sizeof(Sflong_t))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* _lib_pathnative */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sh.strbuf,"%.*Lg",LDBL_DIG,*((Sfdouble_t*)sp));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfprintf(sh.strbuf,"%I*lu",sizeof(Sfulong_t),*((Sfulong_t*)sp));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfprintf(sh.strbuf,"%lu",(unsigned long)((flags&NV_SHORT)?*((uint16_t*)sp):*((uint32_t*)sp)));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfprintf(sh.strbuf,"%I*ld",sizeof(Sflong_t),*((Sflong_t*)sp));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfprintf(sh.strbuf,"%ld",(long)((flags&NV_SHORT)?*((int16_t*)sp):*((int32_t*)sp)));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(nv_isattr(np, NV_HOST|NV_INTEGER)==NV_HOST && sp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * return the host file name given the UNIX name
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* _lib_pathnative */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if((nv_isattr(np, NV_RJUST|NV_ZFILL|NV_LJUST)) && sp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((nv_isattr(np,NV_ZFILL)) && (nv_isattr(np,NV_LJUST)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size = ja_size((char*)sp,size,nv_isattr(np,NV_RJUST|NV_ZFILL));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_MULTIBYTE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* delay free in case <sp> points into free region */
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if(nv_isattr(np,NV_LJUST|NV_RJUST) && nv_isattr(np,NV_LJUST|NV_RJUST)!=(NV_LJUST|NV_RJUST))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dot = base64decode(sp,dot, (void**)0, cp+oldsize, size-oldsize,(void**)0);
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if(size==0 && nv_isattr(np,NV_HOST)!=NV_HOST &&nv_isattr(np,NV_LJUST|NV_RJUST|NV_ZFILL))
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner else if(nv_isattr(np,NV_LJUST|NV_RJUST)==NV_LJUST && dot>size)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner else if(nv_isattr(np, NV_LJUST|NV_RJUST)==NV_RJUST)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner else if(nv_isattr(np, NV_LJUST|NV_RJUST)==NV_LJUST)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* restore original string */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_MULTIBYTE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!was_local && ((flags&NV_EXPORT) || nv_isattr(np,NV_EXPORT)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Right-justify <str> so that it contains no more than
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * <size> characters. If <str> contains fewer than <size>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * characters, left-pad with <fill>. Trailing blanks
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * in <str> will be ignored.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * If the leftmost digit in <str> is not a digit, <fill>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * will default to a blank.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* ignore trailing blanks */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (sp = str, cp = str+n-size; sp <= str+size; *sp++ = *cp++);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (n == 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(n--)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * handle left and right justified fields for multi-byte chars
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * given physical size, return a logical size which reflects the
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * screen width of multi-byte characters
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Multi-width characters replaced by spaces if they cross the boundary
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * <type> is non-zero for right justified fields
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c, n=size;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* check for right justified fields that need truncating */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* left justified and character crosses field boundary */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* save boundary char and replace with spaces */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_MULTIBYTE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char *staknam(register Namval_t *np, char *value)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *p,*q;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin q = stakalloc(strlen(nv_name(np))+(value?strlen(value):0)+2);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *p++ = '=';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(q);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * put the name and attribute into value of attributes variable
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flag = nv_isattr(np,NV_RDONLY|NV_UTOL|NV_LTOU|NV_RJUST|NV_LJUST|NV_ZFILL|NV_INTEGER);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* export doubles as integers for ksh88 compatibility */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin stakputc(c+NV_INTEGER|(flag&~(NV_DOUBLE|NV_EXPNOTE)));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flag &= (NV_RDONLY|NV_UTOL|NV_LTOU|NV_RJUST|NV_LJUST|NV_ZFILL|NV_INTEGER);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* export doubles as integers for ksh88 compatibility */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin *ap->attval++ = ' '+ NV_INTEGER|(flag&~(NV_DOUBLE|NV_EXPNOTE));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nv_isattr(np,NV_RDONLY|NV_UTOL|NV_LTOU|NV_RJUST|NV_LJUST|NV_ZFILL|NV_INTEGER))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Generate the environment list for the child.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_scan(sh.var_tree, attstore,(void*)0,0,(NV_RDONLY|NV_UTOL|NV_LTOU|NV_RJUST|NV_LJUST|NV_ZFILL|NV_INTEGER));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* L_ARGNOD gets generated automatically as full path name of command */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin namec = nv_scan(shp->var_tree,nullscan,(void*)0,NV_EXPORT,NV_EXPORT);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin memcpy((void*)er,environ,shp->nenv*sizeof(char*));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_scan(shp->var_tree, pushnam,&data,NV_EXPORT, NV_EXPORT);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_scan(shp->var_tree, attstore,&data,0,(NV_RDONLY|NV_UTOL|NV_LTOU|NV_RJUST|NV_LJUST|NV_ZFILL|NV_INTEGER));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int scanfilter(Dt_t *dict, void *arg, void *data)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register struct adata *tp = (struct adata*)sp->scandata;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if(!is_abuiltin(np) && tp && tp->tp && nv_type(np)!=tp->tp)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif /*SHOPT_TYPEDEF */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sp->scanmask?(k&sp->scanmask)==sp->scanflags:(!sp->scanflags || (k&sp->scanflags)))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!np->nvalue.cp && !np->nvfun && !nv_isattr(np,~NV_DEFAULT))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Walk through the name-value pairs
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * if <mask> is non-zero, then only nodes with (nvflags&mask)==flags
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * are visited
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * If <mask> is zero, and <flags> non-zero, then nodes with one or
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * more of <flags> is visited
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * If <mask> and <flags> are zero, then all nodes are visted
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint nv_scan(Dt_t *root, void (*fn)(Namval_t*,void*), void *data,int mask, int flags)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * create a new environment scope
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinvoid sh_scope(Shell_t *shp, struct argnod *envlist, int fun)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz nv_setlist(envlist,NV_EXPORT|NV_NOSCOPE|NV_IDENT|NV_ASSIGN,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Remove freeable local space associated with the nvalue field
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * of nnod. This includes any strings representing the value(s) of the
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * node, as well as its dope vector, if it is an array.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Currently this is a dummy, but someday will be needed
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * for reference counting
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic void table_unset(Shell_t *shp, register Dt_t *root, int flags, Dt_t *oroot)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz nv_putval(nq, strdup(nv_getval(nq)), NV_RDONLY);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin while((nq=npnext) && memcmp(np->nvname,nq->nvname,len)==0 && nq->nvname[len]=='.')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Set the value of <np> to 0, and nullify any attributes
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * that <np> may have had. Free any freeable space occupied
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * by the value of <np>. If <np> denotes an array member, it
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * will retain its attributes.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * <flags> can contain NV_RDONLY to override the readonly attribute
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * being cleared.
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * <flags> can contain NV_EXPORT to override preserve nvenv
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_exit(1),e_readonly, nv_name(np));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register struct slnod *slp = (struct slnod*)(np->nvenv);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* free function definition */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *name=nv_name(np),*cp= strrchr(name,'.');
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin npv = nv_open(name,shp->var_tree,NV_NOARRAY|NV_VARNAME|NV_NOADD);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(rp->fname && shp->fpathdict && (rq = (struct Ufunction*)nv_search(rp->fname,shp->fpathdict,0)))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin while(rq = (struct Ufunction*)dtnext(shp->fpathdict,rq));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* This function contains disc */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* called from disc, assign the actual value */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(nv_isarray(np) && np->nvalue.cp!=Empty && np->nvfun)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!nv_isattr(np,NV_MINIMAL) || nv_isattr(np,NV_EXPORT))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!(flags&NV_EXPORT) || nv_isattr(np,NV_IMPORT|NV_EXPORT)==(NV_IMPORT|NV_EXPORT))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * return the node pointer in the highest level scope
7c2fbfb345896881c631598ee3852ce9ce33fb07April ChinNamval_t *sh_scoped(Shell_t *shp, register Namval_t *np)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * return space separated list of names of variables in given tree
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin out = sfnew((Sfio_t*)0,(char*)0,-1,-1,SF_WRITE|SF_STRING);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(np=(Namval_t*)dtfirst(root);np;np=(Namval_t*)dtnext(root,np))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!nv_isnull(np) || np->nvfun || nv_isattr(np,~NV_NOFREE))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void put_optimize(Namval_t* np,const char *val,int flags,Namfun_t *fp)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic Namfun_t *clone_optimize(Namval_t* np, Namval_t *mp, int flags, Namfun_t *fp)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic const Namdisc_t optimize_disc = {sizeof(struct optimize),put_optimize,0,0,0,0,clone_optimize};
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(fp->disc && (fp->disc->getnum || fp->disc->getval))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin op=(struct optimize*)calloc(1,sizeof(struct optimize));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(op=(struct optimize*)shp->optlist; op; op = opnext)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_OPTIMIZE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Return a pointer to a character string that denotes the value
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * of <np>. If <np> refers to an array, return a pointer to
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * the value associated with the current index.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * If the value of <np> is an integer, the string returned will
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * be overwritten by the next call to nv_getval.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * If <np> has no value, 0 is returned.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_OPTIMIZE */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((!np->nvfun || !np->nvfun->disc) && !nv_isattr(np,NV_ARRAY|NV_INTEGER|NV_FUNCT|NV_REF|NV_TABLE))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return("0");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * if NV_RAW flag is on, return pointer to binary data
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * otherwise, base64 encode the data and return this string
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(up->cp && nv_isattr(np,NV_BINARY) && !nv_isattr(np,NV_RAW))
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner base64encode(up->cp, size, (void**)0, cp=getbuf(insize), insize, (void**)&ep);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Sfdouble_t r=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_OPTIMIZE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(np->nvfun || nv_isattr(np,NV_LJUST|NV_RJUST|NV_ZFILL))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(r);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Give <np> the attributes <newatts,> and change its current
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * value to conform to <newatts>. The <size> of left and right
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * justified fields may be given.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvoid nv_newattr (register Namval_t *np, unsigned newatts, int size)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register unsigned int n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* check for restrictions */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh_isoption(SH_RESTRICTED) && ((sp=nv_name(np))==nv_name(PATHNOD) || sp==nv_name(SHELLNOD) || sp==nv_name(ENVNOD) || sp==nv_name(FPATHNOD)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_exit(1),e_restricted,nv_name(np));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* handle attributes that do not change data separately */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* record changes to the environment */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if((size==oldsize|| (n&NV_INTEGER)) && ((n^newatts)&~NV_NOCHANGE)==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* for an array, change all the elements */
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if(size==0 && (newatts&NV_HOST)!=NV_HOST && (newatts&(NV_LJUST|NV_RJUST|NV_ZFILL)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * This version of getenv uses the hash storage to access environment values
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin assume name!=0;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if(name[0] == 'P' && name[1] == 'A' && name[2] == 'T' && name[3] == 'H' && name[4] == 0 || name[0] == 'L' && ((name[1] == 'C' || name[1] == 'D') && name[2] == '_' || name[1] == 'A' && name[1] == 'N') || name[0] == 'V' && name[1] == 'P' && name[2] == 'A' && name[3] == 'T' && name[4] == 'H' && name[5] == 0 || name[0] == '_' && name[1] == 'R' && name[2] == 'L' && name[3] == 'D' || name[0] == '_' && name[1] == 'A' && name[2] == 'S' && name[3] == 'T' && name[4] == '_')
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner else if((np = nv_search(name,sh.var_tree,0)) && nv_isattr(np,NV_EXPORT))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner * Some dynamic linkers will make this file see the libc getenv(),
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner * so sh_getenv() is used for the astintercept() callback. Plain
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner * getenv() is provided for static links.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* _NEXT_SOURCE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * This version of putenv uses the hash storage to assign environment values
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np = nv_open(name,sh.var_tree,NV_EXPORT|NV_IDENT|NV_NOARRAY|NV_ASSIGN);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner * Override libast setenviron().
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np = nv_open(name,sh.var_tree,NV_EXPORT|NV_IDENT|NV_NOARRAY|NV_ASSIGN);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return("");
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner * Same linker dance as with getenv() above.
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * convert <str> to upper case
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * convert <str> to lower case
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register int c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * normalize <cp> and return pointer to subscript if any
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * if <eq> is specified, return pointer to first = not in a subscript
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(c= *cp++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c=='[')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(c=='.')
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin errormsg(SH_DICT,ERROR_exit(1),e_varname,nv_name(np));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!(nr = nv_open(cp, hp, flags|NV_ARRAY|NV_NOREF|NV_NOSCOPE|NV_NOADD|NV_NOFAIL)))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nr= nv_open(cp, hp, flags|NV_NOREF|((flags&NV_MOVE)?0:NV_NOFAIL));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfprintf(shp->strbuf,"%s[%d]%c",nv_name(np),index,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin /* create a virtual node */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(mp = nv_open(sfstruse(shp->strbuf),shp->var_tree,NV_VARNAME|NV_ADD|NV_ARRAY))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Create a reference node from <np> to $np in dictionary <hp>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvoid nv_setref(register Namval_t *np, Dt_t *hp, int flags)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((ep = lastdot(cp,0)) && nv_isattr(np,NV_MINIMAL))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin errormsg(SH_DICT,ERROR_exit(1),e_badref,nv_name(np));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!(nr = nq = nv_open(cp, hp, flags|NV_NOSCOPE|NV_NOADD|NV_NOFAIL)))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz hp = shp->last_root==shp->var_tree?shp->var_tree:shp->var_base;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(shp->last_root == shp->var_tree && root!=shp->var_tree)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz errormsg(SH_DICT,ERROR_exit(1),e_globalref,nv_name(np));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->namespace && nv_dict(shp->namespace)==hp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* bind to earlier scope, or add to global scope */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(hp=dtvnext(hp)) || (nq=nv_search((char*)np,hp,NV_ADD|HASH_BUCKET))==np)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(nq && !ep && (ap=nv_arrayptr(nq)) && !(ap->nelem&(ARRAY_UNDEF|ARRAY_SCAN)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* cause subscript evaluation and return result */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * get the scope corresponding to <index>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * whence uses the same values as lseeek()
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return((Shscope_t*)0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * make <scoped> the top scope and return previous scope
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->st.real_fun && dp==shp->st.real_fun->sdict)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * The inverse of creating a reference node
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * These following are for binary compatibility with the old hash library
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * They will be removed someday
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define extern __EXPORT__
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern void *hashlook(Dt_t *root, const char *name, int mode,int size)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!nv_isattr(np,NV_MINIMAL|NV_EXPORT) && np->nvenv)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Namval_t *nq= sh.last_table, *mp= (Namval_t*)np->nvenv;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfprintf(sh.strbuf,"%s[%s]",nv_name(mp),np->nvname);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfprintf(sh.strbuf,"%s.%s",nv_name(mp),np->nvname);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(table=sh.last_table) || *np->nvname=='.' || table==sh.namespace || np==table)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * returns the data context for a builtin