da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/***********************************************************************
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* This software is part of the ast package *
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner* Copyright (c) 1982-2010 AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* and is licensed under the *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Common Public License, Version 1.0 *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* by AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* A copy of the License is available at *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* http://www.opensource.org/licenses/cpl1.0.txt *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Information and Software Systems Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* AT&T Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Florham Park NJ *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* David Korn <dgk@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin***********************************************************************/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#pragma prototyped
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * AT&T Labs
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "defs.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "variables.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "builtins.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "path.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint nv_compare(Dt_t* dict, Void_t *sp, Void_t *dp, Dtdisc_t *disc)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sp==dp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(strcmp((char*)sp,(char*)dp));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * call the next getval function in the chain
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinchar *nv_getv(Namval_t *np, register Namfun_t *nfp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Namfun_t *fp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((fp = nfp) != NIL(Namfun_t*) && !nv_local)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp = nfp = nfp->next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_local=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(; fp; fp=fp->next)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!fp->disc || (!fp->disc->getnum && !fp->disc->getval))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!nv_isattr(np,NV_NODISC) || fp==(Namfun_t*)nv_arrayptr(np))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fp && fp->disc->getval)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = (*fp->disc->getval)(np,fp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(fp && fp->disc->getnum)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sh.strbuf,"%.*Lg",12,(*fp->disc->getnum)(np,fp));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = sfstruse(sh.strbuf);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_local=1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = nv_getval(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(cp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * call the next getnum function in the chain
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSfdouble_t nv_getn(Namval_t *np, register Namfun_t *nfp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Namfun_t *fp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Sfdouble_t d=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *str;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((fp = nfp) != NIL(Namfun_t*) && !nv_local)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp = nfp = nfp->next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_local=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(; fp; fp=fp->next)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!fp->disc || (!fp->disc->getnum && !fp->disc->getval))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!fp->disc->getnum && nv_isattr(np,NV_INTEGER))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!nv_isattr(np,NV_NODISC) || fp==(Namfun_t*)nv_arrayptr(np))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(fp && fp->disc && fp->disc->getnum)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin d = (*fp->disc->getnum)(np,fp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(nv_isattr(np,NV_INTEGER))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_local = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin d = nv_getnum(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(fp && fp->disc && fp->disc->getval)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin str = (*fp->disc->getval)(np,fp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin str = nv_getv(np,fp?fp:nfp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(str && *str)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(*str=='0')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin str++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin d = sh_arith(str);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(d);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * call the next assign function in the chain
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvoid nv_putv(Namval_t *np, const char *value, int flags, register Namfun_t *nfp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Namfun_t *fp, *fpnext;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((fp=nfp) != NIL(Namfun_t*) && !nv_local)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp = nfp = nfp->next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_local=0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(flags&NV_NODISC)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin fp = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(; fp; fp=fpnext)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fpnext = fp->next;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!fp->disc || !fp->disc->putval)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!value)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(fp->disc || !(fp->nofree&1))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_disc(np,fp,NV_POP);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!(fp->nofree&1))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free((void*)fp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!nv_isattr(np,NV_NODISC) || fp==(Namfun_t*)nv_arrayptr(np))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fp && fp->disc->putval)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*fp->disc->putval)(np,value, flags, fp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_local=1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(value)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_putval(np, value, flags);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin _nv_unset(np, flags&(NV_RDONLY|NV_EXPORT));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#define LOOKUPS 0
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define ASSIGN 1
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define APPEND 2
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define UNASSIGN 3
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#define LOOKUPN 4
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define BLOCKED ((Namval_t*)&nv_local)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstruct vardisc
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Namfun_t fun;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz Namval_t *disc[5];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin};
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstruct blocked
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct blocked *next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Namval_t *np;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int flags;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin void *sub;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int isub;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin};
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic struct blocked *blist;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define isblocked(bp,type) ((bp)->flags & (1<<(type)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define block(bp,type) ((bp)->flags |= (1<<(type)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define unblock(bp,type) ((bp)->flags &= ~(1<<(type)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * returns pointer to blocking structure
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic struct blocked *block_info(Namval_t *np, struct blocked *pp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register struct blocked *bp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin void *sub=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int isub=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nv_isarray(np) && (isub=nv_aindex(np)) < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sub = nv_associative(np,(const char*)0,NV_ACURRENT);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(bp=blist ; bp; bp=bp->next)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(bp->np==np && bp->sub==sub && bp->isub==isub)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(bp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(pp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp->np = np;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp->flags = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp->isub = isub;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp->sub = sub;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp->next = blist;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin blist = pp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(pp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void block_done(struct blocked *bp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin blist = bp = bp->next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(bp && (bp->isub>=0 || bp->sub))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_putsub(bp->np, bp->sub,(bp->isub<0?0:bp->isub)|ARRAY_SETSUB);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * free discipline if no more discipline functions
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void chktfree(register Namval_t *np, register struct vardisc *vp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(n=0; n< sizeof(vp->disc)/sizeof(*vp->disc); n++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(vp->disc[n])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n>=sizeof(vp->disc)/sizeof(*vp->disc))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* no disc left so pop */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Namfun_t *fp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((fp=nv_stack(np, NIL(Namfun_t*))) && !(fp->nofree&1))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free((void*)fp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * This function performs an assignment disc on the given node <np>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void assign(Namval_t *np,const char* val,int flags,Namfun_t *handle)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int type = (flags&NV_APPEND)?APPEND:ASSIGN;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register struct vardisc *vp = (struct vardisc*)handle;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Namval_t *nq = vp->disc[type];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct blocked block, *bp = block_info(np, &block);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Namval_t node;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin union Value *up = np->nvalue.up;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#if SHOPT_TYPEDEF
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Namval_t *tp, *nr;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(val && (tp=nv_type(np)) && (nr=nv_open(val,sh.var_tree,NV_VARNAME|NV_ARRAY|NV_NOADD|NV_NOFAIL)) && tp==nv_type(nr))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin char *sub = nv_getsub(np);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_unset(np);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(sub)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_putsub(np, sub, ARRAY_ADD);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_putval(np,nv_getval(nr), 0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_clone(nr,np,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin goto done;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif /* SHOPT_TYPEDEF */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(val || isblocked(bp,type))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!nq || isblocked(bp,type))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_putv(np,val,flags,handle);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto done;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin node = *SH_VALNOD;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!nv_isnull(SH_VALNOD))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_onattr(SH_VALNOD,NV_NOFREE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_unset(SH_VALNOD);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flags&NV_INTEGER)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_onattr(SH_VALNOD,(flags&(NV_LONG|NV_DOUBLE|NV_EXPNOTE|NV_HEXFLOAT|NV_SHORT)));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_putval(SH_VALNOD, val, (flags&NV_INTEGER)?flags:NV_NOFREE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nq = vp->disc[type=UNASSIGN];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nq && !isblocked(bp,type))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int bflag;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin block(bp,type);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (type==APPEND && (bflag= !isblocked(bp,LOOKUPS)))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz block(bp,LOOKUPS);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_fun(nq,np,(char**)0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unblock(bp,type);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(bflag)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz unblock(bp,LOOKUPS);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!vp->disc[type])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin chktfree(np,vp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(nv_isarray(np))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin np->nvalue.up = up;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(val)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfdouble_t d;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nv_isnull(SH_VALNOD))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(flags&NV_INTEGER)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin d = nv_getnum(SH_VALNOD);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = (char*)(&d);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flags |= (NV_LONG|NV_DOUBLE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flags &= ~NV_SHORT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = nv_getval(SH_VALNOD);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(cp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_putv(np,cp,flags|NV_RDONLY,handle);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_unset(SH_VALNOD);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* restore everything but the nvlink field */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memcpy(&SH_VALNOD->nvname, &node.nvname, sizeof(node)-sizeof(node.nvlink));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(sh_isstate(SH_INIT))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* don't free functions during reinitialization */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_putv(np,val,flags,handle);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(!nq || !isblocked(bp,type))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Dt_t *root = sh_subfuntree(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Namarr_t *ap;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin block(bp,type);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_putv(np, val, flags, handle);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(sh.subshell)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin goto done;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nv_isarray(np) && (ap=nv_arrayptr(np)) && ap->nelem>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto done;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(n=0; n < sizeof(vp->disc)/sizeof(*vp->disc); n++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((nq=vp->disc[n]) && !nv_isattr(nq,NV_NOFREE))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_unset(nq);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dtdelete(root,nq);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unblock(bp,type);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_disc(np,handle,NV_POP);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!(handle->nofree&1))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free(handle);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chindone:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(bp== &block)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin block_done(bp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * This function executes a lookup disc and then performs
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * the lookup on the given node <np>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzstatic char* lookup(Namval_t *np, int type, Sfdouble_t *dp,Namfun_t *handle)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register struct vardisc *vp = (struct vardisc*)handle;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct blocked block, *bp = block_info(np, &block);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz register Namval_t *nq = vp->disc[type];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *cp=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Namval_t node;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin union Value *up = np->nvalue.up;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(nq && !isblocked(bp,type))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin node = *SH_VALNOD;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!nv_isnull(SH_VALNOD))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_onattr(SH_VALNOD,NV_NOFREE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_unset(SH_VALNOD);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(type==LOOKUPN)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz nv_onattr(SH_VALNOD,NV_DOUBLE|NV_INTEGER);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz nv_setsize(SH_VALNOD,10);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz block(bp,type);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_fun(nq,np,(char**)0);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz unblock(bp,type);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(!vp->disc[type])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin chktfree(np,vp);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(type==LOOKUPN)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz cp = (char*)(SH_VALNOD->nvalue.cp);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz *dp = nv_getnum(SH_VALNOD);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else if(cp = nv_getval(SH_VALNOD))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz cp = stkcopy(stkstd,cp);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz _nv_unset(SH_VALNOD,NV_RDONLY);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!nv_isnull(&node))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* restore everything but the nvlink field */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memcpy(&SH_VALNOD->nvname, &node.nvname, sizeof(node)-sizeof(node.nvlink));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(nv_isarray(np))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin np->nvalue.up = up;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!cp)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(type==LOOKUPS)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz cp = nv_getv(np,handle);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz *dp = nv_getn(np,handle);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(bp== &block)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin block_done(bp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(cp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzstatic char* lookups(Namval_t *np, Namfun_t *handle)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz{
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz return(lookup(np,LOOKUPS,(Sfdouble_t*)0,handle));
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz}
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainzstatic Sfdouble_t lookupn(Namval_t *np, Namfun_t *handle)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz Sfdouble_t d;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz lookup(np,LOOKUPN, &d ,handle);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz return(d);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz}
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Set disc on given <event> to <action>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * If action==np, the current disc is returned
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * A null return value indicates that no <event> is known for <np>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * If <event> is NULL, then return the event name after <action>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * If <event> is NULL, and <action> is NULL, return the first event
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinchar *nv_setdisc(register Namval_t* np,register const char *event,Namval_t *action,register Namfun_t *fp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register struct vardisc *vp = (struct vardisc*)np->nvfun;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int type;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *empty = "";
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner while(vp)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner {
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if(vp->fun.disc && (vp->fun.disc->setdisc || vp->fun.disc->putval == assign))
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner break;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner vp = (struct vardisc*)vp->fun.next;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(vp && !vp->fun.disc)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin vp = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(np == (Namval_t*)fp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register const char *name;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int getname=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* top level call, check for get/set */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!event)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!action)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return((char*)nv_discnames[0]);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin getname=1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin event = (char*)action;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin for(type=0; name=nv_discnames[type]; type++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(strcmp(event,name)==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(getname)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin event = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(name && !(name = nv_discnames[++type]))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin action = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!name)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin for(fp=(Namfun_t*)vp; fp; fp=fp->next)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(fp->disc && fp->disc->setdisc)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return((*fp->disc->setdisc)(np,event,action,fp));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(getname)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return((char*)name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!fp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(NIL(char*));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(np != (Namval_t*)fp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* not the top level */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(fp = fp->next)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(fp->disc && fp->disc->setdisc)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return((*fp->disc->setdisc)(np,event,action,fp));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(NIL(char*));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* Handle GET/SET/APPEND/UNSET disc */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(vp && vp->fun.disc->putval!=assign)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin vp = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!vp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz Namdisc_t *dp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(action==np)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return((char*)action);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(!(vp = newof(NIL(struct vardisc*),struct vardisc,1,sizeof(Namdisc_t))))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz dp = (Namdisc_t*)(vp+1);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz vp->fun.disc = dp;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz memset(dp,0,sizeof(*dp));
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz dp->dsize = sizeof(struct vardisc);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz dp->putval = assign;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if(nv_isarray(np) && !nv_arrayptr(np))
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner nv_putsub(np,(char*)0, 1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_stack(np, (Namfun_t*)vp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(action==np)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin action = vp->disc[type];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin empty = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(action)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz Namdisc_t *dp = (Namdisc_t*)vp->fun.disc;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(type==LOOKUPS)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz dp->getval = lookups;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else if(type==LOOKUPN)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz dp->getnum = lookupn;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin vp->disc[type] = action;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct blocked *bp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin action = vp->disc[type];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin vp->disc[type] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(bp=block_info(np,(struct blocked*)0)) || !isblocked(bp,UNASSIGN))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin chktfree(np,vp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(action?(char*)action:empty);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Set disc on given <event> to <action>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * If action==np, the current disc is returned
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * A null return value indicates that no <event> is known for <np>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * If <event> is NULL, then return the event name after <action>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * If <event> is NULL, and <action> is NULL, return the first event
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char *setdisc(register Namval_t* np,register const char *event,Namval_t *action,register Namfun_t *fp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Nambfun_t *vp = (Nambfun_t*)fp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int type,getname=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register const char *name;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin const char **discnames = vp->bnames;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* top level call, check for discipline match */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!event)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!action)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return((char*)discnames[0]);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin getname=1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin event = (char*)action;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(type=0; name=discnames[type]; type++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(strcmp(event,name)==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(getname)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin event = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(name && !(name = discnames[++type]))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin action = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!name)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(nv_setdisc(np,event,action,fp));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(getname)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return((char*)name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* Handle the disciplines */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(action==np)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin action = vp->bltins[type];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(action)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin vp->bltins[type] = action;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin action = vp->bltins[type];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin vp->bltins[type] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(action?(char*)action:"");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void putdisc(Namval_t* np, const char* val, int flag, Namfun_t* fp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_putv(np,val,flag,fp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!val && !(flag&NV_NOFREE))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Nambfun_t *vp = (Nambfun_t*)fp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int i;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(i=0; vp->bnames[i]; i++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Namval_t *mp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((mp=vp->bltins[i]) && !nv_isattr(mp,NV_NOFREE))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(is_abuiltin(mp))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mp->nvfun && !nv_isattr(mp,NV_NOFREE))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free((void*)mp->nvfun);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dtdelete(sh.bltin_tree,mp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free((void*)mp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_disc(np,fp,NV_POP);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!(fp->nofree&1))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free((void*)fp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic const Namdisc_t Nv_bdisc = { 0, putdisc, 0, 0, setdisc };
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April ChinNamfun_t *nv_clone_disc(register Namfun_t *fp, int flags)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Namfun_t *nfp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int size;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(!fp->disc && !fp->next && (fp->nofree&1))
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz return(fp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(size=fp->dsize) && (!fp->disc || !(size=fp->disc->dsize)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size = sizeof(Namfun_t);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(nfp=newof(NIL(Namfun_t*),Namfun_t,1,size-sizeof(Namfun_t))))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memcpy(nfp,fp,size);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz nfp->nofree &= ~1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nfp->nofree |= (flags&NV_RDONLY)?1:0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(nfp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint nv_adddisc(Namval_t *np, const char **names, Namval_t **funs)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Nambfun_t *vp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int n=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register const char **av=names;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(av)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(*av++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(vp = newof(NIL(Nambfun_t*),Nambfun_t,1,n*sizeof(Namval_t*))))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin vp->fun.dsize = sizeof(Nambfun_t)+n*sizeof(Namval_t*);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin vp->fun.nofree |= 2;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin vp->num = n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(funs)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memcpy((void*)vp->bltins, (void*)funs,n*sizeof(Namval_t*));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else while(n>=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin vp->bltins[n--] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin vp->fun.disc = &Nv_bdisc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin vp->bnames = names;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_stack(np,&vp->fun);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * push, pop, clne, or reorder disciplines onto node <np>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * mode can be one of
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * NV_FIRST: Move or push <fp> to top of the stack or delete top
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * NV_LAST: Move or push <fp> to bottom of stack or delete last
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * NV_POP: Delete <fp> from top of the stack
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * NV_CLONE: Replace fp with a copy created my malloc() and return it
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinNamfun_t *nv_disc(register Namval_t *np, register Namfun_t* fp, int mode)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Namfun_t *lp, **lpp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nv_isref(np))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode==NV_CLONE && !fp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin fp->subshell = sh.subshell;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((lp=np->nvfun)==fp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode==NV_CLONE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin lp = nv_clone_disc(fp,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(np->nvfun=lp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode==NV_FIRST || mode==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(fp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np->nvfun = lp->next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode==NV_POP)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(fp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(mode==NV_LAST && (lp->next==0 || lp->next->disc==0))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(fp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* see if <fp> is on the list already */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin lpp = &np->nvfun;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(lp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin while(lp->next && lp->next->disc)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(lp->next==fp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(mode==NV_LAST && fp->next==0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(fp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode==NV_CLONE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin fp = nv_clone_disc(fp,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin lp->next = fp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(fp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin lp->next = fp->next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode==NV_POP)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(fp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode!=NV_LAST)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin lp = lp->next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode==NV_LAST)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin lpp = &lp->next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode==NV_POP)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* push */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_offattr(np,NV_NODISC);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode==NV_LAST)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->next = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((fp->nofree&1) && *lpp)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin fp = nv_clone_disc(fp,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fp->next = *lpp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *lpp = fp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode==NV_FIRST)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(np->nvfun);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(mode==NV_LAST)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(lp=np->nvfun; lp; fp=lp,lp=lp->next);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(fp = np->nvfun)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np->nvfun = fp->next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(fp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * returns discipline pointer if discipline with specified functions
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * is on the discipline stack
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinNamfun_t *nv_hasdisc(Namval_t *np, const Namdisc_t *dp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Namfun_t *fp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(fp=np->nvfun; fp; fp = fp->next)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fp->disc== dp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(fp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstruct notify
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Namfun_t hdr;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char **ptr;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin};
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void put_notify(Namval_t* np,const char *val,int flags,Namfun_t *fp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct notify *pp = (struct notify*)fp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_putv(np,val,flags,fp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_stack(np,fp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_stack(np,(Namfun_t*)0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *pp->ptr = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!(fp->nofree&1))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free((void*)fp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic const Namdisc_t notify_disc = { 0, put_notify };
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint nv_unsetnotify(Namval_t *np, char **addr)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Namfun_t *fp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(fp=np->nvfun;fp;fp=fp->next)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fp->disc->putval==put_notify && ((struct notify*)fp)->ptr==addr)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_stack(np,fp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_stack(np,(Namfun_t*)0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!(fp->nofree&1))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free((void*)fp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint nv_setnotify(Namval_t *np, char **addr)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct notify *pp = newof(0,struct notify, 1,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!pp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp->ptr = addr;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp->hdr.disc = &notify_disc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_stack(np,&pp->hdr);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void *newnode(const char *name)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Namval_t *np = newof(0,Namval_t,1,s=strlen(name)+1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(np)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np->nvname = (char*)np+sizeof(Namval_t);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memcpy(np->nvname,name,s);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return((void*)np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_NAMESPACE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * clone a numeric value
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void *num_clone(register Namval_t *np, void *val)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int size;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin void *nval;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!val)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(nv_isattr(np,NV_DOUBLE)==NV_DOUBLE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nv_isattr(np,NV_LONG))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size = sizeof(Sfdouble_t);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(nv_isattr(np,NV_SHORT))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size = sizeof(float);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size = sizeof(double);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nv_isattr(np,NV_LONG))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size = sizeof(Sflong_t);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(nv_isattr(np,NV_SHORT))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(nv_isattr(np,NV_INT16P)==NV_INT16P)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin size = sizeof(short);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return((void*)np->nvalue.ip);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size = sizeof(int32_t);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(nval = malloc(size)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memcpy(nval,val,size);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(nval);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinvoid clone_all_disc( Namval_t *np, Namval_t *mp, int flags)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register Namfun_t *fp, **mfp = &mp->nvfun, *nfp, *fpnext;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin for(fp=np->nvfun; fp;fp=fpnext)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin fpnext = fp->next;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!fpnext && (flags&NV_COMVAR) && fp->disc && fp->disc->namef)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((fp->nofree&2) && (flags&NV_NODISC))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nfp = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fp->disc && fp->disc->clonef)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nfp = (*fp->disc->clonef)(np,mp,flags,fp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(flags&NV_MOVE)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nfp = fp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nfp = nv_clone_disc(fp,flags);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!nfp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nfp->next = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *mfp = nfp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mfp = &nfp->next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * clone <mp> from <np> flags can be one of the following
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * NV_APPEND - append <np> onto <mp>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * NV_MOVE - move <np> to <mp>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * NV_NOFREE - mark the new node as nofree
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * NV_NODISC - discplines with funs non-zero will not be copied
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * NV_COMVAR - cloning a compound variable
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint nv_clone(Namval_t *np, Namval_t *mp, int flags)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Namfun_t *fp, *fpnext;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin const char *val = mp->nvalue.cp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin unsigned short flag = mp->nvflag;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin unsigned short size = mp->nvsize;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin for(fp=mp->nvfun; fp; fp=fpnext)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin fpnext = fp->next;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!fpnext && (flags&NV_COMVAR) && fp->disc && fp->disc->namef)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin break;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!(fp->nofree&1))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin free((void*)fp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin mp->nvfun = fp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fp=np->nvfun)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(nv_isattr(mp,NV_EXPORT|NV_MINIMAL) == (NV_EXPORT|NV_MINIMAL))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin mp->nvenv = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_offattr(mp,NV_MINIMAL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!(flags&NV_COMVAR) && !nv_isattr(np,NV_MINIMAL) && np->nvenv && !(nv_isattr(mp,NV_MINIMAL)))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin mp->nvenv = np->nvenv;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin mp->nvflag &= NV_MINIMAL;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin mp->nvflag |= np->nvflag&~(NV_ARRAY|NV_MINIMAL|NV_NOFREE);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin flag = mp->nvflag;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin clone_all_disc(np, mp, flags);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flags&NV_APPEND)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(mp->nvsize == size)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_setsize(mp,nv_size(np));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(mp->nvflag == flag)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin mp->nvflag = (np->nvflag&~(NV_MINIMAL))|(mp->nvflag&NV_MINIMAL);
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if(nv_isattr(np,NV_EXPORT))
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner mp->nvflag |= (np->nvflag&NV_MINIMAL);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(mp->nvalue.cp==val && !nv_isattr(np,NV_INTEGER))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(np->nvalue.cp && np->nvalue.cp!=Empty && (flags&NV_COMVAR) && !(flags&NV_MOVE))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(size)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin mp->nvalue.cp = (char*)memdup(np->nvalue.cp,size);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin mp->nvalue.cp = strdup(np->nvalue.cp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_offattr(mp,NV_NOFREE);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(!(mp->nvalue.cp = np->nvalue.cp))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_offattr(mp,NV_NOFREE);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flags&NV_MOVE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(nv_isattr(np,NV_INTEGER))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin mp->nvalue.ip = np->nvalue.ip;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np->nvfun = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np->nvalue.cp = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!nv_isattr(np,NV_MINIMAL) || nv_isattr(mp,NV_EXPORT))
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner {
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner mp->nvenv = np->nvenv;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np->nvenv = 0;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner np->nvflag = 0;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner }
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner else
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner np->nvflag &= NV_MINIMAL;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_setsize(np,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(nv_isattr(np,NV_INTEGER) && mp->nvalue.ip!=np->nvalue.ip)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->nvalue.ip = (int*)num_clone(np,(void*)np->nvalue.ip);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz nv_offattr(mp,NV_NOFREE);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(flags&NV_NOFREE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_onattr(np,NV_NOFREE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * The following discipline is for copy-on-write semantics
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char* clone_getv(Namval_t *np, Namfun_t *handle)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(np->nvalue.np?nv_getval(np->nvalue.np):0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic Sfdouble_t clone_getn(Namval_t *np, Namfun_t *handle)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(np->nvalue.np?nv_getnum(np->nvalue.np):0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void clone_putv(Namval_t *np,const char* val,int flags,Namfun_t *handle)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Namfun_t *dp = nv_stack(np,(Namfun_t*)0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Namval_t *mp = np->nvalue.np;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!sh.subshell)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free((void*)dp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(val)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_clone(mp,np,NV_NOFREE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np->nvalue.cp = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_putval(np,val,flags);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic const Namdisc_t clone_disc =
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin 0,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin clone_putv,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin clone_getv,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin clone_getn
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin};
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinNamval_t *nv_mkclone(Namval_t *mp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Namval_t *np;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Namfun_t *dp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np = newof(0,Namval_t,1,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np->nvflag = mp->nvflag;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np->nvsize = mp->nvsize;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np->nvname = mp->nvname;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np->nvalue.np = mp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np->nvflag = mp->nvflag;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp = newof(0,Namfun_t,1,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp->disc = &clone_disc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_stack(np,dp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dtinsert(nv_dict(sh.namespace),np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_NAMESPACE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinNamval_t *nv_search(const char *name, Dt_t *root, int mode)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Namval_t *np;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Dt_t *dp = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode&HASH_NOSCOPE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dp = dtview(root,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode&HASH_BUCKET)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Namval_t *mp = (void*)name;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(np = dtsearch(root,mp)) && (mode&NV_ADD))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin name = nv_name(mp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(*name=='.' && root==sh.var_tree && !dp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin root = sh.var_base;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np = dtmatch(root,(void*)name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!np && (mode&NV_ADD))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh.namespace && !(mode&HASH_NOSCOPE) && root==sh.var_tree)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin root = nv_dict(sh.namespace);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(!dp && !(mode&HASH_NOSCOPE))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Dt_t *next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(next=dtvnext(root))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin root = next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np = (Namval_t*)dtinsert(root,newnode(name));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(dp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dtview(root,dp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * finds function or builtin for given name and the discipline variable
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * if var!=0 the variable pointer is returned and the built-in name
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * is put onto the stack at the current offset.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * otherwise, a pointer to the builtin (variable or type) is returned
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * and var contains the poiner to the variable
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * if last==0 and first component of name is a reference, nv_bfsearch()
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin will return 0.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinNamval_t *nv_bfsearch(const char *name, Dt_t *root, Namval_t **var, char **last)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int c,offset = staktell();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *sp, *cp=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Namval_t *np, *nq;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin char *dname=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(var)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *var = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* check for . in the name before = */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(sp=(char*)name+1; *sp; sp++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*sp=='=')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(*sp=='[')
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(sp[-1]!='.')
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin dname = sp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin while(*sp=='[')
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sp = nv_endsubscript((Namval_t*)0,(char*)sp,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(sp[-1]!=']')
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(*sp==0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin break;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(*sp!='.')
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(dname)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin cp = dname;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin dname = sp+1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(*sp=='.')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = sp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!cp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(var?nv_search(name,root,0):0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputs(name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakputc(0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!dname)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin dname = cp+1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = stakptr(offset) + (cp-name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(last)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *last = cp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin c = *cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *cp = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nq=nv_open(stakptr(offset),0,NV_VARNAME|NV_ARRAY|NV_NOASSIGN|NV_NOADD|NV_NOFAIL);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin *cp = c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!nq)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto done;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!var)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np = nq;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto done;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *var = nq;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(c=='[')
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_endsubscript(nq, cp,NV_NOADD);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return((Namval_t*)nv_setdisc(nq,dname,nq,(Namfun_t*)nq));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chindone:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin stakseek(offset);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * add or replace built-in version of command corresponding to <path>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * The <bltin> argument is a pointer to the built-in
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * if <extra>==1, the built-in will be deleted
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Special builtins cannot be added or deleted return failure
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * The return value for adding builtins is a pointer to the node or NULL on
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * failure. For delete NULL means success and the node that cannot be
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * deleted is returned on failure.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinNamval_t *sh_addbuiltin(const char *path, int (*bltin)(int, char*[],void*),void *extra)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register const char *name = path_basename(path);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin char *cp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register Namval_t *np, *nq=0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int offset=staktell();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(name==path && (nq=nv_bfsearch(name,sh.bltin_tree,(Namval_t**)0,&cp)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin path = name = stakptr(offset);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(np = nv_search(path,sh.bltin_tree,0))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* exists without a path */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(extra == (void*)1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(np->nvfun && !nv_isattr(np,NV_NOFREE))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free((void*)np->nvfun);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dtdelete(sh.bltin_tree,np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!bltin)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else for(np=(Namval_t*)dtfirst(sh.bltin_tree);np;np=(Namval_t*)dtnext(sh.bltin_tree,np))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(strcmp(name,path_basename(nv_name(np))))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* exists probably with different path so delete it */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(strcmp(path,nv_name(np)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nv_isattr(np,BLT_SPC))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!bltin)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin bltin = np->nvalue.bfp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(np->nvenv)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dtdelete(sh.bltin_tree,np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(extra == (void*)1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!np && !(np = nv_search(path,sh.bltin_tree,bltin?NV_ADD:0)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nv_isattr(np,BLT_SPC))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(extra)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin np->nvfun = (Namfun_t*)extra;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(np);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np->nvenv = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np->nvfun = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(bltin)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np->nvalue.bfp = bltin;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_onattr(np,NV_BLTIN|NV_NOFREE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np->nvfun = (Namfun_t*)extra;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nq)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp=nv_setdisc(nq,cp+1,np,(Namfun_t*)nq);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_close(nq);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!cp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_exit(1),e_baddisc,name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(extra == (void*)1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#undef nv_stack
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinextern Namfun_t *nv_stack(register Namval_t *np, register Namfun_t* fp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(nv_disc(np,fp,0));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstruct table
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Namfun_t fun;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Namval_t *parent;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Shell_t *shp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Dt_t *dict;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin};
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic Namval_t *next_table(register Namval_t* np, Dt_t *root,Namfun_t *fp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct table *tp = (struct table *)fp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(root)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return((Namval_t*)dtnext(root,np));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return((Namval_t*)dtfirst(tp->dict));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic Namval_t *create_table(Namval_t *np,const char *name,int flags,Namfun_t *fp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct table *tp = (struct table *)fp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tp->shp->last_table = np;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(nv_create(name, tp->dict, flags, fp));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic Namfun_t *clone_table(Namval_t* np, Namval_t *mp, int flags, Namfun_t *fp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct table *tp = (struct table*)fp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin struct table *ntp = (struct table*)nv_clone_disc(fp,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Dt_t *oroot=tp->dict,*nroot=dtopen(&_Nvdisc,Dtoset);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!nroot)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memcpy((void*)ntp,(void*)fp,sizeof(struct table));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ntp->dict = nroot;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ntp->parent = nv_lastdict();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(np=(Namval_t*)dtfirst(oroot);np;np=(Namval_t*)dtnext(oroot,np))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp = (Namval_t*)dtinsert(nroot,newnode(np->nvname));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_clone(np,mp,flags);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(&ntp->fun);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void put_table(register Namval_t* np, const char* val, int flags, Namfun_t* fp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Dt_t *root = ((struct table*)fp)->dict;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Namval_t *nq, *mp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Namarr_t *ap;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_putv(np,val,flags,fp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(val)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nv_isarray(np) && (ap=nv_arrayptr(np)) && array_elem(ap))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(mp=(Namval_t*)dtfirst(root);mp;mp=nq)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin _nv_unset(mp,flags);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nq = (Namval_t*)dtnext(root,mp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dtdelete(root,mp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free((void*)mp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dtclose(root);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!(fp->nofree&1))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free((void*)fp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * return space separated list of names of variables in given tree
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic char *get_table(Namval_t *np, Namfun_t *fp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Dt_t *root = ((struct table*)fp)->dict;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static Sfio_t *out;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int first=1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Dt_t *base = dtview(root,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(out)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfseek(out,(Sfoff_t)0,SEEK_SET);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
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 {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!nv_isnull(np) || np->nvfun || nv_isattr(np,~NV_NOFREE))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!first)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputc(out,' ');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin first = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputr(out,np->nvname,-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputc(out,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(base)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dtview(root,base);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return((char*)out->_data);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic const Namdisc_t table_disc =
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sizeof(struct table),
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin put_table,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin get_table,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin 0,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin 0,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin create_table,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin clone_table,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin 0,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin next_table,
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin};
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April ChinNamval_t *nv_parent(Namval_t *np)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin struct table *tp = (struct table *)nv_hasdisc(np,&table_disc);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(tp)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(tp->parent);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin}
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinDt_t *nv_dict(Namval_t* np)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct table *tp = (struct table*)nv_hasdisc(np,&table_disc);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(tp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(tp->dict);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np = sh.last_table;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(np)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(tp = (struct table*)nv_hasdisc(np,&table_disc))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(tp->dict);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if 0
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin np = nv_create(np,(const char*)0, NV_FIRST, (Namfun_t*)0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(sh.var_tree);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * create a mountable name-value pair tree
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinNamval_t *nv_mount(Namval_t *np, const char *name, Dt_t *dict)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Namval_t *mp, *pp=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct table *tp = newof((struct table*)0, struct table,1,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(name)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nv_istable(np))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp = np;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp = nv_lastdict();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(tp = newof((struct table*)0, struct table,1,0)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(name)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Namfun_t *fp = pp->nvfun;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp = (*fp->disc->createf)(pp,name,0,fp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp = np;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!nv_isnull(mp))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_unset(mp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tp->shp = sh_getinterp();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tp->dict = dict;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tp->parent = pp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin tp->fun.disc = &table_disc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_onattr(mp,NV_TABLE);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin nv_disc(mp, &tp->fun, NV_FIRST);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(mp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinconst Namdisc_t *nv_discfun(int which)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch(which)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case NV_DCADD:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(&Nv_bdisc);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case NV_DCRESTRICT:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(&RESTRICTED_disc);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulknerint nv_hasget(Namval_t *np)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner{
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner register Namfun_t *fp;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner for(fp=np->nvfun; fp; fp=fp->next)
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner {
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if(!fp->disc || (!fp->disc->getnum && !fp->disc->getval))
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner continue;
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner return(1);
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner }
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner return(0);
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner}