1*b30d1939SAndy Fiddaman /***********************************************************************
2*b30d1939SAndy Fiddaman * *
3*b30d1939SAndy Fiddaman * This software is part of the ast package *
4*b30d1939SAndy Fiddaman * Copyright (c) 1982-2012 AT&T Intellectual Property *
5*b30d1939SAndy Fiddaman * and is licensed under the *
6*b30d1939SAndy Fiddaman * Eclipse Public License, Version 1.0 *
7*b30d1939SAndy Fiddaman * by AT&T Intellectual Property *
8*b30d1939SAndy Fiddaman * *
9*b30d1939SAndy Fiddaman * A copy of the License is available at *
10*b30d1939SAndy Fiddaman * http://www.eclipse.org/org/documents/epl-v10.html *
11*b30d1939SAndy Fiddaman * (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12*b30d1939SAndy Fiddaman * *
13*b30d1939SAndy Fiddaman * Information and Software Systems Research *
14*b30d1939SAndy Fiddaman * AT&T Research *
15*b30d1939SAndy Fiddaman * Florham Park NJ *
16*b30d1939SAndy Fiddaman * *
17*b30d1939SAndy Fiddaman * David Korn <dgk@research.att.com> *
18*b30d1939SAndy Fiddaman * *
19*b30d1939SAndy Fiddaman ***********************************************************************/
20*b30d1939SAndy Fiddaman #pragma prototyped
21*b30d1939SAndy Fiddaman /*
22*b30d1939SAndy Fiddaman * AT&T Labs
23*b30d1939SAndy Fiddaman *
24*b30d1939SAndy Fiddaman */
25*b30d1939SAndy Fiddaman /*
26*b30d1939SAndy Fiddaman * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
27*b30d1939SAndy Fiddaman */
28*b30d1939SAndy Fiddaman
29*b30d1939SAndy Fiddaman #define putenv ___putenv
30*b30d1939SAndy Fiddaman
31*b30d1939SAndy Fiddaman #include "defs.h"
32*b30d1939SAndy Fiddaman #include "variables.h"
33*b30d1939SAndy Fiddaman #include "path.h"
34*b30d1939SAndy Fiddaman #include "lexstates.h"
35*b30d1939SAndy Fiddaman #include "timeout.h"
36*b30d1939SAndy Fiddaman #include "FEATURE/externs"
37*b30d1939SAndy Fiddaman #include "streval.h"
38*b30d1939SAndy Fiddaman
39*b30d1939SAndy Fiddaman #define NVCACHE 8 /* must be a power of 2 */
40*b30d1939SAndy Fiddaman #define Empty ((char*)(e_sptbnl+3))
41*b30d1939SAndy Fiddaman static char *savesub = 0;
42*b30d1939SAndy Fiddaman static char Null[1];
43*b30d1939SAndy Fiddaman static Namval_t NullNode;
44*b30d1939SAndy Fiddaman static Dt_t *Refdict;
45*b30d1939SAndy Fiddaman static Dtdisc_t _Refdisc =
46*b30d1939SAndy Fiddaman {
47*b30d1939SAndy Fiddaman offsetof(struct Namref,np),sizeof(struct Namval_t*),sizeof(struct Namref)
48*b30d1939SAndy Fiddaman };
49*b30d1939SAndy Fiddaman
50*b30d1939SAndy Fiddaman #if !_lib_pathnative && _lib_uwin_path
51*b30d1939SAndy Fiddaman
52*b30d1939SAndy Fiddaman #define _lib_pathnative 1
53*b30d1939SAndy Fiddaman
54*b30d1939SAndy Fiddaman extern int uwin_path(const char*, char*, int);
55*b30d1939SAndy Fiddaman
56*b30d1939SAndy Fiddaman size_t
pathnative(const char * path,char * buf,size_t siz)57*b30d1939SAndy Fiddaman pathnative(const char* path, char* buf, size_t siz)
58*b30d1939SAndy Fiddaman {
59*b30d1939SAndy Fiddaman return uwin_path(path, buf, siz);
60*b30d1939SAndy Fiddaman }
61*b30d1939SAndy Fiddaman
62*b30d1939SAndy Fiddaman #endif /* _lib_pathnative */
63*b30d1939SAndy Fiddaman
64*b30d1939SAndy Fiddaman static void attstore(Namval_t*,void*);
65*b30d1939SAndy Fiddaman #ifndef _ENV_H
66*b30d1939SAndy Fiddaman static void pushnam(Namval_t*,void*);
67*b30d1939SAndy Fiddaman static char *staknam(Namval_t*, char*);
68*b30d1939SAndy Fiddaman #endif
69*b30d1939SAndy Fiddaman static void rightjust(char*, int, int);
70*b30d1939SAndy Fiddaman static char *lastdot(char*, int);
71*b30d1939SAndy Fiddaman
72*b30d1939SAndy Fiddaman struct adata
73*b30d1939SAndy Fiddaman {
74*b30d1939SAndy Fiddaman Shell_t *sh;
75*b30d1939SAndy Fiddaman Namval_t *tp;
76*b30d1939SAndy Fiddaman char *mapname;
77*b30d1939SAndy Fiddaman char **argnam;
78*b30d1939SAndy Fiddaman int attsize;
79*b30d1939SAndy Fiddaman char *attval;
80*b30d1939SAndy Fiddaman };
81*b30d1939SAndy Fiddaman
82*b30d1939SAndy Fiddaman #if SHOPT_TYPEDEF
83*b30d1939SAndy Fiddaman struct sh_type
84*b30d1939SAndy Fiddaman {
85*b30d1939SAndy Fiddaman void *previous;
86*b30d1939SAndy Fiddaman Namval_t **nodes;
87*b30d1939SAndy Fiddaman Namval_t *rp;
88*b30d1939SAndy Fiddaman short numnodes;
89*b30d1939SAndy Fiddaman short maxnodes;
90*b30d1939SAndy Fiddaman };
91*b30d1939SAndy Fiddaman #endif /*SHOPT_TYPEDEF */
92*b30d1939SAndy Fiddaman
93*b30d1939SAndy Fiddaman #if NVCACHE
94*b30d1939SAndy Fiddaman struct Namcache
95*b30d1939SAndy Fiddaman {
96*b30d1939SAndy Fiddaman struct Cache_entry
97*b30d1939SAndy Fiddaman {
98*b30d1939SAndy Fiddaman Dt_t *root;
99*b30d1939SAndy Fiddaman Dt_t *last_root;
100*b30d1939SAndy Fiddaman char *name;
101*b30d1939SAndy Fiddaman Namval_t *np;
102*b30d1939SAndy Fiddaman Namval_t *last_table;
103*b30d1939SAndy Fiddaman Namval_t *namespace;
104*b30d1939SAndy Fiddaman int flags;
105*b30d1939SAndy Fiddaman short size;
106*b30d1939SAndy Fiddaman short len;
107*b30d1939SAndy Fiddaman } entries[NVCACHE];
108*b30d1939SAndy Fiddaman short index;
109*b30d1939SAndy Fiddaman short ok;
110*b30d1939SAndy Fiddaman };
111*b30d1939SAndy Fiddaman static struct Namcache nvcache;
112*b30d1939SAndy Fiddaman #endif
113*b30d1939SAndy Fiddaman
114*b30d1939SAndy Fiddaman char nv_local = 0;
115*b30d1939SAndy Fiddaman #ifndef _ENV_H
116*b30d1939SAndy Fiddaman static void(*nullscan)(Namval_t*,void*);
117*b30d1939SAndy Fiddaman #endif
118*b30d1939SAndy Fiddaman
119*b30d1939SAndy Fiddaman #if ( SFIO_VERSION <= 20010201L )
120*b30d1939SAndy Fiddaman # define _data data
121*b30d1939SAndy Fiddaman #endif
122*b30d1939SAndy Fiddaman
123*b30d1939SAndy Fiddaman #if !SHOPT_MULTIBYTE
124*b30d1939SAndy Fiddaman # define mbchar(p) (*(unsigned char*)p++)
125*b30d1939SAndy Fiddaman #endif /* SHOPT_MULTIBYTE */
126*b30d1939SAndy Fiddaman
127*b30d1939SAndy Fiddaman /* ======== name value pair routines ======== */
128*b30d1939SAndy Fiddaman
129*b30d1939SAndy Fiddaman #include "shnodes.h"
130*b30d1939SAndy Fiddaman #include "builtins.h"
131*b30d1939SAndy Fiddaman
getbuf(size_t len)132*b30d1939SAndy Fiddaman static char *getbuf(size_t len)
133*b30d1939SAndy Fiddaman {
134*b30d1939SAndy Fiddaman static char *buf;
135*b30d1939SAndy Fiddaman static size_t buflen;
136*b30d1939SAndy Fiddaman if(buflen < len)
137*b30d1939SAndy Fiddaman {
138*b30d1939SAndy Fiddaman if(buflen==0)
139*b30d1939SAndy Fiddaman buf = (char*)malloc(len);
140*b30d1939SAndy Fiddaman else
141*b30d1939SAndy Fiddaman buf = (char*)realloc(buf,len);
142*b30d1939SAndy Fiddaman buflen = len;
143*b30d1939SAndy Fiddaman }
144*b30d1939SAndy Fiddaman return(buf);
145*b30d1939SAndy Fiddaman }
146*b30d1939SAndy Fiddaman
147*b30d1939SAndy Fiddaman #ifdef _ENV_H
sh_envput(Env_t * ep,Namval_t * np)148*b30d1939SAndy Fiddaman void sh_envput(Env_t* ep,Namval_t *np)
149*b30d1939SAndy Fiddaman {
150*b30d1939SAndy Fiddaman int offset = staktell();
151*b30d1939SAndy Fiddaman Namarr_t *ap = nv_arrayptr(np);
152*b30d1939SAndy Fiddaman char *val;
153*b30d1939SAndy Fiddaman if(ap)
154*b30d1939SAndy Fiddaman {
155*b30d1939SAndy Fiddaman if(ap->nelem&ARRAY_UNDEF)
156*b30d1939SAndy Fiddaman nv_putsub(np,"0",0L);
157*b30d1939SAndy Fiddaman else if(!(val=nv_getsub(np)) || strcmp(val,"0"))
158*b30d1939SAndy Fiddaman return;
159*b30d1939SAndy Fiddaman }
160*b30d1939SAndy Fiddaman if(!(val = nv_getval(np)))
161*b30d1939SAndy Fiddaman return;
162*b30d1939SAndy Fiddaman stakputs(nv_name(np));
163*b30d1939SAndy Fiddaman stakputc('=');
164*b30d1939SAndy Fiddaman stakputs(val);
165*b30d1939SAndy Fiddaman stakseek(offset);
166*b30d1939SAndy Fiddaman env_add(ep,stakptr(offset),ENV_STRDUP);
167*b30d1939SAndy Fiddaman }
168*b30d1939SAndy Fiddaman #endif
169*b30d1939SAndy Fiddaman
170*b30d1939SAndy Fiddaman /*
171*b30d1939SAndy Fiddaman * output variable name in format for re-input
172*b30d1939SAndy Fiddaman */
nv_outname(Sfio_t * out,char * name,int len)173*b30d1939SAndy Fiddaman void nv_outname(Sfio_t *out, char *name, int len)
174*b30d1939SAndy Fiddaman {
175*b30d1939SAndy Fiddaman const char *cp=name, *sp;
176*b30d1939SAndy Fiddaman int c, offset = staktell();
177*b30d1939SAndy Fiddaman while(sp= strchr(cp,'['))
178*b30d1939SAndy Fiddaman {
179*b30d1939SAndy Fiddaman if(len>0 && cp+len <= sp)
180*b30d1939SAndy Fiddaman break;
181*b30d1939SAndy Fiddaman sfwrite(out,cp,++sp-cp);
182*b30d1939SAndy Fiddaman stakseek(offset);
183*b30d1939SAndy Fiddaman while(c= *sp++)
184*b30d1939SAndy Fiddaman {
185*b30d1939SAndy Fiddaman if(c==']')
186*b30d1939SAndy Fiddaman break;
187*b30d1939SAndy Fiddaman else if(c=='\\')
188*b30d1939SAndy Fiddaman {
189*b30d1939SAndy Fiddaman if(*sp=='[' || *sp==']' || *sp=='\\')
190*b30d1939SAndy Fiddaman c = *sp++;
191*b30d1939SAndy Fiddaman }
192*b30d1939SAndy Fiddaman stakputc(c);
193*b30d1939SAndy Fiddaman }
194*b30d1939SAndy Fiddaman stakputc(0);
195*b30d1939SAndy Fiddaman sfputr(out,sh_fmtq(stakptr(offset)),-1);
196*b30d1939SAndy Fiddaman if(len>0)
197*b30d1939SAndy Fiddaman {
198*b30d1939SAndy Fiddaman sfputc(out,']');
199*b30d1939SAndy Fiddaman return;
200*b30d1939SAndy Fiddaman }
201*b30d1939SAndy Fiddaman cp = sp-1;
202*b30d1939SAndy Fiddaman }
203*b30d1939SAndy Fiddaman if(*cp)
204*b30d1939SAndy Fiddaman {
205*b30d1939SAndy Fiddaman if(len>0)
206*b30d1939SAndy Fiddaman sfwrite(out,cp,len);
207*b30d1939SAndy Fiddaman else
208*b30d1939SAndy Fiddaman sfputr(out,cp,-1);
209*b30d1939SAndy Fiddaman }
210*b30d1939SAndy Fiddaman stakseek(offset);
211*b30d1939SAndy Fiddaman }
212*b30d1939SAndy Fiddaman
213*b30d1939SAndy Fiddaman #if SHOPT_TYPEDEF
nv_addnode(Namval_t * np,int remove)214*b30d1939SAndy Fiddaman Namval_t *nv_addnode(Namval_t* np, int remove)
215*b30d1939SAndy Fiddaman {
216*b30d1939SAndy Fiddaman Shell_t *shp = sh_getinterp();
217*b30d1939SAndy Fiddaman register struct sh_type *sp = (struct sh_type*)shp->mktype;
218*b30d1939SAndy Fiddaman register int i;
219*b30d1939SAndy Fiddaman register char *name=0;
220*b30d1939SAndy Fiddaman if(sp->numnodes==0 && !nv_isnull(np) && shp->last_table)
221*b30d1939SAndy Fiddaman {
222*b30d1939SAndy Fiddaman /* could be an redefine */
223*b30d1939SAndy Fiddaman Dt_t *root = nv_dict(shp->last_table);
224*b30d1939SAndy Fiddaman sp->rp = np;
225*b30d1939SAndy Fiddaman nv_delete(np,root,NV_NOFREE);
226*b30d1939SAndy Fiddaman np = nv_search(sp->rp->nvname,root,NV_ADD);
227*b30d1939SAndy Fiddaman }
228*b30d1939SAndy Fiddaman if(sp->numnodes && memcmp(np->nvname,NV_CLASS,sizeof(NV_CLASS)-1))
229*b30d1939SAndy Fiddaman {
230*b30d1939SAndy Fiddaman name = (sp->nodes[0])->nvname;
231*b30d1939SAndy Fiddaman i = strlen(name);
232*b30d1939SAndy Fiddaman if(memcmp(np->nvname,name,i))
233*b30d1939SAndy Fiddaman return(np);
234*b30d1939SAndy Fiddaman }
235*b30d1939SAndy Fiddaman if(sp->rp && sp->numnodes)
236*b30d1939SAndy Fiddaman {
237*b30d1939SAndy Fiddaman /* check for a redefine */
238*b30d1939SAndy Fiddaman if(name && np->nvname[i]=='.' && np->nvname[i+1]=='_' && np->nvname[i+2]==0)
239*b30d1939SAndy Fiddaman sp->rp = 0;
240*b30d1939SAndy Fiddaman else
241*b30d1939SAndy Fiddaman {
242*b30d1939SAndy Fiddaman Dt_t *root = nv_dict(shp->last_table);
243*b30d1939SAndy Fiddaman nv_delete(sp->nodes[0],root,NV_NOFREE);
244*b30d1939SAndy Fiddaman dtinsert(root,sp->rp);
245*b30d1939SAndy Fiddaman errormsg(SH_DICT,ERROR_exit(1),e_redef,sp->nodes[0]->nvname);
246*b30d1939SAndy Fiddaman }
247*b30d1939SAndy Fiddaman }
248*b30d1939SAndy Fiddaman for(i=0; i < sp->numnodes; i++)
249*b30d1939SAndy Fiddaman {
250*b30d1939SAndy Fiddaman if(np == sp->nodes[i])
251*b30d1939SAndy Fiddaman {
252*b30d1939SAndy Fiddaman if(remove)
253*b30d1939SAndy Fiddaman {
254*b30d1939SAndy Fiddaman while(++i < sp->numnodes)
255*b30d1939SAndy Fiddaman sp->nodes[i-1] = sp->nodes[i];
256*b30d1939SAndy Fiddaman sp->numnodes--;
257*b30d1939SAndy Fiddaman }
258*b30d1939SAndy Fiddaman return(np);
259*b30d1939SAndy Fiddaman }
260*b30d1939SAndy Fiddaman }
261*b30d1939SAndy Fiddaman if(remove)
262*b30d1939SAndy Fiddaman return(np);
263*b30d1939SAndy Fiddaman if(sp->numnodes==sp->maxnodes)
264*b30d1939SAndy Fiddaman {
265*b30d1939SAndy Fiddaman sp->maxnodes += 20;
266*b30d1939SAndy Fiddaman sp->nodes = (Namval_t**)realloc(sp->nodes,sizeof(Namval_t*)*sp->maxnodes);
267*b30d1939SAndy Fiddaman }
268*b30d1939SAndy Fiddaman sp->nodes[sp->numnodes++] = np;
269*b30d1939SAndy Fiddaman return(np);
270*b30d1939SAndy Fiddaman }
271*b30d1939SAndy Fiddaman #endif /* SHOPT_TYPEDEF */
272*b30d1939SAndy Fiddaman
273*b30d1939SAndy Fiddaman /*
274*b30d1939SAndy Fiddaman * given a list of assignments, determine <name> is on the list
275*b30d1939SAndy Fiddaman returns a pointer to the argnod on the list or NULL
276*b30d1939SAndy Fiddaman */
nv_onlist(struct argnod * arg,const char * name)277*b30d1939SAndy Fiddaman struct argnod *nv_onlist(struct argnod *arg, const char *name)
278*b30d1939SAndy Fiddaman {
279*b30d1939SAndy Fiddaman char *cp;
280*b30d1939SAndy Fiddaman int len = strlen(name);
281*b30d1939SAndy Fiddaman for(;arg; arg=arg->argnxt.ap)
282*b30d1939SAndy Fiddaman {
283*b30d1939SAndy Fiddaman if(*arg->argval==0 && arg->argchn.ap && !(arg->argflag&~(ARG_APPEND|ARG_QUOTED|ARG_MESSAGE)))
284*b30d1939SAndy Fiddaman cp = ((struct fornod*)arg->argchn.ap)->fornam;
285*b30d1939SAndy Fiddaman else
286*b30d1939SAndy Fiddaman cp = arg->argval;
287*b30d1939SAndy Fiddaman if(memcmp(cp,name,len)==0 && (cp[len]==0 || cp[len]=='='))
288*b30d1939SAndy Fiddaman return(arg);
289*b30d1939SAndy Fiddaman }
290*b30d1939SAndy Fiddaman return(0);
291*b30d1939SAndy Fiddaman }
292*b30d1939SAndy Fiddaman
293*b30d1939SAndy Fiddaman /*
294*b30d1939SAndy Fiddaman * Perform parameter assignment for a linked list of parameters
295*b30d1939SAndy Fiddaman * <flags> contains attributes for the parameters
296*b30d1939SAndy Fiddaman */
nv_setlist(register struct argnod * arg,register int flags,Namval_t * typ)297*b30d1939SAndy Fiddaman void nv_setlist(register struct argnod *arg,register int flags, Namval_t *typ)
298*b30d1939SAndy Fiddaman {
299*b30d1939SAndy Fiddaman Shell_t *shp = sh_getinterp();
300*b30d1939SAndy Fiddaman register char *cp;
301*b30d1939SAndy Fiddaman register Namval_t *np, *mp;
302*b30d1939SAndy Fiddaman char *trap=shp->st.trap[SH_DEBUGTRAP];
303*b30d1939SAndy Fiddaman char *prefix = shp->prefix;
304*b30d1939SAndy Fiddaman int traceon = (sh_isoption(SH_XTRACE)!=0);
305*b30d1939SAndy Fiddaman int array = (flags&(NV_ARRAY|NV_IARRAY));
306*b30d1939SAndy Fiddaman Namarr_t *ap;
307*b30d1939SAndy Fiddaman Namval_t node;
308*b30d1939SAndy Fiddaman struct Namref nr;
309*b30d1939SAndy Fiddaman #if SHOPT_TYPEDEF
310*b30d1939SAndy Fiddaman int maketype = flags&NV_TYPE;
311*b30d1939SAndy Fiddaman struct sh_type shtp;
312*b30d1939SAndy Fiddaman if(maketype)
313*b30d1939SAndy Fiddaman {
314*b30d1939SAndy Fiddaman shtp.previous = shp->mktype;
315*b30d1939SAndy Fiddaman shp->mktype=(void*)&shtp;
316*b30d1939SAndy Fiddaman shtp.numnodes=0;
317*b30d1939SAndy Fiddaman shtp.maxnodes = 20;
318*b30d1939SAndy Fiddaman shtp.rp = 0;
319*b30d1939SAndy Fiddaman shtp.nodes =(Namval_t**)malloc(shtp.maxnodes*sizeof(Namval_t*));
320*b30d1939SAndy Fiddaman }
321*b30d1939SAndy Fiddaman #endif /* SHOPT_TYPEDEF*/
322*b30d1939SAndy Fiddaman #if SHOPT_NAMESPACE
323*b30d1939SAndy Fiddaman if(shp->namespace && nv_dict(shp->namespace)==shp->var_tree)
324*b30d1939SAndy Fiddaman flags |= NV_NOSCOPE;
325*b30d1939SAndy Fiddaman #endif /* SHOPT_NAMESPACE */
326*b30d1939SAndy Fiddaman flags &= ~(NV_TYPE|NV_ARRAY|NV_IARRAY);
327*b30d1939SAndy Fiddaman if(sh_isoption(SH_ALLEXPORT))
328*b30d1939SAndy Fiddaman flags |= NV_EXPORT;
329*b30d1939SAndy Fiddaman if(shp->prefix)
330*b30d1939SAndy Fiddaman {
331*b30d1939SAndy Fiddaman flags &= ~(NV_IDENT|NV_EXPORT);
332*b30d1939SAndy Fiddaman flags |= NV_VARNAME;
333*b30d1939SAndy Fiddaman }
334*b30d1939SAndy Fiddaman else
335*b30d1939SAndy Fiddaman shp->prefix_root = shp->first_root = 0;
336*b30d1939SAndy Fiddaman for(;arg; arg=arg->argnxt.ap)
337*b30d1939SAndy Fiddaman {
338*b30d1939SAndy Fiddaman shp->used_pos = 0;
339*b30d1939SAndy Fiddaman if(arg->argflag&ARG_MAC)
340*b30d1939SAndy Fiddaman {
341*b30d1939SAndy Fiddaman shp->prefix = 0;
342*b30d1939SAndy Fiddaman cp = sh_mactrim(shp,arg->argval,(flags&NV_NOREF)?-3:-1);
343*b30d1939SAndy Fiddaman shp->prefix = prefix;
344*b30d1939SAndy Fiddaman }
345*b30d1939SAndy Fiddaman else
346*b30d1939SAndy Fiddaman {
347*b30d1939SAndy Fiddaman stakseek(0);
348*b30d1939SAndy Fiddaman if(*arg->argval==0 && arg->argchn.ap && !(arg->argflag&~(ARG_APPEND|ARG_QUOTED|ARG_MESSAGE)))
349*b30d1939SAndy Fiddaman {
350*b30d1939SAndy Fiddaman int flag = (NV_VARNAME|NV_ARRAY|NV_ASSIGN);
351*b30d1939SAndy Fiddaman int sub=0;
352*b30d1939SAndy Fiddaman struct fornod *fp=(struct fornod*)arg->argchn.ap;
353*b30d1939SAndy Fiddaman register Shnode_t *tp=fp->fortre;
354*b30d1939SAndy Fiddaman flag |= (flags&(NV_NOSCOPE|NV_STATIC|NV_FARRAY));
355*b30d1939SAndy Fiddaman if(arg->argflag&ARG_QUOTED)
356*b30d1939SAndy Fiddaman cp = sh_mactrim(shp,fp->fornam,-1);
357*b30d1939SAndy Fiddaman else
358*b30d1939SAndy Fiddaman cp = fp->fornam;
359*b30d1939SAndy Fiddaman error_info.line = fp->fortyp-shp->st.firstline;
360*b30d1939SAndy Fiddaman if(!array && tp->tre.tretyp!=TLST && tp->com.comset && !tp->com.comarg && tp->com.comset->argval[0]==0 && tp->com.comset->argval[1]=='[')
361*b30d1939SAndy Fiddaman array |= (tp->com.comset->argflag&ARG_MESSAGE)?NV_IARRAY:NV_ARRAY;
362*b30d1939SAndy Fiddaman if(prefix && tp->com.comset && *cp=='[')
363*b30d1939SAndy Fiddaman {
364*b30d1939SAndy Fiddaman shp->prefix = 0;
365*b30d1939SAndy Fiddaman np = nv_open(prefix,shp->last_root,flag);
366*b30d1939SAndy Fiddaman shp->prefix = prefix;
367*b30d1939SAndy Fiddaman if(np)
368*b30d1939SAndy Fiddaman {
369*b30d1939SAndy Fiddaman if(nv_isvtree(np) && !nv_isarray(np))
370*b30d1939SAndy Fiddaman {
371*b30d1939SAndy Fiddaman stakputc('.');
372*b30d1939SAndy Fiddaman stakputs(cp);
373*b30d1939SAndy Fiddaman cp = stakfreeze(1);
374*b30d1939SAndy Fiddaman }
375*b30d1939SAndy Fiddaman nv_close(np);
376*b30d1939SAndy Fiddaman }
377*b30d1939SAndy Fiddaman }
378*b30d1939SAndy Fiddaman np = nv_open(cp,shp->var_tree,flag|NV_ASSIGN);
379*b30d1939SAndy Fiddaman if((arg->argflag&ARG_APPEND) && (tp->tre.tretyp&COMMSK)==TCOM && tp->com.comset && !nv_isvtree(np) && (((ap=nv_arrayptr(np)) && !ap->fun && !nv_opensub(np)) || (!ap && nv_isarray(np) && tp->com.comarg && !((mp=nv_search(tp->com.comarg->argval,shp->fun_tree,0)) && nv_isattr(mp,BLT_DCL)))))
380*b30d1939SAndy Fiddaman {
381*b30d1939SAndy Fiddaman if(tp->com.comarg)
382*b30d1939SAndy Fiddaman {
383*b30d1939SAndy Fiddaman struct argnod *ap = tp->com.comset;
384*b30d1939SAndy Fiddaman while(ap->argnxt.ap)
385*b30d1939SAndy Fiddaman ap = ap->argnxt.ap;
386*b30d1939SAndy Fiddaman ap->argnxt.ap = tp->com.comarg;
387*b30d1939SAndy Fiddaman
388*b30d1939SAndy Fiddaman }
389*b30d1939SAndy Fiddaman tp->com.comarg = tp->com.comset;
390*b30d1939SAndy Fiddaman tp->com.comset = 0;
391*b30d1939SAndy Fiddaman tp->com.comtyp = COMSCAN;
392*b30d1939SAndy Fiddaman }
393*b30d1939SAndy Fiddaman if(nv_isattr(np,NV_RDONLY) && np->nvfun && !(flags&NV_RDONLY))
394*b30d1939SAndy Fiddaman errormsg(SH_DICT,ERROR_exit(1),e_readonly, nv_name(np));
395*b30d1939SAndy Fiddaman if(nv_isattr(np,NV_NOFREE) && nv_isnull(np))
396*b30d1939SAndy Fiddaman nv_offattr(np,NV_NOFREE);
397*b30d1939SAndy Fiddaman if(nv_istable(np))
398*b30d1939SAndy Fiddaman _nv_unset(np,0);
399*b30d1939SAndy Fiddaman if(typ && !array && (!shp->prefix || nv_isnull(np) || nv_isarray(np)))
400*b30d1939SAndy Fiddaman {
401*b30d1939SAndy Fiddaman if(!(nv_isnull(np)) && !nv_isarray(np))
402*b30d1939SAndy Fiddaman _nv_unset(np,0);
403*b30d1939SAndy Fiddaman nv_settype(np,typ,0);
404*b30d1939SAndy Fiddaman }
405*b30d1939SAndy Fiddaman if((flags&NV_STATIC) && !nv_isattr(np,NV_EXPORT) && !nv_isnull(np))
406*b30d1939SAndy Fiddaman #if SHOPT_TYPEDEF
407*b30d1939SAndy Fiddaman goto check_type;
408*b30d1939SAndy Fiddaman #else
409*b30d1939SAndy Fiddaman continue;
410*b30d1939SAndy Fiddaman #endif /* SHOPT_TYPEDEF */
411*b30d1939SAndy Fiddaman ap=nv_arrayptr(np);
412*b30d1939SAndy Fiddaman #if SHOPT_FIXEDARRAY
413*b30d1939SAndy Fiddaman if(ap && ap->fixed)
414*b30d1939SAndy Fiddaman flags |= NV_FARRAY;
415*b30d1939SAndy Fiddaman #endif /* SHOPT_FIXEDARRAY */
416*b30d1939SAndy Fiddaman if(array && (!ap || !ap->hdr.type))
417*b30d1939SAndy Fiddaman {
418*b30d1939SAndy Fiddaman #if SHOPT_FIXEDARRAY
419*b30d1939SAndy Fiddaman if(!(arg->argflag&ARG_APPEND) && (!ap || !ap->fixed))
420*b30d1939SAndy Fiddaman #else
421*b30d1939SAndy Fiddaman if(!(arg->argflag&ARG_APPEND))
422*b30d1939SAndy Fiddaman #endif /* SHOPT_FIXEDARRAY */
423*b30d1939SAndy Fiddaman _nv_unset(np,NV_EXPORT);
424*b30d1939SAndy Fiddaman if(array&NV_ARRAY)
425*b30d1939SAndy Fiddaman {
426*b30d1939SAndy Fiddaman nv_setarray(np,nv_associative);
427*b30d1939SAndy Fiddaman }
428*b30d1939SAndy Fiddaman else
429*b30d1939SAndy Fiddaman {
430*b30d1939SAndy Fiddaman nv_onattr(np,NV_ARRAY);
431*b30d1939SAndy Fiddaman }
432*b30d1939SAndy Fiddaman }
433*b30d1939SAndy Fiddaman if(array && tp->tre.tretyp!=TLST && !tp->com.comset && !tp->com.comarg)
434*b30d1939SAndy Fiddaman {
435*b30d1939SAndy Fiddaman #if SHOPT_TYPEDEF
436*b30d1939SAndy Fiddaman goto check_type;
437*b30d1939SAndy Fiddaman #else
438*b30d1939SAndy Fiddaman continue;
439*b30d1939SAndy Fiddaman #endif /* SHOPT_TYPEDEF */
440*b30d1939SAndy Fiddaman }
441*b30d1939SAndy Fiddaman /* check for array assignment */
442*b30d1939SAndy Fiddaman if(tp->tre.tretyp!=TLST && tp->com.comarg && !tp->com.comset && ((array&NV_IARRAY) || !((mp=tp->com.comnamp) && nv_isattr(mp,BLT_DCL))))
443*b30d1939SAndy Fiddaman {
444*b30d1939SAndy Fiddaman int argc;
445*b30d1939SAndy Fiddaman Dt_t *last_root = shp->last_root;
446*b30d1939SAndy Fiddaman char **argv = sh_argbuild(shp,&argc,&tp->com,0);
447*b30d1939SAndy Fiddaman shp->last_root = last_root;
448*b30d1939SAndy Fiddaman #if SHOPT_TYPEDEF
449*b30d1939SAndy Fiddaman if(shp->mktype && shp->dot_depth==0 && np==((struct sh_type*)shp->mktype)->nodes[0])
450*b30d1939SAndy Fiddaman {
451*b30d1939SAndy Fiddaman shp->mktype = 0;
452*b30d1939SAndy Fiddaman errormsg(SH_DICT,ERROR_exit(1),"%s: not a known type name",argv[0]);
453*b30d1939SAndy Fiddaman }
454*b30d1939SAndy Fiddaman #endif /* SHOPT_TYPEDEF */
455*b30d1939SAndy Fiddaman if(!(arg->argflag&ARG_APPEND))
456*b30d1939SAndy Fiddaman {
457*b30d1939SAndy Fiddaman #if SHOPT_FIXEDARRAY
458*b30d1939SAndy Fiddaman if(!nv_isarray(np) || ((ap=nv_arrayptr(np)) && !ap->fixed && (ap->nelem&ARRAY_MASK)))
459*b30d1939SAndy Fiddaman #else
460*b30d1939SAndy Fiddaman if(!nv_isarray(np) || ((ap=nv_arrayptr(np)) && (ap->nelem&ARRAY_MASK)))
461*b30d1939SAndy Fiddaman #endif /* SHOPT_FIXEDARRAY */
462*b30d1939SAndy Fiddaman {
463*b30d1939SAndy Fiddaman if(ap)
464*b30d1939SAndy Fiddaman ap->nelem |= ARRAY_UNDEF;
465*b30d1939SAndy Fiddaman _nv_unset(np,NV_EXPORT);
466*b30d1939SAndy Fiddaman }
467*b30d1939SAndy Fiddaman }
468*b30d1939SAndy Fiddaman nv_setvec(np,(arg->argflag&ARG_APPEND),argc,argv);
469*b30d1939SAndy Fiddaman if(traceon || trap)
470*b30d1939SAndy Fiddaman {
471*b30d1939SAndy Fiddaman int n = -1;
472*b30d1939SAndy Fiddaman char *name = nv_name(np);
473*b30d1939SAndy Fiddaman if(arg->argflag&ARG_APPEND)
474*b30d1939SAndy Fiddaman n = '+';
475*b30d1939SAndy Fiddaman if(trap)
476*b30d1939SAndy Fiddaman sh_debug(shp,trap,name,(char*)0,argv,(arg->argflag&ARG_APPEND)|ARG_ASSIGN);
477*b30d1939SAndy Fiddaman if(traceon)
478*b30d1939SAndy Fiddaman {
479*b30d1939SAndy Fiddaman sh_trace(shp,NIL(char**),0);
480*b30d1939SAndy Fiddaman sfputr(sfstderr,name,n);
481*b30d1939SAndy Fiddaman sfwrite(sfstderr,"=( ",3);
482*b30d1939SAndy Fiddaman while(cp= *argv++)
483*b30d1939SAndy Fiddaman sfputr(sfstderr,sh_fmtq(cp),' ');
484*b30d1939SAndy Fiddaman sfwrite(sfstderr,")\n",2);
485*b30d1939SAndy Fiddaman }
486*b30d1939SAndy Fiddaman }
487*b30d1939SAndy Fiddaman #if SHOPT_TYPEDEF
488*b30d1939SAndy Fiddaman goto check_type;
489*b30d1939SAndy Fiddaman #else
490*b30d1939SAndy Fiddaman continue;
491*b30d1939SAndy Fiddaman #endif /* SHOPT_TYPEDEF */
492*b30d1939SAndy Fiddaman }
493*b30d1939SAndy Fiddaman if((tp->tre.tretyp&COMMSK)==TFUN)
494*b30d1939SAndy Fiddaman goto skip;
495*b30d1939SAndy Fiddaman if(tp->tre.tretyp==0 && !tp->com.comset && !tp->com.comarg)
496*b30d1939SAndy Fiddaman {
497*b30d1939SAndy Fiddaman if(!(arg->argflag&ARG_APPEND) && nv_isattr(np,NV_BINARY|NV_NOFREE|NV_RAW)!=(NV_BINARY|NV_NOFREE|NV_RAW))
498*b30d1939SAndy Fiddaman _nv_unset(np,NV_EXPORT);
499*b30d1939SAndy Fiddaman goto skip;
500*b30d1939SAndy Fiddaman }
501*b30d1939SAndy Fiddaman if(tp->tre.tretyp==TLST || !tp->com.comset || tp->com.comset->argval[0]!='[')
502*b30d1939SAndy Fiddaman {
503*b30d1939SAndy Fiddaman if(tp->tre.tretyp!=TLST && !tp->com.comnamp && tp->com.comset && tp->com.comset->argval[0]==0 && tp->com.comset->argchn.ap)
504*b30d1939SAndy Fiddaman {
505*b30d1939SAndy Fiddaman if(prefix || np)
506*b30d1939SAndy Fiddaman cp = stakcopy(nv_name(np));
507*b30d1939SAndy Fiddaman shp->prefix = cp;
508*b30d1939SAndy Fiddaman if(tp->com.comset->argval[1]=='[')
509*b30d1939SAndy Fiddaman {
510*b30d1939SAndy Fiddaman if((arg->argflag&ARG_APPEND) && (!nv_isarray(np) || (nv_aindex(np)>=0)))
511*b30d1939SAndy Fiddaman _nv_unset(np,0);
512*b30d1939SAndy Fiddaman if(!(array&NV_IARRAY) && !(tp->com.comset->argflag&ARG_MESSAGE))
513*b30d1939SAndy Fiddaman nv_setarray(np,nv_associative);
514*b30d1939SAndy Fiddaman }
515*b30d1939SAndy Fiddaman nv_setlist(tp->com.comset,flags&~NV_STATIC,0);
516*b30d1939SAndy Fiddaman shp->prefix = prefix;
517*b30d1939SAndy Fiddaman if(tp->com.comset->argval[1]!='[')
518*b30d1939SAndy Fiddaman nv_setvtree(np);
519*b30d1939SAndy Fiddaman nv_close(np);
520*b30d1939SAndy Fiddaman #if SHOPT_TYPEDEF
521*b30d1939SAndy Fiddaman goto check_type;
522*b30d1939SAndy Fiddaman #else
523*b30d1939SAndy Fiddaman continue;
524*b30d1939SAndy Fiddaman #endif /* SHOPT_TYPEDEF */
525*b30d1939SAndy Fiddaman }
526*b30d1939SAndy Fiddaman if(*cp!='.' && *cp!='[' && strchr(cp,'['))
527*b30d1939SAndy Fiddaman {
528*b30d1939SAndy Fiddaman cp = stakcopy(nv_name(np));
529*b30d1939SAndy Fiddaman nv_close(np);
530*b30d1939SAndy Fiddaman if(!(arg->argflag&ARG_APPEND))
531*b30d1939SAndy Fiddaman flag &= ~NV_ARRAY;
532*b30d1939SAndy Fiddaman shp->prefix_root = shp->first_root;
533*b30d1939SAndy Fiddaman np = nv_open(cp,shp->prefix_root?shp->prefix_root:shp->var_tree,flag);
534*b30d1939SAndy Fiddaman }
535*b30d1939SAndy Fiddaman if(arg->argflag&ARG_APPEND)
536*b30d1939SAndy Fiddaman {
537*b30d1939SAndy Fiddaman if(nv_isarray(np))
538*b30d1939SAndy Fiddaman {
539*b30d1939SAndy Fiddaman if((sub=nv_aimax(np)) < 0 && nv_arrayptr(np))
540*b30d1939SAndy Fiddaman errormsg(SH_DICT,ERROR_exit(1),e_badappend,nv_name(np));
541*b30d1939SAndy Fiddaman if(sub>=0)
542*b30d1939SAndy Fiddaman sub++;
543*b30d1939SAndy Fiddaman }
544*b30d1939SAndy Fiddaman if(!nv_isnull(np) && np->nvalue.cp!=Empty && !nv_isvtree(np))
545*b30d1939SAndy Fiddaman sub=1;
546*b30d1939SAndy Fiddaman }
547*b30d1939SAndy Fiddaman else if(((np->nvalue.cp && np->nvalue.cp!=Empty)||nv_isvtree(np)|| nv_arrayptr(np)) && !nv_type(np))
548*b30d1939SAndy Fiddaman {
549*b30d1939SAndy Fiddaman _nv_unset(np,NV_EXPORT);
550*b30d1939SAndy Fiddaman if(ap && ap->fun)
551*b30d1939SAndy Fiddaman nv_setarray(np,nv_associative);
552*b30d1939SAndy Fiddaman
553*b30d1939SAndy Fiddaman }
554*b30d1939SAndy Fiddaman }
555*b30d1939SAndy Fiddaman else
556*b30d1939SAndy Fiddaman {
557*b30d1939SAndy Fiddaman if(!(arg->argflag&ARG_APPEND))
558*b30d1939SAndy Fiddaman _nv_unset(np,NV_EXPORT);
559*b30d1939SAndy Fiddaman if(!sh_isoption(SH_BASH) && !(array&NV_IARRAY) && !nv_isarray(np))
560*b30d1939SAndy Fiddaman nv_setarray(np,nv_associative);
561*b30d1939SAndy Fiddaman }
562*b30d1939SAndy Fiddaman skip:
563*b30d1939SAndy Fiddaman if(sub>0)
564*b30d1939SAndy Fiddaman {
565*b30d1939SAndy Fiddaman sfprintf(stkstd,"%s[%d]",prefix?nv_name(np):cp,sub);
566*b30d1939SAndy Fiddaman shp->prefix = stakfreeze(1);
567*b30d1939SAndy Fiddaman nv_putsub(np,(char*)0,ARRAY_ADD|ARRAY_FILL|sub);
568*b30d1939SAndy Fiddaman }
569*b30d1939SAndy Fiddaman else if(prefix)
570*b30d1939SAndy Fiddaman shp->prefix = stakcopy(nv_name(np));
571*b30d1939SAndy Fiddaman else
572*b30d1939SAndy Fiddaman shp->prefix = cp;
573*b30d1939SAndy Fiddaman shp->last_table = 0;
574*b30d1939SAndy Fiddaman if(shp->prefix)
575*b30d1939SAndy Fiddaman {
576*b30d1939SAndy Fiddaman if(*shp->prefix=='_' && shp->prefix[1]=='.' && nv_isref(L_ARGNOD))
577*b30d1939SAndy Fiddaman {
578*b30d1939SAndy Fiddaman sfprintf(stkstd,"%s%s",nv_name(L_ARGNOD->nvalue.nrp->np),shp->prefix+1);
579*b30d1939SAndy Fiddaman shp->prefix = stkfreeze(stkstd,1);
580*b30d1939SAndy Fiddaman }
581*b30d1939SAndy Fiddaman memset(&nr,0,sizeof(nr));
582*b30d1939SAndy Fiddaman memcpy(&node,L_ARGNOD,sizeof(node));
583*b30d1939SAndy Fiddaman L_ARGNOD->nvalue.nrp = &nr;
584*b30d1939SAndy Fiddaman nr.np = np;
585*b30d1939SAndy Fiddaman nr.root = shp->last_root;
586*b30d1939SAndy Fiddaman nr.table = shp->last_table;
587*b30d1939SAndy Fiddaman L_ARGNOD->nvflag = NV_REF|NV_NOFREE;
588*b30d1939SAndy Fiddaman L_ARGNOD->nvfun = 0;
589*b30d1939SAndy Fiddaman }
590*b30d1939SAndy Fiddaman sh_exec(tp,sh_isstate(SH_ERREXIT));
591*b30d1939SAndy Fiddaman #if SHOPT_TYPEDEF
592*b30d1939SAndy Fiddaman if(shp->prefix)
593*b30d1939SAndy Fiddaman #endif
594*b30d1939SAndy Fiddaman {
595*b30d1939SAndy Fiddaman L_ARGNOD->nvalue.nrp = node.nvalue.nrp;
596*b30d1939SAndy Fiddaman L_ARGNOD->nvflag = node.nvflag;
597*b30d1939SAndy Fiddaman L_ARGNOD->nvfun = node.nvfun;
598*b30d1939SAndy Fiddaman }
599*b30d1939SAndy Fiddaman shp->prefix = prefix;
600*b30d1939SAndy Fiddaman if(nv_isarray(np) && (mp=nv_opensub(np)))
601*b30d1939SAndy Fiddaman np = mp;
602*b30d1939SAndy Fiddaman while(tp->tre.tretyp==TLST)
603*b30d1939SAndy Fiddaman {
604*b30d1939SAndy Fiddaman if(!tp->lst.lstlef || !tp->lst.lstlef->tre.tretyp==TCOM || tp->lst.lstlef->com.comarg || tp->lst.lstlef->com.comset && tp->lst.lstlef->com.comset->argval[0]!='[')
605*b30d1939SAndy Fiddaman break;
606*b30d1939SAndy Fiddaman tp = tp->lst.lstrit;
607*b30d1939SAndy Fiddaman
608*b30d1939SAndy Fiddaman }
609*b30d1939SAndy Fiddaman if(!nv_isarray(np) && !typ && (tp->com.comarg || !tp->com.comset || tp->com.comset->argval[0]!='['))
610*b30d1939SAndy Fiddaman {
611*b30d1939SAndy Fiddaman nv_setvtree(np);
612*b30d1939SAndy Fiddaman if(tp->com.comarg || tp->com.comset)
613*b30d1939SAndy Fiddaman np->nvfun->dsize = 0;
614*b30d1939SAndy Fiddaman }
615*b30d1939SAndy Fiddaman #if SHOPT_TYPEDEF
616*b30d1939SAndy Fiddaman goto check_type;
617*b30d1939SAndy Fiddaman #else
618*b30d1939SAndy Fiddaman continue;
619*b30d1939SAndy Fiddaman #endif /* SHOPT_TYPEDEF */
620*b30d1939SAndy Fiddaman }
621*b30d1939SAndy Fiddaman cp = arg->argval;
622*b30d1939SAndy Fiddaman mp = 0;
623*b30d1939SAndy Fiddaman }
624*b30d1939SAndy Fiddaman np = nv_open(cp,shp->prefix_root?shp->prefix_root:shp->var_tree,flags);
625*b30d1939SAndy Fiddaman if(!np->nvfun && (flags&NV_NOREF))
626*b30d1939SAndy Fiddaman {
627*b30d1939SAndy Fiddaman if(shp->used_pos)
628*b30d1939SAndy Fiddaman nv_onattr(np,NV_PARAM);
629*b30d1939SAndy Fiddaman else
630*b30d1939SAndy Fiddaman nv_offattr(np,NV_PARAM);
631*b30d1939SAndy Fiddaman }
632*b30d1939SAndy Fiddaman if(traceon || trap)
633*b30d1939SAndy Fiddaman {
634*b30d1939SAndy Fiddaman register char *sp=cp;
635*b30d1939SAndy Fiddaman char *name=nv_name(np);
636*b30d1939SAndy Fiddaman char *sub=0;
637*b30d1939SAndy Fiddaman int append = 0;
638*b30d1939SAndy Fiddaman if(nv_isarray(np))
639*b30d1939SAndy Fiddaman sub = savesub;
640*b30d1939SAndy Fiddaman if(cp=lastdot(sp,'='))
641*b30d1939SAndy Fiddaman {
642*b30d1939SAndy Fiddaman if(cp[-1]=='+')
643*b30d1939SAndy Fiddaman append = ARG_APPEND;
644*b30d1939SAndy Fiddaman cp++;
645*b30d1939SAndy Fiddaman }
646*b30d1939SAndy Fiddaman if(traceon)
647*b30d1939SAndy Fiddaman {
648*b30d1939SAndy Fiddaman sh_trace(shp,NIL(char**),0);
649*b30d1939SAndy Fiddaman nv_outname(sfstderr,name,-1);
650*b30d1939SAndy Fiddaman if(sub)
651*b30d1939SAndy Fiddaman sfprintf(sfstderr,"[%s]",sh_fmtq(sub));
652*b30d1939SAndy Fiddaman if(cp)
653*b30d1939SAndy Fiddaman {
654*b30d1939SAndy Fiddaman if(append)
655*b30d1939SAndy Fiddaman sfputc(sfstderr,'+');
656*b30d1939SAndy Fiddaman sfprintf(sfstderr,"=%s\n",sh_fmtq(cp));
657*b30d1939SAndy Fiddaman }
658*b30d1939SAndy Fiddaman }
659*b30d1939SAndy Fiddaman if(trap)
660*b30d1939SAndy Fiddaman {
661*b30d1939SAndy Fiddaman char *av[2];
662*b30d1939SAndy Fiddaman av[0] = cp;
663*b30d1939SAndy Fiddaman av[1] = 0;
664*b30d1939SAndy Fiddaman sh_debug(shp,trap,name,sub,av,append);
665*b30d1939SAndy Fiddaman }
666*b30d1939SAndy Fiddaman }
667*b30d1939SAndy Fiddaman #if SHOPT_TYPEDEF
668*b30d1939SAndy Fiddaman check_type:
669*b30d1939SAndy Fiddaman if(maketype)
670*b30d1939SAndy Fiddaman {
671*b30d1939SAndy Fiddaman nv_open(shtp.nodes[0]->nvname,shp->var_tree,NV_ASSIGN|NV_VARNAME|NV_NOADD|NV_NOFAIL);
672*b30d1939SAndy Fiddaman np = nv_mktype(shtp.nodes,shtp.numnodes);
673*b30d1939SAndy Fiddaman free((void*)shtp.nodes);
674*b30d1939SAndy Fiddaman shp->mktype = shtp.previous;
675*b30d1939SAndy Fiddaman maketype = 0;
676*b30d1939SAndy Fiddaman if(shp->namespace)
677*b30d1939SAndy Fiddaman free(shp->prefix);
678*b30d1939SAndy Fiddaman shp->prefix = 0;
679*b30d1939SAndy Fiddaman if(nr.np == np)
680*b30d1939SAndy Fiddaman {
681*b30d1939SAndy Fiddaman L_ARGNOD->nvalue.nrp = node.nvalue.nrp;
682*b30d1939SAndy Fiddaman L_ARGNOD->nvflag = node.nvflag;
683*b30d1939SAndy Fiddaman L_ARGNOD->nvfun = node.nvfun;
684*b30d1939SAndy Fiddaman }
685*b30d1939SAndy Fiddaman }
686*b30d1939SAndy Fiddaman #endif /* SHOPT_TYPEDEF */
687*b30d1939SAndy Fiddaman }
688*b30d1939SAndy Fiddaman }
689*b30d1939SAndy Fiddaman
690*b30d1939SAndy Fiddaman /*
691*b30d1939SAndy Fiddaman * copy the subscript onto the stack
692*b30d1939SAndy Fiddaman */
stak_subscript(const char * sub,int last)693*b30d1939SAndy Fiddaman static void stak_subscript(const char *sub, int last)
694*b30d1939SAndy Fiddaman {
695*b30d1939SAndy Fiddaman register int c;
696*b30d1939SAndy Fiddaman stakputc('[');
697*b30d1939SAndy Fiddaman while(c= *sub++)
698*b30d1939SAndy Fiddaman {
699*b30d1939SAndy Fiddaman if(c=='[' || c==']' || c=='\\')
700*b30d1939SAndy Fiddaman stakputc('\\');
701*b30d1939SAndy Fiddaman stakputc(c);
702*b30d1939SAndy Fiddaman }
703*b30d1939SAndy Fiddaman stakputc(last);
704*b30d1939SAndy Fiddaman }
705*b30d1939SAndy Fiddaman
706*b30d1939SAndy Fiddaman /*
707*b30d1939SAndy Fiddaman * construct a new name from a prefix and base name on the stack
708*b30d1939SAndy Fiddaman */
copystack(const char * prefix,register const char * name,const char * sub)709*b30d1939SAndy Fiddaman static char *copystack(const char *prefix, register const char *name, const char *sub)
710*b30d1939SAndy Fiddaman {
711*b30d1939SAndy Fiddaman register int last=0,offset = staktell();
712*b30d1939SAndy Fiddaman if(prefix)
713*b30d1939SAndy Fiddaman {
714*b30d1939SAndy Fiddaman stakputs(prefix);
715*b30d1939SAndy Fiddaman if(*stakptr(staktell()-1)=='.')
716*b30d1939SAndy Fiddaman stakseek(staktell()-1);
717*b30d1939SAndy Fiddaman if(*name=='.' && name[1]=='[')
718*b30d1939SAndy Fiddaman last = staktell()+2;
719*b30d1939SAndy Fiddaman if(*name!='[' && *name!='.' && *name!='=' && *name!='+')
720*b30d1939SAndy Fiddaman stakputc('.');
721*b30d1939SAndy Fiddaman if(*name=='.' && (name[1]=='=' || name[1]==0))
722*b30d1939SAndy Fiddaman stakputc('.');
723*b30d1939SAndy Fiddaman }
724*b30d1939SAndy Fiddaman if(last)
725*b30d1939SAndy Fiddaman {
726*b30d1939SAndy Fiddaman stakputs(name);
727*b30d1939SAndy Fiddaman if(sh_checkid(stakptr(last),(char*)0))
728*b30d1939SAndy Fiddaman stakseek(staktell()-2);
729*b30d1939SAndy Fiddaman }
730*b30d1939SAndy Fiddaman if(sub)
731*b30d1939SAndy Fiddaman stak_subscript(sub,']');
732*b30d1939SAndy Fiddaman if(!last)
733*b30d1939SAndy Fiddaman stakputs(name);
734*b30d1939SAndy Fiddaman stakputc(0);
735*b30d1939SAndy Fiddaman return(stakptr(offset));
736*b30d1939SAndy Fiddaman }
737*b30d1939SAndy Fiddaman
738*b30d1939SAndy Fiddaman /*
739*b30d1939SAndy Fiddaman * grow this stack string <name> by <n> bytes and move from cp-1 to end
740*b30d1939SAndy Fiddaman * right by <n>. Returns beginning of string on the stack
741*b30d1939SAndy Fiddaman */
stack_extend(const char * cname,char * cp,int n)742*b30d1939SAndy Fiddaman static char *stack_extend(const char *cname, char *cp, int n)
743*b30d1939SAndy Fiddaman {
744*b30d1939SAndy Fiddaman register char *name = (char*)cname;
745*b30d1939SAndy Fiddaman int offset = name - stakptr(0);
746*b30d1939SAndy Fiddaman int m = cp-name;
747*b30d1939SAndy Fiddaman stakseek(offset + strlen(name)+n+1);
748*b30d1939SAndy Fiddaman name = stakptr(offset);
749*b30d1939SAndy Fiddaman cp = name + m;
750*b30d1939SAndy Fiddaman m = strlen(cp)+1;
751*b30d1939SAndy Fiddaman while(m-->0)
752*b30d1939SAndy Fiddaman cp[n+m]=cp[m];
753*b30d1939SAndy Fiddaman return((char*)name);
754*b30d1939SAndy Fiddaman }
755*b30d1939SAndy Fiddaman
nv_create(const char * name,Dt_t * root,int flags,Namfun_t * dp)756*b30d1939SAndy Fiddaman Namval_t *nv_create(const char *name, Dt_t *root, int flags, Namfun_t *dp)
757*b30d1939SAndy Fiddaman {
758*b30d1939SAndy Fiddaman Shell_t *shp = sh_getinterp();
759*b30d1939SAndy Fiddaman char *sub=0, *cp=(char*)name, *sp, *xp;
760*b30d1939SAndy Fiddaman register int c;
761*b30d1939SAndy Fiddaman register Namval_t *np=0, *nq=0;
762*b30d1939SAndy Fiddaman Namfun_t *fp=0;
763*b30d1939SAndy Fiddaman long mode, add=0;
764*b30d1939SAndy Fiddaman int copy=0,isref,top=0,noscope=(flags&NV_NOSCOPE);
765*b30d1939SAndy Fiddaman int nofree=0, level=0;
766*b30d1939SAndy Fiddaman #if SHOPT_FIXEDARRAY
767*b30d1939SAndy Fiddaman Namarr_t *ap;
768*b30d1939SAndy Fiddaman #endif /* SHOPT_FIXEDARRAY */
769*b30d1939SAndy Fiddaman if(root==shp->var_tree)
770*b30d1939SAndy Fiddaman {
771*b30d1939SAndy Fiddaman if(dtvnext(root))
772*b30d1939SAndy Fiddaman top = 1;
773*b30d1939SAndy Fiddaman else
774*b30d1939SAndy Fiddaman flags &= ~NV_NOSCOPE;
775*b30d1939SAndy Fiddaman }
776*b30d1939SAndy Fiddaman if(!dp->disc)
777*b30d1939SAndy Fiddaman copy = dp->nofree&1;
778*b30d1939SAndy Fiddaman if(*cp=='.')
779*b30d1939SAndy Fiddaman cp++;
780*b30d1939SAndy Fiddaman while(1)
781*b30d1939SAndy Fiddaman {
782*b30d1939SAndy Fiddaman switch(c = *(unsigned char*)(sp = cp))
783*b30d1939SAndy Fiddaman {
784*b30d1939SAndy Fiddaman case '[':
785*b30d1939SAndy Fiddaman if(flags&NV_NOARRAY)
786*b30d1939SAndy Fiddaman {
787*b30d1939SAndy Fiddaman dp->last = cp;
788*b30d1939SAndy Fiddaman return(np);
789*b30d1939SAndy Fiddaman }
790*b30d1939SAndy Fiddaman cp = nv_endsubscript((Namval_t*)0,sp,0);
791*b30d1939SAndy Fiddaman if(sp==name || sp[-1]=='.')
792*b30d1939SAndy Fiddaman c = *(sp = cp);
793*b30d1939SAndy Fiddaman goto skip;
794*b30d1939SAndy Fiddaman case '.':
795*b30d1939SAndy Fiddaman if(flags&NV_IDENT)
796*b30d1939SAndy Fiddaman return(0);
797*b30d1939SAndy Fiddaman if(root==shp->var_tree)
798*b30d1939SAndy Fiddaman flags &= ~NV_EXPORT;
799*b30d1939SAndy Fiddaman if(!copy && !(flags&NV_NOREF))
800*b30d1939SAndy Fiddaman {
801*b30d1939SAndy Fiddaman c = sp-name;
802*b30d1939SAndy Fiddaman copy = cp-name;
803*b30d1939SAndy Fiddaman dp->nofree |= 1;
804*b30d1939SAndy Fiddaman name = copystack((const char*)0, name,(const char*)0);
805*b30d1939SAndy Fiddaman cp = (char*)name+copy;
806*b30d1939SAndy Fiddaman sp = (char*)name+c;
807*b30d1939SAndy Fiddaman c = '.';
808*b30d1939SAndy Fiddaman }
809*b30d1939SAndy Fiddaman /* FALLTHROUGH */
810*b30d1939SAndy Fiddaman skip:
811*b30d1939SAndy Fiddaman case '+':
812*b30d1939SAndy Fiddaman case '=':
813*b30d1939SAndy Fiddaman *sp = 0;
814*b30d1939SAndy Fiddaman /* FALLTHROUGH */
815*b30d1939SAndy Fiddaman case 0:
816*b30d1939SAndy Fiddaman isref = 0;
817*b30d1939SAndy Fiddaman dp->last = cp;
818*b30d1939SAndy Fiddaman mode = (c=='.' || (flags&NV_NOADD))?add:NV_ADD;
819*b30d1939SAndy Fiddaman if(level++ || ((flags&NV_NOSCOPE) && c!='.'))
820*b30d1939SAndy Fiddaman mode |= HASH_NOSCOPE;
821*b30d1939SAndy Fiddaman np=0;
822*b30d1939SAndy Fiddaman if(top)
823*b30d1939SAndy Fiddaman {
824*b30d1939SAndy Fiddaman struct Ufunction *rp;
825*b30d1939SAndy Fiddaman if((rp=shp->st.real_fun) && !rp->sdict && (flags&NV_STATIC))
826*b30d1939SAndy Fiddaman {
827*b30d1939SAndy Fiddaman Dt_t *dp = dtview(shp->var_tree,(Dt_t*)0);
828*b30d1939SAndy Fiddaman rp->sdict = dtopen(&_Nvdisc,Dtoset);
829*b30d1939SAndy Fiddaman dtview(rp->sdict,dp);
830*b30d1939SAndy Fiddaman dtview(shp->var_tree,rp->sdict);
831*b30d1939SAndy Fiddaman }
832*b30d1939SAndy Fiddaman if(np = nv_search(name,shp->var_tree,0))
833*b30d1939SAndy Fiddaman {
834*b30d1939SAndy Fiddaman #if SHOPT_NAMESPACE
835*b30d1939SAndy Fiddaman if(shp->var_tree->walk==shp->var_base || (shp->var_tree->walk!=shp->var_tree && shp->namespace && nv_dict(shp->namespace)==shp->var_tree->walk))
836*b30d1939SAndy Fiddaman #else
837*b30d1939SAndy Fiddaman if(shp->var_tree->walk==shp->var_base)
838*b30d1939SAndy Fiddaman #endif /* SHOPT_NAMESPACE */
839*b30d1939SAndy Fiddaman {
840*b30d1939SAndy Fiddaman #if SHOPT_NAMESPACE
841*b30d1939SAndy Fiddaman if(!(nq = nv_search((char*)np,shp->var_base,HASH_BUCKET)))
842*b30d1939SAndy Fiddaman #endif /* SHOPT_NAMESPACE */
843*b30d1939SAndy Fiddaman nq = np;
844*b30d1939SAndy Fiddaman shp->last_root = shp->var_tree->walk;
845*b30d1939SAndy Fiddaman if((flags&NV_NOSCOPE) && *cp!='.')
846*b30d1939SAndy Fiddaman {
847*b30d1939SAndy Fiddaman if(mode==0)
848*b30d1939SAndy Fiddaman root = shp->var_tree->walk;
849*b30d1939SAndy Fiddaman else
850*b30d1939SAndy Fiddaman {
851*b30d1939SAndy Fiddaman nv_delete(np,(Dt_t*)0,NV_NOFREE);
852*b30d1939SAndy Fiddaman np = 0;
853*b30d1939SAndy Fiddaman }
854*b30d1939SAndy Fiddaman }
855*b30d1939SAndy Fiddaman }
856*b30d1939SAndy Fiddaman else
857*b30d1939SAndy Fiddaman {
858*b30d1939SAndy Fiddaman if(shp->var_tree->walk)
859*b30d1939SAndy Fiddaman root = shp->var_tree->walk;
860*b30d1939SAndy Fiddaman flags |= NV_NOSCOPE;
861*b30d1939SAndy Fiddaman noscope = 1;
862*b30d1939SAndy Fiddaman }
863*b30d1939SAndy Fiddaman }
864*b30d1939SAndy Fiddaman if(rp && rp->sdict && (flags&NV_STATIC))
865*b30d1939SAndy Fiddaman {
866*b30d1939SAndy Fiddaman root = rp->sdict;
867*b30d1939SAndy Fiddaman if(np && shp->var_tree->walk==shp->var_tree)
868*b30d1939SAndy Fiddaman {
869*b30d1939SAndy Fiddaman _nv_unset(np,0);
870*b30d1939SAndy Fiddaman nv_delete(np,shp->var_tree,0);
871*b30d1939SAndy Fiddaman np = 0;
872*b30d1939SAndy Fiddaman }
873*b30d1939SAndy Fiddaman if(!np || shp->var_tree->walk!=root)
874*b30d1939SAndy Fiddaman np = nv_search(name,root,HASH_NOSCOPE|NV_ADD);
875*b30d1939SAndy Fiddaman }
876*b30d1939SAndy Fiddaman }
877*b30d1939SAndy Fiddaman #if SHOPT_NAMESPACE
878*b30d1939SAndy Fiddaman if(!np && !noscope && *name!='.' && shp->namespace && root==shp->var_tree)
879*b30d1939SAndy Fiddaman root = nv_dict(shp->namespace);
880*b30d1939SAndy Fiddaman #endif /* SHOPT_NAMESPACE */
881*b30d1939SAndy Fiddaman if(np || (np = nv_search(name,root,mode)))
882*b30d1939SAndy Fiddaman {
883*b30d1939SAndy Fiddaman isref = nv_isref(np);
884*b30d1939SAndy Fiddaman shp->openmatch = root->walk?root->walk:root;
885*b30d1939SAndy Fiddaman if(top)
886*b30d1939SAndy Fiddaman {
887*b30d1939SAndy Fiddaman if(nq==np)
888*b30d1939SAndy Fiddaman {
889*b30d1939SAndy Fiddaman flags &= ~NV_NOSCOPE;
890*b30d1939SAndy Fiddaman root = shp->last_root;
891*b30d1939SAndy Fiddaman }
892*b30d1939SAndy Fiddaman else if(nq)
893*b30d1939SAndy Fiddaman {
894*b30d1939SAndy Fiddaman if(nv_isnull(np) && c!='.' && ((np->nvfun=nv_cover(nq)) || nq==OPTINDNOD))
895*b30d1939SAndy Fiddaman {
896*b30d1939SAndy Fiddaman np->nvname = nq->nvname;
897*b30d1939SAndy Fiddaman #if SHOPT_NAMESPACE
898*b30d1939SAndy Fiddaman if(shp->namespace && nv_dict(shp->namespace)==shp->var_tree && nv_isattr(nq,NV_EXPORT))
899*b30d1939SAndy Fiddaman nv_onattr(np,NV_EXPORT);
900*b30d1939SAndy Fiddaman #endif /* SHOPT_NAMESPACE */
901*b30d1939SAndy Fiddaman if(nq==OPTINDNOD)
902*b30d1939SAndy Fiddaman {
903*b30d1939SAndy Fiddaman np->nvfun = nq->nvfun;
904*b30d1939SAndy Fiddaman np->nvalue.lp = (&shp->st.optindex);
905*b30d1939SAndy Fiddaman nv_onattr(np,NV_INTEGER|NV_NOFREE);
906*b30d1939SAndy Fiddaman }
907*b30d1939SAndy Fiddaman }
908*b30d1939SAndy Fiddaman flags |= NV_NOSCOPE;
909*b30d1939SAndy Fiddaman }
910*b30d1939SAndy Fiddaman }
911*b30d1939SAndy Fiddaman else if(add && nv_isnull(np) && c=='.' && cp[1]!='.')
912*b30d1939SAndy Fiddaman nv_setvtree(np);
913*b30d1939SAndy Fiddaman #if SHOPT_NAMESPACE
914*b30d1939SAndy Fiddaman if(shp->namespace && root==nv_dict(shp->namespace))
915*b30d1939SAndy Fiddaman {
916*b30d1939SAndy Fiddaman flags |= NV_NOSCOPE;
917*b30d1939SAndy Fiddaman shp->last_table = shp->namespace;
918*b30d1939SAndy Fiddaman }
919*b30d1939SAndy Fiddaman #endif /* SHOPT_NAMESPACE */
920*b30d1939SAndy Fiddaman }
921*b30d1939SAndy Fiddaman if(c)
922*b30d1939SAndy Fiddaman *sp = c;
923*b30d1939SAndy Fiddaman top = 0;
924*b30d1939SAndy Fiddaman if(isref)
925*b30d1939SAndy Fiddaman {
926*b30d1939SAndy Fiddaman #if SHOPT_FIXEDARRAY
927*b30d1939SAndy Fiddaman int n=0,dim;
928*b30d1939SAndy Fiddaman #endif /* SHOPT_FIXEDARRAY */
929*b30d1939SAndy Fiddaman #if NVCACHE
930*b30d1939SAndy Fiddaman nvcache.ok = 0;
931*b30d1939SAndy Fiddaman #endif
932*b30d1939SAndy Fiddaman if(c=='.') /* don't optimize */
933*b30d1939SAndy Fiddaman shp->argaddr = 0;
934*b30d1939SAndy Fiddaman else if((flags&NV_NOREF) && (c!='[' && *cp!='.'))
935*b30d1939SAndy Fiddaman {
936*b30d1939SAndy Fiddaman if(c && !(flags&NV_NOADD))
937*b30d1939SAndy Fiddaman nv_unref(np);
938*b30d1939SAndy Fiddaman return(np);
939*b30d1939SAndy Fiddaman }
940*b30d1939SAndy Fiddaman while(nv_isref(np) && np->nvalue.cp)
941*b30d1939SAndy Fiddaman {
942*b30d1939SAndy Fiddaman root = nv_reftree(np);
943*b30d1939SAndy Fiddaman shp->last_root = root;
944*b30d1939SAndy Fiddaman shp->last_table = nv_reftable(np);
945*b30d1939SAndy Fiddaman sub = nv_refsub(np);
946*b30d1939SAndy Fiddaman #if SHOPT_FIXEDARRAY
947*b30d1939SAndy Fiddaman n = nv_refindex(np);
948*b30d1939SAndy Fiddaman dim = nv_refdimen(np);
949*b30d1939SAndy Fiddaman #endif /* SHOPT_FIXEDARRAY */
950*b30d1939SAndy Fiddaman np = nv_refnode(np);
951*b30d1939SAndy Fiddaman #if SHOPT_FIXEDARRAY
952*b30d1939SAndy Fiddaman if(n)
953*b30d1939SAndy Fiddaman {
954*b30d1939SAndy Fiddaman ap = nv_arrayptr(np);
955*b30d1939SAndy Fiddaman ap->nelem = dim;
956*b30d1939SAndy Fiddaman nv_putsub(np,(char*)0,n);
957*b30d1939SAndy Fiddaman }
958*b30d1939SAndy Fiddaman else
959*b30d1939SAndy Fiddaman #endif /* SHOPT_FIXEDARRAY */
960*b30d1939SAndy Fiddaman if(sub && c!='.')
961*b30d1939SAndy Fiddaman nv_putsub(np,sub,0L);
962*b30d1939SAndy Fiddaman flags |= NV_NOSCOPE;
963*b30d1939SAndy Fiddaman noscope = 1;
964*b30d1939SAndy Fiddaman }
965*b30d1939SAndy Fiddaman shp->first_root = root;
966*b30d1939SAndy Fiddaman if(nv_isref(np) && (c=='[' || c=='.' || !(flags&NV_ASSIGN)))
967*b30d1939SAndy Fiddaman errormsg(SH_DICT,ERROR_exit(1),e_noref,nv_name(np));
968*b30d1939SAndy Fiddaman if(sub && c==0)
969*b30d1939SAndy Fiddaman {
970*b30d1939SAndy Fiddaman if(flags&NV_ARRAY)
971*b30d1939SAndy Fiddaman {
972*b30d1939SAndy Fiddaman Namarr_t *ap = nv_arrayptr(np);
973*b30d1939SAndy Fiddaman nq = nv_opensub(np);
974*b30d1939SAndy Fiddaman if((flags&NV_ASSIGN) && (!nq || nv_isnull(nq)))
975*b30d1939SAndy Fiddaman ap->nelem++;
976*b30d1939SAndy Fiddaman if(!nq)
977*b30d1939SAndy Fiddaman goto addsub;
978*b30d1939SAndy Fiddaman else
979*b30d1939SAndy Fiddaman np = nq;
980*b30d1939SAndy Fiddaman }
981*b30d1939SAndy Fiddaman return(np);
982*b30d1939SAndy Fiddaman }
983*b30d1939SAndy Fiddaman if(np==nq)
984*b30d1939SAndy Fiddaman flags &= ~(noscope?0:NV_NOSCOPE);
985*b30d1939SAndy Fiddaman #if SHOPT_FIXEDARRAY
986*b30d1939SAndy Fiddaman else if(c || n)
987*b30d1939SAndy Fiddaman #else
988*b30d1939SAndy Fiddaman else if(c)
989*b30d1939SAndy Fiddaman #endif /* SHOPT_FIXEDARRAY */
990*b30d1939SAndy Fiddaman {
991*b30d1939SAndy Fiddaman #if SHOPT_FIXEDARRAY
992*b30d1939SAndy Fiddaman static char null[1] = "";
993*b30d1939SAndy Fiddaman #endif /* SHOPT_FIXEDARRAY */
994*b30d1939SAndy Fiddaman c = (cp-sp);
995*b30d1939SAndy Fiddaman copy = strlen(cp=nv_name(np));
996*b30d1939SAndy Fiddaman dp->nofree |= 1;
997*b30d1939SAndy Fiddaman #if SHOPT_FIXEDARRAY
998*b30d1939SAndy Fiddaman if(*sp==0)
999*b30d1939SAndy Fiddaman name = cp;
1000*b30d1939SAndy Fiddaman else
1001*b30d1939SAndy Fiddaman #endif /* SHOPT_FIXEDARRAY */
1002*b30d1939SAndy Fiddaman name = copystack(cp,sp,sub);
1003*b30d1939SAndy Fiddaman sp = (char*)name + copy;
1004*b30d1939SAndy Fiddaman cp = sp+c;
1005*b30d1939SAndy Fiddaman c = *sp;
1006*b30d1939SAndy Fiddaman if(!noscope)
1007*b30d1939SAndy Fiddaman flags &= ~NV_NOSCOPE;
1008*b30d1939SAndy Fiddaman #if SHOPT_FIXEDARRAY
1009*b30d1939SAndy Fiddaman if(c==0)
1010*b30d1939SAndy Fiddaman nv_endsubscript(np,null,NV_ADD);
1011*b30d1939SAndy Fiddaman #endif /* SHOPT_FIXEDARRAY */
1012*b30d1939SAndy Fiddaman }
1013*b30d1939SAndy Fiddaman flags |= NV_NOREF;
1014*b30d1939SAndy Fiddaman if(*cp==0 && nv_isnull(np) && !nv_isarray(np))
1015*b30d1939SAndy Fiddaman nofree = NV_NOFREE;
1016*b30d1939SAndy Fiddaman }
1017*b30d1939SAndy Fiddaman shp->last_root = root;
1018*b30d1939SAndy Fiddaman if(*cp && cp[1]=='.')
1019*b30d1939SAndy Fiddaman cp++;
1020*b30d1939SAndy Fiddaman if(c=='.' && (cp[1]==0 || cp[1]=='=' || cp[1]=='+'))
1021*b30d1939SAndy Fiddaman {
1022*b30d1939SAndy Fiddaman nv_local = 1;
1023*b30d1939SAndy Fiddaman if(np)
1024*b30d1939SAndy Fiddaman nv_onattr(np,nofree);
1025*b30d1939SAndy Fiddaman return(np);
1026*b30d1939SAndy Fiddaman }
1027*b30d1939SAndy Fiddaman if(cp[-1]=='.')
1028*b30d1939SAndy Fiddaman cp--;
1029*b30d1939SAndy Fiddaman do
1030*b30d1939SAndy Fiddaman {
1031*b30d1939SAndy Fiddaman #if SHOPT_FIXEDARRAY
1032*b30d1939SAndy Fiddaman int fixed;
1033*b30d1939SAndy Fiddaman #endif /* SHOPT_FIXEDARRAY */
1034*b30d1939SAndy Fiddaman if(!np)
1035*b30d1939SAndy Fiddaman {
1036*b30d1939SAndy Fiddaman if(!nq && *sp=='[' && *cp==0 && cp[-1]==']')
1037*b30d1939SAndy Fiddaman {
1038*b30d1939SAndy Fiddaman /*
1039*b30d1939SAndy Fiddaman * for backward compatibility
1040*b30d1939SAndy Fiddaman * evaluate subscript for
1041*b30d1939SAndy Fiddaman * possible side effects
1042*b30d1939SAndy Fiddaman */
1043*b30d1939SAndy Fiddaman cp[-1] = 0;
1044*b30d1939SAndy Fiddaman sh_arith(shp,sp+1);
1045*b30d1939SAndy Fiddaman cp[-1] = ']';
1046*b30d1939SAndy Fiddaman }
1047*b30d1939SAndy Fiddaman return(np);
1048*b30d1939SAndy Fiddaman }
1049*b30d1939SAndy Fiddaman #if SHOPT_FIXEDARRAY
1050*b30d1939SAndy Fiddaman fixed = 0;
1051*b30d1939SAndy Fiddaman if((ap=nv_arrayptr(np)) && ap->fixed)
1052*b30d1939SAndy Fiddaman fixed = 1;
1053*b30d1939SAndy Fiddaman #endif /* SHOPT_FIXEDARRAY */
1054*b30d1939SAndy Fiddaman if(c=='[' || (c=='.' && nv_isarray(np)))
1055*b30d1939SAndy Fiddaman {
1056*b30d1939SAndy Fiddaman int n = 0;
1057*b30d1939SAndy Fiddaman sub = 0;
1058*b30d1939SAndy Fiddaman mode &= ~HASH_NOSCOPE;
1059*b30d1939SAndy Fiddaman if(c=='[')
1060*b30d1939SAndy Fiddaman {
1061*b30d1939SAndy Fiddaman #if SHOPT_FIXEDARRAY
1062*b30d1939SAndy Fiddaman Namarr_t *ap = nv_arrayptr(np);
1063*b30d1939SAndy Fiddaman #endif /* SHOPT_FIXEDARRAY */
1064*b30d1939SAndy Fiddaman #if 0
1065*b30d1939SAndy Fiddaman int scan = ap?(ap->nelem&ARRAY_SCAN):0;
1066*b30d1939SAndy Fiddaman #endif
1067*b30d1939SAndy Fiddaman n = mode|nv_isarray(np);
1068*b30d1939SAndy Fiddaman if(!mode && (flags&NV_ARRAY) && ((c=sp[1])=='*' || c=='@') && sp[2]==']')
1069*b30d1939SAndy Fiddaman {
1070*b30d1939SAndy Fiddaman /* not implemented yet */
1071*b30d1939SAndy Fiddaman dp->last = cp;
1072*b30d1939SAndy Fiddaman return(np);
1073*b30d1939SAndy Fiddaman }
1074*b30d1939SAndy Fiddaman #if SHOPT_FIXEDARRAY
1075*b30d1939SAndy Fiddaman if(fixed)
1076*b30d1939SAndy Fiddaman flags |= NV_FARRAY;
1077*b30d1939SAndy Fiddaman else
1078*b30d1939SAndy Fiddaman #endif /* SHOPT_FIXEDARRAY */
1079*b30d1939SAndy Fiddaman if((n&NV_ADD)&&(flags&NV_ARRAY))
1080*b30d1939SAndy Fiddaman n |= ARRAY_FILL;
1081*b30d1939SAndy Fiddaman if(flags&NV_ASSIGN)
1082*b30d1939SAndy Fiddaman n |= NV_ADD;
1083*b30d1939SAndy Fiddaman cp = nv_endsubscript(np,sp,n|(flags&(NV_ASSIGN|NV_FARRAY)));
1084*b30d1939SAndy Fiddaman #if SHOPT_FIXEDARRAY
1085*b30d1939SAndy Fiddaman flags &= ~NV_FARRAY;
1086*b30d1939SAndy Fiddaman if(fixed)
1087*b30d1939SAndy Fiddaman flags &= ~NV_ARRAY;
1088*b30d1939SAndy Fiddaman
1089*b30d1939SAndy Fiddaman #endif /* SHOPT_FIXEDARRAY */
1090*b30d1939SAndy Fiddaman #if 0
1091*b30d1939SAndy Fiddaman if(scan)
1092*b30d1939SAndy Fiddaman nv_putsub(np,NIL(char*),ARRAY_SCAN);
1093*b30d1939SAndy Fiddaman #endif
1094*b30d1939SAndy Fiddaman }
1095*b30d1939SAndy Fiddaman else
1096*b30d1939SAndy Fiddaman cp = sp;
1097*b30d1939SAndy Fiddaman if((c = *cp)=='.' || (c=='[' && nv_isarray(np)) || (n&ARRAY_FILL) || ((ap || (flags&NV_ASSIGN)) && (flags&NV_ARRAY)))
1098*b30d1939SAndy Fiddaman
1099*b30d1939SAndy Fiddaman {
1100*b30d1939SAndy Fiddaman int m = cp-sp;
1101*b30d1939SAndy Fiddaman sub = m?nv_getsub(np):0;
1102*b30d1939SAndy Fiddaman if(!sub)
1103*b30d1939SAndy Fiddaman {
1104*b30d1939SAndy Fiddaman if(m && !(n&NV_ADD))
1105*b30d1939SAndy Fiddaman return(0);
1106*b30d1939SAndy Fiddaman sub = "0";
1107*b30d1939SAndy Fiddaman }
1108*b30d1939SAndy Fiddaman n = strlen(sub)+2;
1109*b30d1939SAndy Fiddaman if(!copy)
1110*b30d1939SAndy Fiddaman {
1111*b30d1939SAndy Fiddaman copy = cp-name;
1112*b30d1939SAndy Fiddaman dp->nofree |= 1;
1113*b30d1939SAndy Fiddaman name = copystack((const char*)0, name,(const char*)0);
1114*b30d1939SAndy Fiddaman cp = (char*)name+copy;
1115*b30d1939SAndy Fiddaman sp = cp-m;
1116*b30d1939SAndy Fiddaman }
1117*b30d1939SAndy Fiddaman if(n <= m)
1118*b30d1939SAndy Fiddaman {
1119*b30d1939SAndy Fiddaman if(n)
1120*b30d1939SAndy Fiddaman {
1121*b30d1939SAndy Fiddaman memcpy(sp+1,sub,n-2);
1122*b30d1939SAndy Fiddaman sp[n-1] = ']';
1123*b30d1939SAndy Fiddaman }
1124*b30d1939SAndy Fiddaman if(n < m)
1125*b30d1939SAndy Fiddaman {
1126*b30d1939SAndy Fiddaman char *dp = sp+n;
1127*b30d1939SAndy Fiddaman while(*dp++=*cp++);
1128*b30d1939SAndy Fiddaman cp = sp+n;
1129*b30d1939SAndy Fiddaman }
1130*b30d1939SAndy Fiddaman }
1131*b30d1939SAndy Fiddaman else
1132*b30d1939SAndy Fiddaman {
1133*b30d1939SAndy Fiddaman int r = n-m;
1134*b30d1939SAndy Fiddaman m = sp-name;
1135*b30d1939SAndy Fiddaman name = stack_extend(name, cp-1, r);
1136*b30d1939SAndy Fiddaman sp = (char*)name + m;
1137*b30d1939SAndy Fiddaman *sp = '[';
1138*b30d1939SAndy Fiddaman memcpy(sp+1,sub,n-2);
1139*b30d1939SAndy Fiddaman sp[n-1] = ']';
1140*b30d1939SAndy Fiddaman cp = sp+n;
1141*b30d1939SAndy Fiddaman
1142*b30d1939SAndy Fiddaman }
1143*b30d1939SAndy Fiddaman }
1144*b30d1939SAndy Fiddaman else if(c==0 && mode && (n=nv_aindex(np))>0)
1145*b30d1939SAndy Fiddaman nv_putsub(np,(char*)0,n);
1146*b30d1939SAndy Fiddaman #if SHOPT_FIXEDARRAY
1147*b30d1939SAndy Fiddaman else if(n==0 && !fixed && (c==0 || (c=='[' && !nv_isarray(np))))
1148*b30d1939SAndy Fiddaman #else
1149*b30d1939SAndy Fiddaman else if(n==0 && (c==0 || (c=='[' && !nv_isarray(np))))
1150*b30d1939SAndy Fiddaman #endif /* SHOPT_FIXEDARRAY */
1151*b30d1939SAndy Fiddaman {
1152*b30d1939SAndy Fiddaman /* subscript must be 0*/
1153*b30d1939SAndy Fiddaman cp[-1] = 0;
1154*b30d1939SAndy Fiddaman n = sh_arith(shp,sp+1);
1155*b30d1939SAndy Fiddaman cp[-1] = ']';
1156*b30d1939SAndy Fiddaman if(n)
1157*b30d1939SAndy Fiddaman return(0);
1158*b30d1939SAndy Fiddaman if(c)
1159*b30d1939SAndy Fiddaman sp = cp;
1160*b30d1939SAndy Fiddaman }
1161*b30d1939SAndy Fiddaman dp->last = cp;
1162*b30d1939SAndy Fiddaman if(nv_isarray(np) && (c=='[' || c=='.' || (flags&NV_ARRAY)))
1163*b30d1939SAndy Fiddaman {
1164*b30d1939SAndy Fiddaman addsub:
1165*b30d1939SAndy Fiddaman sp = cp;
1166*b30d1939SAndy Fiddaman if(!(nq = nv_opensub(np)))
1167*b30d1939SAndy Fiddaman {
1168*b30d1939SAndy Fiddaman Namarr_t *ap = nv_arrayptr(np);
1169*b30d1939SAndy Fiddaman if(!sub && (flags&NV_NOADD))
1170*b30d1939SAndy Fiddaman return(0);
1171*b30d1939SAndy Fiddaman n = mode|((flags&NV_NOADD)?0:NV_ADD);
1172*b30d1939SAndy Fiddaman if(!ap && (n&NV_ADD))
1173*b30d1939SAndy Fiddaman {
1174*b30d1939SAndy Fiddaman nv_putsub(np,sub,ARRAY_FILL);
1175*b30d1939SAndy Fiddaman ap = nv_arrayptr(np);
1176*b30d1939SAndy Fiddaman }
1177*b30d1939SAndy Fiddaman if(n && ap && !ap->table)
1178*b30d1939SAndy Fiddaman ap->table = dtopen(&_Nvdisc,Dtoset);
1179*b30d1939SAndy Fiddaman if(ap && ap->table && (nq=nv_search(sub,ap->table,n)))
1180*b30d1939SAndy Fiddaman nq->nvenv = (char*)np;
1181*b30d1939SAndy Fiddaman if(nq && nv_isnull(nq))
1182*b30d1939SAndy Fiddaman nq = nv_arraychild(np,nq,c);
1183*b30d1939SAndy Fiddaman }
1184*b30d1939SAndy Fiddaman if(nq)
1185*b30d1939SAndy Fiddaman {
1186*b30d1939SAndy Fiddaman if(c=='.' && !nv_isvtree(nq))
1187*b30d1939SAndy Fiddaman {
1188*b30d1939SAndy Fiddaman if(flags&NV_NOADD)
1189*b30d1939SAndy Fiddaman return(0);
1190*b30d1939SAndy Fiddaman nv_setvtree(nq);
1191*b30d1939SAndy Fiddaman }
1192*b30d1939SAndy Fiddaman nv_onattr(np,nofree);
1193*b30d1939SAndy Fiddaman nofree = 0;
1194*b30d1939SAndy Fiddaman np = nq;
1195*b30d1939SAndy Fiddaman }
1196*b30d1939SAndy Fiddaman else if(memcmp(cp,"[0]",3))
1197*b30d1939SAndy Fiddaman return(nq);
1198*b30d1939SAndy Fiddaman else
1199*b30d1939SAndy Fiddaman {
1200*b30d1939SAndy Fiddaman /* ignore [0] */
1201*b30d1939SAndy Fiddaman dp->last = cp += 3;
1202*b30d1939SAndy Fiddaman c = *cp;
1203*b30d1939SAndy Fiddaman }
1204*b30d1939SAndy Fiddaman }
1205*b30d1939SAndy Fiddaman }
1206*b30d1939SAndy Fiddaman #if SHOPT_FIXEDARRAY
1207*b30d1939SAndy Fiddaman else if(nv_isarray(np) && (!fixed || cp[-1]!=']'))
1208*b30d1939SAndy Fiddaman #else
1209*b30d1939SAndy Fiddaman else if(nv_isarray(np))
1210*b30d1939SAndy Fiddaman #endif /* SHOPT_FIXEDARRAY */
1211*b30d1939SAndy Fiddaman {
1212*b30d1939SAndy Fiddaman if(c==0 && (flags&NV_MOVE))
1213*b30d1939SAndy Fiddaman return(np);
1214*b30d1939SAndy Fiddaman nv_putsub(np,NIL(char*),ARRAY_UNDEF);
1215*b30d1939SAndy Fiddaman }
1216*b30d1939SAndy Fiddaman nv_onattr(np,nofree);
1217*b30d1939SAndy Fiddaman nofree = 0;
1218*b30d1939SAndy Fiddaman if(c=='.' && (fp=np->nvfun))
1219*b30d1939SAndy Fiddaman {
1220*b30d1939SAndy Fiddaman for(; fp; fp=fp->next)
1221*b30d1939SAndy Fiddaman {
1222*b30d1939SAndy Fiddaman if(fp->disc && fp->disc->createf)
1223*b30d1939SAndy Fiddaman break;
1224*b30d1939SAndy Fiddaman }
1225*b30d1939SAndy Fiddaman if(fp)
1226*b30d1939SAndy Fiddaman {
1227*b30d1939SAndy Fiddaman if((nq = (*fp->disc->createf)(np,cp+1,flags,fp)) == np)
1228*b30d1939SAndy Fiddaman {
1229*b30d1939SAndy Fiddaman add = NV_ADD;
1230*b30d1939SAndy Fiddaman shp->last_table = 0;
1231*b30d1939SAndy Fiddaman break;
1232*b30d1939SAndy Fiddaman }
1233*b30d1939SAndy Fiddaman else if(np=nq)
1234*b30d1939SAndy Fiddaman {
1235*b30d1939SAndy Fiddaman if((c = *(sp=cp=dp->last=fp->last))==0)
1236*b30d1939SAndy Fiddaman {
1237*b30d1939SAndy Fiddaman if(nv_isarray(np) && sp[-1]!=']')
1238*b30d1939SAndy Fiddaman nv_putsub(np,NIL(char*),ARRAY_UNDEF);
1239*b30d1939SAndy Fiddaman return(np);
1240*b30d1939SAndy Fiddaman }
1241*b30d1939SAndy Fiddaman }
1242*b30d1939SAndy Fiddaman }
1243*b30d1939SAndy Fiddaman }
1244*b30d1939SAndy Fiddaman }
1245*b30d1939SAndy Fiddaman while(c=='[');
1246*b30d1939SAndy Fiddaman if(c!='.' || cp[1]=='.')
1247*b30d1939SAndy Fiddaman return(np);
1248*b30d1939SAndy Fiddaman cp++;
1249*b30d1939SAndy Fiddaman break;
1250*b30d1939SAndy Fiddaman default:
1251*b30d1939SAndy Fiddaman dp->last = cp;
1252*b30d1939SAndy Fiddaman if((c = mbchar(cp)) && !isaletter(c))
1253*b30d1939SAndy Fiddaman return(np);
1254*b30d1939SAndy Fiddaman while(xp=cp, c=mbchar(cp), isaname(c));
1255*b30d1939SAndy Fiddaman cp = xp;
1256*b30d1939SAndy Fiddaman }
1257*b30d1939SAndy Fiddaman }
1258*b30d1939SAndy Fiddaman return(np);
1259*b30d1939SAndy Fiddaman }
1260*b30d1939SAndy Fiddaman
1261*b30d1939SAndy Fiddaman /*
1262*b30d1939SAndy Fiddaman * delete the node <np> from the dictionary <root> and clear from the cache
1263*b30d1939SAndy Fiddaman * if <root> is NULL, only the cache is cleared
1264*b30d1939SAndy Fiddaman * if flags does not contain NV_NOFREE, the node is freed
1265*b30d1939SAndy Fiddaman * if np==0 && !root && flags==0, delete the Refdict dictionary
1266*b30d1939SAndy Fiddaman */
nv_delete(Namval_t * np,Dt_t * root,int flags)1267*b30d1939SAndy Fiddaman void nv_delete(Namval_t* np, Dt_t *root, int flags)
1268*b30d1939SAndy Fiddaman {
1269*b30d1939SAndy Fiddaman #if NVCACHE
1270*b30d1939SAndy Fiddaman register int c;
1271*b30d1939SAndy Fiddaman struct Cache_entry *xp;
1272*b30d1939SAndy Fiddaman for(c=0,xp=nvcache.entries ; c < NVCACHE; xp= &nvcache.entries[++c])
1273*b30d1939SAndy Fiddaman {
1274*b30d1939SAndy Fiddaman if(xp->np==np)
1275*b30d1939SAndy Fiddaman xp->root = 0;
1276*b30d1939SAndy Fiddaman }
1277*b30d1939SAndy Fiddaman #endif
1278*b30d1939SAndy Fiddaman if(!np && !root && flags==0)
1279*b30d1939SAndy Fiddaman {
1280*b30d1939SAndy Fiddaman if(Refdict)
1281*b30d1939SAndy Fiddaman dtclose(Refdict);
1282*b30d1939SAndy Fiddaman Refdict = 0;
1283*b30d1939SAndy Fiddaman return;
1284*b30d1939SAndy Fiddaman }
1285*b30d1939SAndy Fiddaman if(root || !(flags&NV_NOFREE))
1286*b30d1939SAndy Fiddaman {
1287*b30d1939SAndy Fiddaman if(!(flags&NV_FUNCTION) && Refdict)
1288*b30d1939SAndy Fiddaman {
1289*b30d1939SAndy Fiddaman Namval_t **key = &np;
1290*b30d1939SAndy Fiddaman struct Namref *rp;
1291*b30d1939SAndy Fiddaman while(rp = (struct Namref*)dtmatch(Refdict,(void*)key))
1292*b30d1939SAndy Fiddaman {
1293*b30d1939SAndy Fiddaman if(rp->sub)
1294*b30d1939SAndy Fiddaman free(rp->sub);
1295*b30d1939SAndy Fiddaman rp->sub = 0;
1296*b30d1939SAndy Fiddaman rp = dtdelete(Refdict,(void*)rp);
1297*b30d1939SAndy Fiddaman rp->np = &NullNode;
1298*b30d1939SAndy Fiddaman }
1299*b30d1939SAndy Fiddaman }
1300*b30d1939SAndy Fiddaman }
1301*b30d1939SAndy Fiddaman if(root)
1302*b30d1939SAndy Fiddaman {
1303*b30d1939SAndy Fiddaman if(dtdelete(root,np))
1304*b30d1939SAndy Fiddaman {
1305*b30d1939SAndy Fiddaman if(!(flags&NV_NOFREE) && ((flags&NV_FUNCTION) || !nv_subsaved(np)))
1306*b30d1939SAndy Fiddaman {
1307*b30d1939SAndy Fiddaman Namarr_t *ap;
1308*b30d1939SAndy Fiddaman if(nv_isarray(np) && np->nvfun &&
1309*b30d1939SAndy Fiddaman (ap=nv_arrayptr(np)) && array_assoc(ap)) {
1310*b30d1939SAndy Fiddaman while(nv_associative(np,0,NV_ANEXT))
1311*b30d1939SAndy Fiddaman nv_associative(np, 0, NV_ADELETE);
1312*b30d1939SAndy Fiddaman nv_associative(np, 0, NV_AFREE);
1313*b30d1939SAndy Fiddaman free((void*)np->nvfun);
1314*b30d1939SAndy Fiddaman }
1315*b30d1939SAndy Fiddaman free((void*)np);
1316*b30d1939SAndy Fiddaman }
1317*b30d1939SAndy Fiddaman }
1318*b30d1939SAndy Fiddaman #if 0
1319*b30d1939SAndy Fiddaman else
1320*b30d1939SAndy Fiddaman {
1321*b30d1939SAndy Fiddaman sfprintf(sfstderr,"%s not deleted\n",nv_name(np));
1322*b30d1939SAndy Fiddaman sfsync(sfstderr);
1323*b30d1939SAndy Fiddaman }
1324*b30d1939SAndy Fiddaman #endif
1325*b30d1939SAndy Fiddaman }
1326*b30d1939SAndy Fiddaman }
1327*b30d1939SAndy Fiddaman
1328*b30d1939SAndy Fiddaman /*
1329*b30d1939SAndy Fiddaman * Put <arg> into associative memory.
1330*b30d1939SAndy Fiddaman * If <flags> & NV_ARRAY then follow array to next subscript
1331*b30d1939SAndy Fiddaman * If <flags> & NV_NOARRAY then subscript is not allowed
1332*b30d1939SAndy Fiddaman * If <flags> & NV_NOSCOPE then use the current scope only
1333*b30d1939SAndy Fiddaman * If <flags> & NV_ASSIGN then assignment is allowed
1334*b30d1939SAndy Fiddaman * If <flags> & NV_IDENT then name must be an identifier
1335*b30d1939SAndy Fiddaman * If <flags> & NV_VARNAME then name must be a valid variable name
1336*b30d1939SAndy Fiddaman * If <flags> & NV_NOADD then node will not be added if not found
1337*b30d1939SAndy Fiddaman * If <flags> & NV_NOREF then don't follow reference
1338*b30d1939SAndy Fiddaman * If <flags> & NV_NOFAIL then don't generate an error message on failure
1339*b30d1939SAndy Fiddaman * If <flags> & NV_STATIC then unset before an assignment
1340*b30d1939SAndy Fiddaman * If <flags> & NV_UNJUST then unset attributes before assignment
1341*b30d1939SAndy Fiddaman * SH_INIT is only set while initializing the environment
1342*b30d1939SAndy Fiddaman */
nv_open(const char * name,Dt_t * root,int flags)1343*b30d1939SAndy Fiddaman Namval_t *nv_open(const char *name, Dt_t *root, int flags)
1344*b30d1939SAndy Fiddaman {
1345*b30d1939SAndy Fiddaman Shell_t *shp = sh_getinterp();
1346*b30d1939SAndy Fiddaman register char *cp=(char*)name;
1347*b30d1939SAndy Fiddaman register int c;
1348*b30d1939SAndy Fiddaman register Namval_t *np=0;
1349*b30d1939SAndy Fiddaman Namfun_t fun;
1350*b30d1939SAndy Fiddaman int append=0;
1351*b30d1939SAndy Fiddaman const char *msg = e_varname;
1352*b30d1939SAndy Fiddaman char *fname = 0;
1353*b30d1939SAndy Fiddaman int offset = staktell();
1354*b30d1939SAndy Fiddaman Dt_t *funroot;
1355*b30d1939SAndy Fiddaman #if NVCACHE
1356*b30d1939SAndy Fiddaman struct Cache_entry *xp;
1357*b30d1939SAndy Fiddaman #endif
1358*b30d1939SAndy Fiddaman
1359*b30d1939SAndy Fiddaman sh_stats(STAT_NVOPEN);
1360*b30d1939SAndy Fiddaman memset(&fun,0,sizeof(fun));
1361*b30d1939SAndy Fiddaman shp->openmatch = 0;
1362*b30d1939SAndy Fiddaman shp->last_table = 0;
1363*b30d1939SAndy Fiddaman if(!root)
1364*b30d1939SAndy Fiddaman root = shp->var_tree;
1365*b30d1939SAndy Fiddaman shp->last_root = root;
1366*b30d1939SAndy Fiddaman if(root==shp->fun_tree)
1367*b30d1939SAndy Fiddaman {
1368*b30d1939SAndy Fiddaman flags |= NV_NOREF;
1369*b30d1939SAndy Fiddaman msg = e_badfun;
1370*b30d1939SAndy Fiddaman if(strchr(name,'.'))
1371*b30d1939SAndy Fiddaman {
1372*b30d1939SAndy Fiddaman name = cp = copystack(0,name,(const char*)0);
1373*b30d1939SAndy Fiddaman fname = strrchr(cp,'.');
1374*b30d1939SAndy Fiddaman *fname = 0;
1375*b30d1939SAndy Fiddaman fun.nofree |= 1;
1376*b30d1939SAndy Fiddaman flags &= ~NV_IDENT;
1377*b30d1939SAndy Fiddaman funroot = root;
1378*b30d1939SAndy Fiddaman root = shp->var_tree;
1379*b30d1939SAndy Fiddaman }
1380*b30d1939SAndy Fiddaman }
1381*b30d1939SAndy Fiddaman else if(!(flags&(NV_IDENT|NV_VARNAME|NV_ASSIGN)))
1382*b30d1939SAndy Fiddaman {
1383*b30d1939SAndy Fiddaman long mode = ((flags&NV_NOADD)?0:NV_ADD);
1384*b30d1939SAndy Fiddaman if(flags&NV_NOSCOPE)
1385*b30d1939SAndy Fiddaman mode |= HASH_SCOPE|HASH_NOSCOPE;
1386*b30d1939SAndy Fiddaman np = nv_search(name,root,mode);
1387*b30d1939SAndy Fiddaman if(np && !(flags&NV_REF))
1388*b30d1939SAndy Fiddaman {
1389*b30d1939SAndy Fiddaman while(nv_isref(np))
1390*b30d1939SAndy Fiddaman {
1391*b30d1939SAndy Fiddaman shp->last_table = nv_reftable(np);
1392*b30d1939SAndy Fiddaman np = nv_refnode(np);
1393*b30d1939SAndy Fiddaman }
1394*b30d1939SAndy Fiddaman }
1395*b30d1939SAndy Fiddaman return(np);
1396*b30d1939SAndy Fiddaman }
1397*b30d1939SAndy Fiddaman else if(shp->prefix && (flags&NV_ASSIGN))
1398*b30d1939SAndy Fiddaman {
1399*b30d1939SAndy Fiddaman name = cp = copystack(shp->prefix,name,(const char*)0);
1400*b30d1939SAndy Fiddaman fun.nofree |= 1;
1401*b30d1939SAndy Fiddaman }
1402*b30d1939SAndy Fiddaman c = *(unsigned char*)cp;
1403*b30d1939SAndy Fiddaman if(root==shp->alias_tree)
1404*b30d1939SAndy Fiddaman {
1405*b30d1939SAndy Fiddaman msg = e_aliname;
1406*b30d1939SAndy Fiddaman while((c= *(unsigned char*)cp++) && (c!='=') && (c!='/') &&
1407*b30d1939SAndy Fiddaman (c>=0x200 || !(c=sh_lexstates[ST_NORM][c]) || c==S_EPAT || c==S_COLON));
1408*b30d1939SAndy Fiddaman if(shp->subshell && c=='=')
1409*b30d1939SAndy Fiddaman root = sh_subaliastree(1);
1410*b30d1939SAndy Fiddaman if(c= *--cp)
1411*b30d1939SAndy Fiddaman *cp = 0;
1412*b30d1939SAndy Fiddaman np = nv_search(name, root, (flags&NV_NOADD)?0:NV_ADD);
1413*b30d1939SAndy Fiddaman if(c)
1414*b30d1939SAndy Fiddaman *cp = c;
1415*b30d1939SAndy Fiddaman goto skip;
1416*b30d1939SAndy Fiddaman }
1417*b30d1939SAndy Fiddaman else if(flags&NV_IDENT)
1418*b30d1939SAndy Fiddaman msg = e_ident;
1419*b30d1939SAndy Fiddaman else if(c=='.')
1420*b30d1939SAndy Fiddaman {
1421*b30d1939SAndy Fiddaman c = *++cp;
1422*b30d1939SAndy Fiddaman flags |= NV_NOREF;
1423*b30d1939SAndy Fiddaman if(root==shp->var_tree)
1424*b30d1939SAndy Fiddaman root = shp->var_base;
1425*b30d1939SAndy Fiddaman shp->last_table = 0;
1426*b30d1939SAndy Fiddaman }
1427*b30d1939SAndy Fiddaman if(c= !isaletter(c))
1428*b30d1939SAndy Fiddaman goto skip;
1429*b30d1939SAndy Fiddaman #if NVCACHE
1430*b30d1939SAndy Fiddaman for(c=0,xp=nvcache.entries ; c < NVCACHE; xp= &nvcache.entries[++c])
1431*b30d1939SAndy Fiddaman {
1432*b30d1939SAndy Fiddaman if(xp->root!=root)
1433*b30d1939SAndy Fiddaman continue;
1434*b30d1939SAndy Fiddaman if(*name==*xp->name && xp->namespace==shp->namespace && (flags&(NV_ARRAY|NV_NOSCOPE))==xp->flags && memcmp(xp->name,name,xp->len)==0 && (name[xp->len]==0 || name[xp->len]=='=' || name[xp->len]=='+'))
1435*b30d1939SAndy Fiddaman {
1436*b30d1939SAndy Fiddaman sh_stats(STAT_NVHITS);
1437*b30d1939SAndy Fiddaman np = xp->np;
1438*b30d1939SAndy Fiddaman cp = (char*)name+xp->len;
1439*b30d1939SAndy Fiddaman if(nv_isarray(np) && !(flags&NV_MOVE))
1440*b30d1939SAndy Fiddaman nv_putsub(np,NIL(char*),ARRAY_UNDEF);
1441*b30d1939SAndy Fiddaman shp->last_table = xp->last_table;
1442*b30d1939SAndy Fiddaman shp->last_root = xp->last_root;
1443*b30d1939SAndy Fiddaman goto nocache;
1444*b30d1939SAndy Fiddaman }
1445*b30d1939SAndy Fiddaman }
1446*b30d1939SAndy Fiddaman nvcache.ok = 1;
1447*b30d1939SAndy Fiddaman #endif
1448*b30d1939SAndy Fiddaman np = nv_create(name, root, flags, &fun);
1449*b30d1939SAndy Fiddaman cp = fun.last;
1450*b30d1939SAndy Fiddaman #if NVCACHE
1451*b30d1939SAndy Fiddaman if(np && nvcache.ok && cp[-1]!=']')
1452*b30d1939SAndy Fiddaman {
1453*b30d1939SAndy Fiddaman xp = &nvcache.entries[nvcache.index];
1454*b30d1939SAndy Fiddaman if(*cp)
1455*b30d1939SAndy Fiddaman {
1456*b30d1939SAndy Fiddaman char *sp = strchr(name,*cp);
1457*b30d1939SAndy Fiddaman if(!sp)
1458*b30d1939SAndy Fiddaman goto nocache;
1459*b30d1939SAndy Fiddaman xp->len = sp-name;
1460*b30d1939SAndy Fiddaman }
1461*b30d1939SAndy Fiddaman else
1462*b30d1939SAndy Fiddaman xp->len = strlen(name);
1463*b30d1939SAndy Fiddaman c = roundof(xp->len+1,32);
1464*b30d1939SAndy Fiddaman if(c > xp->size)
1465*b30d1939SAndy Fiddaman {
1466*b30d1939SAndy Fiddaman if(xp->size==0)
1467*b30d1939SAndy Fiddaman xp->name = malloc(c);
1468*b30d1939SAndy Fiddaman else
1469*b30d1939SAndy Fiddaman xp->name = realloc(xp->name,c);
1470*b30d1939SAndy Fiddaman xp->size = c;
1471*b30d1939SAndy Fiddaman }
1472*b30d1939SAndy Fiddaman memcpy(xp->name,name,xp->len);
1473*b30d1939SAndy Fiddaman xp->name[xp->len] = 0;
1474*b30d1939SAndy Fiddaman xp->root = root;
1475*b30d1939SAndy Fiddaman xp->np = np;
1476*b30d1939SAndy Fiddaman xp->namespace = shp->namespace;
1477*b30d1939SAndy Fiddaman xp->last_table = shp->last_table;
1478*b30d1939SAndy Fiddaman xp->last_root = shp->last_root;
1479*b30d1939SAndy Fiddaman xp->flags = (flags&(NV_ARRAY|NV_NOSCOPE));
1480*b30d1939SAndy Fiddaman nvcache.index = (nvcache.index+1)&(NVCACHE-1);
1481*b30d1939SAndy Fiddaman }
1482*b30d1939SAndy Fiddaman nocache:
1483*b30d1939SAndy Fiddaman nvcache.ok = 0;
1484*b30d1939SAndy Fiddaman #endif
1485*b30d1939SAndy Fiddaman if(fname)
1486*b30d1939SAndy Fiddaman {
1487*b30d1939SAndy Fiddaman c = ((flags&NV_NOSCOPE)?HASH_NOSCOPE:0)|((flags&NV_NOADD)?0:NV_ADD);
1488*b30d1939SAndy Fiddaman *fname = '.';
1489*b30d1939SAndy Fiddaman np = nv_search(name, funroot, c);
1490*b30d1939SAndy Fiddaman *fname = 0;
1491*b30d1939SAndy Fiddaman }
1492*b30d1939SAndy Fiddaman else
1493*b30d1939SAndy Fiddaman {
1494*b30d1939SAndy Fiddaman if(*cp=='.' && cp[1]=='.')
1495*b30d1939SAndy Fiddaman {
1496*b30d1939SAndy Fiddaman append |= NV_NODISC;
1497*b30d1939SAndy Fiddaman cp+=2;
1498*b30d1939SAndy Fiddaman }
1499*b30d1939SAndy Fiddaman if(*cp=='+' && cp[1]=='=')
1500*b30d1939SAndy Fiddaman {
1501*b30d1939SAndy Fiddaman append |= NV_APPEND;
1502*b30d1939SAndy Fiddaman cp++;
1503*b30d1939SAndy Fiddaman }
1504*b30d1939SAndy Fiddaman }
1505*b30d1939SAndy Fiddaman c = *cp;
1506*b30d1939SAndy Fiddaman skip:
1507*b30d1939SAndy Fiddaman #if SHOPT_TYPEDEF
1508*b30d1939SAndy Fiddaman if(np && shp->mktype)
1509*b30d1939SAndy Fiddaman np = nv_addnode(np,0);
1510*b30d1939SAndy Fiddaman #endif /* SHOPT_TYPEDEF */
1511*b30d1939SAndy Fiddaman if(c=='=' && np && (flags&NV_ASSIGN))
1512*b30d1939SAndy Fiddaman {
1513*b30d1939SAndy Fiddaman cp++;
1514*b30d1939SAndy Fiddaman if(sh_isstate(SH_INIT))
1515*b30d1939SAndy Fiddaman {
1516*b30d1939SAndy Fiddaman nv_putval(np, cp, NV_RDONLY);
1517*b30d1939SAndy Fiddaman if(np==PWDNOD)
1518*b30d1939SAndy Fiddaman nv_onattr(np,NV_TAGGED);
1519*b30d1939SAndy Fiddaman }
1520*b30d1939SAndy Fiddaman else
1521*b30d1939SAndy Fiddaman {
1522*b30d1939SAndy Fiddaman char *sub=0, *prefix= shp->prefix;
1523*b30d1939SAndy Fiddaman Namval_t *mp;
1524*b30d1939SAndy Fiddaman Namarr_t *ap;
1525*b30d1939SAndy Fiddaman int isref;
1526*b30d1939SAndy Fiddaman shp->prefix = 0;
1527*b30d1939SAndy Fiddaman if((flags&NV_STATIC) && !shp->mktype)
1528*b30d1939SAndy Fiddaman {
1529*b30d1939SAndy Fiddaman if(!nv_isnull(np))
1530*b30d1939SAndy Fiddaman {
1531*b30d1939SAndy Fiddaman shp->prefix = prefix;
1532*b30d1939SAndy Fiddaman return(np);
1533*b30d1939SAndy Fiddaman }
1534*b30d1939SAndy Fiddaman }
1535*b30d1939SAndy Fiddaman isref = nv_isref(np);
1536*b30d1939SAndy Fiddaman #if SHOPT_FIXEDARRAY
1537*b30d1939SAndy Fiddaman if(sh_isoption(SH_XTRACE) && (ap=nv_arrayptr(np)) && !ap->fixed)
1538*b30d1939SAndy Fiddaman #else
1539*b30d1939SAndy Fiddaman if(sh_isoption(SH_XTRACE) && nv_isarray(np))
1540*b30d1939SAndy Fiddaman #endif /* SHOPT_FIXEDARRAY */
1541*b30d1939SAndy Fiddaman sub = nv_getsub(np);
1542*b30d1939SAndy Fiddaman c = msg==e_aliname? 0: (append | (flags&NV_EXPORT));
1543*b30d1939SAndy Fiddaman if(isref)
1544*b30d1939SAndy Fiddaman nv_offattr(np,NV_REF);
1545*b30d1939SAndy Fiddaman if(!append && (flags&NV_UNJUST))
1546*b30d1939SAndy Fiddaman {
1547*b30d1939SAndy Fiddaman if(!np->nvfun)
1548*b30d1939SAndy Fiddaman _nv_unset(np,NV_EXPORT);
1549*b30d1939SAndy Fiddaman }
1550*b30d1939SAndy Fiddaman if(flags&NV_MOVE)
1551*b30d1939SAndy Fiddaman {
1552*b30d1939SAndy Fiddaman if(ap=nv_arrayptr(np))
1553*b30d1939SAndy Fiddaman {
1554*b30d1939SAndy Fiddaman if(mp=nv_opensub(np))
1555*b30d1939SAndy Fiddaman np = mp;
1556*b30d1939SAndy Fiddaman else if(!array_assoc(ap) && (mp = nv_open(cp,shp->var_tree,NV_NOFAIL|NV_VARNAME|NV_NOARRAY|NV_NOASSIGN|NV_NOADD)) && nv_isvtree(np))
1557*b30d1939SAndy Fiddaman {
1558*b30d1939SAndy Fiddaman ap->nelem |= ARRAY_TREE;
1559*b30d1939SAndy Fiddaman nv_putsub(np,(char*)0,ARRAY_ADD|nv_aindex(np));
1560*b30d1939SAndy Fiddaman np = nv_opensub(np);
1561*b30d1939SAndy Fiddaman ap->nelem &= ~ARRAY_TREE;
1562*b30d1939SAndy Fiddaman ap->nelem -= 1;
1563*b30d1939SAndy Fiddaman }
1564*b30d1939SAndy Fiddaman }
1565*b30d1939SAndy Fiddaman _nv_unset(np,NV_EXPORT);
1566*b30d1939SAndy Fiddaman }
1567*b30d1939SAndy Fiddaman nv_putval(np, cp, c);
1568*b30d1939SAndy Fiddaman if(isref)
1569*b30d1939SAndy Fiddaman {
1570*b30d1939SAndy Fiddaman if(nv_search((char*)np,shp->var_base,HASH_BUCKET))
1571*b30d1939SAndy Fiddaman shp->last_root = shp->var_base;
1572*b30d1939SAndy Fiddaman nv_setref(np,(Dt_t*)0,NV_VARNAME);
1573*b30d1939SAndy Fiddaman }
1574*b30d1939SAndy Fiddaman savesub = sub;
1575*b30d1939SAndy Fiddaman shp->prefix = prefix;
1576*b30d1939SAndy Fiddaman }
1577*b30d1939SAndy Fiddaman nv_onattr(np, flags&NV_ATTRIBUTES);
1578*b30d1939SAndy Fiddaman }
1579*b30d1939SAndy Fiddaman else if(c)
1580*b30d1939SAndy Fiddaman {
1581*b30d1939SAndy Fiddaman if(flags&NV_NOFAIL)
1582*b30d1939SAndy Fiddaman return(0);
1583*b30d1939SAndy Fiddaman if(c=='.')
1584*b30d1939SAndy Fiddaman msg = e_noparent;
1585*b30d1939SAndy Fiddaman else if(c=='[')
1586*b30d1939SAndy Fiddaman msg = e_noarray;
1587*b30d1939SAndy Fiddaman errormsg(SH_DICT,ERROR_exit(1),msg,name);
1588*b30d1939SAndy Fiddaman }
1589*b30d1939SAndy Fiddaman if(fun.nofree&1)
1590*b30d1939SAndy Fiddaman stakseek(offset);
1591*b30d1939SAndy Fiddaman return(np);
1592*b30d1939SAndy Fiddaman }
1593*b30d1939SAndy Fiddaman
1594*b30d1939SAndy Fiddaman #if SHOPT_MULTIBYTE
1595*b30d1939SAndy Fiddaman static int ja_size(char*, int, int);
1596*b30d1939SAndy Fiddaman static void ja_restore(void);
1597*b30d1939SAndy Fiddaman static char *savep;
1598*b30d1939SAndy Fiddaman static char savechars[8+1];
1599*b30d1939SAndy Fiddaman #endif /* SHOPT_MULTIBYTE */
1600*b30d1939SAndy Fiddaman
1601*b30d1939SAndy Fiddaman /*
1602*b30d1939SAndy Fiddaman * put value <string> into name-value node <np>.
1603*b30d1939SAndy Fiddaman * If <np> is an array, then the element given by the
1604*b30d1939SAndy Fiddaman * current index is assigned to.
1605*b30d1939SAndy Fiddaman * If <flags> contains NV_RDONLY, readonly attribute is ignored
1606*b30d1939SAndy Fiddaman * If <flags> contains NV_INTEGER, string is a pointer to a number
1607*b30d1939SAndy Fiddaman * If <flags> contains NV_NOFREE, previous value is freed, and <string>
1608*b30d1939SAndy Fiddaman * becomes value of node and <flags> becomes attributes
1609*b30d1939SAndy Fiddaman */
nv_putval(register Namval_t * np,const char * string,int flags)1610*b30d1939SAndy Fiddaman void nv_putval(register Namval_t *np, const char *string, int flags)
1611*b30d1939SAndy Fiddaman {
1612*b30d1939SAndy Fiddaman Shell_t *shp = sh_getinterp();
1613*b30d1939SAndy Fiddaman register const char *sp=string;
1614*b30d1939SAndy Fiddaman register union Value *up;
1615*b30d1939SAndy Fiddaman register char *cp;
1616*b30d1939SAndy Fiddaman register int size = 0;
1617*b30d1939SAndy Fiddaman register int dot;
1618*b30d1939SAndy Fiddaman int was_local = nv_local;
1619*b30d1939SAndy Fiddaman union Value u;
1620*b30d1939SAndy Fiddaman #if SHOPT_FIXEDARRAY
1621*b30d1939SAndy Fiddaman Namarr_t *ap;
1622*b30d1939SAndy Fiddaman #endif /* SHOPT_FIXEDARRAY */
1623*b30d1939SAndy Fiddaman if(!(flags&NV_RDONLY) && nv_isattr (np, NV_RDONLY))
1624*b30d1939SAndy Fiddaman errormsg(SH_DICT,ERROR_exit(1),e_readonly, nv_name(np));
1625*b30d1939SAndy Fiddaman /* The following could cause the shell to fork if assignment
1626*b30d1939SAndy Fiddaman * would cause a side effect
1627*b30d1939SAndy Fiddaman */
1628*b30d1939SAndy Fiddaman shp->argaddr = 0;
1629*b30d1939SAndy Fiddaman if(shp->subshell && !nv_local && !(flags&NV_RDONLY))
1630*b30d1939SAndy Fiddaman np = sh_assignok(np,1);
1631*b30d1939SAndy Fiddaman if(np->nvfun && np->nvfun->disc && !(flags&NV_NODISC) && !nv_isref(np))
1632*b30d1939SAndy Fiddaman {
1633*b30d1939SAndy Fiddaman /* This function contains disc */
1634*b30d1939SAndy Fiddaman if(!nv_local)
1635*b30d1939SAndy Fiddaman {
1636*b30d1939SAndy Fiddaman nv_local=1;
1637*b30d1939SAndy Fiddaman nv_putv(np,sp,flags,np->nvfun);
1638*b30d1939SAndy Fiddaman if(sp && ((flags&NV_EXPORT) || nv_isattr(np,NV_EXPORT)))
1639*b30d1939SAndy Fiddaman sh_envput(shp->env,np);
1640*b30d1939SAndy Fiddaman return;
1641*b30d1939SAndy Fiddaman }
1642*b30d1939SAndy Fiddaman /* called from disc, assign the actual value */
1643*b30d1939SAndy Fiddaman }
1644*b30d1939SAndy Fiddaman flags &= ~NV_NODISC;
1645*b30d1939SAndy Fiddaman nv_local=0;
1646*b30d1939SAndy Fiddaman if(flags&(NV_NOREF|NV_NOFREE))
1647*b30d1939SAndy Fiddaman {
1648*b30d1939SAndy Fiddaman if(np->nvalue.cp && np->nvalue.cp!=sp && !nv_isattr(np,NV_NOFREE))
1649*b30d1939SAndy Fiddaman free((void*)np->nvalue.cp);
1650*b30d1939SAndy Fiddaman np->nvalue.cp = (char*)sp;
1651*b30d1939SAndy Fiddaman nv_setattr(np,(flags&~NV_RDONLY)|NV_NOFREE);
1652*b30d1939SAndy Fiddaman return;
1653*b30d1939SAndy Fiddaman }
1654*b30d1939SAndy Fiddaman up= &np->nvalue;
1655*b30d1939SAndy Fiddaman if(nv_isattr(np,NV_INT16P) == NV_INT16)
1656*b30d1939SAndy Fiddaman {
1657*b30d1939SAndy Fiddaman if(!np->nvalue.up || !nv_isarray(np))
1658*b30d1939SAndy Fiddaman {
1659*b30d1939SAndy Fiddaman up = &u;
1660*b30d1939SAndy Fiddaman up->up = &np->nvalue;
1661*b30d1939SAndy Fiddaman }
1662*b30d1939SAndy Fiddaman }
1663*b30d1939SAndy Fiddaman #if SHOPT_FIXEDARRAY
1664*b30d1939SAndy Fiddaman else if(np->nvalue.up && nv_isarray(np) && (ap=nv_arrayptr(np)) && !ap->fixed)
1665*b30d1939SAndy Fiddaman #else
1666*b30d1939SAndy Fiddaman else if(np->nvalue.up && nv_isarray(np) && nv_arrayptr(np))
1667*b30d1939SAndy Fiddaman #endif /* SHOPT_FIXEDARRAY */
1668*b30d1939SAndy Fiddaman up = np->nvalue.up;
1669*b30d1939SAndy Fiddaman if(up && up->cp==Empty)
1670*b30d1939SAndy Fiddaman up->cp = 0;
1671*b30d1939SAndy Fiddaman if(nv_isattr(np,NV_EXPORT))
1672*b30d1939SAndy Fiddaman nv_offattr(np,NV_IMPORT);
1673*b30d1939SAndy Fiddaman if(nv_isattr (np, NV_INTEGER))
1674*b30d1939SAndy Fiddaman {
1675*b30d1939SAndy Fiddaman if(nv_isattr(np, NV_DOUBLE) == NV_DOUBLE)
1676*b30d1939SAndy Fiddaman {
1677*b30d1939SAndy Fiddaman if(nv_isattr(np, NV_LONG) && sizeof(double)<sizeof(Sfdouble_t))
1678*b30d1939SAndy Fiddaman {
1679*b30d1939SAndy Fiddaman Sfdouble_t ld, old=0;
1680*b30d1939SAndy Fiddaman if(flags&NV_INTEGER)
1681*b30d1939SAndy Fiddaman {
1682*b30d1939SAndy Fiddaman if(flags&NV_LONG)
1683*b30d1939SAndy Fiddaman ld = *((Sfdouble_t*)sp);
1684*b30d1939SAndy Fiddaman else if(flags&NV_SHORT)
1685*b30d1939SAndy Fiddaman ld = *((float*)sp);
1686*b30d1939SAndy Fiddaman else
1687*b30d1939SAndy Fiddaman ld = *((double*)sp);
1688*b30d1939SAndy Fiddaman }
1689*b30d1939SAndy Fiddaman else
1690*b30d1939SAndy Fiddaman ld = sh_arith(shp,sp);
1691*b30d1939SAndy Fiddaman if(!up->ldp)
1692*b30d1939SAndy Fiddaman up->ldp = new_of(Sfdouble_t,0);
1693*b30d1939SAndy Fiddaman else if(flags&NV_APPEND)
1694*b30d1939SAndy Fiddaman old = *(up->ldp);
1695*b30d1939SAndy Fiddaman *(up->ldp) = old?ld+old:ld;
1696*b30d1939SAndy Fiddaman }
1697*b30d1939SAndy Fiddaman else
1698*b30d1939SAndy Fiddaman {
1699*b30d1939SAndy Fiddaman double d,od=0;
1700*b30d1939SAndy Fiddaman if(flags&NV_INTEGER)
1701*b30d1939SAndy Fiddaman {
1702*b30d1939SAndy Fiddaman if(flags&NV_LONG)
1703*b30d1939SAndy Fiddaman d = (double)(*(Sfdouble_t*)sp);
1704*b30d1939SAndy Fiddaman else if(flags&NV_SHORT)
1705*b30d1939SAndy Fiddaman d = (double)(*(float*)sp);
1706*b30d1939SAndy Fiddaman else
1707*b30d1939SAndy Fiddaman d = *(double*)sp;
1708*b30d1939SAndy Fiddaman }
1709*b30d1939SAndy Fiddaman else
1710*b30d1939SAndy Fiddaman d = sh_arith(shp,sp);
1711*b30d1939SAndy Fiddaman if(!up->dp)
1712*b30d1939SAndy Fiddaman up->dp = new_of(double,0);
1713*b30d1939SAndy Fiddaman else if(flags&NV_APPEND)
1714*b30d1939SAndy Fiddaman od = *(up->dp);
1715*b30d1939SAndy Fiddaman *(up->dp) = od?d+od:d;
1716*b30d1939SAndy Fiddaman }
1717*b30d1939SAndy Fiddaman }
1718*b30d1939SAndy Fiddaman else
1719*b30d1939SAndy Fiddaman {
1720*b30d1939SAndy Fiddaman if(nv_isattr(np, NV_LONG) && sizeof(int32_t)<sizeof(Sflong_t))
1721*b30d1939SAndy Fiddaman {
1722*b30d1939SAndy Fiddaman Sflong_t ll=0,oll=0;
1723*b30d1939SAndy Fiddaman if(flags&NV_INTEGER)
1724*b30d1939SAndy Fiddaman {
1725*b30d1939SAndy Fiddaman if((flags&NV_DOUBLE) == NV_DOUBLE)
1726*b30d1939SAndy Fiddaman {
1727*b30d1939SAndy Fiddaman if(flags&NV_LONG)
1728*b30d1939SAndy Fiddaman ll = *((Sfdouble_t*)sp);
1729*b30d1939SAndy Fiddaman else if(flags&NV_SHORT)
1730*b30d1939SAndy Fiddaman ll = *((float*)sp);
1731*b30d1939SAndy Fiddaman else
1732*b30d1939SAndy Fiddaman ll = *((double*)sp);
1733*b30d1939SAndy Fiddaman }
1734*b30d1939SAndy Fiddaman else if(nv_isattr(np,NV_UNSIGN))
1735*b30d1939SAndy Fiddaman {
1736*b30d1939SAndy Fiddaman if(flags&NV_LONG)
1737*b30d1939SAndy Fiddaman ll = *((Sfulong_t*)sp);
1738*b30d1939SAndy Fiddaman else if(flags&NV_SHORT)
1739*b30d1939SAndy Fiddaman ll = *((uint16_t*)sp);
1740*b30d1939SAndy Fiddaman else
1741*b30d1939SAndy Fiddaman ll = *((uint32_t*)sp);
1742*b30d1939SAndy Fiddaman }
1743*b30d1939SAndy Fiddaman else
1744*b30d1939SAndy Fiddaman {
1745*b30d1939SAndy Fiddaman if(flags&NV_LONG)
1746*b30d1939SAndy Fiddaman ll = *((Sflong_t*)sp);
1747*b30d1939SAndy Fiddaman else if(flags&NV_SHORT)
1748*b30d1939SAndy Fiddaman ll = *((uint16_t*)sp);
1749*b30d1939SAndy Fiddaman else
1750*b30d1939SAndy Fiddaman ll = *((uint32_t*)sp);
1751*b30d1939SAndy Fiddaman }
1752*b30d1939SAndy Fiddaman }
1753*b30d1939SAndy Fiddaman else if(sp)
1754*b30d1939SAndy Fiddaman ll = (Sflong_t)sh_arith(shp,sp);
1755*b30d1939SAndy Fiddaman if(!up->llp)
1756*b30d1939SAndy Fiddaman up->llp = new_of(Sflong_t,0);
1757*b30d1939SAndy Fiddaman else if(flags&NV_APPEND)
1758*b30d1939SAndy Fiddaman oll = *(up->llp);
1759*b30d1939SAndy Fiddaman *(up->llp) = ll+oll;
1760*b30d1939SAndy Fiddaman }
1761*b30d1939SAndy Fiddaman else
1762*b30d1939SAndy Fiddaman {
1763*b30d1939SAndy Fiddaman int32_t l=0,ol=0;
1764*b30d1939SAndy Fiddaman if(flags&NV_INTEGER)
1765*b30d1939SAndy Fiddaman {
1766*b30d1939SAndy Fiddaman if((flags&NV_DOUBLE) == NV_DOUBLE)
1767*b30d1939SAndy Fiddaman {
1768*b30d1939SAndy Fiddaman Sflong_t ll;
1769*b30d1939SAndy Fiddaman if(flags&NV_LONG)
1770*b30d1939SAndy Fiddaman ll = *((Sfdouble_t*)sp);
1771*b30d1939SAndy Fiddaman else if(flags&NV_SHORT)
1772*b30d1939SAndy Fiddaman ll = *((float*)sp);
1773*b30d1939SAndy Fiddaman else
1774*b30d1939SAndy Fiddaman ll = *((double*)sp);
1775*b30d1939SAndy Fiddaman l = (int32_t)ll;
1776*b30d1939SAndy Fiddaman }
1777*b30d1939SAndy Fiddaman else if(nv_isattr(np,NV_UNSIGN))
1778*b30d1939SAndy Fiddaman {
1779*b30d1939SAndy Fiddaman if(flags&NV_LONG)
1780*b30d1939SAndy Fiddaman l = *((Sfulong_t*)sp);
1781*b30d1939SAndy Fiddaman else if(flags&NV_SHORT)
1782*b30d1939SAndy Fiddaman l = *((uint16_t*)sp);
1783*b30d1939SAndy Fiddaman else
1784*b30d1939SAndy Fiddaman l = *(uint32_t*)sp;
1785*b30d1939SAndy Fiddaman }
1786*b30d1939SAndy Fiddaman else
1787*b30d1939SAndy Fiddaman {
1788*b30d1939SAndy Fiddaman if(flags&NV_LONG)
1789*b30d1939SAndy Fiddaman l = *((Sflong_t*)sp);
1790*b30d1939SAndy Fiddaman else if(flags&NV_SHORT)
1791*b30d1939SAndy Fiddaman l = *((int16_t*)sp);
1792*b30d1939SAndy Fiddaman else
1793*b30d1939SAndy Fiddaman l = *(int32_t*)sp;
1794*b30d1939SAndy Fiddaman }
1795*b30d1939SAndy Fiddaman }
1796*b30d1939SAndy Fiddaman else if(sp)
1797*b30d1939SAndy Fiddaman {
1798*b30d1939SAndy Fiddaman Sfdouble_t ld = sh_arith(shp,sp);
1799*b30d1939SAndy Fiddaman if(ld<0)
1800*b30d1939SAndy Fiddaman l = (int32_t)ld;
1801*b30d1939SAndy Fiddaman else
1802*b30d1939SAndy Fiddaman l = (uint32_t)ld;
1803*b30d1939SAndy Fiddaman }
1804*b30d1939SAndy Fiddaman if(nv_size(np) <= 1)
1805*b30d1939SAndy Fiddaman nv_setsize(np,10);
1806*b30d1939SAndy Fiddaman if(nv_isattr (np, NV_SHORT))
1807*b30d1939SAndy Fiddaman {
1808*b30d1939SAndy Fiddaman int16_t s=0;
1809*b30d1939SAndy Fiddaman if(flags&NV_APPEND)
1810*b30d1939SAndy Fiddaman s = *up->sp;
1811*b30d1939SAndy Fiddaman *(up->sp) = s+(int16_t)l;
1812*b30d1939SAndy Fiddaman nv_onattr(np,NV_NOFREE);
1813*b30d1939SAndy Fiddaman }
1814*b30d1939SAndy Fiddaman else
1815*b30d1939SAndy Fiddaman {
1816*b30d1939SAndy Fiddaman if(!up->lp)
1817*b30d1939SAndy Fiddaman up->lp = new_of(int32_t,0);
1818*b30d1939SAndy Fiddaman else if(flags&NV_APPEND)
1819*b30d1939SAndy Fiddaman ol = *(up->lp);
1820*b30d1939SAndy Fiddaman *(up->lp) = l+ol;
1821*b30d1939SAndy Fiddaman }
1822*b30d1939SAndy Fiddaman }
1823*b30d1939SAndy Fiddaman }
1824*b30d1939SAndy Fiddaman }
1825*b30d1939SAndy Fiddaman else
1826*b30d1939SAndy Fiddaman {
1827*b30d1939SAndy Fiddaman const char *tofree=0;
1828*b30d1939SAndy Fiddaman int offset,append;
1829*b30d1939SAndy Fiddaman #if _lib_pathnative
1830*b30d1939SAndy Fiddaman char buff[PATH_MAX];
1831*b30d1939SAndy Fiddaman #endif /* _lib_pathnative */
1832*b30d1939SAndy Fiddaman if(flags&NV_INTEGER)
1833*b30d1939SAndy Fiddaman {
1834*b30d1939SAndy Fiddaman if((flags&NV_DOUBLE)==NV_DOUBLE)
1835*b30d1939SAndy Fiddaman {
1836*b30d1939SAndy Fiddaman if(flags&NV_LONG)
1837*b30d1939SAndy Fiddaman sfprintf(shp->strbuf,"%.*Lg",LDBL_DIG,*((Sfdouble_t*)sp));
1838*b30d1939SAndy Fiddaman else
1839*b30d1939SAndy Fiddaman sfprintf(shp->strbuf,"%.*g",DBL_DIG,*((double*)sp));
1840*b30d1939SAndy Fiddaman }
1841*b30d1939SAndy Fiddaman else if(flags&NV_UNSIGN)
1842*b30d1939SAndy Fiddaman {
1843*b30d1939SAndy Fiddaman if(flags&NV_LONG)
1844*b30d1939SAndy Fiddaman sfprintf(shp->strbuf,"%I*lu",sizeof(Sfulong_t),*((Sfulong_t*)sp));
1845*b30d1939SAndy Fiddaman else
1846*b30d1939SAndy Fiddaman sfprintf(shp->strbuf,"%lu",(unsigned long)((flags&NV_SHORT)?*((uint16_t*)sp):*((uint32_t*)sp)));
1847*b30d1939SAndy Fiddaman }
1848*b30d1939SAndy Fiddaman else
1849*b30d1939SAndy Fiddaman {
1850*b30d1939SAndy Fiddaman if(flags&NV_LONG)
1851*b30d1939SAndy Fiddaman sfprintf(shp->strbuf,"%I*ld",sizeof(Sflong_t),*((Sflong_t*)sp));
1852*b30d1939SAndy Fiddaman else
1853*b30d1939SAndy Fiddaman sfprintf(shp->strbuf,"%ld",(long)((flags&NV_SHORT)?*((int16_t*)sp):*((int32_t*)sp)));
1854*b30d1939SAndy Fiddaman }
1855*b30d1939SAndy Fiddaman sp = sfstruse(shp->strbuf);
1856*b30d1939SAndy Fiddaman }
1857*b30d1939SAndy Fiddaman if(nv_isattr(np, NV_HOST|NV_INTEGER)==NV_HOST && sp)
1858*b30d1939SAndy Fiddaman {
1859*b30d1939SAndy Fiddaman #ifdef _lib_pathnative
1860*b30d1939SAndy Fiddaman /*
1861*b30d1939SAndy Fiddaman * return the host file name given the UNIX name
1862*b30d1939SAndy Fiddaman */
1863*b30d1939SAndy Fiddaman pathnative(sp,buff,sizeof(buff));
1864*b30d1939SAndy Fiddaman if(buff[1]==':' && buff[2]=='/')
1865*b30d1939SAndy Fiddaman {
1866*b30d1939SAndy Fiddaman buff[2] = '\\';
1867*b30d1939SAndy Fiddaman if(*buff>='A' && *buff<='Z')
1868*b30d1939SAndy Fiddaman *buff += 'a'-'A';
1869*b30d1939SAndy Fiddaman }
1870*b30d1939SAndy Fiddaman sp = buff;
1871*b30d1939SAndy Fiddaman #else
1872*b30d1939SAndy Fiddaman ;
1873*b30d1939SAndy Fiddaman #endif /* _lib_pathnative */
1874*b30d1939SAndy Fiddaman }
1875*b30d1939SAndy Fiddaman else if((nv_isattr(np, NV_RJUST|NV_ZFILL|NV_LJUST)) && sp)
1876*b30d1939SAndy Fiddaman {
1877*b30d1939SAndy Fiddaman for(;*sp == ' '|| *sp=='\t';sp++);
1878*b30d1939SAndy Fiddaman if((nv_isattr(np,NV_ZFILL)) && (nv_isattr(np,NV_LJUST)))
1879*b30d1939SAndy Fiddaman for(;*sp=='0';sp++);
1880*b30d1939SAndy Fiddaman size = nv_size(np);
1881*b30d1939SAndy Fiddaman #if SHOPT_MULTIBYTE
1882*b30d1939SAndy Fiddaman if(size)
1883*b30d1939SAndy Fiddaman size = ja_size((char*)sp,size,nv_isattr(np,NV_RJUST|NV_ZFILL));
1884*b30d1939SAndy Fiddaman #endif /* SHOPT_MULTIBYTE */
1885*b30d1939SAndy Fiddaman }
1886*b30d1939SAndy Fiddaman if(!up->cp || *up->cp==0)
1887*b30d1939SAndy Fiddaman flags &= ~NV_APPEND;
1888*b30d1939SAndy Fiddaman if(!nv_isattr(np, NV_NOFREE))
1889*b30d1939SAndy Fiddaman {
1890*b30d1939SAndy Fiddaman /* delay free in case <sp> points into free region */
1891*b30d1939SAndy Fiddaman tofree = up->cp;
1892*b30d1939SAndy Fiddaman }
1893*b30d1939SAndy Fiddaman if(nv_isattr(np,NV_BINARY) && !(flags&NV_RAW))
1894*b30d1939SAndy Fiddaman tofree = 0;
1895*b30d1939SAndy Fiddaman if(nv_isattr(np,NV_LJUST|NV_RJUST) && nv_isattr(np,NV_LJUST|NV_RJUST)!=(NV_LJUST|NV_RJUST))
1896*b30d1939SAndy Fiddaman tofree = 0;
1897*b30d1939SAndy Fiddaman if (sp)
1898*b30d1939SAndy Fiddaman {
1899*b30d1939SAndy Fiddaman append=0;
1900*b30d1939SAndy Fiddaman if(sp==up->cp && !(flags&NV_APPEND))
1901*b30d1939SAndy Fiddaman return;
1902*b30d1939SAndy Fiddaman dot = strlen(sp);
1903*b30d1939SAndy Fiddaman #if (_AST_VERSION>=20030127L)
1904*b30d1939SAndy Fiddaman if(nv_isattr(np,NV_BINARY))
1905*b30d1939SAndy Fiddaman {
1906*b30d1939SAndy Fiddaman int oldsize = (flags&NV_APPEND)?nv_size(np):0;
1907*b30d1939SAndy Fiddaman if(flags&NV_RAW)
1908*b30d1939SAndy Fiddaman {
1909*b30d1939SAndy Fiddaman if(tofree)
1910*b30d1939SAndy Fiddaman {
1911*b30d1939SAndy Fiddaman free((void*)tofree);
1912*b30d1939SAndy Fiddaman nv_offattr(np,NV_NOFREE);
1913*b30d1939SAndy Fiddaman }
1914*b30d1939SAndy Fiddaman up->cp = sp;
1915*b30d1939SAndy Fiddaman return;
1916*b30d1939SAndy Fiddaman }
1917*b30d1939SAndy Fiddaman size = 0;
1918*b30d1939SAndy Fiddaman if(nv_isattr(np,NV_ZFILL))
1919*b30d1939SAndy Fiddaman size = nv_size(np);
1920*b30d1939SAndy Fiddaman if(size==0)
1921*b30d1939SAndy Fiddaman size = oldsize + (3*dot/4);
1922*b30d1939SAndy Fiddaman *(cp = (char*)malloc(size+1)) = 0;
1923*b30d1939SAndy Fiddaman nv_offattr(np,NV_NOFREE);
1924*b30d1939SAndy Fiddaman if(oldsize)
1925*b30d1939SAndy Fiddaman memcpy((void*)cp,(void*)up->cp,oldsize);
1926*b30d1939SAndy Fiddaman up->cp = cp;
1927*b30d1939SAndy Fiddaman if(size <= oldsize)
1928*b30d1939SAndy Fiddaman return;
1929*b30d1939SAndy Fiddaman dot = base64decode(sp,dot, (void**)0, cp+oldsize, size-oldsize,(void**)0);
1930*b30d1939SAndy Fiddaman dot += oldsize;
1931*b30d1939SAndy Fiddaman if(!nv_isattr(np,NV_ZFILL) || nv_size(np)==0)
1932*b30d1939SAndy Fiddaman nv_setsize(np,dot);
1933*b30d1939SAndy Fiddaman else if(nv_isattr(np,NV_ZFILL) && (size>dot))
1934*b30d1939SAndy Fiddaman memset((void*)&cp[dot],0,size-dot);
1935*b30d1939SAndy Fiddaman return;
1936*b30d1939SAndy Fiddaman }
1937*b30d1939SAndy Fiddaman else
1938*b30d1939SAndy Fiddaman #endif
1939*b30d1939SAndy Fiddaman {
1940*b30d1939SAndy Fiddaman if(size==0 && nv_isattr(np,NV_HOST)!=NV_HOST &&nv_isattr(np,NV_LJUST|NV_RJUST|NV_ZFILL))
1941*b30d1939SAndy Fiddaman {
1942*b30d1939SAndy Fiddaman nv_setsize(np,size=dot);
1943*b30d1939SAndy Fiddaman tofree = up->cp;
1944*b30d1939SAndy Fiddaman }
1945*b30d1939SAndy Fiddaman else if(size > dot)
1946*b30d1939SAndy Fiddaman dot = size;
1947*b30d1939SAndy Fiddaman else if(nv_isattr(np,NV_LJUST|NV_RJUST)==NV_LJUST && dot>size)
1948*b30d1939SAndy Fiddaman dot = size;
1949*b30d1939SAndy Fiddaman if(flags&NV_APPEND)
1950*b30d1939SAndy Fiddaman {
1951*b30d1939SAndy Fiddaman if(dot==0)
1952*b30d1939SAndy Fiddaman return;
1953*b30d1939SAndy Fiddaman append = strlen(up->cp);
1954*b30d1939SAndy Fiddaman if(!tofree || size)
1955*b30d1939SAndy Fiddaman {
1956*b30d1939SAndy Fiddaman offset = staktell();
1957*b30d1939SAndy Fiddaman stakputs(up->cp);
1958*b30d1939SAndy Fiddaman stakputs(sp);
1959*b30d1939SAndy Fiddaman stakputc(0);
1960*b30d1939SAndy Fiddaman sp = stakptr(offset);
1961*b30d1939SAndy Fiddaman dot += append;
1962*b30d1939SAndy Fiddaman append = 0;
1963*b30d1939SAndy Fiddaman }
1964*b30d1939SAndy Fiddaman else
1965*b30d1939SAndy Fiddaman {
1966*b30d1939SAndy Fiddaman flags &= ~NV_APPEND;
1967*b30d1939SAndy Fiddaman }
1968*b30d1939SAndy Fiddaman }
1969*b30d1939SAndy Fiddaman }
1970*b30d1939SAndy Fiddaman if(size==0 || tofree || dot || !(cp=(char*)up->cp))
1971*b30d1939SAndy Fiddaman {
1972*b30d1939SAndy Fiddaman if(dot==0 && !nv_isattr(np,NV_LJUST|NV_RJUST))
1973*b30d1939SAndy Fiddaman {
1974*b30d1939SAndy Fiddaman cp = Null;
1975*b30d1939SAndy Fiddaman nv_onattr(np,NV_NOFREE);
1976*b30d1939SAndy Fiddaman }
1977*b30d1939SAndy Fiddaman else
1978*b30d1939SAndy Fiddaman {
1979*b30d1939SAndy Fiddaman if(tofree && tofree!=Empty && tofree!=Null)
1980*b30d1939SAndy Fiddaman {
1981*b30d1939SAndy Fiddaman cp = (char*)realloc((void*)tofree,((unsigned)dot+append+8));
1982*b30d1939SAndy Fiddaman tofree = 0;
1983*b30d1939SAndy Fiddaman }
1984*b30d1939SAndy Fiddaman else
1985*b30d1939SAndy Fiddaman cp = (char*)malloc(((unsigned)dot+8));
1986*b30d1939SAndy Fiddaman cp[dot+append] = 0;
1987*b30d1939SAndy Fiddaman nv_offattr(np,NV_NOFREE);
1988*b30d1939SAndy Fiddaman }
1989*b30d1939SAndy Fiddaman }
1990*b30d1939SAndy Fiddaman
1991*b30d1939SAndy Fiddaman }
1992*b30d1939SAndy Fiddaman else
1993*b30d1939SAndy Fiddaman cp = 0;
1994*b30d1939SAndy Fiddaman up->cp = cp;
1995*b30d1939SAndy Fiddaman if(sp)
1996*b30d1939SAndy Fiddaman {
1997*b30d1939SAndy Fiddaman int c = cp[dot+append];
1998*b30d1939SAndy Fiddaman memmove(cp+append,sp,dot);
1999*b30d1939SAndy Fiddaman cp[dot+append] = c;
2000*b30d1939SAndy Fiddaman if(nv_isattr(np, NV_RJUST) && nv_isattr(np, NV_ZFILL))
2001*b30d1939SAndy Fiddaman rightjust(cp,size,'0');
2002*b30d1939SAndy Fiddaman else if(nv_isattr(np, NV_LJUST|NV_RJUST)==NV_RJUST)
2003*b30d1939SAndy Fiddaman rightjust(cp,size,' ');
2004*b30d1939SAndy Fiddaman else if(nv_isattr(np, NV_LJUST|NV_RJUST)==NV_LJUST)
2005*b30d1939SAndy Fiddaman {
2006*b30d1939SAndy Fiddaman register char *dp;
2007*b30d1939SAndy Fiddaman dp = strlen (cp) + cp;
2008*b30d1939SAndy Fiddaman cp = cp+size;
2009*b30d1939SAndy Fiddaman for (; dp < cp; *dp++ = ' ');
2010*b30d1939SAndy Fiddaman }
2011*b30d1939SAndy Fiddaman #if SHOPT_MULTIBYTE
2012*b30d1939SAndy Fiddaman /* restore original string */
2013*b30d1939SAndy Fiddaman if(savep)
2014*b30d1939SAndy Fiddaman ja_restore();
2015*b30d1939SAndy Fiddaman #endif /* SHOPT_MULTIBYTE */
2016*b30d1939SAndy Fiddaman }
2017*b30d1939SAndy Fiddaman if(flags&NV_APPEND)
2018*b30d1939SAndy Fiddaman stakseek(offset);
2019*b30d1939SAndy Fiddaman if(tofree && tofree!=Empty && tofree!=Null)
2020*b30d1939SAndy Fiddaman free((void*)tofree);
2021*b30d1939SAndy Fiddaman }
2022*b30d1939SAndy Fiddaman if(!was_local && ((flags&NV_EXPORT) || nv_isattr(np,NV_EXPORT)))
2023*b30d1939SAndy Fiddaman sh_envput(shp->env,np);
2024*b30d1939SAndy Fiddaman return;
2025*b30d1939SAndy Fiddaman }
2026*b30d1939SAndy Fiddaman
2027*b30d1939SAndy Fiddaman /*
2028*b30d1939SAndy Fiddaman *
2029*b30d1939SAndy Fiddaman * Right-justify <str> so that it contains no more than
2030*b30d1939SAndy Fiddaman * <size> characters. If <str> contains fewer than <size>
2031*b30d1939SAndy Fiddaman * characters, left-pad with <fill>. Trailing blanks
2032*b30d1939SAndy Fiddaman * in <str> will be ignored.
2033*b30d1939SAndy Fiddaman *
2034*b30d1939SAndy Fiddaman * If the leftmost digit in <str> is not a digit, <fill>
2035*b30d1939SAndy Fiddaman * will default to a blank.
2036*b30d1939SAndy Fiddaman */
rightjust(char * str,int size,int fill)2037*b30d1939SAndy Fiddaman static void rightjust(char *str, int size, int fill)
2038*b30d1939SAndy Fiddaman {
2039*b30d1939SAndy Fiddaman register int n;
2040*b30d1939SAndy Fiddaman register char *cp,*sp;
2041*b30d1939SAndy Fiddaman n = strlen(str);
2042*b30d1939SAndy Fiddaman
2043*b30d1939SAndy Fiddaman /* ignore trailing blanks */
2044*b30d1939SAndy Fiddaman for(cp=str+n;n && *--cp == ' ';n--);
2045*b30d1939SAndy Fiddaman if (n == size)
2046*b30d1939SAndy Fiddaman return;
2047*b30d1939SAndy Fiddaman if(n > size)
2048*b30d1939SAndy Fiddaman {
2049*b30d1939SAndy Fiddaman *(str+n) = 0;
2050*b30d1939SAndy Fiddaman for (sp = str, cp = str+n-size; sp <= str+size; *sp++ = *cp++);
2051*b30d1939SAndy Fiddaman return;
2052*b30d1939SAndy Fiddaman }
2053*b30d1939SAndy Fiddaman else *(sp = str+size) = 0;
2054*b30d1939SAndy Fiddaman if (n == 0)
2055*b30d1939SAndy Fiddaman {
2056*b30d1939SAndy Fiddaman while (sp > str)
2057*b30d1939SAndy Fiddaman *--sp = ' ';
2058*b30d1939SAndy Fiddaman return;
2059*b30d1939SAndy Fiddaman }
2060*b30d1939SAndy Fiddaman while(n--)
2061*b30d1939SAndy Fiddaman {
2062*b30d1939SAndy Fiddaman sp--;
2063*b30d1939SAndy Fiddaman *sp = *cp--;
2064*b30d1939SAndy Fiddaman }
2065*b30d1939SAndy Fiddaman if(!isdigit(*str))
2066*b30d1939SAndy Fiddaman fill = ' ';
2067*b30d1939SAndy Fiddaman while(sp>str)
2068*b30d1939SAndy Fiddaman *--sp = fill;
2069*b30d1939SAndy Fiddaman return;
2070*b30d1939SAndy Fiddaman }
2071*b30d1939SAndy Fiddaman
2072*b30d1939SAndy Fiddaman #if SHOPT_MULTIBYTE
2073*b30d1939SAndy Fiddaman /*
2074*b30d1939SAndy Fiddaman * handle left and right justified fields for multi-byte chars
2075*b30d1939SAndy Fiddaman * given physical size, return a logical size which reflects the
2076*b30d1939SAndy Fiddaman * screen width of multi-byte characters
2077*b30d1939SAndy Fiddaman * Multi-width characters replaced by spaces if they cross the boundary
2078*b30d1939SAndy Fiddaman * <type> is non-zero for right justified fields
2079*b30d1939SAndy Fiddaman */
2080*b30d1939SAndy Fiddaman
ja_size(char * str,int size,int type)2081*b30d1939SAndy Fiddaman static int ja_size(char *str,int size,int type)
2082*b30d1939SAndy Fiddaman {
2083*b30d1939SAndy Fiddaman register char *cp = str;
2084*b30d1939SAndy Fiddaman register int c, n=size;
2085*b30d1939SAndy Fiddaman register int outsize;
2086*b30d1939SAndy Fiddaman register char *oldcp=cp;
2087*b30d1939SAndy Fiddaman int oldn;
2088*b30d1939SAndy Fiddaman wchar_t w;
2089*b30d1939SAndy Fiddaman while(*cp)
2090*b30d1939SAndy Fiddaman {
2091*b30d1939SAndy Fiddaman oldn = n;
2092*b30d1939SAndy Fiddaman w = mbchar(cp);
2093*b30d1939SAndy Fiddaman if((outsize = mbwidth(w)) <0)
2094*b30d1939SAndy Fiddaman outsize = 0;
2095*b30d1939SAndy Fiddaman size -= outsize;
2096*b30d1939SAndy Fiddaman c = cp-oldcp;
2097*b30d1939SAndy Fiddaman n += (c-outsize);
2098*b30d1939SAndy Fiddaman oldcp = cp;
2099*b30d1939SAndy Fiddaman if(size<=0 && type==0)
2100*b30d1939SAndy Fiddaman break;
2101*b30d1939SAndy Fiddaman }
2102*b30d1939SAndy Fiddaman /* check for right justified fields that need truncating */
2103*b30d1939SAndy Fiddaman if(size <0)
2104*b30d1939SAndy Fiddaman {
2105*b30d1939SAndy Fiddaman if(type==0)
2106*b30d1939SAndy Fiddaman {
2107*b30d1939SAndy Fiddaman /* left justified and character crosses field boundary */
2108*b30d1939SAndy Fiddaman n = oldn;
2109*b30d1939SAndy Fiddaman /* save boundary char and replace with spaces */
2110*b30d1939SAndy Fiddaman size = c;
2111*b30d1939SAndy Fiddaman savechars[size] = 0;
2112*b30d1939SAndy Fiddaman while(size--)
2113*b30d1939SAndy Fiddaman {
2114*b30d1939SAndy Fiddaman savechars[size] = cp[size];
2115*b30d1939SAndy Fiddaman cp[size] = ' ';
2116*b30d1939SAndy Fiddaman }
2117*b30d1939SAndy Fiddaman savep = cp;
2118*b30d1939SAndy Fiddaman }
2119*b30d1939SAndy Fiddaman size = -size;
2120*b30d1939SAndy Fiddaman if(type)
2121*b30d1939SAndy Fiddaman n -= (ja_size(str,size,0)-size);
2122*b30d1939SAndy Fiddaman }
2123*b30d1939SAndy Fiddaman return(n);
2124*b30d1939SAndy Fiddaman }
2125*b30d1939SAndy Fiddaman
ja_restore(void)2126*b30d1939SAndy Fiddaman static void ja_restore(void)
2127*b30d1939SAndy Fiddaman {
2128*b30d1939SAndy Fiddaman register char *cp = savechars;
2129*b30d1939SAndy Fiddaman while(*cp)
2130*b30d1939SAndy Fiddaman *savep++ = *cp++;
2131*b30d1939SAndy Fiddaman savep = 0;
2132*b30d1939SAndy Fiddaman }
2133*b30d1939SAndy Fiddaman #endif /* SHOPT_MULTIBYTE */
2134*b30d1939SAndy Fiddaman
2135*b30d1939SAndy Fiddaman #ifndef _ENV_H
staknam(register Namval_t * np,char * value)2136*b30d1939SAndy Fiddaman static char *staknam(register Namval_t *np, char *value)
2137*b30d1939SAndy Fiddaman {
2138*b30d1939SAndy Fiddaman register char *p,*q;
2139*b30d1939SAndy Fiddaman q = stakalloc(strlen(nv_name(np))+(value?strlen(value):0)+2);
2140*b30d1939SAndy Fiddaman p=strcopy(q,nv_name(np));
2141*b30d1939SAndy Fiddaman if(value)
2142*b30d1939SAndy Fiddaman {
2143*b30d1939SAndy Fiddaman *p++ = '=';
2144*b30d1939SAndy Fiddaman strcpy(p,value);
2145*b30d1939SAndy Fiddaman }
2146*b30d1939SAndy Fiddaman return(q);
2147*b30d1939SAndy Fiddaman }
2148*b30d1939SAndy Fiddaman #endif
2149*b30d1939SAndy Fiddaman
2150*b30d1939SAndy Fiddaman /*
2151*b30d1939SAndy Fiddaman * put the name and attribute into value of attributes variable
2152*b30d1939SAndy Fiddaman */
2153*b30d1939SAndy Fiddaman #ifdef _ENV_H
attstore(register Namval_t * np,void * data)2154*b30d1939SAndy Fiddaman static void attstore(register Namval_t *np, void *data)
2155*b30d1939SAndy Fiddaman {
2156*b30d1939SAndy Fiddaman register int flag, c = ' ';
2157*b30d1939SAndy Fiddaman NOT_USED(data);
2158*b30d1939SAndy Fiddaman if(!(nv_isattr(np,NV_EXPORT)))
2159*b30d1939SAndy Fiddaman return;
2160*b30d1939SAndy Fiddaman flag = nv_isattr(np,NV_RDONLY|NV_UTOL|NV_LTOU|NV_RJUST|NV_LJUST|NV_ZFILL|NV_INTEGER);
2161*b30d1939SAndy Fiddaman stakputc('=');
2162*b30d1939SAndy Fiddaman if((flag&NV_DOUBLE) == NV_DOUBLE)
2163*b30d1939SAndy Fiddaman {
2164*b30d1939SAndy Fiddaman /* export doubles as integers for ksh88 compatibility */
2165*b30d1939SAndy Fiddaman stakputc(c+NV_INTEGER|(flag&~(NV_DOUBLE|NV_EXPNOTE)));
2166*b30d1939SAndy Fiddaman }
2167*b30d1939SAndy Fiddaman else
2168*b30d1939SAndy Fiddaman {
2169*b30d1939SAndy Fiddaman stakputc(c+flag);
2170*b30d1939SAndy Fiddaman if(flag&NV_INTEGER)
2171*b30d1939SAndy Fiddaman c += nv_size(np);
2172*b30d1939SAndy Fiddaman }
2173*b30d1939SAndy Fiddaman stakputc(c);
2174*b30d1939SAndy Fiddaman stakputs(nv_name(np));
2175*b30d1939SAndy Fiddaman }
2176*b30d1939SAndy Fiddaman #else
attstore(register Namval_t * np,void * data)2177*b30d1939SAndy Fiddaman static void attstore(register Namval_t *np, void *data)
2178*b30d1939SAndy Fiddaman {
2179*b30d1939SAndy Fiddaman register int flag = np->nvflag;
2180*b30d1939SAndy Fiddaman register struct adata *ap = (struct adata*)data;
2181*b30d1939SAndy Fiddaman ap->sh = sh_getinterp();
2182*b30d1939SAndy Fiddaman ap->tp = 0;
2183*b30d1939SAndy Fiddaman if(!(flag&NV_EXPORT) || (flag&NV_FUNCT))
2184*b30d1939SAndy Fiddaman return;
2185*b30d1939SAndy Fiddaman if((flag&(NV_UTOL|NV_LTOU|NV_INTEGER)) == (NV_UTOL|NV_LTOU))
2186*b30d1939SAndy Fiddaman {
2187*b30d1939SAndy Fiddaman data = (void*)nv_mapchar(np,0);
2188*b30d1939SAndy Fiddaman if(strcmp(data,e_tolower) && strcmp(data,e_toupper))
2189*b30d1939SAndy Fiddaman return;
2190*b30d1939SAndy Fiddaman }
2191*b30d1939SAndy Fiddaman flag &= (NV_RDONLY|NV_UTOL|NV_LTOU|NV_RJUST|NV_LJUST|NV_ZFILL|NV_INTEGER);
2192*b30d1939SAndy Fiddaman *ap->attval++ = '=';
2193*b30d1939SAndy Fiddaman if((flag&NV_DOUBLE) == NV_DOUBLE)
2194*b30d1939SAndy Fiddaman {
2195*b30d1939SAndy Fiddaman /* export doubles as integers for ksh88 compatibility */
2196*b30d1939SAndy Fiddaman *ap->attval++ = ' '+ NV_INTEGER|(flag&~(NV_DOUBLE|NV_EXPNOTE));
2197*b30d1939SAndy Fiddaman *ap->attval = ' ';
2198*b30d1939SAndy Fiddaman }
2199*b30d1939SAndy Fiddaman else
2200*b30d1939SAndy Fiddaman {
2201*b30d1939SAndy Fiddaman *ap->attval++ = ' '+flag;
2202*b30d1939SAndy Fiddaman if(flag&NV_INTEGER)
2203*b30d1939SAndy Fiddaman *ap->attval = ' ' + nv_size(np);
2204*b30d1939SAndy Fiddaman else
2205*b30d1939SAndy Fiddaman *ap->attval = ' ';
2206*b30d1939SAndy Fiddaman }
2207*b30d1939SAndy Fiddaman ap->attval = strcopy(++ap->attval,nv_name(np));
2208*b30d1939SAndy Fiddaman }
2209*b30d1939SAndy Fiddaman #endif
2210*b30d1939SAndy Fiddaman
2211*b30d1939SAndy Fiddaman #ifndef _ENV_H
pushnam(Namval_t * np,void * data)2212*b30d1939SAndy Fiddaman static void pushnam(Namval_t *np, void *data)
2213*b30d1939SAndy Fiddaman {
2214*b30d1939SAndy Fiddaman register char *value;
2215*b30d1939SAndy Fiddaman register struct adata *ap = (struct adata*)data;
2216*b30d1939SAndy Fiddaman ap->sh = sh_getinterp();
2217*b30d1939SAndy Fiddaman ap->tp = 0;
2218*b30d1939SAndy Fiddaman if(nv_isattr(np,NV_IMPORT) && np->nvenv)
2219*b30d1939SAndy Fiddaman *ap->argnam++ = np->nvenv;
2220*b30d1939SAndy Fiddaman else if(value=nv_getval(np))
2221*b30d1939SAndy Fiddaman *ap->argnam++ = staknam(np,value);
2222*b30d1939SAndy Fiddaman if(nv_isattr(np,NV_RDONLY|NV_UTOL|NV_LTOU|NV_RJUST|NV_LJUST|NV_ZFILL|NV_INTEGER))
2223*b30d1939SAndy Fiddaman ap->attsize += (strlen(nv_name(np))+4);
2224*b30d1939SAndy Fiddaman }
2225*b30d1939SAndy Fiddaman #endif
2226*b30d1939SAndy Fiddaman
2227*b30d1939SAndy Fiddaman /*
2228*b30d1939SAndy Fiddaman * Generate the environment list for the child.
2229*b30d1939SAndy Fiddaman */
2230*b30d1939SAndy Fiddaman
2231*b30d1939SAndy Fiddaman #ifdef _ENV_H
sh_envgen(void)2232*b30d1939SAndy Fiddaman char **sh_envgen(void)
2233*b30d1939SAndy Fiddaman {
2234*b30d1939SAndy Fiddaman Shell_t *shp = sh_getinterp();
2235*b30d1939SAndy Fiddaman int offset,tell;
2236*b30d1939SAndy Fiddaman register char **er;
2237*b30d1939SAndy Fiddaman env_delete(shp->env,"_");
2238*b30d1939SAndy Fiddaman er = env_get(shp->env);
2239*b30d1939SAndy Fiddaman offset = staktell();
2240*b30d1939SAndy Fiddaman stakputs(e_envmarker);
2241*b30d1939SAndy Fiddaman tell = staktell();
2242*b30d1939SAndy Fiddaman nv_scan(shp->var_tree, attstore,(void*)0,0,(NV_RDONLY|NV_UTOL|NV_LTOU|NV_RJUST|NV_LJUST|NV_ZFILL|NV_INTEGER));
2243*b30d1939SAndy Fiddaman if(tell ==staktell())
2244*b30d1939SAndy Fiddaman stakseek(offset);
2245*b30d1939SAndy Fiddaman else
2246*b30d1939SAndy Fiddaman *--er = stakfreeze(1)+offset;
2247*b30d1939SAndy Fiddaman return(er);
2248*b30d1939SAndy Fiddaman }
2249*b30d1939SAndy Fiddaman #else
sh_envgen(void)2250*b30d1939SAndy Fiddaman char **sh_envgen(void)
2251*b30d1939SAndy Fiddaman {
2252*b30d1939SAndy Fiddaman register char **er;
2253*b30d1939SAndy Fiddaman register int namec;
2254*b30d1939SAndy Fiddaman register char *cp;
2255*b30d1939SAndy Fiddaman struct adata data;
2256*b30d1939SAndy Fiddaman Shell_t *shp = sh_getinterp();
2257*b30d1939SAndy Fiddaman data.sh = shp;
2258*b30d1939SAndy Fiddaman data.tp = 0;
2259*b30d1939SAndy Fiddaman data.mapname = 0;
2260*b30d1939SAndy Fiddaman /* L_ARGNOD gets generated automatically as full path name of command */
2261*b30d1939SAndy Fiddaman nv_offattr(L_ARGNOD,NV_EXPORT);
2262*b30d1939SAndy Fiddaman data.attsize = 6;
2263*b30d1939SAndy Fiddaman namec = nv_scan(shp->var_tree,nullscan,(void*)0,NV_EXPORT,NV_EXPORT);
2264*b30d1939SAndy Fiddaman namec += shp->nenv;
2265*b30d1939SAndy Fiddaman er = (char**)stakalloc((namec+4)*sizeof(char*));
2266*b30d1939SAndy Fiddaman data.argnam = (er+=2) + shp->nenv;
2267*b30d1939SAndy Fiddaman if(shp->nenv)
2268*b30d1939SAndy Fiddaman memcpy((void*)er,environ,shp->nenv*sizeof(char*));
2269*b30d1939SAndy Fiddaman nv_scan(shp->var_tree, pushnam,&data,NV_EXPORT, NV_EXPORT);
2270*b30d1939SAndy Fiddaman *data.argnam = (char*)stakalloc(data.attsize);
2271*b30d1939SAndy Fiddaman cp = data.attval = strcopy(*data.argnam,e_envmarker);
2272*b30d1939SAndy Fiddaman nv_scan(shp->var_tree, attstore,&data,0,(NV_RDONLY|NV_UTOL|NV_LTOU|NV_RJUST|NV_LJUST|NV_ZFILL|NV_INTEGER));
2273*b30d1939SAndy Fiddaman *data.attval = 0;
2274*b30d1939SAndy Fiddaman if(cp!=data.attval)
2275*b30d1939SAndy Fiddaman data.argnam++;
2276*b30d1939SAndy Fiddaman *data.argnam = 0;
2277*b30d1939SAndy Fiddaman return(er);
2278*b30d1939SAndy Fiddaman }
2279*b30d1939SAndy Fiddaman #endif
2280*b30d1939SAndy Fiddaman
2281*b30d1939SAndy Fiddaman struct scan
2282*b30d1939SAndy Fiddaman {
2283*b30d1939SAndy Fiddaman void (*scanfn)(Namval_t*, void*);
2284*b30d1939SAndy Fiddaman int scanmask;
2285*b30d1939SAndy Fiddaman int scanflags;
2286*b30d1939SAndy Fiddaman int scancount;
2287*b30d1939SAndy Fiddaman void *scandata;
2288*b30d1939SAndy Fiddaman };
2289*b30d1939SAndy Fiddaman
scanfilter(Dt_t * dict,void * arg,void * data)2290*b30d1939SAndy Fiddaman static int scanfilter(Dt_t *dict, void *arg, void *data)
2291*b30d1939SAndy Fiddaman {
2292*b30d1939SAndy Fiddaman register Namval_t *np = (Namval_t*)arg;
2293*b30d1939SAndy Fiddaman register int k=np->nvflag;
2294*b30d1939SAndy Fiddaman register struct scan *sp = (struct scan*)data;
2295*b30d1939SAndy Fiddaman register struct adata *tp = (struct adata*)sp->scandata;
2296*b30d1939SAndy Fiddaman char *cp;
2297*b30d1939SAndy Fiddaman NOT_USED(dict);
2298*b30d1939SAndy Fiddaman #if SHOPT_TYPEDEF
2299*b30d1939SAndy Fiddaman if(!is_abuiltin(np) && tp && tp->tp && nv_type(np)!=tp->tp)
2300*b30d1939SAndy Fiddaman return(0);
2301*b30d1939SAndy Fiddaman #endif /*SHOPT_TYPEDEF */
2302*b30d1939SAndy Fiddaman if(sp->scanmask==NV_TABLE && nv_isvtree(np))
2303*b30d1939SAndy Fiddaman k = NV_TABLE;
2304*b30d1939SAndy Fiddaman if(sp->scanmask?(k&sp->scanmask)==sp->scanflags:(!sp->scanflags || (k&sp->scanflags)))
2305*b30d1939SAndy Fiddaman {
2306*b30d1939SAndy Fiddaman if(tp && tp->mapname)
2307*b30d1939SAndy Fiddaman {
2308*b30d1939SAndy Fiddaman if(sp->scanflags==NV_FUNCTION || sp->scanflags==(NV_NOFREE|NV_BINARY|NV_RAW))
2309*b30d1939SAndy Fiddaman {
2310*b30d1939SAndy Fiddaman int n = strlen(tp->mapname);
2311*b30d1939SAndy Fiddaman if(memcmp(np->nvname,tp->mapname,n) || np->nvname[n]!='.' || strchr(&np->nvname[n+1],'.'))
2312*b30d1939SAndy Fiddaman return(0);
2313*b30d1939SAndy Fiddaman }
2314*b30d1939SAndy Fiddaman else if((sp->scanflags==NV_UTOL||sp->scanflags==NV_LTOU) && (cp=(char*)nv_mapchar(np,0)) && strcmp(cp,tp->mapname))
2315*b30d1939SAndy Fiddaman return(0);
2316*b30d1939SAndy Fiddaman }
2317*b30d1939SAndy Fiddaman if(!np->nvalue.cp && !np->nvfun && !nv_isattr(np,~NV_DEFAULT))
2318*b30d1939SAndy Fiddaman return(0);
2319*b30d1939SAndy Fiddaman if(sp->scanfn)
2320*b30d1939SAndy Fiddaman {
2321*b30d1939SAndy Fiddaman if(nv_isarray(np))
2322*b30d1939SAndy Fiddaman nv_putsub(np,NIL(char*),0L);
2323*b30d1939SAndy Fiddaman (*sp->scanfn)(np,sp->scandata);
2324*b30d1939SAndy Fiddaman }
2325*b30d1939SAndy Fiddaman sp->scancount++;
2326*b30d1939SAndy Fiddaman }
2327*b30d1939SAndy Fiddaman return(0);
2328*b30d1939SAndy Fiddaman }
2329*b30d1939SAndy Fiddaman
2330*b30d1939SAndy Fiddaman /*
2331*b30d1939SAndy Fiddaman * Walk through the name-value pairs
2332*b30d1939SAndy Fiddaman * if <mask> is non-zero, then only nodes with (nvflags&mask)==flags
2333*b30d1939SAndy Fiddaman * are visited
2334*b30d1939SAndy Fiddaman * If <mask> is zero, and <flags> non-zero, then nodes with one or
2335*b30d1939SAndy Fiddaman * more of <flags> is visited
2336*b30d1939SAndy Fiddaman * If <mask> and <flags> are zero, then all nodes are visted
2337*b30d1939SAndy Fiddaman */
nv_scan(Dt_t * root,void (* fn)(Namval_t *,void *),void * data,int mask,int flags)2338*b30d1939SAndy Fiddaman int nv_scan(Dt_t *root, void (*fn)(Namval_t*,void*), void *data,int mask, int flags)
2339*b30d1939SAndy Fiddaman {
2340*b30d1939SAndy Fiddaman Namval_t *np;
2341*b30d1939SAndy Fiddaman Dt_t *base=0;
2342*b30d1939SAndy Fiddaman struct scan sdata;
2343*b30d1939SAndy Fiddaman int (*hashfn)(Dt_t*, void*, void*);
2344*b30d1939SAndy Fiddaman sdata.scanmask = mask;
2345*b30d1939SAndy Fiddaman sdata.scanflags = flags&~NV_NOSCOPE;
2346*b30d1939SAndy Fiddaman sdata.scanfn = fn;
2347*b30d1939SAndy Fiddaman sdata.scancount = 0;
2348*b30d1939SAndy Fiddaman sdata.scandata = data;
2349*b30d1939SAndy Fiddaman hashfn = scanfilter;
2350*b30d1939SAndy Fiddaman if(flags&NV_NOSCOPE)
2351*b30d1939SAndy Fiddaman base = dtview((Dt_t*)root,0);
2352*b30d1939SAndy Fiddaman for(np=(Namval_t*)dtfirst(root);np; np=(Namval_t*)dtnext(root,np))
2353*b30d1939SAndy Fiddaman hashfn(root, np, &sdata);
2354*b30d1939SAndy Fiddaman if(base)
2355*b30d1939SAndy Fiddaman dtview((Dt_t*)root,base);
2356*b30d1939SAndy Fiddaman return(sdata.scancount);
2357*b30d1939SAndy Fiddaman }
2358*b30d1939SAndy Fiddaman
2359*b30d1939SAndy Fiddaman /*
2360*b30d1939SAndy Fiddaman * create a new environment scope
2361*b30d1939SAndy Fiddaman */
sh_scope(Shell_t * shp,struct argnod * envlist,int fun)2362*b30d1939SAndy Fiddaman void sh_scope(Shell_t *shp, struct argnod *envlist, int fun)
2363*b30d1939SAndy Fiddaman {
2364*b30d1939SAndy Fiddaman register Dt_t *newscope, *newroot=shp->var_base;
2365*b30d1939SAndy Fiddaman struct Ufunction *rp;
2366*b30d1939SAndy Fiddaman #if SHOPT_NAMESPACE
2367*b30d1939SAndy Fiddaman if(shp->namespace)
2368*b30d1939SAndy Fiddaman newroot = nv_dict(shp->namespace);
2369*b30d1939SAndy Fiddaman #endif /* SHOPT_NAMESPACE */
2370*b30d1939SAndy Fiddaman newscope = dtopen(&_Nvdisc,Dtoset);
2371*b30d1939SAndy Fiddaman if(envlist)
2372*b30d1939SAndy Fiddaman {
2373*b30d1939SAndy Fiddaman dtview(newscope,(Dt_t*)shp->var_tree);
2374*b30d1939SAndy Fiddaman shp->var_tree = newscope;
2375*b30d1939SAndy Fiddaman nv_setlist(envlist,NV_EXPORT|NV_NOSCOPE|NV_IDENT|NV_ASSIGN,0);
2376*b30d1939SAndy Fiddaman if(!fun)
2377*b30d1939SAndy Fiddaman return;
2378*b30d1939SAndy Fiddaman shp->var_tree = dtview(newscope,0);
2379*b30d1939SAndy Fiddaman }
2380*b30d1939SAndy Fiddaman if((rp=shp->st.real_fun) && rp->sdict)
2381*b30d1939SAndy Fiddaman {
2382*b30d1939SAndy Fiddaman dtview(rp->sdict,newroot);
2383*b30d1939SAndy Fiddaman newroot = rp->sdict;
2384*b30d1939SAndy Fiddaman
2385*b30d1939SAndy Fiddaman }
2386*b30d1939SAndy Fiddaman dtview(newscope,(Dt_t*)newroot);
2387*b30d1939SAndy Fiddaman shp->var_tree = newscope;
2388*b30d1939SAndy Fiddaman }
2389*b30d1939SAndy Fiddaman
2390*b30d1939SAndy Fiddaman /*
2391*b30d1939SAndy Fiddaman * Remove freeable local space associated with the nvalue field
2392*b30d1939SAndy Fiddaman * of nnod. This includes any strings representing the value(s) of the
2393*b30d1939SAndy Fiddaman * node, as well as its dope vector, if it is an array.
2394*b30d1939SAndy Fiddaman */
2395*b30d1939SAndy Fiddaman
sh_envnolocal(register Namval_t * np,void * data)2396*b30d1939SAndy Fiddaman void sh_envnolocal (register Namval_t *np, void *data)
2397*b30d1939SAndy Fiddaman {
2398*b30d1939SAndy Fiddaman struct adata *tp = (struct adata*)data;
2399*b30d1939SAndy Fiddaman char *cp=0;
2400*b30d1939SAndy Fiddaman if(np==VERSIONNOD && nv_isref(np))
2401*b30d1939SAndy Fiddaman return;
2402*b30d1939SAndy Fiddaman if(np==L_ARGNOD)
2403*b30d1939SAndy Fiddaman return;
2404*b30d1939SAndy Fiddaman if(np == tp->sh->namespace)
2405*b30d1939SAndy Fiddaman return;
2406*b30d1939SAndy Fiddaman if(nv_isref(np))
2407*b30d1939SAndy Fiddaman nv_unref(np);
2408*b30d1939SAndy Fiddaman if(nv_isattr(np,NV_EXPORT) && nv_isarray(np))
2409*b30d1939SAndy Fiddaman {
2410*b30d1939SAndy Fiddaman nv_putsub(np,NIL(char*),0);
2411*b30d1939SAndy Fiddaman if(cp = nv_getval(np))
2412*b30d1939SAndy Fiddaman cp = strdup(cp);
2413*b30d1939SAndy Fiddaman }
2414*b30d1939SAndy Fiddaman if(nv_isattr(np,NV_EXPORT|NV_NOFREE))
2415*b30d1939SAndy Fiddaman {
2416*b30d1939SAndy Fiddaman if(nv_isref(np) && np!=VERSIONNOD)
2417*b30d1939SAndy Fiddaman {
2418*b30d1939SAndy Fiddaman nv_offattr(np,NV_NOFREE|NV_REF);
2419*b30d1939SAndy Fiddaman free((void*)np->nvalue.nrp);
2420*b30d1939SAndy Fiddaman np->nvalue.cp = 0;
2421*b30d1939SAndy Fiddaman }
2422*b30d1939SAndy Fiddaman if(!cp)
2423*b30d1939SAndy Fiddaman return;
2424*b30d1939SAndy Fiddaman }
2425*b30d1939SAndy Fiddaman if(nv_isarray(np))
2426*b30d1939SAndy Fiddaman nv_putsub(np,NIL(char*),ARRAY_UNDEF);
2427*b30d1939SAndy Fiddaman _nv_unset(np,NV_RDONLY);
2428*b30d1939SAndy Fiddaman nv_setattr(np,0);
2429*b30d1939SAndy Fiddaman if(cp)
2430*b30d1939SAndy Fiddaman {
2431*b30d1939SAndy Fiddaman nv_putval(np,cp,0);
2432*b30d1939SAndy Fiddaman free((void*)cp);
2433*b30d1939SAndy Fiddaman }
2434*b30d1939SAndy Fiddaman }
2435*b30d1939SAndy Fiddaman
2436*b30d1939SAndy Fiddaman /*
2437*b30d1939SAndy Fiddaman * Currently this is a dummy, but someday will be needed
2438*b30d1939SAndy Fiddaman * for reference counting
2439*b30d1939SAndy Fiddaman */
nv_close(Namval_t * np)2440*b30d1939SAndy Fiddaman void nv_close(Namval_t *np)
2441*b30d1939SAndy Fiddaman {
2442*b30d1939SAndy Fiddaman NOT_USED(np);
2443*b30d1939SAndy Fiddaman }
2444*b30d1939SAndy Fiddaman
table_unset(Shell_t * shp,register Dt_t * root,int flags,Dt_t * oroot)2445*b30d1939SAndy Fiddaman static void table_unset(Shell_t *shp, register Dt_t *root, int flags, Dt_t *oroot)
2446*b30d1939SAndy Fiddaman {
2447*b30d1939SAndy Fiddaman register Namval_t *np,*nq, *npnext;
2448*b30d1939SAndy Fiddaman for(np=(Namval_t*)dtfirst(root);np;np=npnext)
2449*b30d1939SAndy Fiddaman {
2450*b30d1939SAndy Fiddaman if(nq=dtsearch(oroot,np))
2451*b30d1939SAndy Fiddaman {
2452*b30d1939SAndy Fiddaman if(nv_cover(nq))
2453*b30d1939SAndy Fiddaman {
2454*b30d1939SAndy Fiddaman int subshell = shp->subshell;
2455*b30d1939SAndy Fiddaman shp->subshell = 0;
2456*b30d1939SAndy Fiddaman if(nv_isattr(nq, NV_INTEGER))
2457*b30d1939SAndy Fiddaman {
2458*b30d1939SAndy Fiddaman Sfdouble_t d = nv_getnum(nq);
2459*b30d1939SAndy Fiddaman nv_putval(nq,(char*)&d,NV_LDOUBLE);
2460*b30d1939SAndy Fiddaman }
2461*b30d1939SAndy Fiddaman else if(shp->test&4)
2462*b30d1939SAndy Fiddaman nv_putval(nq, strdup(nv_getval(nq)), NV_RDONLY);
2463*b30d1939SAndy Fiddaman else
2464*b30d1939SAndy Fiddaman nv_putval(nq, nv_getval(nq), NV_RDONLY);
2465*b30d1939SAndy Fiddaman shp->subshell = subshell;
2466*b30d1939SAndy Fiddaman np->nvfun = 0;
2467*b30d1939SAndy Fiddaman }
2468*b30d1939SAndy Fiddaman if(nv_isattr(nq,NV_EXPORT))
2469*b30d1939SAndy Fiddaman sh_envput(shp->env,nq);
2470*b30d1939SAndy Fiddaman }
2471*b30d1939SAndy Fiddaman shp->last_root = root;
2472*b30d1939SAndy Fiddaman shp->last_table = 0;
2473*b30d1939SAndy Fiddaman if(nv_isvtree(np))
2474*b30d1939SAndy Fiddaman {
2475*b30d1939SAndy Fiddaman int len = strlen(np->nvname);
2476*b30d1939SAndy Fiddaman npnext = (Namval_t*)dtnext(root,np);
2477*b30d1939SAndy Fiddaman while((nq=npnext) && memcmp(np->nvname,nq->nvname,len)==0 && nq->nvname[len]=='.')
2478*b30d1939SAndy Fiddaman
2479*b30d1939SAndy Fiddaman {
2480*b30d1939SAndy Fiddaman _nv_unset(nq,flags);
2481*b30d1939SAndy Fiddaman npnext = (Namval_t*)dtnext(root,nq);
2482*b30d1939SAndy Fiddaman nv_delete(nq,root,0);
2483*b30d1939SAndy Fiddaman }
2484*b30d1939SAndy Fiddaman }
2485*b30d1939SAndy Fiddaman npnext = (Namval_t*)dtnext(root,np);
2486*b30d1939SAndy Fiddaman _nv_unset(np,flags);
2487*b30d1939SAndy Fiddaman nv_delete(np,root,0);
2488*b30d1939SAndy Fiddaman }
2489*b30d1939SAndy Fiddaman }
2490*b30d1939SAndy Fiddaman
2491*b30d1939SAndy Fiddaman /*
2492*b30d1939SAndy Fiddaman *
2493*b30d1939SAndy Fiddaman * Set the value of <np> to 0, and nullify any attributes
2494*b30d1939SAndy Fiddaman * that <np> may have had. Free any freeable space occupied
2495*b30d1939SAndy Fiddaman * by the value of <np>. If <np> denotes an array member, it
2496*b30d1939SAndy Fiddaman * will retain its attributes.
2497*b30d1939SAndy Fiddaman * <flags> can contain NV_RDONLY to override the readonly attribute
2498*b30d1939SAndy Fiddaman * being cleared.
2499*b30d1939SAndy Fiddaman * <flags> can contain NV_EXPORT to override preserve nvenv
2500*b30d1939SAndy Fiddaman */
_nv_unset(register Namval_t * np,int flags)2501*b30d1939SAndy Fiddaman void _nv_unset(register Namval_t *np,int flags)
2502*b30d1939SAndy Fiddaman {
2503*b30d1939SAndy Fiddaman Shell_t *shp = sh_getinterp();
2504*b30d1939SAndy Fiddaman register union Value *up;
2505*b30d1939SAndy Fiddaman #if SHOPT_FIXEDARRAY
2506*b30d1939SAndy Fiddaman Namarr_t *ap;
2507*b30d1939SAndy Fiddaman #endif /* SHOPT_FIXEDARRAY */
2508*b30d1939SAndy Fiddaman if(!(flags&NV_RDONLY) && nv_isattr (np,NV_RDONLY))
2509*b30d1939SAndy Fiddaman errormsg(SH_DICT,ERROR_exit(1),e_readonly, nv_name(np));
2510*b30d1939SAndy Fiddaman if(is_afunction(np) && np->nvalue.ip)
2511*b30d1939SAndy Fiddaman {
2512*b30d1939SAndy Fiddaman register struct slnod *slp = (struct slnod*)(np->nvenv);
2513*b30d1939SAndy Fiddaman if(shp->st.real_fun == np->nvalue.rp)
2514*b30d1939SAndy Fiddaman {
2515*b30d1939SAndy Fiddaman np->nvalue.rp->running |= 1;
2516*b30d1939SAndy Fiddaman return;
2517*b30d1939SAndy Fiddaman }
2518*b30d1939SAndy Fiddaman if(slp && !nv_isattr(np,NV_NOFREE))
2519*b30d1939SAndy Fiddaman {
2520*b30d1939SAndy Fiddaman struct Ufunction *rq,*rp = np->nvalue.rp;
2521*b30d1939SAndy Fiddaman /* free function definition */
2522*b30d1939SAndy Fiddaman register char *name=nv_name(np),*cp= strrchr(name,'.');
2523*b30d1939SAndy Fiddaman if(cp)
2524*b30d1939SAndy Fiddaman {
2525*b30d1939SAndy Fiddaman Namval_t *npv;
2526*b30d1939SAndy Fiddaman *cp = 0;
2527*b30d1939SAndy Fiddaman npv = nv_open(name,shp->var_tree,NV_NOARRAY|NV_VARNAME|NV_NOADD);
2528*b30d1939SAndy Fiddaman *cp++ = '.';
2529*b30d1939SAndy Fiddaman if(npv && npv!=shp->namespace)
2530*b30d1939SAndy Fiddaman nv_setdisc(npv,cp,NIL(Namval_t*),(Namfun_t*)npv);
2531*b30d1939SAndy Fiddaman }
2532*b30d1939SAndy Fiddaman if(rp->fname && shp->fpathdict && (rq = (struct Ufunction*)nv_search(rp->fname,shp->fpathdict,0)))
2533*b30d1939SAndy Fiddaman {
2534*b30d1939SAndy Fiddaman do
2535*b30d1939SAndy Fiddaman {
2536*b30d1939SAndy Fiddaman if(rq->np != np)
2537*b30d1939SAndy Fiddaman continue;
2538*b30d1939SAndy Fiddaman dtdelete(shp->fpathdict,rq);
2539*b30d1939SAndy Fiddaman break;
2540*b30d1939SAndy Fiddaman }
2541*b30d1939SAndy Fiddaman while(rq = (struct Ufunction*)dtnext(shp->fpathdict,rq));
2542*b30d1939SAndy Fiddaman }
2543*b30d1939SAndy Fiddaman if(rp->sdict)
2544*b30d1939SAndy Fiddaman {
2545*b30d1939SAndy Fiddaman Namval_t *mp, *nq;
2546*b30d1939SAndy Fiddaman for(mp=(Namval_t*)dtfirst(rp->sdict);mp;mp=nq)
2547*b30d1939SAndy Fiddaman {
2548*b30d1939SAndy Fiddaman nq = dtnext(rp->sdict,mp);
2549*b30d1939SAndy Fiddaman _nv_unset(mp,NV_RDONLY);
2550*b30d1939SAndy Fiddaman nv_delete(mp,rp->sdict,0);
2551*b30d1939SAndy Fiddaman }
2552*b30d1939SAndy Fiddaman dtclose(rp->sdict);
2553*b30d1939SAndy Fiddaman }
2554*b30d1939SAndy Fiddaman stakdelete(slp->slptr);
2555*b30d1939SAndy Fiddaman free((void*)np->nvalue.ip);
2556*b30d1939SAndy Fiddaman np->nvalue.ip = 0;
2557*b30d1939SAndy Fiddaman }
2558*b30d1939SAndy Fiddaman goto done;
2559*b30d1939SAndy Fiddaman }
2560*b30d1939SAndy Fiddaman if(shp->subshell)
2561*b30d1939SAndy Fiddaman np = sh_assignok(np,0);
2562*b30d1939SAndy Fiddaman nv_offattr(np,NV_NODISC);
2563*b30d1939SAndy Fiddaman if(np->nvfun && !nv_isref(np))
2564*b30d1939SAndy Fiddaman {
2565*b30d1939SAndy Fiddaman /* This function contains disc */
2566*b30d1939SAndy Fiddaman if(!nv_local)
2567*b30d1939SAndy Fiddaman {
2568*b30d1939SAndy Fiddaman nv_local=1;
2569*b30d1939SAndy Fiddaman nv_putv(np,NIL(char*),flags,np->nvfun);
2570*b30d1939SAndy Fiddaman nv_local=0;
2571*b30d1939SAndy Fiddaman return;
2572*b30d1939SAndy Fiddaman }
2573*b30d1939SAndy Fiddaman /* called from disc, assign the actual value */
2574*b30d1939SAndy Fiddaman nv_local=0;
2575*b30d1939SAndy Fiddaman }
2576*b30d1939SAndy Fiddaman if(nv_isattr(np,NV_INT16P) == NV_INT16)
2577*b30d1939SAndy Fiddaman {
2578*b30d1939SAndy Fiddaman np->nvalue.cp = nv_isarray(np)?Empty:0;
2579*b30d1939SAndy Fiddaman goto done;
2580*b30d1939SAndy Fiddaman }
2581*b30d1939SAndy Fiddaman #if SHOPT_FIXEDARRAY
2582*b30d1939SAndy Fiddaman else if(np->nvalue.up && nv_isarray(np) && (ap=nv_arrayptr(np)) && !ap->fixed)
2583*b30d1939SAndy Fiddaman #else
2584*b30d1939SAndy Fiddaman else if(np->nvalue.up && nv_isarray(np) && nv_arrayptr(np))
2585*b30d1939SAndy Fiddaman #endif /* SHOPT_FIXEDARRAY */
2586*b30d1939SAndy Fiddaman up = np->nvalue.up;
2587*b30d1939SAndy Fiddaman else if(nv_isref(np) && !nv_isattr(np,NV_EXPORT|NV_MINIMAL) && np->nvalue.nrp)
2588*b30d1939SAndy Fiddaman {
2589*b30d1939SAndy Fiddaman
2590*b30d1939SAndy Fiddaman if(np->nvalue.nrp->root)
2591*b30d1939SAndy Fiddaman dtdelete(Refdict,(void*)np->nvalue.nrp);
2592*b30d1939SAndy Fiddaman if(np->nvalue.nrp->sub)
2593*b30d1939SAndy Fiddaman free(np->nvalue.nrp->sub);
2594*b30d1939SAndy Fiddaman free((void*)np->nvalue.nrp);
2595*b30d1939SAndy Fiddaman np->nvalue.cp = 0;
2596*b30d1939SAndy Fiddaman up = 0;
2597*b30d1939SAndy Fiddaman }
2598*b30d1939SAndy Fiddaman else
2599*b30d1939SAndy Fiddaman up = &np->nvalue;
2600*b30d1939SAndy Fiddaman if(up && up->cp)
2601*b30d1939SAndy Fiddaman {
2602*b30d1939SAndy Fiddaman if(up->cp!=Empty && up->cp!=Null && !nv_isattr(np, NV_NOFREE))
2603*b30d1939SAndy Fiddaman free((void*)up->cp);
2604*b30d1939SAndy Fiddaman up->cp = 0;
2605*b30d1939SAndy Fiddaman }
2606*b30d1939SAndy Fiddaman done:
2607*b30d1939SAndy Fiddaman if(!nv_isarray(np) || !nv_arrayptr(np))
2608*b30d1939SAndy Fiddaman {
2609*b30d1939SAndy Fiddaman nv_setsize(np,0);
2610*b30d1939SAndy Fiddaman if(!nv_isattr(np,NV_MINIMAL) || nv_isattr(np,NV_EXPORT))
2611*b30d1939SAndy Fiddaman {
2612*b30d1939SAndy Fiddaman if(nv_isattr(np,NV_EXPORT) && !strchr(np->nvname,'['))
2613*b30d1939SAndy Fiddaman env_delete(shp->env,nv_name(np));
2614*b30d1939SAndy Fiddaman if(!(flags&NV_EXPORT) || nv_isattr(np,NV_EXPORT))
2615*b30d1939SAndy Fiddaman np->nvenv = 0;
2616*b30d1939SAndy Fiddaman nv_setattr(np,0);
2617*b30d1939SAndy Fiddaman }
2618*b30d1939SAndy Fiddaman else
2619*b30d1939SAndy Fiddaman {
2620*b30d1939SAndy Fiddaman nv_setattr(np,NV_MINIMAL);
2621*b30d1939SAndy Fiddaman nv_delete(np,(Dt_t*)0,0);
2622*b30d1939SAndy Fiddaman }
2623*b30d1939SAndy Fiddaman }
2624*b30d1939SAndy Fiddaman }
2625*b30d1939SAndy Fiddaman
2626*b30d1939SAndy Fiddaman /*
2627*b30d1939SAndy Fiddaman * return the node pointer in the highest level scope
2628*b30d1939SAndy Fiddaman */
sh_scoped(Shell_t * shp,register Namval_t * np)2629*b30d1939SAndy Fiddaman Namval_t *sh_scoped(Shell_t *shp, register Namval_t *np)
2630*b30d1939SAndy Fiddaman {
2631*b30d1939SAndy Fiddaman if(!dtvnext(shp->var_tree))
2632*b30d1939SAndy Fiddaman return(np);
2633*b30d1939SAndy Fiddaman return(dtsearch(shp->var_tree,np));
2634*b30d1939SAndy Fiddaman }
2635*b30d1939SAndy Fiddaman
2636*b30d1939SAndy Fiddaman #if 1
2637*b30d1939SAndy Fiddaman /*
2638*b30d1939SAndy Fiddaman * return space separated list of names of variables in given tree
2639*b30d1939SAndy Fiddaman */
tableval(Dt_t * root)2640*b30d1939SAndy Fiddaman static char *tableval(Dt_t *root)
2641*b30d1939SAndy Fiddaman {
2642*b30d1939SAndy Fiddaman static Sfio_t *out;
2643*b30d1939SAndy Fiddaman register Namval_t *np;
2644*b30d1939SAndy Fiddaman register int first=1;
2645*b30d1939SAndy Fiddaman register Dt_t *base = dtview(root,0);
2646*b30d1939SAndy Fiddaman if(out)
2647*b30d1939SAndy Fiddaman sfseek(out,(Sfoff_t)0,SEEK_SET);
2648*b30d1939SAndy Fiddaman else
2649*b30d1939SAndy Fiddaman out = sfnew((Sfio_t*)0,(char*)0,-1,-1,SF_WRITE|SF_STRING);
2650*b30d1939SAndy Fiddaman for(np=(Namval_t*)dtfirst(root);np;np=(Namval_t*)dtnext(root,np))
2651*b30d1939SAndy Fiddaman {
2652*b30d1939SAndy Fiddaman if(!nv_isnull(np) || np->nvfun || nv_isattr(np,~NV_NOFREE))
2653*b30d1939SAndy Fiddaman {
2654*b30d1939SAndy Fiddaman if(!first)
2655*b30d1939SAndy Fiddaman sfputc(out,' ');
2656*b30d1939SAndy Fiddaman else
2657*b30d1939SAndy Fiddaman first = 0;
2658*b30d1939SAndy Fiddaman sfputr(out,np->nvname,-1);
2659*b30d1939SAndy Fiddaman }
2660*b30d1939SAndy Fiddaman }
2661*b30d1939SAndy Fiddaman sfputc(out,0);
2662*b30d1939SAndy Fiddaman if(base)
2663*b30d1939SAndy Fiddaman dtview(root,base);
2664*b30d1939SAndy Fiddaman return((char*)out->_data);
2665*b30d1939SAndy Fiddaman }
2666*b30d1939SAndy Fiddaman #endif
2667*b30d1939SAndy Fiddaman
2668*b30d1939SAndy Fiddaman #if SHOPT_OPTIMIZE
2669*b30d1939SAndy Fiddaman struct optimize
2670*b30d1939SAndy Fiddaman {
2671*b30d1939SAndy Fiddaman Namfun_t hdr;
2672*b30d1939SAndy Fiddaman Shell_t *sh;
2673*b30d1939SAndy Fiddaman char **ptr;
2674*b30d1939SAndy Fiddaman struct optimize *next;
2675*b30d1939SAndy Fiddaman Namval_t *np;
2676*b30d1939SAndy Fiddaman };
2677*b30d1939SAndy Fiddaman
2678*b30d1939SAndy Fiddaman static struct optimize *opt_free;
2679*b30d1939SAndy Fiddaman
optimize_clear(Namval_t * np,Namfun_t * fp)2680*b30d1939SAndy Fiddaman static void optimize_clear(Namval_t* np, Namfun_t *fp)
2681*b30d1939SAndy Fiddaman {
2682*b30d1939SAndy Fiddaman struct optimize *op = (struct optimize*)fp;
2683*b30d1939SAndy Fiddaman nv_stack(np,fp);
2684*b30d1939SAndy Fiddaman nv_stack(np,(Namfun_t*)0);
2685*b30d1939SAndy Fiddaman for(;op && op->np==np; op=op->next)
2686*b30d1939SAndy Fiddaman {
2687*b30d1939SAndy Fiddaman if(op->ptr)
2688*b30d1939SAndy Fiddaman {
2689*b30d1939SAndy Fiddaman *op->ptr = 0;
2690*b30d1939SAndy Fiddaman op->ptr = 0;
2691*b30d1939SAndy Fiddaman }
2692*b30d1939SAndy Fiddaman }
2693*b30d1939SAndy Fiddaman }
2694*b30d1939SAndy Fiddaman
put_optimize(Namval_t * np,const char * val,int flags,Namfun_t * fp)2695*b30d1939SAndy Fiddaman static void put_optimize(Namval_t* np,const char *val,int flags,Namfun_t *fp)
2696*b30d1939SAndy Fiddaman {
2697*b30d1939SAndy Fiddaman nv_putv(np,val,flags,fp);
2698*b30d1939SAndy Fiddaman optimize_clear(np,fp);
2699*b30d1939SAndy Fiddaman }
2700*b30d1939SAndy Fiddaman
clone_optimize(Namval_t * np,Namval_t * mp,int flags,Namfun_t * fp)2701*b30d1939SAndy Fiddaman static Namfun_t *clone_optimize(Namval_t* np, Namval_t *mp, int flags, Namfun_t *fp)
2702*b30d1939SAndy Fiddaman {
2703*b30d1939SAndy Fiddaman return((Namfun_t*)0);
2704*b30d1939SAndy Fiddaman }
2705*b30d1939SAndy Fiddaman
2706*b30d1939SAndy Fiddaman static const Namdisc_t optimize_disc = {sizeof(struct optimize),put_optimize,0,0,0,0,clone_optimize};
2707*b30d1939SAndy Fiddaman
nv_optimize(Namval_t * np)2708*b30d1939SAndy Fiddaman void nv_optimize(Namval_t *np)
2709*b30d1939SAndy Fiddaman {
2710*b30d1939SAndy Fiddaman Shell_t *shp = sh_getinterp();
2711*b30d1939SAndy Fiddaman register Namfun_t *fp;
2712*b30d1939SAndy Fiddaman register struct optimize *op, *xp;
2713*b30d1939SAndy Fiddaman if(shp->argaddr)
2714*b30d1939SAndy Fiddaman {
2715*b30d1939SAndy Fiddaman if(np==SH_LINENO)
2716*b30d1939SAndy Fiddaman {
2717*b30d1939SAndy Fiddaman shp->argaddr = 0;
2718*b30d1939SAndy Fiddaman return;
2719*b30d1939SAndy Fiddaman }
2720*b30d1939SAndy Fiddaman for(fp=np->nvfun; fp; fp = fp->next)
2721*b30d1939SAndy Fiddaman {
2722*b30d1939SAndy Fiddaman if(fp->disc && (fp->disc->getnum || fp->disc->getval))
2723*b30d1939SAndy Fiddaman {
2724*b30d1939SAndy Fiddaman shp->argaddr = 0;
2725*b30d1939SAndy Fiddaman return;
2726*b30d1939SAndy Fiddaman }
2727*b30d1939SAndy Fiddaman if(fp->disc== &optimize_disc)
2728*b30d1939SAndy Fiddaman break;
2729*b30d1939SAndy Fiddaman }
2730*b30d1939SAndy Fiddaman if((xp= (struct optimize*)fp) && xp->ptr==shp->argaddr)
2731*b30d1939SAndy Fiddaman return;
2732*b30d1939SAndy Fiddaman if(op = opt_free)
2733*b30d1939SAndy Fiddaman opt_free = op->next;
2734*b30d1939SAndy Fiddaman else
2735*b30d1939SAndy Fiddaman op=(struct optimize*)calloc(1,sizeof(struct optimize));
2736*b30d1939SAndy Fiddaman op->ptr = shp->argaddr;
2737*b30d1939SAndy Fiddaman op->np = np;
2738*b30d1939SAndy Fiddaman if(xp)
2739*b30d1939SAndy Fiddaman {
2740*b30d1939SAndy Fiddaman op->hdr.disc = 0;
2741*b30d1939SAndy Fiddaman op->next = xp->next;
2742*b30d1939SAndy Fiddaman xp->next = op;
2743*b30d1939SAndy Fiddaman }
2744*b30d1939SAndy Fiddaman else
2745*b30d1939SAndy Fiddaman {
2746*b30d1939SAndy Fiddaman op->hdr.disc = &optimize_disc;
2747*b30d1939SAndy Fiddaman op->next = (struct optimize*)shp->optlist;
2748*b30d1939SAndy Fiddaman shp->optlist = (void*)op;
2749*b30d1939SAndy Fiddaman nv_stack(np,&op->hdr);
2750*b30d1939SAndy Fiddaman }
2751*b30d1939SAndy Fiddaman }
2752*b30d1939SAndy Fiddaman }
2753*b30d1939SAndy Fiddaman
sh_optclear(Shell_t * shp,void * old)2754*b30d1939SAndy Fiddaman void sh_optclear(Shell_t *shp, void *old)
2755*b30d1939SAndy Fiddaman {
2756*b30d1939SAndy Fiddaman register struct optimize *op,*opnext;
2757*b30d1939SAndy Fiddaman for(op=(struct optimize*)shp->optlist; op; op = opnext)
2758*b30d1939SAndy Fiddaman {
2759*b30d1939SAndy Fiddaman opnext = op->next;
2760*b30d1939SAndy Fiddaman if(op->ptr && op->hdr.disc)
2761*b30d1939SAndy Fiddaman {
2762*b30d1939SAndy Fiddaman nv_stack(op->np,&op->hdr);
2763*b30d1939SAndy Fiddaman nv_stack(op->np,(Namfun_t*)0);
2764*b30d1939SAndy Fiddaman }
2765*b30d1939SAndy Fiddaman op->next = opt_free;
2766*b30d1939SAndy Fiddaman opt_free = op;
2767*b30d1939SAndy Fiddaman }
2768*b30d1939SAndy Fiddaman shp->optlist = old;
2769*b30d1939SAndy Fiddaman }
2770*b30d1939SAndy Fiddaman
2771*b30d1939SAndy Fiddaman #else
2772*b30d1939SAndy Fiddaman # define optimize_clear(np,fp)
2773*b30d1939SAndy Fiddaman #endif /* SHOPT_OPTIMIZE */
2774*b30d1939SAndy Fiddaman
2775*b30d1939SAndy Fiddaman /*
2776*b30d1939SAndy Fiddaman * Return a pointer to a character string that denotes the value
2777*b30d1939SAndy Fiddaman * of <np>. If <np> refers to an array, return a pointer to
2778*b30d1939SAndy Fiddaman * the value associated with the current index.
2779*b30d1939SAndy Fiddaman *
2780*b30d1939SAndy Fiddaman * If the value of <np> is an integer, the string returned will
2781*b30d1939SAndy Fiddaman * be overwritten by the next call to nv_getval.
2782*b30d1939SAndy Fiddaman *
2783*b30d1939SAndy Fiddaman * If <np> has no value, 0 is returned.
2784*b30d1939SAndy Fiddaman */
2785*b30d1939SAndy Fiddaman
nv_getval(register Namval_t * np)2786*b30d1939SAndy Fiddaman char *nv_getval(register Namval_t *np)
2787*b30d1939SAndy Fiddaman {
2788*b30d1939SAndy Fiddaman Shell_t *shp = sh_getinterp();
2789*b30d1939SAndy Fiddaman register union Value *up= &np->nvalue;
2790*b30d1939SAndy Fiddaman register int numeric;
2791*b30d1939SAndy Fiddaman #if SHOPT_OPTIMIZE
2792*b30d1939SAndy Fiddaman if(!nv_local && shp->argaddr)
2793*b30d1939SAndy Fiddaman nv_optimize(np);
2794*b30d1939SAndy Fiddaman #endif /* SHOPT_OPTIMIZE */
2795*b30d1939SAndy Fiddaman if((!np->nvfun || !np->nvfun->disc) && !nv_isattr(np,NV_ARRAY|NV_INTEGER|NV_FUNCT|NV_REF))
2796*b30d1939SAndy Fiddaman goto done;
2797*b30d1939SAndy Fiddaman if(nv_isref(np))
2798*b30d1939SAndy Fiddaman {
2799*b30d1939SAndy Fiddaman char *sub;
2800*b30d1939SAndy Fiddaman if(!np->nvalue.cp)
2801*b30d1939SAndy Fiddaman return(0);
2802*b30d1939SAndy Fiddaman shp->last_table = nv_reftable(np);
2803*b30d1939SAndy Fiddaman sub=nv_refsub(np);
2804*b30d1939SAndy Fiddaman np = nv_refnode(np);
2805*b30d1939SAndy Fiddaman if(sub)
2806*b30d1939SAndy Fiddaman {
2807*b30d1939SAndy Fiddaman sfprintf(shp->strbuf,"%s[%s]",nv_name(np),sub);
2808*b30d1939SAndy Fiddaman return(sfstruse(shp->strbuf));
2809*b30d1939SAndy Fiddaman }
2810*b30d1939SAndy Fiddaman return(nv_name(np));
2811*b30d1939SAndy Fiddaman }
2812*b30d1939SAndy Fiddaman if(np->nvfun && np->nvfun->disc)
2813*b30d1939SAndy Fiddaman {
2814*b30d1939SAndy Fiddaman if(!nv_local)
2815*b30d1939SAndy Fiddaman {
2816*b30d1939SAndy Fiddaman nv_local=1;
2817*b30d1939SAndy Fiddaman return(nv_getv(np, np->nvfun));
2818*b30d1939SAndy Fiddaman }
2819*b30d1939SAndy Fiddaman nv_local=0;
2820*b30d1939SAndy Fiddaman }
2821*b30d1939SAndy Fiddaman numeric = ((nv_isattr (np, NV_INTEGER)) != 0);
2822*b30d1939SAndy Fiddaman if(numeric)
2823*b30d1939SAndy Fiddaman {
2824*b30d1939SAndy Fiddaman Sflong_t ll;
2825*b30d1939SAndy Fiddaman if(!up->cp)
2826*b30d1939SAndy Fiddaman return("0");
2827*b30d1939SAndy Fiddaman if(nv_isattr (np,NV_DOUBLE)==NV_DOUBLE)
2828*b30d1939SAndy Fiddaman {
2829*b30d1939SAndy Fiddaman Sfdouble_t ld;
2830*b30d1939SAndy Fiddaman double d;
2831*b30d1939SAndy Fiddaman char *format;
2832*b30d1939SAndy Fiddaman if(nv_isattr(np,NV_LONG))
2833*b30d1939SAndy Fiddaman {
2834*b30d1939SAndy Fiddaman ld = *up->ldp;
2835*b30d1939SAndy Fiddaman if(nv_isattr (np,NV_EXPNOTE))
2836*b30d1939SAndy Fiddaman format = "%.*Lg";
2837*b30d1939SAndy Fiddaman else if(nv_isattr (np,NV_HEXFLOAT))
2838*b30d1939SAndy Fiddaman format = "%.*La";
2839*b30d1939SAndy Fiddaman else
2840*b30d1939SAndy Fiddaman format = "%.*Lf";
2841*b30d1939SAndy Fiddaman sfprintf(shp->strbuf,format,nv_size(np),ld);
2842*b30d1939SAndy Fiddaman }
2843*b30d1939SAndy Fiddaman else
2844*b30d1939SAndy Fiddaman {
2845*b30d1939SAndy Fiddaman d = *up->dp;
2846*b30d1939SAndy Fiddaman if(nv_isattr (np,NV_EXPNOTE))
2847*b30d1939SAndy Fiddaman format = "%.*g";
2848*b30d1939SAndy Fiddaman else if(nv_isattr (np,NV_HEXFLOAT))
2849*b30d1939SAndy Fiddaman format = "%.*a";
2850*b30d1939SAndy Fiddaman else
2851*b30d1939SAndy Fiddaman format = "%.*f";
2852*b30d1939SAndy Fiddaman sfprintf(shp->strbuf,format,nv_size(np),d);
2853*b30d1939SAndy Fiddaman }
2854*b30d1939SAndy Fiddaman return(sfstruse(shp->strbuf));
2855*b30d1939SAndy Fiddaman }
2856*b30d1939SAndy Fiddaman else if(nv_isattr(np,NV_UNSIGN))
2857*b30d1939SAndy Fiddaman {
2858*b30d1939SAndy Fiddaman if(nv_isattr (np,NV_LONG))
2859*b30d1939SAndy Fiddaman ll = *(Sfulong_t*)up->llp;
2860*b30d1939SAndy Fiddaman else if(nv_isattr (np,NV_SHORT))
2861*b30d1939SAndy Fiddaman {
2862*b30d1939SAndy Fiddaman if(nv_isattr(np,NV_INT16P)==NV_INT16P)
2863*b30d1939SAndy Fiddaman ll = *(uint16_t*)(up->sp);
2864*b30d1939SAndy Fiddaman else
2865*b30d1939SAndy Fiddaman ll = (uint16_t)up->s;
2866*b30d1939SAndy Fiddaman }
2867*b30d1939SAndy Fiddaman else
2868*b30d1939SAndy Fiddaman ll = *(uint32_t*)(up->lp);
2869*b30d1939SAndy Fiddaman }
2870*b30d1939SAndy Fiddaman else if(nv_isattr (np,NV_LONG))
2871*b30d1939SAndy Fiddaman ll = *up->llp;
2872*b30d1939SAndy Fiddaman else if(nv_isattr (np,NV_SHORT))
2873*b30d1939SAndy Fiddaman {
2874*b30d1939SAndy Fiddaman if(nv_isattr(np,NV_INT16P)==NV_INT16P)
2875*b30d1939SAndy Fiddaman ll = *up->sp;
2876*b30d1939SAndy Fiddaman else
2877*b30d1939SAndy Fiddaman ll = up->s;
2878*b30d1939SAndy Fiddaman }
2879*b30d1939SAndy Fiddaman else
2880*b30d1939SAndy Fiddaman ll = *(up->lp);
2881*b30d1939SAndy Fiddaman if((numeric=nv_size(np))==10)
2882*b30d1939SAndy Fiddaman {
2883*b30d1939SAndy Fiddaman if(nv_isattr(np,NV_UNSIGN))
2884*b30d1939SAndy Fiddaman {
2885*b30d1939SAndy Fiddaman sfprintf(shp->strbuf,"%I*u",sizeof(ll),ll);
2886*b30d1939SAndy Fiddaman return(sfstruse(shp->strbuf));
2887*b30d1939SAndy Fiddaman }
2888*b30d1939SAndy Fiddaman numeric = 0;
2889*b30d1939SAndy Fiddaman }
2890*b30d1939SAndy Fiddaman return(fmtbase(ll,numeric, numeric&&numeric!=10));
2891*b30d1939SAndy Fiddaman }
2892*b30d1939SAndy Fiddaman done:
2893*b30d1939SAndy Fiddaman #if (_AST_VERSION>=20030127L)
2894*b30d1939SAndy Fiddaman /*
2895*b30d1939SAndy Fiddaman * if NV_RAW flag is on, return pointer to binary data
2896*b30d1939SAndy Fiddaman * otherwise, base64 encode the data and return this string
2897*b30d1939SAndy Fiddaman */
2898*b30d1939SAndy Fiddaman if(up->cp && nv_isattr(np,NV_BINARY) && !nv_isattr(np,NV_RAW))
2899*b30d1939SAndy Fiddaman {
2900*b30d1939SAndy Fiddaman char *cp;
2901*b30d1939SAndy Fiddaman char *ep;
2902*b30d1939SAndy Fiddaman int size= nv_size(np), insize=(4*size)/3+size/45+8;
2903*b30d1939SAndy Fiddaman base64encode(up->cp, size, (void**)0, cp=getbuf(insize), insize, (void**)&ep);
2904*b30d1939SAndy Fiddaman *ep = 0;
2905*b30d1939SAndy Fiddaman return(cp);
2906*b30d1939SAndy Fiddaman }
2907*b30d1939SAndy Fiddaman #endif
2908*b30d1939SAndy Fiddaman if(!nv_isattr(np,NV_LJUST|NV_RJUST) && (numeric=nv_size(np)) && up->cp && up->cp[numeric])
2909*b30d1939SAndy Fiddaman {
2910*b30d1939SAndy Fiddaman char *cp = getbuf(numeric+1);
2911*b30d1939SAndy Fiddaman memcpy(cp,up->cp,numeric);
2912*b30d1939SAndy Fiddaman cp[numeric]=0;
2913*b30d1939SAndy Fiddaman return(cp);
2914*b30d1939SAndy Fiddaman }
2915*b30d1939SAndy Fiddaman return ((char*)up->cp);
2916*b30d1939SAndy Fiddaman }
2917*b30d1939SAndy Fiddaman
nv_getnum(register Namval_t * np)2918*b30d1939SAndy Fiddaman Sfdouble_t nv_getnum(register Namval_t *np)
2919*b30d1939SAndy Fiddaman {
2920*b30d1939SAndy Fiddaman Shell_t *shp = sh_getinterp();
2921*b30d1939SAndy Fiddaman register union Value *up;
2922*b30d1939SAndy Fiddaman register Sfdouble_t r=0;
2923*b30d1939SAndy Fiddaman register char *str;
2924*b30d1939SAndy Fiddaman #if SHOPT_OPTIMIZE
2925*b30d1939SAndy Fiddaman if(!nv_local && shp->argaddr)
2926*b30d1939SAndy Fiddaman nv_optimize(np);
2927*b30d1939SAndy Fiddaman #endif /* SHOPT_OPTIMIZE */
2928*b30d1939SAndy Fiddaman if(nv_istable(np))
2929*b30d1939SAndy Fiddaman errormsg(SH_DICT,ERROR_exit(1),e_number,nv_name(np));
2930*b30d1939SAndy Fiddaman if(np->nvfun && np->nvfun->disc)
2931*b30d1939SAndy Fiddaman {
2932*b30d1939SAndy Fiddaman if(!nv_local)
2933*b30d1939SAndy Fiddaman {
2934*b30d1939SAndy Fiddaman nv_local=1;
2935*b30d1939SAndy Fiddaman return(nv_getn(np, np->nvfun));
2936*b30d1939SAndy Fiddaman }
2937*b30d1939SAndy Fiddaman nv_local=0;
2938*b30d1939SAndy Fiddaman }
2939*b30d1939SAndy Fiddaman if(nv_isref(np))
2940*b30d1939SAndy Fiddaman {
2941*b30d1939SAndy Fiddaman str = nv_refsub(np);
2942*b30d1939SAndy Fiddaman np = nv_refnode(np);
2943*b30d1939SAndy Fiddaman if(str)
2944*b30d1939SAndy Fiddaman nv_putsub(np,str,0L);
2945*b30d1939SAndy Fiddaman }
2946*b30d1939SAndy Fiddaman if(nv_isattr (np, NV_INTEGER))
2947*b30d1939SAndy Fiddaman {
2948*b30d1939SAndy Fiddaman up= &np->nvalue;
2949*b30d1939SAndy Fiddaman if(!up->lp || up->cp==Empty)
2950*b30d1939SAndy Fiddaman r = 0;
2951*b30d1939SAndy Fiddaman else if(nv_isattr(np, NV_DOUBLE)==NV_DOUBLE)
2952*b30d1939SAndy Fiddaman {
2953*b30d1939SAndy Fiddaman if(nv_isattr(np, NV_LONG))
2954*b30d1939SAndy Fiddaman r = *up->ldp;
2955*b30d1939SAndy Fiddaman else
2956*b30d1939SAndy Fiddaman r = *up->dp;
2957*b30d1939SAndy Fiddaman }
2958*b30d1939SAndy Fiddaman else if(nv_isattr(np, NV_UNSIGN))
2959*b30d1939SAndy Fiddaman {
2960*b30d1939SAndy Fiddaman if(nv_isattr(np, NV_LONG))
2961*b30d1939SAndy Fiddaman r = (Sflong_t)*((Sfulong_t*)up->llp);
2962*b30d1939SAndy Fiddaman else if(nv_isattr(np, NV_SHORT))
2963*b30d1939SAndy Fiddaman {
2964*b30d1939SAndy Fiddaman if(nv_isattr(np,NV_INT16P)==NV_INT16P)
2965*b30d1939SAndy Fiddaman r = (Sflong_t)(*(uint16_t*)up->sp);
2966*b30d1939SAndy Fiddaman else
2967*b30d1939SAndy Fiddaman r = (Sflong_t)((uint16_t)up->s);
2968*b30d1939SAndy Fiddaman }
2969*b30d1939SAndy Fiddaman else
2970*b30d1939SAndy Fiddaman r = *((uint32_t*)up->lp);
2971*b30d1939SAndy Fiddaman }
2972*b30d1939SAndy Fiddaman else
2973*b30d1939SAndy Fiddaman {
2974*b30d1939SAndy Fiddaman if(nv_isattr(np, NV_LONG))
2975*b30d1939SAndy Fiddaman r = *up->llp;
2976*b30d1939SAndy Fiddaman else if(nv_isattr(np, NV_SHORT))
2977*b30d1939SAndy Fiddaman {
2978*b30d1939SAndy Fiddaman if(nv_isattr(np,NV_INT16P)==NV_INT16P)
2979*b30d1939SAndy Fiddaman r = *up->sp;
2980*b30d1939SAndy Fiddaman else
2981*b30d1939SAndy Fiddaman r = up->s;
2982*b30d1939SAndy Fiddaman }
2983*b30d1939SAndy Fiddaman else
2984*b30d1939SAndy Fiddaman r = *up->lp;
2985*b30d1939SAndy Fiddaman }
2986*b30d1939SAndy Fiddaman }
2987*b30d1939SAndy Fiddaman else if((str=nv_getval(np)) && *str!=0)
2988*b30d1939SAndy Fiddaman {
2989*b30d1939SAndy Fiddaman if(nv_isattr(np,NV_LJUST|NV_RJUST) || (*str=='0' && !(str[1]=='x'||str[1]=='X')))
2990*b30d1939SAndy Fiddaman {
2991*b30d1939SAndy Fiddaman while(*str=='0')
2992*b30d1939SAndy Fiddaman str++;
2993*b30d1939SAndy Fiddaman }
2994*b30d1939SAndy Fiddaman r = sh_arith(shp,str);
2995*b30d1939SAndy Fiddaman }
2996*b30d1939SAndy Fiddaman return(r);
2997*b30d1939SAndy Fiddaman }
2998*b30d1939SAndy Fiddaman
2999*b30d1939SAndy Fiddaman /*
3000*b30d1939SAndy Fiddaman * Give <np> the attributes <newatts,> and change its current
3001*b30d1939SAndy Fiddaman * value to conform to <newatts>. The <size> of left and right
3002*b30d1939SAndy Fiddaman * justified fields may be given.
3003*b30d1939SAndy Fiddaman */
nv_newattr(register Namval_t * np,unsigned newatts,int size)3004*b30d1939SAndy Fiddaman void nv_newattr (register Namval_t *np, unsigned newatts, int size)
3005*b30d1939SAndy Fiddaman {
3006*b30d1939SAndy Fiddaman Shell_t *shp = sh_getinterp();
3007*b30d1939SAndy Fiddaman register char *sp;
3008*b30d1939SAndy Fiddaman register char *cp = 0;
3009*b30d1939SAndy Fiddaman register unsigned int n;
3010*b30d1939SAndy Fiddaman Namval_t *mp = 0;
3011*b30d1939SAndy Fiddaman Namarr_t *ap = 0;
3012*b30d1939SAndy Fiddaman int oldsize,oldatts,trans;
3013*b30d1939SAndy Fiddaman Namfun_t *fp= (newatts&NV_NODISC)?np->nvfun:0;
3014*b30d1939SAndy Fiddaman char *prefix = shp->prefix;
3015*b30d1939SAndy Fiddaman newatts &= ~NV_NODISC;
3016*b30d1939SAndy Fiddaman
3017*b30d1939SAndy Fiddaman /* check for restrictions */
3018*b30d1939SAndy Fiddaman if(sh_isoption(SH_RESTRICTED) && ((sp=nv_name(np))==nv_name(PATHNOD) || sp==nv_name(SHELLNOD) || sp==nv_name(ENVNOD) || sp==nv_name(FPATHNOD)))
3019*b30d1939SAndy Fiddaman errormsg(SH_DICT,ERROR_exit(1),e_restricted,nv_name(np));
3020*b30d1939SAndy Fiddaman /* handle attributes that do not change data separately */
3021*b30d1939SAndy Fiddaman n = np->nvflag;
3022*b30d1939SAndy Fiddaman trans = !(n&NV_INTEGER) && (n&(NV_LTOU|NV_UTOL));
3023*b30d1939SAndy Fiddaman if(newatts&NV_EXPORT)
3024*b30d1939SAndy Fiddaman nv_offattr(np,NV_IMPORT);
3025*b30d1939SAndy Fiddaman if(((n^newatts)&NV_EXPORT))
3026*b30d1939SAndy Fiddaman {
3027*b30d1939SAndy Fiddaman /* record changes to the environment */
3028*b30d1939SAndy Fiddaman if(n&NV_EXPORT)
3029*b30d1939SAndy Fiddaman {
3030*b30d1939SAndy Fiddaman nv_offattr(np,NV_EXPORT);
3031*b30d1939SAndy Fiddaman env_delete(shp->env,nv_name(np));
3032*b30d1939SAndy Fiddaman }
3033*b30d1939SAndy Fiddaman else
3034*b30d1939SAndy Fiddaman {
3035*b30d1939SAndy Fiddaman nv_onattr(np,NV_EXPORT);
3036*b30d1939SAndy Fiddaman sh_envput(shp->env,np);
3037*b30d1939SAndy Fiddaman }
3038*b30d1939SAndy Fiddaman if((n^newatts)==NV_EXPORT)
3039*b30d1939SAndy Fiddaman return;
3040*b30d1939SAndy Fiddaman }
3041*b30d1939SAndy Fiddaman oldsize = nv_size(np);
3042*b30d1939SAndy Fiddaman if((size==oldsize|| (n&NV_INTEGER)) && !trans && ((n^newatts)&~NV_NOCHANGE)==0)
3043*b30d1939SAndy Fiddaman {
3044*b30d1939SAndy Fiddaman if(size)
3045*b30d1939SAndy Fiddaman nv_setsize(np,size);
3046*b30d1939SAndy Fiddaman nv_offattr(np, ~NV_NOFREE);
3047*b30d1939SAndy Fiddaman nv_onattr(np, newatts);
3048*b30d1939SAndy Fiddaman return;
3049*b30d1939SAndy Fiddaman }
3050*b30d1939SAndy Fiddaman /* for an array, change all the elements */
3051*b30d1939SAndy Fiddaman if((ap=nv_arrayptr(np)) && ap->nelem>0)
3052*b30d1939SAndy Fiddaman nv_putsub(np,NIL(char*),ARRAY_SCAN);
3053*b30d1939SAndy Fiddaman oldsize = nv_size(np);
3054*b30d1939SAndy Fiddaman oldatts = np->nvflag;
3055*b30d1939SAndy Fiddaman if(fp)
3056*b30d1939SAndy Fiddaman np->nvfun = 0;
3057*b30d1939SAndy Fiddaman if(ap) /* add element to prevent array deletion */
3058*b30d1939SAndy Fiddaman {
3059*b30d1939SAndy Fiddaman ap->nelem++;
3060*b30d1939SAndy Fiddaman #if SHOPT_FIXEDARRAY
3061*b30d1939SAndy Fiddaman if(ap->fixed)
3062*b30d1939SAndy Fiddaman {
3063*b30d1939SAndy Fiddaman nv_setsize(np,size);
3064*b30d1939SAndy Fiddaman np->nvflag &= NV_ARRAY;
3065*b30d1939SAndy Fiddaman np->nvflag |= newatts;
3066*b30d1939SAndy Fiddaman goto skip;
3067*b30d1939SAndy Fiddaman }
3068*b30d1939SAndy Fiddaman #endif /* SHOPT_TYPEDEF */
3069*b30d1939SAndy Fiddaman }
3070*b30d1939SAndy Fiddaman do
3071*b30d1939SAndy Fiddaman {
3072*b30d1939SAndy Fiddaman nv_setsize(np,oldsize);
3073*b30d1939SAndy Fiddaman np->nvflag = oldatts;
3074*b30d1939SAndy Fiddaman if (sp = nv_getval(np))
3075*b30d1939SAndy Fiddaman {
3076*b30d1939SAndy Fiddaman if(nv_isattr(np,NV_ZFILL))
3077*b30d1939SAndy Fiddaman while(*sp=='0') sp++;
3078*b30d1939SAndy Fiddaman cp = (char*)malloc((n=strlen (sp)) + 8);
3079*b30d1939SAndy Fiddaman strcpy(cp, sp);
3080*b30d1939SAndy Fiddaman if(sp && (mp=nv_opensub(np)))
3081*b30d1939SAndy Fiddaman {
3082*b30d1939SAndy Fiddaman if(trans)
3083*b30d1939SAndy Fiddaman {
3084*b30d1939SAndy Fiddaman nv_disc(np, &ap->hdr,NV_POP);
3085*b30d1939SAndy Fiddaman nv_clone(np,mp,0);
3086*b30d1939SAndy Fiddaman nv_disc(np, &ap->hdr,NV_FIRST);
3087*b30d1939SAndy Fiddaman nv_offattr(mp,NV_ARRAY);
3088*b30d1939SAndy Fiddaman }
3089*b30d1939SAndy Fiddaman nv_newattr(mp,newatts&~NV_ARRAY,size);
3090*b30d1939SAndy Fiddaman }
3091*b30d1939SAndy Fiddaman if(!mp)
3092*b30d1939SAndy Fiddaman {
3093*b30d1939SAndy Fiddaman if(ap)
3094*b30d1939SAndy Fiddaman ap->nelem &= ~ARRAY_SCAN;
3095*b30d1939SAndy Fiddaman if(!trans)
3096*b30d1939SAndy Fiddaman _nv_unset(np,NV_RDONLY|NV_EXPORT);
3097*b30d1939SAndy Fiddaman if(ap)
3098*b30d1939SAndy Fiddaman ap->nelem |= ARRAY_SCAN;
3099*b30d1939SAndy Fiddaman }
3100*b30d1939SAndy Fiddaman if(size==0 && (newatts&NV_HOST)!=NV_HOST && (newatts&(NV_LJUST|NV_RJUST|NV_ZFILL)))
3101*b30d1939SAndy Fiddaman size = n;
3102*b30d1939SAndy Fiddaman }
3103*b30d1939SAndy Fiddaman else if(!trans)
3104*b30d1939SAndy Fiddaman _nv_unset(np,NV_EXPORT);
3105*b30d1939SAndy Fiddaman nv_setsize(np,size);
3106*b30d1939SAndy Fiddaman np->nvflag &= (NV_ARRAY|NV_NOFREE);
3107*b30d1939SAndy Fiddaman np->nvflag |= newatts;
3108*b30d1939SAndy Fiddaman if (cp)
3109*b30d1939SAndy Fiddaman {
3110*b30d1939SAndy Fiddaman if(!mp)
3111*b30d1939SAndy Fiddaman nv_putval (np, cp, NV_RDONLY);
3112*b30d1939SAndy Fiddaman free(cp);
3113*b30d1939SAndy Fiddaman }
3114*b30d1939SAndy Fiddaman }
3115*b30d1939SAndy Fiddaman while(ap && nv_nextsub(np));
3116*b30d1939SAndy Fiddaman #if SHOPT_FIXEDARRAY
3117*b30d1939SAndy Fiddaman skip:
3118*b30d1939SAndy Fiddaman #endif /* SHOPT_TYPEDEF */
3119*b30d1939SAndy Fiddaman if(fp)
3120*b30d1939SAndy Fiddaman np->nvfun = fp;
3121*b30d1939SAndy Fiddaman if(ap)
3122*b30d1939SAndy Fiddaman ap->nelem--;
3123*b30d1939SAndy Fiddaman shp->prefix = prefix;
3124*b30d1939SAndy Fiddaman return;
3125*b30d1939SAndy Fiddaman }
3126*b30d1939SAndy Fiddaman
oldgetenv(const char * string)3127*b30d1939SAndy Fiddaman static char *oldgetenv(const char *string)
3128*b30d1939SAndy Fiddaman {
3129*b30d1939SAndy Fiddaman register char c0,c1;
3130*b30d1939SAndy Fiddaman register const char *cp, *sp;
3131*b30d1939SAndy Fiddaman register char **av = environ;
3132*b30d1939SAndy Fiddaman if(!string || (c0= *string)==0)
3133*b30d1939SAndy Fiddaman return(0);
3134*b30d1939SAndy Fiddaman if((c1=*++string)==0)
3135*b30d1939SAndy Fiddaman c1= '=';
3136*b30d1939SAndy Fiddaman while(cp = *av++)
3137*b30d1939SAndy Fiddaman {
3138*b30d1939SAndy Fiddaman if(cp[0]!=c0 || cp[1]!=c1)
3139*b30d1939SAndy Fiddaman continue;
3140*b30d1939SAndy Fiddaman sp = string;
3141*b30d1939SAndy Fiddaman while(*sp && *sp++ == *++cp);
3142*b30d1939SAndy Fiddaman if(*sp==0 && *++cp=='=')
3143*b30d1939SAndy Fiddaman return((char*)(cp+1));
3144*b30d1939SAndy Fiddaman }
3145*b30d1939SAndy Fiddaman return(0);
3146*b30d1939SAndy Fiddaman }
3147*b30d1939SAndy Fiddaman
3148*b30d1939SAndy Fiddaman /*
3149*b30d1939SAndy Fiddaman * This version of getenv uses the hash storage to access environment values
3150*b30d1939SAndy Fiddaman */
sh_getenv(const char * name)3151*b30d1939SAndy Fiddaman char *sh_getenv(const char *name)
3152*b30d1939SAndy Fiddaman {
3153*b30d1939SAndy Fiddaman Shell_t *shp = sh_getinterp();
3154*b30d1939SAndy Fiddaman register Namval_t *np;
3155*b30d1939SAndy Fiddaman if(!shp->var_tree)
3156*b30d1939SAndy Fiddaman {
3157*b30d1939SAndy Fiddaman #if 0
3158*b30d1939SAndy Fiddaman if(name[0] == 'P' && name[1] == 'A' && name[2] == 'T' && name[3] == 'H' && name[4] == 0 || name[0] == 'L' && ((name[1] == 'C' || name[1] == 'D') && name[2] == '_' || name[1] == 'A' && name[1] == 'N') || name[0] == 'V' && name[1] == 'P' && name[2] == 'A' && name[3] == 'T' && name[4] == 'H' && name[5] == 0 || name[0] == '_' && name[1] == 'R' && name[2] == 'L' && name[3] == 'D' || name[0] == '_' && name[1] == 'A' && name[2] == 'S' && name[3] == 'T' && name[4] == '_')
3159*b30d1939SAndy Fiddaman #endif
3160*b30d1939SAndy Fiddaman return(oldgetenv(name));
3161*b30d1939SAndy Fiddaman }
3162*b30d1939SAndy Fiddaman else if((np = nv_search(name,shp->var_tree,0)) && nv_isattr(np,NV_EXPORT))
3163*b30d1939SAndy Fiddaman return(nv_getval(np));
3164*b30d1939SAndy Fiddaman return(0);
3165*b30d1939SAndy Fiddaman }
3166*b30d1939SAndy Fiddaman
3167*b30d1939SAndy Fiddaman #ifndef _NEXT_SOURCE
3168*b30d1939SAndy Fiddaman /*
3169*b30d1939SAndy Fiddaman * Some dynamic linkers will make this file see the libc getenv(),
3170*b30d1939SAndy Fiddaman * so sh_getenv() is used for the astintercept() callback. Plain
3171*b30d1939SAndy Fiddaman * getenv() is provided for static links.
3172*b30d1939SAndy Fiddaman */
getenv(const char * name)3173*b30d1939SAndy Fiddaman char *getenv(const char *name)
3174*b30d1939SAndy Fiddaman {
3175*b30d1939SAndy Fiddaman return sh_getenv(name);
3176*b30d1939SAndy Fiddaman }
3177*b30d1939SAndy Fiddaman #endif /* _NEXT_SOURCE */
3178*b30d1939SAndy Fiddaman
3179*b30d1939SAndy Fiddaman #undef putenv
3180*b30d1939SAndy Fiddaman /*
3181*b30d1939SAndy Fiddaman * This version of putenv uses the hash storage to assign environment values
3182*b30d1939SAndy Fiddaman */
putenv(const char * name)3183*b30d1939SAndy Fiddaman int putenv(const char *name)
3184*b30d1939SAndy Fiddaman {
3185*b30d1939SAndy Fiddaman Shell_t *shp = sh_getinterp();
3186*b30d1939SAndy Fiddaman register Namval_t *np;
3187*b30d1939SAndy Fiddaman if(name)
3188*b30d1939SAndy Fiddaman {
3189*b30d1939SAndy Fiddaman np = nv_open(name,shp->var_tree,NV_EXPORT|NV_IDENT|NV_NOARRAY|NV_ASSIGN);
3190*b30d1939SAndy Fiddaman if(!strchr(name,'='))
3191*b30d1939SAndy Fiddaman _nv_unset(np,0);
3192*b30d1939SAndy Fiddaman }
3193*b30d1939SAndy Fiddaman return(0);
3194*b30d1939SAndy Fiddaman }
3195*b30d1939SAndy Fiddaman
3196*b30d1939SAndy Fiddaman /*
3197*b30d1939SAndy Fiddaman * Override libast setenviron().
3198*b30d1939SAndy Fiddaman */
sh_setenviron(const char * name)3199*b30d1939SAndy Fiddaman char* sh_setenviron(const char *name)
3200*b30d1939SAndy Fiddaman {
3201*b30d1939SAndy Fiddaman Shell_t *shp = sh_getinterp();
3202*b30d1939SAndy Fiddaman register Namval_t *np;
3203*b30d1939SAndy Fiddaman if(name)
3204*b30d1939SAndy Fiddaman {
3205*b30d1939SAndy Fiddaman np = nv_open(name,shp->var_tree,NV_EXPORT|NV_IDENT|NV_NOARRAY|NV_ASSIGN);
3206*b30d1939SAndy Fiddaman if(strchr(name,'='))
3207*b30d1939SAndy Fiddaman return(nv_getval(np));
3208*b30d1939SAndy Fiddaman _nv_unset(np,0);
3209*b30d1939SAndy Fiddaman }
3210*b30d1939SAndy Fiddaman return("");
3211*b30d1939SAndy Fiddaman }
3212*b30d1939SAndy Fiddaman
3213*b30d1939SAndy Fiddaman /*
3214*b30d1939SAndy Fiddaman * Same linker dance as with getenv() above.
3215*b30d1939SAndy Fiddaman */
setenviron(const char * name)3216*b30d1939SAndy Fiddaman char* setenviron(const char *name)
3217*b30d1939SAndy Fiddaman {
3218*b30d1939SAndy Fiddaman return sh_setenviron(name);
3219*b30d1939SAndy Fiddaman }
3220*b30d1939SAndy Fiddaman
3221*b30d1939SAndy Fiddaman /*
3222*b30d1939SAndy Fiddaman * normalize <cp> and return pointer to subscript if any
3223*b30d1939SAndy Fiddaman * if <eq> is specified, return pointer to first = not in a subscript
3224*b30d1939SAndy Fiddaman */
lastdot(char * cp,int eq)3225*b30d1939SAndy Fiddaman static char *lastdot(char *cp, int eq)
3226*b30d1939SAndy Fiddaman {
3227*b30d1939SAndy Fiddaman register char *ep=0;
3228*b30d1939SAndy Fiddaman register int c;
3229*b30d1939SAndy Fiddaman if(eq)
3230*b30d1939SAndy Fiddaman cp++;
3231*b30d1939SAndy Fiddaman while(c= mbchar(cp))
3232*b30d1939SAndy Fiddaman {
3233*b30d1939SAndy Fiddaman if(c=='[')
3234*b30d1939SAndy Fiddaman {
3235*b30d1939SAndy Fiddaman if(*cp==']')
3236*b30d1939SAndy Fiddaman cp++;
3237*b30d1939SAndy Fiddaman else
3238*b30d1939SAndy Fiddaman cp = nv_endsubscript((Namval_t*)0,ep=cp,0);
3239*b30d1939SAndy Fiddaman }
3240*b30d1939SAndy Fiddaman else if(c=='.')
3241*b30d1939SAndy Fiddaman {
3242*b30d1939SAndy Fiddaman if(*cp=='[')
3243*b30d1939SAndy Fiddaman {
3244*b30d1939SAndy Fiddaman cp = nv_endsubscript((Namval_t*)0,ep=cp,0);
3245*b30d1939SAndy Fiddaman if((ep=sh_checkid(ep+1,cp)) < cp)
3246*b30d1939SAndy Fiddaman cp=strcpy(ep,cp);
3247*b30d1939SAndy Fiddaman }
3248*b30d1939SAndy Fiddaman ep = 0;
3249*b30d1939SAndy Fiddaman }
3250*b30d1939SAndy Fiddaman else if(eq && c == '=')
3251*b30d1939SAndy Fiddaman return(cp-1);
3252*b30d1939SAndy Fiddaman }
3253*b30d1939SAndy Fiddaman return(eq?0:ep);
3254*b30d1939SAndy Fiddaman }
3255*b30d1939SAndy Fiddaman
nv_rename(register Namval_t * np,int flags)3256*b30d1939SAndy Fiddaman int nv_rename(register Namval_t *np, int flags)
3257*b30d1939SAndy Fiddaman {
3258*b30d1939SAndy Fiddaman Shell_t *shp = sh_getinterp();
3259*b30d1939SAndy Fiddaman register Namval_t *mp=0,*nr=0;
3260*b30d1939SAndy Fiddaman register char *cp;
3261*b30d1939SAndy Fiddaman int arraynp=0,arraynr,index= -1;
3262*b30d1939SAndy Fiddaman Namval_t *last_table = shp->last_table;
3263*b30d1939SAndy Fiddaman Dt_t *last_root = shp->last_root;
3264*b30d1939SAndy Fiddaman Dt_t *hp = 0;
3265*b30d1939SAndy Fiddaman char *nvenv=0,*prefix=shp->prefix;
3266*b30d1939SAndy Fiddaman Namarr_t *ap;
3267*b30d1939SAndy Fiddaman if(nv_isattr(np,NV_PARAM) && shp->st.prevst)
3268*b30d1939SAndy Fiddaman {
3269*b30d1939SAndy Fiddaman if(!(hp=(Dt_t*)shp->st.prevst->save_tree))
3270*b30d1939SAndy Fiddaman hp = dtvnext(shp->var_tree);
3271*b30d1939SAndy Fiddaman }
3272*b30d1939SAndy Fiddaman if(!nv_isattr(np,NV_MINIMAL))
3273*b30d1939SAndy Fiddaman nvenv = np->nvenv;
3274*b30d1939SAndy Fiddaman if(nvenv || (cp = nv_name(np)) && nv_isarray(np) && cp[strlen(cp)-1] == ']')
3275*b30d1939SAndy Fiddaman arraynp = 1;
3276*b30d1939SAndy Fiddaman if(!(cp=nv_getval(np)))
3277*b30d1939SAndy Fiddaman {
3278*b30d1939SAndy Fiddaman if(flags&NV_MOVE)
3279*b30d1939SAndy Fiddaman errormsg(SH_DICT,ERROR_exit(1),e_varname,"");
3280*b30d1939SAndy Fiddaman return(0);
3281*b30d1939SAndy Fiddaman }
3282*b30d1939SAndy Fiddaman if(lastdot(cp,0) && nv_isattr(np,NV_MINIMAL))
3283*b30d1939SAndy Fiddaman errormsg(SH_DICT,ERROR_exit(1),e_varname,nv_name(np));
3284*b30d1939SAndy Fiddaman arraynr = cp[strlen(cp)-1] == ']';
3285*b30d1939SAndy Fiddaman if(nv_isarray(np) && !(mp=nv_opensub(np)))
3286*b30d1939SAndy Fiddaman index=nv_aindex(np);
3287*b30d1939SAndy Fiddaman shp->prefix = 0;
3288*b30d1939SAndy Fiddaman if(!hp)
3289*b30d1939SAndy Fiddaman hp = shp->var_tree;
3290*b30d1939SAndy Fiddaman if(!(nr = nv_open(cp, hp, flags|NV_ARRAY|NV_NOSCOPE|NV_NOADD|NV_NOFAIL)))
3291*b30d1939SAndy Fiddaman {
3292*b30d1939SAndy Fiddaman #if SHOPT_NAMESPACE
3293*b30d1939SAndy Fiddaman if(shp->namespace)
3294*b30d1939SAndy Fiddaman hp = nv_dict(shp->namespace);
3295*b30d1939SAndy Fiddaman else
3296*b30d1939SAndy Fiddaman #endif /* SHOPT_NAMESPACE */
3297*b30d1939SAndy Fiddaman hp = shp->var_base;
3298*b30d1939SAndy Fiddaman }
3299*b30d1939SAndy Fiddaman else if(shp->last_root)
3300*b30d1939SAndy Fiddaman hp = shp->last_root;
3301*b30d1939SAndy Fiddaman if(!nr)
3302*b30d1939SAndy Fiddaman nr= nv_open(cp, hp, flags|NV_NOREF|((flags&NV_MOVE)?0:NV_NOFAIL));
3303*b30d1939SAndy Fiddaman shp->prefix = prefix;
3304*b30d1939SAndy Fiddaman if(!nr)
3305*b30d1939SAndy Fiddaman {
3306*b30d1939SAndy Fiddaman if(!nv_isvtree(np))
3307*b30d1939SAndy Fiddaman _nv_unset(np,0);
3308*b30d1939SAndy Fiddaman return(0);
3309*b30d1939SAndy Fiddaman }
3310*b30d1939SAndy Fiddaman if(!mp && index>=0 && nv_isvtree(nr))
3311*b30d1939SAndy Fiddaman {
3312*b30d1939SAndy Fiddaman sfprintf(shp->strbuf,"%s[%d]%c",nv_name(np),index,0);
3313*b30d1939SAndy Fiddaman /* create a virtual node */
3314*b30d1939SAndy Fiddaman if(mp = nv_open(sfstruse(shp->strbuf),shp->var_tree,NV_VARNAME|NV_ADD|NV_ARRAY))
3315*b30d1939SAndy Fiddaman {
3316*b30d1939SAndy Fiddaman if(ap = nv_arrayptr(np))
3317*b30d1939SAndy Fiddaman ap->nelem++;
3318*b30d1939SAndy Fiddaman mp->nvenv = nvenv = (void*)np;
3319*b30d1939SAndy Fiddaman }
3320*b30d1939SAndy Fiddaman }
3321*b30d1939SAndy Fiddaman if(mp)
3322*b30d1939SAndy Fiddaman {
3323*b30d1939SAndy Fiddaman nvenv = (char*)np;
3324*b30d1939SAndy Fiddaman np = mp;
3325*b30d1939SAndy Fiddaman }
3326*b30d1939SAndy Fiddaman if(nr==np)
3327*b30d1939SAndy Fiddaman {
3328*b30d1939SAndy Fiddaman if(index<0)
3329*b30d1939SAndy Fiddaman return(0);
3330*b30d1939SAndy Fiddaman if(cp = nv_getval(np))
3331*b30d1939SAndy Fiddaman cp = strdup(cp);
3332*b30d1939SAndy Fiddaman }
3333*b30d1939SAndy Fiddaman _nv_unset(np,NV_EXPORT);
3334*b30d1939SAndy Fiddaman if(nr==np)
3335*b30d1939SAndy Fiddaman {
3336*b30d1939SAndy Fiddaman nv_putsub(np,(char*)0, index);
3337*b30d1939SAndy Fiddaman nv_putval(np,cp,0);
3338*b30d1939SAndy Fiddaman free((void*)cp);
3339*b30d1939SAndy Fiddaman return(1);
3340*b30d1939SAndy Fiddaman }
3341*b30d1939SAndy Fiddaman shp->prev_table = shp->last_table;
3342*b30d1939SAndy Fiddaman shp->prev_root = shp->last_root;
3343*b30d1939SAndy Fiddaman shp->last_table = last_table;
3344*b30d1939SAndy Fiddaman shp->last_root = last_root;
3345*b30d1939SAndy Fiddaman if(flags&NV_MOVE)
3346*b30d1939SAndy Fiddaman {
3347*b30d1939SAndy Fiddaman if(arraynp && !nv_isattr(np,NV_MINIMAL) && (mp=(Namval_t*)np->nvenv) && (ap=nv_arrayptr(mp)))
3348*b30d1939SAndy Fiddaman ap->nelem++;
3349*b30d1939SAndy Fiddaman }
3350*b30d1939SAndy Fiddaman if((nv_arrayptr(nr) && !arraynr) || nv_isvtree(nr))
3351*b30d1939SAndy Fiddaman {
3352*b30d1939SAndy Fiddaman if(ap=nv_arrayptr(np))
3353*b30d1939SAndy Fiddaman {
3354*b30d1939SAndy Fiddaman if(!ap->table)
3355*b30d1939SAndy Fiddaman ap->table = dtopen(&_Nvdisc,Dtoset);
3356*b30d1939SAndy Fiddaman if(ap->table)
3357*b30d1939SAndy Fiddaman mp = nv_search(nv_getsub(np),ap->table,NV_ADD);
3358*b30d1939SAndy Fiddaman nv_arraychild(np,mp,0);
3359*b30d1939SAndy Fiddaman nvenv = (void*)np;
3360*b30d1939SAndy Fiddaman }
3361*b30d1939SAndy Fiddaman else
3362*b30d1939SAndy Fiddaman mp = np;
3363*b30d1939SAndy Fiddaman nv_clone(nr,mp,(flags&NV_MOVE)|NV_COMVAR);
3364*b30d1939SAndy Fiddaman mp->nvenv = nvenv;
3365*b30d1939SAndy Fiddaman if(flags&NV_MOVE)
3366*b30d1939SAndy Fiddaman {
3367*b30d1939SAndy Fiddaman if(arraynr && !nv_isattr(nr,NV_MINIMAL) && (mp=(Namval_t*)nr->nvenv) && (ap=nv_arrayptr(mp)))
3368*b30d1939SAndy Fiddaman {
3369*b30d1939SAndy Fiddaman nv_putsub(mp,nr->nvname,0);
3370*b30d1939SAndy Fiddaman _nv_unset(mp,0);
3371*b30d1939SAndy Fiddaman }
3372*b30d1939SAndy Fiddaman nv_delete(nr,(Dt_t*)0,NV_NOFREE);
3373*b30d1939SAndy Fiddaman }
3374*b30d1939SAndy Fiddaman }
3375*b30d1939SAndy Fiddaman else
3376*b30d1939SAndy Fiddaman {
3377*b30d1939SAndy Fiddaman nv_putval(np,nv_getval(nr),0);
3378*b30d1939SAndy Fiddaman if(flags&NV_MOVE)
3379*b30d1939SAndy Fiddaman {
3380*b30d1939SAndy Fiddaman if(!nv_isattr(nr,NV_MINIMAL) && (mp=(Namval_t*)(nr->nvenv)) && (ap=nv_arrayptr(mp)))
3381*b30d1939SAndy Fiddaman ap->nelem--;
3382*b30d1939SAndy Fiddaman _nv_unset(nr,0);
3383*b30d1939SAndy Fiddaman }
3384*b30d1939SAndy Fiddaman }
3385*b30d1939SAndy Fiddaman return(1);
3386*b30d1939SAndy Fiddaman }
3387*b30d1939SAndy Fiddaman
3388*b30d1939SAndy Fiddaman /*
3389*b30d1939SAndy Fiddaman * Create a reference node from <np> to $np in dictionary <hp>
3390*b30d1939SAndy Fiddaman */
nv_setref(register Namval_t * np,Dt_t * hp,int flags)3391*b30d1939SAndy Fiddaman void nv_setref(register Namval_t *np, Dt_t *hp, int flags)
3392*b30d1939SAndy Fiddaman {
3393*b30d1939SAndy Fiddaman Shell_t *shp = sh_getinterp();
3394*b30d1939SAndy Fiddaman register Namval_t *nq=0, *nr=0;
3395*b30d1939SAndy Fiddaman register char *ep,*cp;
3396*b30d1939SAndy Fiddaman Dt_t *root = shp->last_root, *hpnext=0;
3397*b30d1939SAndy Fiddaman Namarr_t *ap=0;
3398*b30d1939SAndy Fiddaman Dt_t *openmatch;
3399*b30d1939SAndy Fiddaman if(nv_isref(np))
3400*b30d1939SAndy Fiddaman return;
3401*b30d1939SAndy Fiddaman if(nv_isarray(np))
3402*b30d1939SAndy Fiddaman errormsg(SH_DICT,ERROR_exit(1),e_badref,nv_name(np));
3403*b30d1939SAndy Fiddaman if(!(cp=nv_getval(np)))
3404*b30d1939SAndy Fiddaman {
3405*b30d1939SAndy Fiddaman _nv_unset(np,0);
3406*b30d1939SAndy Fiddaman nv_onattr(np,NV_REF);
3407*b30d1939SAndy Fiddaman return;
3408*b30d1939SAndy Fiddaman }
3409*b30d1939SAndy Fiddaman if((ep = lastdot(cp,0)) && nv_isattr(np,NV_MINIMAL))
3410*b30d1939SAndy Fiddaman errormsg(SH_DICT,ERROR_exit(1),e_badref,nv_name(np));
3411*b30d1939SAndy Fiddaman if(hp)
3412*b30d1939SAndy Fiddaman hpnext = dtvnext(hp);
3413*b30d1939SAndy Fiddaman if((nr=nv_open(cp, hp?hp:shp->var_tree, flags|NV_NOSCOPE|NV_NOADD|NV_NOFAIL)))
3414*b30d1939SAndy Fiddaman nq = nr;
3415*b30d1939SAndy Fiddaman else if(hpnext && dtvnext(hpnext)==shp->var_base && (nr=nv_open(cp,hpnext,flags|NV_NOSCOPE|NV_NOADD|NV_NOFAIL)))
3416*b30d1939SAndy Fiddaman nq = nr;
3417*b30d1939SAndy Fiddaman else if((openmatch=shp->openmatch) && hpnext==shp->var_base && (nr=nv_open(cp,hpnext,flags|NV_NOSCOPE|NV_NOADD|NV_NOFAIL)))
3418*b30d1939SAndy Fiddaman nq = nr;
3419*b30d1939SAndy Fiddaman if(nq)
3420*b30d1939SAndy Fiddaman hp = shp->last_root;
3421*b30d1939SAndy Fiddaman else
3422*b30d1939SAndy Fiddaman hp = hp?(openmatch?openmatch:shp->var_base):shp->var_tree;
3423*b30d1939SAndy Fiddaman if(nr==np)
3424*b30d1939SAndy Fiddaman {
3425*b30d1939SAndy Fiddaman if(shp->namespace && nv_dict(shp->namespace)==hp)
3426*b30d1939SAndy Fiddaman errormsg(SH_DICT,ERROR_exit(1),e_selfref,nv_name(np));
3427*b30d1939SAndy Fiddaman /* bind to earlier scope, or add to global scope */
3428*b30d1939SAndy Fiddaman if(!(hp=dtvnext(hp)) || (nq=nv_search((char*)np,hp,NV_ADD|HASH_BUCKET))==np)
3429*b30d1939SAndy Fiddaman errormsg(SH_DICT,ERROR_exit(1),e_selfref,nv_name(np));
3430*b30d1939SAndy Fiddaman if(nv_isarray(nq))
3431*b30d1939SAndy Fiddaman nv_putsub(nq,(char*)0,ARRAY_UNDEF);
3432*b30d1939SAndy Fiddaman }
3433*b30d1939SAndy Fiddaman #if SHOPT_FIXEDARRAY
3434*b30d1939SAndy Fiddaman if(nq && ep && nv_isarray(nq) && !((ap=nv_arrayptr(nq)) && ap->fixed) && !nv_getsub(nq))
3435*b30d1939SAndy Fiddaman #else
3436*b30d1939SAndy Fiddaman if(nq && ep && nv_isarray(nq) && !nv_getsub(nq))
3437*b30d1939SAndy Fiddaman #endif /* SHOPT_FIXEDARRAY */
3438*b30d1939SAndy Fiddaman {
3439*b30d1939SAndy Fiddaman if(!nv_arrayptr(nq))
3440*b30d1939SAndy Fiddaman {
3441*b30d1939SAndy Fiddaman nv_putsub(nq,"1",ARRAY_FILL);
3442*b30d1939SAndy Fiddaman _nv_unset(nq,NV_RDONLY);
3443*b30d1939SAndy Fiddaman }
3444*b30d1939SAndy Fiddaman nv_endsubscript(nq,ep-1,NV_ARRAY);
3445*b30d1939SAndy Fiddaman }
3446*b30d1939SAndy Fiddaman if(!nr)
3447*b30d1939SAndy Fiddaman {
3448*b30d1939SAndy Fiddaman shp->last_root = 0;
3449*b30d1939SAndy Fiddaman nr= nq = nv_open(cp, hp, flags);
3450*b30d1939SAndy Fiddaman if(shp->last_root)
3451*b30d1939SAndy Fiddaman hp = shp->last_root;
3452*b30d1939SAndy Fiddaman }
3453*b30d1939SAndy Fiddaman if(shp->last_root == shp->var_tree && root!=shp->var_tree)
3454*b30d1939SAndy Fiddaman {
3455*b30d1939SAndy Fiddaman _nv_unset(np,NV_RDONLY);
3456*b30d1939SAndy Fiddaman nv_onattr(np,NV_REF);
3457*b30d1939SAndy Fiddaman errormsg(SH_DICT,ERROR_exit(1),e_globalref,nv_name(np));
3458*b30d1939SAndy Fiddaman }
3459*b30d1939SAndy Fiddaman shp->instance = 1;
3460*b30d1939SAndy Fiddaman if(nq && !ep && (ap=nv_arrayptr(nq)) && !(ap->nelem&(ARRAY_UNDEF|ARRAY_SCAN)))
3461*b30d1939SAndy Fiddaman ep = nv_getsub(nq);
3462*b30d1939SAndy Fiddaman #if SHOPT_FIXEDARRAY
3463*b30d1939SAndy Fiddaman if(ep && !(ap && ap->fixed))
3464*b30d1939SAndy Fiddaman #else
3465*b30d1939SAndy Fiddaman if(ep)
3466*b30d1939SAndy Fiddaman #endif /* SHOPT_FIXEDARRAY */
3467*b30d1939SAndy Fiddaman {
3468*b30d1939SAndy Fiddaman /* cause subscript evaluation and return result */
3469*b30d1939SAndy Fiddaman if(nv_isarray(nq))
3470*b30d1939SAndy Fiddaman ep = nv_getsub(nq);
3471*b30d1939SAndy Fiddaman else
3472*b30d1939SAndy Fiddaman {
3473*b30d1939SAndy Fiddaman int n;
3474*b30d1939SAndy Fiddaman ep[n=strlen(ep)-1] = 0;
3475*b30d1939SAndy Fiddaman nv_putsub(nr, ep, ARRAY_FILL);
3476*b30d1939SAndy Fiddaman ep[n] = ']';
3477*b30d1939SAndy Fiddaman if(nq = nv_opensub(nr))
3478*b30d1939SAndy Fiddaman ep = 0;
3479*b30d1939SAndy Fiddaman else
3480*b30d1939SAndy Fiddaman ep = nv_getsub(nq=nr);
3481*b30d1939SAndy Fiddaman }
3482*b30d1939SAndy Fiddaman }
3483*b30d1939SAndy Fiddaman shp->instance = 0;
3484*b30d1939SAndy Fiddaman shp->last_root = root;
3485*b30d1939SAndy Fiddaman _nv_unset(np,0);
3486*b30d1939SAndy Fiddaman nv_delete(np,(Dt_t*)0,0);
3487*b30d1939SAndy Fiddaman np->nvalue.nrp = newof(0,struct Namref,1,sizeof(Dtlink_t));
3488*b30d1939SAndy Fiddaman np->nvalue.nrp->np = nq;
3489*b30d1939SAndy Fiddaman np->nvalue.nrp->root = hp;
3490*b30d1939SAndy Fiddaman if(ep)
3491*b30d1939SAndy Fiddaman {
3492*b30d1939SAndy Fiddaman #if SHOPT_FIXEDARRAY
3493*b30d1939SAndy Fiddaman if(ap && ap->fixed)
3494*b30d1939SAndy Fiddaman np->nvalue.nrp->curi = ARRAY_FIXED|nv_arrfixed(nq,(Sfio_t*)0,1,&np->nvalue.nrp->dim);
3495*b30d1939SAndy Fiddaman else
3496*b30d1939SAndy Fiddaman #endif /* SHOPT_FIXEDARRAY */
3497*b30d1939SAndy Fiddaman np->nvalue.nrp->sub = strdup(ep);
3498*b30d1939SAndy Fiddaman }
3499*b30d1939SAndy Fiddaman np->nvalue.nrp->table = shp->last_table;
3500*b30d1939SAndy Fiddaman nv_onattr(np,NV_REF|NV_NOFREE);
3501*b30d1939SAndy Fiddaman if(!Refdict)
3502*b30d1939SAndy Fiddaman {
3503*b30d1939SAndy Fiddaman NullNode.nvname = ".deleted";
3504*b30d1939SAndy Fiddaman NullNode.nvflag = NV_RDONLY;
3505*b30d1939SAndy Fiddaman Refdict = dtopen(&_Refdisc,Dtobag);
3506*b30d1939SAndy Fiddaman }
3507*b30d1939SAndy Fiddaman dtinsert(Refdict,np->nvalue.nrp);
3508*b30d1939SAndy Fiddaman }
3509*b30d1939SAndy Fiddaman
3510*b30d1939SAndy Fiddaman /*
3511*b30d1939SAndy Fiddaman * get the scope corresponding to <index>
3512*b30d1939SAndy Fiddaman * whence uses the same values as lseeek()
3513*b30d1939SAndy Fiddaman */
sh_getscope(int index,int whence)3514*b30d1939SAndy Fiddaman Shscope_t *sh_getscope(int index, int whence)
3515*b30d1939SAndy Fiddaman {
3516*b30d1939SAndy Fiddaman Shell_t *shp = sh_getinterp();
3517*b30d1939SAndy Fiddaman register struct sh_scoped *sp, *topmost;
3518*b30d1939SAndy Fiddaman if(whence==SEEK_CUR)
3519*b30d1939SAndy Fiddaman sp = &shp->st;
3520*b30d1939SAndy Fiddaman else
3521*b30d1939SAndy Fiddaman {
3522*b30d1939SAndy Fiddaman if ((struct sh_scoped*)shp->topscope != shp->st.self)
3523*b30d1939SAndy Fiddaman topmost = (struct sh_scoped*)shp->topscope;
3524*b30d1939SAndy Fiddaman else
3525*b30d1939SAndy Fiddaman topmost = &(shp->st);
3526*b30d1939SAndy Fiddaman sp = topmost;
3527*b30d1939SAndy Fiddaman if(whence==SEEK_SET)
3528*b30d1939SAndy Fiddaman {
3529*b30d1939SAndy Fiddaman int n =0;
3530*b30d1939SAndy Fiddaman while(sp = sp->prevst)
3531*b30d1939SAndy Fiddaman n++;
3532*b30d1939SAndy Fiddaman index = n - index;
3533*b30d1939SAndy Fiddaman sp = topmost;
3534*b30d1939SAndy Fiddaman }
3535*b30d1939SAndy Fiddaman }
3536*b30d1939SAndy Fiddaman if(index < 0)
3537*b30d1939SAndy Fiddaman return((Shscope_t*)0);
3538*b30d1939SAndy Fiddaman while(index-- && (sp = sp->prevst));
3539*b30d1939SAndy Fiddaman return((Shscope_t*)sp);
3540*b30d1939SAndy Fiddaman }
3541*b30d1939SAndy Fiddaman
3542*b30d1939SAndy Fiddaman /*
3543*b30d1939SAndy Fiddaman * make <scoped> the top scope and return previous scope
3544*b30d1939SAndy Fiddaman */
sh_setscope(Shscope_t * scope)3545*b30d1939SAndy Fiddaman Shscope_t *sh_setscope(Shscope_t *scope)
3546*b30d1939SAndy Fiddaman {
3547*b30d1939SAndy Fiddaman Shell_t *shp = sh_getinterp();
3548*b30d1939SAndy Fiddaman Shscope_t *old = (Shscope_t*)shp->st.self;
3549*b30d1939SAndy Fiddaman *shp->st.self = shp->st;
3550*b30d1939SAndy Fiddaman shp->st = *((struct sh_scoped*)scope);
3551*b30d1939SAndy Fiddaman shp->var_tree = scope->var_tree;
3552*b30d1939SAndy Fiddaman SH_PATHNAMENOD->nvalue.cp = shp->st.filename;
3553*b30d1939SAndy Fiddaman SH_FUNNAMENOD->nvalue.cp = shp->st.funname;
3554*b30d1939SAndy Fiddaman return(old);
3555*b30d1939SAndy Fiddaman }
3556*b30d1939SAndy Fiddaman
sh_unscope(Shell_t * shp)3557*b30d1939SAndy Fiddaman void sh_unscope(Shell_t *shp)
3558*b30d1939SAndy Fiddaman {
3559*b30d1939SAndy Fiddaman register Dt_t *root = shp->var_tree;
3560*b30d1939SAndy Fiddaman register Dt_t *dp = dtview(root,(Dt_t*)0);
3561*b30d1939SAndy Fiddaman if(dp)
3562*b30d1939SAndy Fiddaman {
3563*b30d1939SAndy Fiddaman table_unset(shp,root,NV_RDONLY|NV_NOSCOPE,dp);
3564*b30d1939SAndy Fiddaman if(shp->st.real_fun && dp==shp->st.real_fun->sdict)
3565*b30d1939SAndy Fiddaman {
3566*b30d1939SAndy Fiddaman dp = dtview(dp,(Dt_t*)0);
3567*b30d1939SAndy Fiddaman shp->st.real_fun->sdict->view = dp;
3568*b30d1939SAndy Fiddaman }
3569*b30d1939SAndy Fiddaman shp->var_tree=dp;
3570*b30d1939SAndy Fiddaman dtclose(root);
3571*b30d1939SAndy Fiddaman }
3572*b30d1939SAndy Fiddaman }
3573*b30d1939SAndy Fiddaman
3574*b30d1939SAndy Fiddaman /*
3575*b30d1939SAndy Fiddaman * The inverse of creating a reference node
3576*b30d1939SAndy Fiddaman */
nv_unref(register Namval_t * np)3577*b30d1939SAndy Fiddaman void nv_unref(register Namval_t *np)
3578*b30d1939SAndy Fiddaman {
3579*b30d1939SAndy Fiddaman Namval_t *nq;
3580*b30d1939SAndy Fiddaman if(!nv_isref(np))
3581*b30d1939SAndy Fiddaman return;
3582*b30d1939SAndy Fiddaman nv_offattr(np,NV_NOFREE|NV_REF);
3583*b30d1939SAndy Fiddaman if(!np->nvalue.nrp)
3584*b30d1939SAndy Fiddaman return;
3585*b30d1939SAndy Fiddaman nq = nv_refnode(np);
3586*b30d1939SAndy Fiddaman if(Refdict)
3587*b30d1939SAndy Fiddaman {
3588*b30d1939SAndy Fiddaman if(np->nvalue.nrp->sub)
3589*b30d1939SAndy Fiddaman free(np->nvalue.nrp->sub);
3590*b30d1939SAndy Fiddaman dtdelete(Refdict,(void*)np->nvalue.nrp);
3591*b30d1939SAndy Fiddaman }
3592*b30d1939SAndy Fiddaman free((void*)np->nvalue.nrp);
3593*b30d1939SAndy Fiddaman np->nvalue.cp = strdup(nv_name(nq));
3594*b30d1939SAndy Fiddaman #if SHOPT_OPTIMIZE
3595*b30d1939SAndy Fiddaman {
3596*b30d1939SAndy Fiddaman Namfun_t *fp;
3597*b30d1939SAndy Fiddaman for(fp=nq->nvfun; fp; fp = fp->next)
3598*b30d1939SAndy Fiddaman {
3599*b30d1939SAndy Fiddaman if(fp->disc== &optimize_disc)
3600*b30d1939SAndy Fiddaman {
3601*b30d1939SAndy Fiddaman optimize_clear(nq,fp);
3602*b30d1939SAndy Fiddaman return;
3603*b30d1939SAndy Fiddaman }
3604*b30d1939SAndy Fiddaman }
3605*b30d1939SAndy Fiddaman }
3606*b30d1939SAndy Fiddaman #endif
3607*b30d1939SAndy Fiddaman }
3608*b30d1939SAndy Fiddaman
3609*b30d1939SAndy Fiddaman /*
3610*b30d1939SAndy Fiddaman * These following are for binary compatibility with the old hash library
3611*b30d1939SAndy Fiddaman * They will be removed someday
3612*b30d1939SAndy Fiddaman */
3613*b30d1939SAndy Fiddaman
3614*b30d1939SAndy Fiddaman #if defined(__IMPORT__) && defined(__EXPORT__)
3615*b30d1939SAndy Fiddaman # define extern __EXPORT__
3616*b30d1939SAndy Fiddaman #endif
3617*b30d1939SAndy Fiddaman
3618*b30d1939SAndy Fiddaman #undef hashscope
3619*b30d1939SAndy Fiddaman
hashscope(Dt_t * root)3620*b30d1939SAndy Fiddaman extern Dt_t *hashscope(Dt_t *root)
3621*b30d1939SAndy Fiddaman {
3622*b30d1939SAndy Fiddaman return(dtvnext(root));
3623*b30d1939SAndy Fiddaman }
3624*b30d1939SAndy Fiddaman
3625*b30d1939SAndy Fiddaman #undef hashfree
3626*b30d1939SAndy Fiddaman
hashfree(Dt_t * root)3627*b30d1939SAndy Fiddaman extern Dt_t *hashfree(Dt_t *root)
3628*b30d1939SAndy Fiddaman {
3629*b30d1939SAndy Fiddaman Dt_t *dp = dtvnext(root);
3630*b30d1939SAndy Fiddaman dtclose(root);
3631*b30d1939SAndy Fiddaman return(dp);
3632*b30d1939SAndy Fiddaman }
3633*b30d1939SAndy Fiddaman
3634*b30d1939SAndy Fiddaman #undef hashname
3635*b30d1939SAndy Fiddaman
hashname(void * obj)3636*b30d1939SAndy Fiddaman extern char *hashname(void *obj)
3637*b30d1939SAndy Fiddaman {
3638*b30d1939SAndy Fiddaman Namval_t *np = (Namval_t*)obj;
3639*b30d1939SAndy Fiddaman return(np->nvname);
3640*b30d1939SAndy Fiddaman }
3641*b30d1939SAndy Fiddaman
3642*b30d1939SAndy Fiddaman #undef hashlook
3643*b30d1939SAndy Fiddaman
hashlook(Dt_t * root,const char * name,int mode,int size)3644*b30d1939SAndy Fiddaman extern void *hashlook(Dt_t *root, const char *name, int mode,int size)
3645*b30d1939SAndy Fiddaman {
3646*b30d1939SAndy Fiddaman NOT_USED(size);
3647*b30d1939SAndy Fiddaman return((void*)nv_search(name,root,mode));
3648*b30d1939SAndy Fiddaman }
3649*b30d1939SAndy Fiddaman
nv_name(register Namval_t * np)3650*b30d1939SAndy Fiddaman char *nv_name(register Namval_t *np)
3651*b30d1939SAndy Fiddaman {
3652*b30d1939SAndy Fiddaman Shell_t *shp = sh_getinterp();
3653*b30d1939SAndy Fiddaman register Namval_t *table;
3654*b30d1939SAndy Fiddaman register Namfun_t *fp;
3655*b30d1939SAndy Fiddaman #if SHOPT_FIXEDARRAY
3656*b30d1939SAndy Fiddaman Namarr_t *ap;
3657*b30d1939SAndy Fiddaman #endif /* SHOPT_FIXEDARRAY */
3658*b30d1939SAndy Fiddaman char *cp;
3659*b30d1939SAndy Fiddaman if(is_abuiltin(np) || is_afunction(np))
3660*b30d1939SAndy Fiddaman {
3661*b30d1939SAndy Fiddaman #if SHOPT_NAMESPACE
3662*b30d1939SAndy Fiddaman if(shp->namespace && is_afunction(np))
3663*b30d1939SAndy Fiddaman {
3664*b30d1939SAndy Fiddaman char *name = nv_name(shp->namespace);
3665*b30d1939SAndy Fiddaman int n = strlen(name);
3666*b30d1939SAndy Fiddaman if(memcmp(np->nvname,name,n)==0 && np->nvname[n]=='.')
3667*b30d1939SAndy Fiddaman return(np->nvname+n+1);
3668*b30d1939SAndy Fiddaman }
3669*b30d1939SAndy Fiddaman #endif /* SHOPT_NAMESPACE */
3670*b30d1939SAndy Fiddaman return(np->nvname);
3671*b30d1939SAndy Fiddaman }
3672*b30d1939SAndy Fiddaman #if SHOPT_FIXEDARRAY
3673*b30d1939SAndy Fiddaman ap = nv_arrayptr(np);
3674*b30d1939SAndy Fiddaman #endif /* SHOPT_FIXEDARRAY */
3675*b30d1939SAndy Fiddaman if(!nv_isattr(np,NV_MINIMAL|NV_EXPORT) && np->nvenv)
3676*b30d1939SAndy Fiddaman {
3677*b30d1939SAndy Fiddaman Namval_t *nq= shp->last_table, *mp= (Namval_t*)np->nvenv;
3678*b30d1939SAndy Fiddaman if(np==shp->last_table)
3679*b30d1939SAndy Fiddaman shp->last_table = 0;
3680*b30d1939SAndy Fiddaman if(nv_isarray(mp))
3681*b30d1939SAndy Fiddaman sfprintf(shp->strbuf,"%s[%s]",nv_name(mp),np->nvname);
3682*b30d1939SAndy Fiddaman else
3683*b30d1939SAndy Fiddaman sfprintf(shp->strbuf,"%s.%s",nv_name(mp),np->nvname);
3684*b30d1939SAndy Fiddaman shp->last_table = nq;
3685*b30d1939SAndy Fiddaman return(sfstruse(shp->strbuf));
3686*b30d1939SAndy Fiddaman }
3687*b30d1939SAndy Fiddaman if(nv_istable(np))
3688*b30d1939SAndy Fiddaman #if 1
3689*b30d1939SAndy Fiddaman shp->last_table = nv_parent(np);
3690*b30d1939SAndy Fiddaman #else
3691*b30d1939SAndy Fiddaman shp->last_table = nv_create(np,0, NV_LAST,(Namfun_t*)0);
3692*b30d1939SAndy Fiddaman #endif
3693*b30d1939SAndy Fiddaman else if(!nv_isref(np))
3694*b30d1939SAndy Fiddaman {
3695*b30d1939SAndy Fiddaman for(fp= np->nvfun ; fp; fp=fp->next)
3696*b30d1939SAndy Fiddaman if(fp->disc && fp->disc->namef)
3697*b30d1939SAndy Fiddaman {
3698*b30d1939SAndy Fiddaman if(np==shp->last_table)
3699*b30d1939SAndy Fiddaman shp->last_table = 0;
3700*b30d1939SAndy Fiddaman return((*fp->disc->namef)(np,fp));
3701*b30d1939SAndy Fiddaman }
3702*b30d1939SAndy Fiddaman }
3703*b30d1939SAndy Fiddaman if(!(table=shp->last_table) || *np->nvname=='.' || table==shp->namespace || np==table)
3704*b30d1939SAndy Fiddaman {
3705*b30d1939SAndy Fiddaman #if SHOPT_FIXEDARRAY
3706*b30d1939SAndy Fiddaman if(!ap || !ap->fixed || (ap->nelem&ARRAY_UNDEF))
3707*b30d1939SAndy Fiddaman return(np->nvname);
3708*b30d1939SAndy Fiddaman table = 0;
3709*b30d1939SAndy Fiddaman #else
3710*b30d1939SAndy Fiddaman return(np->nvname);
3711*b30d1939SAndy Fiddaman #endif /* SHOPT_FIXEDARRAY */
3712*b30d1939SAndy Fiddaman }
3713*b30d1939SAndy Fiddaman if(table)
3714*b30d1939SAndy Fiddaman {
3715*b30d1939SAndy Fiddaman cp = nv_name(table);
3716*b30d1939SAndy Fiddaman sfprintf(shp->strbuf,"%s.%s",cp,np->nvname);
3717*b30d1939SAndy Fiddaman }
3718*b30d1939SAndy Fiddaman else
3719*b30d1939SAndy Fiddaman sfprintf(shp->strbuf,"%s",np->nvname);
3720*b30d1939SAndy Fiddaman #if SHOPT_FIXEDARRAY
3721*b30d1939SAndy Fiddaman if(ap && ap->fixed)
3722*b30d1939SAndy Fiddaman nv_arrfixed(np,shp->strbuf,1,(char*)0);
3723*b30d1939SAndy Fiddaman #endif /* SHOPT_FIXEDARRAY */
3724*b30d1939SAndy Fiddaman return(sfstruse(shp->strbuf));
3725*b30d1939SAndy Fiddaman }
3726*b30d1939SAndy Fiddaman
nv_lastdict(void)3727*b30d1939SAndy Fiddaman Namval_t *nv_lastdict(void)
3728*b30d1939SAndy Fiddaman {
3729*b30d1939SAndy Fiddaman Shell_t *shp = sh_getinterp();
3730*b30d1939SAndy Fiddaman return(shp->last_table);
3731*b30d1939SAndy Fiddaman }
3732*b30d1939SAndy Fiddaman
3733*b30d1939SAndy Fiddaman #undef nv_context
3734*b30d1939SAndy Fiddaman /*
3735*b30d1939SAndy Fiddaman * returns the data context for a builtin
3736*b30d1939SAndy Fiddaman */
nv_context(Namval_t * np)3737*b30d1939SAndy Fiddaman void *nv_context(Namval_t *np)
3738*b30d1939SAndy Fiddaman {
3739*b30d1939SAndy Fiddaman return((void*)np->nvfun);
3740*b30d1939SAndy Fiddaman }
3741*b30d1939SAndy Fiddaman
3742*b30d1939SAndy Fiddaman #define DISABLE /* proto workaround */
3743*b30d1939SAndy Fiddaman
DISABLE(register Namval_t * np)3744*b30d1939SAndy Fiddaman int nv_isnull DISABLE (register Namval_t *np)
3745*b30d1939SAndy Fiddaman {
3746*b30d1939SAndy Fiddaman return(nv_isnull(np));
3747*b30d1939SAndy Fiddaman }
3748*b30d1939SAndy Fiddaman
3749*b30d1939SAndy Fiddaman #undef nv_setsize
nv_setsize(register Namval_t * np,int size)3750*b30d1939SAndy Fiddaman int nv_setsize(register Namval_t *np, int size)
3751*b30d1939SAndy Fiddaman {
3752*b30d1939SAndy Fiddaman int oldsize = nv_size(np);
3753*b30d1939SAndy Fiddaman if(size>=0)
3754*b30d1939SAndy Fiddaman np->nvsize = size;
3755*b30d1939SAndy Fiddaman return(oldsize);
3756*b30d1939SAndy Fiddaman }
3757*b30d1939SAndy Fiddaman
nv_shell(Namval_t * np)3758*b30d1939SAndy Fiddaman Shell_t *nv_shell(Namval_t *np)
3759*b30d1939SAndy Fiddaman {
3760*b30d1939SAndy Fiddaman Namfun_t *fp;
3761*b30d1939SAndy Fiddaman for(fp=np->nvfun;fp;fp=fp->next)
3762*b30d1939SAndy Fiddaman {
3763*b30d1939SAndy Fiddaman if(!fp->disc)
3764*b30d1939SAndy Fiddaman return((Shell_t*)fp->last);
3765*b30d1939SAndy Fiddaman }
3766*b30d1939SAndy Fiddaman return(0);
3767*b30d1939SAndy Fiddaman }
3768*b30d1939SAndy Fiddaman
3769*b30d1939SAndy Fiddaman #undef nv_unset
3770*b30d1939SAndy Fiddaman
nv_unset(register Namval_t * np)3771*b30d1939SAndy Fiddaman void nv_unset(register Namval_t *np)
3772*b30d1939SAndy Fiddaman {
3773*b30d1939SAndy Fiddaman _nv_unset(np,0);
3774*b30d1939SAndy Fiddaman return;
3775*b30d1939SAndy Fiddaman }
3776