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 * David Korn
23*b30d1939SAndy Fiddaman * AT&T Labs
24*b30d1939SAndy Fiddaman *
25*b30d1939SAndy Fiddaman */
26*b30d1939SAndy Fiddaman #include "defs.h"
27*b30d1939SAndy Fiddaman #include "io.h"
28*b30d1939SAndy Fiddaman #include "variables.h"
29*b30d1939SAndy Fiddaman
30*b30d1939SAndy Fiddaman static const char sh_opttype[] =
31*b30d1939SAndy Fiddaman "[-1c?\n@(#)$Id: type (AT&T Labs Research) 2008-07-01 $\n]"
32*b30d1939SAndy Fiddaman USAGE_LICENSE
33*b30d1939SAndy Fiddaman "[+NAME?\f?\f - set the type of variables to \b\f?\f\b]"
34*b30d1939SAndy Fiddaman "[+DESCRIPTION?\b\f?\f\b sets the type on each of the variables specified "
35*b30d1939SAndy Fiddaman "by \aname\a to \b\f?\f\b. If \b=\b\avalue\a is specified, "
36*b30d1939SAndy Fiddaman "the variable \aname\a is set to \avalue\a before the variable "
37*b30d1939SAndy Fiddaman "is converted to \b\f?\f\b.]"
38*b30d1939SAndy Fiddaman "[+?If no \aname\as are specified then the names and values of all "
39*b30d1939SAndy Fiddaman "variables of this type are written to standard output.]"
40*b30d1939SAndy Fiddaman "[+?\b\f?\f\b is built-in to the shell as a declaration command so that "
41*b30d1939SAndy Fiddaman "field splitting and pathname expansion are not performed on "
42*b30d1939SAndy Fiddaman "the arguments. Tilde expansion occurs on \avalue\a.]"
43*b30d1939SAndy Fiddaman "[r?Enables readonly. Once enabled, the value cannot be changed or unset.]"
44*b30d1939SAndy Fiddaman "[a]:?[type?Indexed array. Each \aname\a will converted to an index "
45*b30d1939SAndy Fiddaman "array of type \b\f?\f\b. If a variable already exists, the current "
46*b30d1939SAndy Fiddaman "value will become index \b0\b. If \b[\b\atype\a\b]]\b is "
47*b30d1939SAndy Fiddaman "specified, each subscript is interpreted as a value of enumeration "
48*b30d1939SAndy Fiddaman "type \atype\a.]"
49*b30d1939SAndy Fiddaman "[A?Associative array. Each \aname\a will converted to an associate "
50*b30d1939SAndy Fiddaman "array of type \b\f?\f\b. If a variable already exists, the current "
51*b30d1939SAndy Fiddaman "value will become subscript \b0\b.]"
52*b30d1939SAndy Fiddaman "[h]:[string?Used within a type definition to provide a help string "
53*b30d1939SAndy Fiddaman "for variable \aname\a. Otherwise, it is ignored.]"
54*b30d1939SAndy Fiddaman "[S?Used with a type definition to indicate that the variable is shared by "
55*b30d1939SAndy Fiddaman "each instance of the type. When used inside a function defined "
56*b30d1939SAndy Fiddaman "with the \bfunction\b reserved word, the specified variables "
57*b30d1939SAndy Fiddaman "will have function static scope. Otherwise, the variable is "
58*b30d1939SAndy Fiddaman "unset prior to processing the assignment list.]"
59*b30d1939SAndy Fiddaman "[+DETAILS]\ftypes\f"
60*b30d1939SAndy Fiddaman "\n"
61*b30d1939SAndy Fiddaman "\n[name[=value]...]\n"
62*b30d1939SAndy Fiddaman "\n"
63*b30d1939SAndy Fiddaman "[+EXIT STATUS?]{"
64*b30d1939SAndy Fiddaman "[+0?Successful completion.]"
65*b30d1939SAndy Fiddaman "[+>0?An error occurred.]"
66*b30d1939SAndy Fiddaman "}"
67*b30d1939SAndy Fiddaman
68*b30d1939SAndy Fiddaman "[+SEE ALSO?\fother\f \breadonly\b(1), \btypeset\b(1)]"
69*b30d1939SAndy Fiddaman ;
70*b30d1939SAndy Fiddaman
71*b30d1939SAndy Fiddaman typedef struct Namtype Namtype_t;
72*b30d1939SAndy Fiddaman typedef struct Namchld
73*b30d1939SAndy Fiddaman {
74*b30d1939SAndy Fiddaman Namfun_t fun;
75*b30d1939SAndy Fiddaman Namtype_t *ptype;
76*b30d1939SAndy Fiddaman Namtype_t *ttype;
77*b30d1939SAndy Fiddaman } Namchld_t;
78*b30d1939SAndy Fiddaman
79*b30d1939SAndy Fiddaman struct Namtype
80*b30d1939SAndy Fiddaman {
81*b30d1939SAndy Fiddaman Namfun_t fun;
82*b30d1939SAndy Fiddaman Shell_t *sh;
83*b30d1939SAndy Fiddaman Namval_t *np;
84*b30d1939SAndy Fiddaman Namval_t *parent;
85*b30d1939SAndy Fiddaman Namval_t *bp;
86*b30d1939SAndy Fiddaman Namval_t *cp;
87*b30d1939SAndy Fiddaman #if SHOPT_NAMESPACE
88*b30d1939SAndy Fiddaman Namval_t *nsp;
89*b30d1939SAndy Fiddaman #endif /* SHOPT_NAMESPACE */
90*b30d1939SAndy Fiddaman char *nodes;
91*b30d1939SAndy Fiddaman char *data;
92*b30d1939SAndy Fiddaman Namchld_t childfun;
93*b30d1939SAndy Fiddaman int numnodes;
94*b30d1939SAndy Fiddaman char **names;
95*b30d1939SAndy Fiddaman size_t dsize;
96*b30d1939SAndy Fiddaman short strsize;
97*b30d1939SAndy Fiddaman unsigned short ndisc;
98*b30d1939SAndy Fiddaman unsigned short current;
99*b30d1939SAndy Fiddaman unsigned short nref;
100*b30d1939SAndy Fiddaman };
101*b30d1939SAndy Fiddaman
102*b30d1939SAndy Fiddaman #if 0
103*b30d1939SAndy Fiddaman struct type
104*b30d1939SAndy Fiddaman {
105*b30d1939SAndy Fiddaman Namtype_t hdr;
106*b30d1939SAndy Fiddaman unsigned short ndisc;
107*b30d1939SAndy Fiddaman unsigned short current;
108*b30d1939SAndy Fiddaman unsigned short nref;
109*b30d1939SAndy Fiddaman };
110*b30d1939SAndy Fiddaman #endif
111*b30d1939SAndy Fiddaman
112*b30d1939SAndy Fiddaman typedef struct
113*b30d1939SAndy Fiddaman {
114*b30d1939SAndy Fiddaman char _cSfdouble_t;
115*b30d1939SAndy Fiddaman Sfdouble_t _dSfdouble_t;
116*b30d1939SAndy Fiddaman char _cdouble;
117*b30d1939SAndy Fiddaman double _ddouble;
118*b30d1939SAndy Fiddaman char _cfloat;
119*b30d1939SAndy Fiddaman float _dfloat;
120*b30d1939SAndy Fiddaman char _cSflong_t;
121*b30d1939SAndy Fiddaman Sflong_t _dSflong_t;
122*b30d1939SAndy Fiddaman char _clong;
123*b30d1939SAndy Fiddaman long _dlong;
124*b30d1939SAndy Fiddaman char _cshort;
125*b30d1939SAndy Fiddaman short _dshort;
126*b30d1939SAndy Fiddaman char _cpointer;
127*b30d1939SAndy Fiddaman char *_dpointer;
128*b30d1939SAndy Fiddaman int32_t _cint32_t;
129*b30d1939SAndy Fiddaman int32_t *_dint32_t;
130*b30d1939SAndy Fiddaman } _Align_;
131*b30d1939SAndy Fiddaman
132*b30d1939SAndy Fiddaman #define alignof(t) ((char*)&((_Align_*)0)->_d##t-(char*)&((_Align_*)0)->_c##t)
133*b30d1939SAndy Fiddaman
134*b30d1939SAndy Fiddaman static void put_type(Namval_t*, const char*, int, Namfun_t*);
135*b30d1939SAndy Fiddaman static Namval_t* create_type(Namval_t*, const char*, int, Namfun_t*);
136*b30d1939SAndy Fiddaman static Namfun_t* clone_type(Namval_t*, Namval_t*, int, Namfun_t*);
137*b30d1939SAndy Fiddaman static Namval_t* next_type(Namval_t*, Dt_t*, Namfun_t*);
138*b30d1939SAndy Fiddaman
139*b30d1939SAndy Fiddaman static const Namdisc_t type_disc =
140*b30d1939SAndy Fiddaman {
141*b30d1939SAndy Fiddaman sizeof(Namtype_t),
142*b30d1939SAndy Fiddaman put_type,
143*b30d1939SAndy Fiddaman 0,
144*b30d1939SAndy Fiddaman 0,
145*b30d1939SAndy Fiddaman 0,
146*b30d1939SAndy Fiddaman create_type,
147*b30d1939SAndy Fiddaman clone_type,
148*b30d1939SAndy Fiddaman 0,
149*b30d1939SAndy Fiddaman next_type,
150*b30d1939SAndy Fiddaman 0,
151*b30d1939SAndy Fiddaman #if 0
152*b30d1939SAndy Fiddaman read_type
153*b30d1939SAndy Fiddaman #endif
154*b30d1939SAndy Fiddaman };
155*b30d1939SAndy Fiddaman
nv_datasize(Namval_t * np,size_t * offset)156*b30d1939SAndy Fiddaman size_t nv_datasize(Namval_t *np, size_t *offset)
157*b30d1939SAndy Fiddaman {
158*b30d1939SAndy Fiddaman size_t s=0, a=0;
159*b30d1939SAndy Fiddaman if(nv_isattr(np,NV_INTEGER))
160*b30d1939SAndy Fiddaman {
161*b30d1939SAndy Fiddaman if(nv_isattr(np,NV_DOUBLE)==NV_DOUBLE)
162*b30d1939SAndy Fiddaman {
163*b30d1939SAndy Fiddaman if(nv_isattr(np, NV_LONG))
164*b30d1939SAndy Fiddaman {
165*b30d1939SAndy Fiddaman a = alignof(Sfdouble_t);
166*b30d1939SAndy Fiddaman s = sizeof(Sfdouble_t);
167*b30d1939SAndy Fiddaman }
168*b30d1939SAndy Fiddaman else if(nv_isattr(np, NV_SHORT))
169*b30d1939SAndy Fiddaman {
170*b30d1939SAndy Fiddaman a = alignof(float);
171*b30d1939SAndy Fiddaman s = sizeof(float);
172*b30d1939SAndy Fiddaman }
173*b30d1939SAndy Fiddaman else
174*b30d1939SAndy Fiddaman {
175*b30d1939SAndy Fiddaman a = alignof(double);
176*b30d1939SAndy Fiddaman s = sizeof(double);
177*b30d1939SAndy Fiddaman }
178*b30d1939SAndy Fiddaman }
179*b30d1939SAndy Fiddaman else
180*b30d1939SAndy Fiddaman {
181*b30d1939SAndy Fiddaman if(nv_isattr(np, NV_LONG))
182*b30d1939SAndy Fiddaman {
183*b30d1939SAndy Fiddaman a = alignof(Sflong_t);
184*b30d1939SAndy Fiddaman s = sizeof(Sflong_t);
185*b30d1939SAndy Fiddaman }
186*b30d1939SAndy Fiddaman else if(nv_isattr(np, NV_SHORT))
187*b30d1939SAndy Fiddaman {
188*b30d1939SAndy Fiddaman a = alignof(short);
189*b30d1939SAndy Fiddaman s = sizeof(short);
190*b30d1939SAndy Fiddaman }
191*b30d1939SAndy Fiddaman else
192*b30d1939SAndy Fiddaman {
193*b30d1939SAndy Fiddaman a = alignof(int32_t);
194*b30d1939SAndy Fiddaman s = sizeof(int32_t);
195*b30d1939SAndy Fiddaman }
196*b30d1939SAndy Fiddaman }
197*b30d1939SAndy Fiddaman }
198*b30d1939SAndy Fiddaman else if(nv_isattr(np, NV_BINARY) || nv_isattr(np,NV_LJUST|NV_RJUST|NV_ZFILL))
199*b30d1939SAndy Fiddaman s = nv_size(np);
200*b30d1939SAndy Fiddaman else
201*b30d1939SAndy Fiddaman {
202*b30d1939SAndy Fiddaman a = alignof(pointer);
203*b30d1939SAndy Fiddaman s = nv_size(np);
204*b30d1939SAndy Fiddaman }
205*b30d1939SAndy Fiddaman if(a>1 && offset)
206*b30d1939SAndy Fiddaman *offset = a*((*offset +a-1)/a);
207*b30d1939SAndy Fiddaman return(s);
208*b30d1939SAndy Fiddaman }
209*b30d1939SAndy Fiddaman
name_chtype(Namval_t * np,Namfun_t * fp)210*b30d1939SAndy Fiddaman static char *name_chtype(Namval_t *np, Namfun_t *fp)
211*b30d1939SAndy Fiddaman {
212*b30d1939SAndy Fiddaman Namchld_t *pp = (Namchld_t*)fp;
213*b30d1939SAndy Fiddaman char *cp, *sub;
214*b30d1939SAndy Fiddaman Namval_t *tp = sh.last_table;
215*b30d1939SAndy Fiddaman Namval_t *nq = pp->ptype->np;
216*b30d1939SAndy Fiddaman Namarr_t *ap;
217*b30d1939SAndy Fiddaman if(nv_isattr(np,NV_REF|NV_TAGGED)==(NV_REF|NV_TAGGED))
218*b30d1939SAndy Fiddaman sh.last_table = 0;
219*b30d1939SAndy Fiddaman cp = nv_name(nq);
220*b30d1939SAndy Fiddaman if((ap = nv_arrayptr(nq)) && !(ap->nelem&ARRAY_UNDEF) && (sub= nv_getsub(nq)))
221*b30d1939SAndy Fiddaman sfprintf(sh.strbuf,"%s[%s].%s",cp,sub,np->nvname);
222*b30d1939SAndy Fiddaman else
223*b30d1939SAndy Fiddaman sfprintf(sh.strbuf,"%s.%s",cp,np->nvname);
224*b30d1939SAndy Fiddaman #if SHOPT_FIXEDARRAY
225*b30d1939SAndy Fiddaman if((ap=nv_arrayptr(np)) && ap->fixed)
226*b30d1939SAndy Fiddaman nv_arrfixed(np,sh.strbuf,1,(char*)0);
227*b30d1939SAndy Fiddaman #endif /* SHOPT_FIXEDARRAY */
228*b30d1939SAndy Fiddaman sh.last_table = tp;
229*b30d1939SAndy Fiddaman return(sfstruse(sh.strbuf));
230*b30d1939SAndy Fiddaman }
231*b30d1939SAndy Fiddaman
put_chtype(Namval_t * np,const char * val,int flag,Namfun_t * fp)232*b30d1939SAndy Fiddaman static void put_chtype(Namval_t* np, const char* val, int flag, Namfun_t* fp)
233*b30d1939SAndy Fiddaman {
234*b30d1939SAndy Fiddaman if(!val && nv_isattr(np,NV_REF))
235*b30d1939SAndy Fiddaman return;
236*b30d1939SAndy Fiddaman nv_putv(np,val,flag,fp);
237*b30d1939SAndy Fiddaman if(!val)
238*b30d1939SAndy Fiddaman {
239*b30d1939SAndy Fiddaman Namchld_t *pp = (Namchld_t*)fp;
240*b30d1939SAndy Fiddaman size_t dsize=0,offset = (char*)np-(char*)pp->ptype;
241*b30d1939SAndy Fiddaman Namval_t *mp = (Namval_t*)((char*)pp->ttype+offset);
242*b30d1939SAndy Fiddaman dsize = nv_datasize(mp,&dsize);
243*b30d1939SAndy Fiddaman if(mp->nvalue.cp >= pp->ttype->data && mp->nvalue.cp < (char*)pp+pp->ttype->fun.dsize)
244*b30d1939SAndy Fiddaman {
245*b30d1939SAndy Fiddaman np->nvalue.cp = pp->ptype->data + (mp->nvalue.cp-pp->ptype->data);
246*b30d1939SAndy Fiddaman if(np->nvalue.cp!=mp->nvalue.cp)
247*b30d1939SAndy Fiddaman memcpy((char*)np->nvalue.cp,mp->nvalue.cp,dsize);
248*b30d1939SAndy Fiddaman }
249*b30d1939SAndy Fiddaman else if(!nv_isarray(mp) && mp->nvalue.cp)
250*b30d1939SAndy Fiddaman {
251*b30d1939SAndy Fiddaman np->nvalue.cp = mp->nvalue.cp;
252*b30d1939SAndy Fiddaman nv_onattr(np,NV_NOFREE);
253*b30d1939SAndy Fiddaman }
254*b30d1939SAndy Fiddaman np->nvsize = mp->nvsize;
255*b30d1939SAndy Fiddaman np->nvflag = mp->nvflag&~NV_RDONLY;
256*b30d1939SAndy Fiddaman }
257*b30d1939SAndy Fiddaman }
258*b30d1939SAndy Fiddaman
clone_chtype(Namval_t * np,Namval_t * mp,int flags,Namfun_t * fp)259*b30d1939SAndy Fiddaman static Namfun_t *clone_chtype(Namval_t* np, Namval_t *mp, int flags, Namfun_t *fp)
260*b30d1939SAndy Fiddaman {
261*b30d1939SAndy Fiddaman if(flags&NV_NODISC)
262*b30d1939SAndy Fiddaman return(0);
263*b30d1939SAndy Fiddaman return(nv_clone_disc(fp,flags));
264*b30d1939SAndy Fiddaman }
265*b30d1939SAndy Fiddaman
266*b30d1939SAndy Fiddaman static const Namdisc_t chtype_disc =
267*b30d1939SAndy Fiddaman {
268*b30d1939SAndy Fiddaman sizeof(Namchld_t),
269*b30d1939SAndy Fiddaman put_chtype,
270*b30d1939SAndy Fiddaman 0,
271*b30d1939SAndy Fiddaman 0,
272*b30d1939SAndy Fiddaman 0,
273*b30d1939SAndy Fiddaman 0,
274*b30d1939SAndy Fiddaman clone_chtype,
275*b30d1939SAndy Fiddaman name_chtype
276*b30d1939SAndy Fiddaman };
277*b30d1939SAndy Fiddaman
findref(void * nodes,int n)278*b30d1939SAndy Fiddaman static Namval_t *findref(void *nodes, int n)
279*b30d1939SAndy Fiddaman {
280*b30d1939SAndy Fiddaman Namval_t *tp,*np = nv_namptr(nodes,n);
281*b30d1939SAndy Fiddaman char *name = np->nvname;
282*b30d1939SAndy Fiddaman int i=n, len= strrchr(name,'.')-name;
283*b30d1939SAndy Fiddaman Namtype_t *pp;
284*b30d1939SAndy Fiddaman while(--i>0)
285*b30d1939SAndy Fiddaman {
286*b30d1939SAndy Fiddaman np = nv_namptr(nodes,i);
287*b30d1939SAndy Fiddaman if(np->nvname[len]==0)
288*b30d1939SAndy Fiddaman {
289*b30d1939SAndy Fiddaman tp = nv_type(np);
290*b30d1939SAndy Fiddaman pp = (Namtype_t*)nv_hasdisc(tp,&type_disc);
291*b30d1939SAndy Fiddaman return(nv_namptr(pp->nodes,n-i-1));
292*b30d1939SAndy Fiddaman }
293*b30d1939SAndy Fiddaman }
294*b30d1939SAndy Fiddaman return(0);
295*b30d1939SAndy Fiddaman }
296*b30d1939SAndy Fiddaman
fixnode(Namtype_t * dp,Namtype_t * pp,int i,struct Namref * nrp,int flag)297*b30d1939SAndy Fiddaman static int fixnode(Namtype_t *dp, Namtype_t *pp, int i, struct Namref *nrp,int flag)
298*b30d1939SAndy Fiddaman {
299*b30d1939SAndy Fiddaman Namval_t *nq = nv_namptr(dp->nodes,i);
300*b30d1939SAndy Fiddaman Namfun_t *fp;
301*b30d1939SAndy Fiddaman if(fp=nv_hasdisc(nq,&chtype_disc))
302*b30d1939SAndy Fiddaman nv_disc(nq, fp, NV_POP);
303*b30d1939SAndy Fiddaman if(nv_isattr(nq,NV_REF))
304*b30d1939SAndy Fiddaman {
305*b30d1939SAndy Fiddaman nq->nvalue.nrp = nrp++;
306*b30d1939SAndy Fiddaman nv_setsize(nq,0);
307*b30d1939SAndy Fiddaman if(strchr(nq->nvname,'.'))
308*b30d1939SAndy Fiddaman nq->nvalue.nrp->np = findref(dp->nodes,i);
309*b30d1939SAndy Fiddaman else
310*b30d1939SAndy Fiddaman nq->nvalue.nrp->np = nv_namptr(pp->childfun.ttype->nodes,i);
311*b30d1939SAndy Fiddaman nq->nvalue.nrp->root = sh.last_root;
312*b30d1939SAndy Fiddaman nq->nvalue.nrp->table = pp->np;
313*b30d1939SAndy Fiddaman nq ->nvflag = NV_REF|NV_NOFREE|NV_MINIMAL;
314*b30d1939SAndy Fiddaman return(1);
315*b30d1939SAndy Fiddaman }
316*b30d1939SAndy Fiddaman if(nq->nvalue.cp || nq->nvfun)
317*b30d1939SAndy Fiddaman {
318*b30d1939SAndy Fiddaman const char *data = nq->nvalue.cp;
319*b30d1939SAndy Fiddaman if(nq->nvfun)
320*b30d1939SAndy Fiddaman {
321*b30d1939SAndy Fiddaman Namval_t *np = nv_namptr(pp->nodes,i);
322*b30d1939SAndy Fiddaman if(nv_isarray(nq))
323*b30d1939SAndy Fiddaman nq->nvalue.cp = 0;
324*b30d1939SAndy Fiddaman nq->nvfun = 0;
325*b30d1939SAndy Fiddaman if(nv_isarray(nq) && ((flag&NV_IARRAY) || nv_type(np)))
326*b30d1939SAndy Fiddaman clone_all_disc(np,nq,flag&~NV_TYPE);
327*b30d1939SAndy Fiddaman else
328*b30d1939SAndy Fiddaman clone_all_disc(np,nq,flag);
329*b30d1939SAndy Fiddaman if(fp)
330*b30d1939SAndy Fiddaman nv_disc(np, fp, NV_LAST);
331*b30d1939SAndy Fiddaman }
332*b30d1939SAndy Fiddaman #if 0
333*b30d1939SAndy Fiddaman if(nq->nvalue.cp >= pp->data && nq->nvalue.cp < (char*)pp +pp->fun.dsize)
334*b30d1939SAndy Fiddaman nq->nvalue.cp = dp->data + (nq->nvalue.cp-pp->data);
335*b30d1939SAndy Fiddaman #else
336*b30d1939SAndy Fiddaman if(data >= pp->data && data < (char*)pp +pp->fun.dsize)
337*b30d1939SAndy Fiddaman nq->nvalue.cp = dp->data + (data-pp->data);
338*b30d1939SAndy Fiddaman #endif
339*b30d1939SAndy Fiddaman else if(!nq->nvfun && pp->childfun.ttype!=pp->childfun.ptype)
340*b30d1939SAndy Fiddaman {
341*b30d1939SAndy Fiddaman Namval_t *nr = nv_namptr( pp->childfun.ttype->nodes,i);
342*b30d1939SAndy Fiddaman if(nr->nvalue.cp!=nq->nvalue.cp)
343*b30d1939SAndy Fiddaman {
344*b30d1939SAndy Fiddaman if(i=nv_size(nq))
345*b30d1939SAndy Fiddaman {
346*b30d1939SAndy Fiddaman const char *cp = nq->nvalue.cp;
347*b30d1939SAndy Fiddaman nq->nvalue.cp = (char*)malloc(i);
348*b30d1939SAndy Fiddaman memcpy((char*)nq->nvalue.cp,cp,i);
349*b30d1939SAndy Fiddaman }
350*b30d1939SAndy Fiddaman else
351*b30d1939SAndy Fiddaman nq->nvalue.cp = strdup(nq->nvalue.cp);
352*b30d1939SAndy Fiddaman nv_offattr(nq,NV_NOFREE);
353*b30d1939SAndy Fiddaman }
354*b30d1939SAndy Fiddaman }
355*b30d1939SAndy Fiddaman else if(nq->nvalue.cp==Empty)
356*b30d1939SAndy Fiddaman nv_offattr(nq,NV_NOFREE);
357*b30d1939SAndy Fiddaman
358*b30d1939SAndy Fiddaman }
359*b30d1939SAndy Fiddaman if(fp)
360*b30d1939SAndy Fiddaman nv_disc(nq, &dp->childfun.fun, NV_LAST);
361*b30d1939SAndy Fiddaman return(0);
362*b30d1939SAndy Fiddaman }
363*b30d1939SAndy Fiddaman
clone_type(Namval_t * np,Namval_t * mp,int flags,Namfun_t * fp)364*b30d1939SAndy Fiddaman static Namfun_t *clone_type(Namval_t* np, Namval_t *mp, int flags, Namfun_t *fp)
365*b30d1939SAndy Fiddaman {
366*b30d1939SAndy Fiddaman Namtype_t *dp, *pp=(Namtype_t*)fp;
367*b30d1939SAndy Fiddaman register int i;
368*b30d1939SAndy Fiddaman register Namval_t *nq, *nr;
369*b30d1939SAndy Fiddaman size_t size = fp->dsize;
370*b30d1939SAndy Fiddaman int save, offset=staktell();
371*b30d1939SAndy Fiddaman char *cp;
372*b30d1939SAndy Fiddaman Dt_t *root = sh.last_root;
373*b30d1939SAndy Fiddaman Namval_t *last_table = sh.last_table;
374*b30d1939SAndy Fiddaman struct Namref *nrp = 0;
375*b30d1939SAndy Fiddaman Namarr_t *ap;
376*b30d1939SAndy Fiddaman if(flags&NV_MOVE)
377*b30d1939SAndy Fiddaman {
378*b30d1939SAndy Fiddaman pp->np = mp;
379*b30d1939SAndy Fiddaman pp->childfun.ptype = pp;
380*b30d1939SAndy Fiddaman return(fp);
381*b30d1939SAndy Fiddaman }
382*b30d1939SAndy Fiddaman if(flags&NV_TYPE)
383*b30d1939SAndy Fiddaman return(nv_clone_disc(fp,flags));
384*b30d1939SAndy Fiddaman if(size==0 && (!fp->disc || (size=fp->disc->dsize)==0))
385*b30d1939SAndy Fiddaman size = sizeof(Namfun_t);
386*b30d1939SAndy Fiddaman dp = (Namtype_t*)malloc(size+pp->nref*sizeof(struct Namref));
387*b30d1939SAndy Fiddaman if(pp->nref)
388*b30d1939SAndy Fiddaman {
389*b30d1939SAndy Fiddaman nrp = (struct Namref*)((char*)dp + size);
390*b30d1939SAndy Fiddaman memset((void*)nrp,0,pp->nref*sizeof(struct Namref));
391*b30d1939SAndy Fiddaman }
392*b30d1939SAndy Fiddaman memcpy((void*)dp,(void*)pp,size);
393*b30d1939SAndy Fiddaman #if 0
394*b30d1939SAndy Fiddaman dp->parent = nv_lastdict();
395*b30d1939SAndy Fiddaman #else
396*b30d1939SAndy Fiddaman dp->parent = mp;
397*b30d1939SAndy Fiddaman #endif
398*b30d1939SAndy Fiddaman dp->fun.nofree = (flags&NV_RDONLY?1:0);
399*b30d1939SAndy Fiddaman dp->np = mp;
400*b30d1939SAndy Fiddaman dp->childfun.ptype = dp;
401*b30d1939SAndy Fiddaman #if 0
402*b30d1939SAndy Fiddaman dp->childfun.ttype = (Namtype_t*)nv_hasdisc(dp->fun.type,&type_disc);
403*b30d1939SAndy Fiddaman #endif
404*b30d1939SAndy Fiddaman dp->nodes = (char*)(dp+1);
405*b30d1939SAndy Fiddaman dp->data = (char*)dp + (pp->data - (char*)pp);
406*b30d1939SAndy Fiddaman for(i=dp->numnodes; --i >= 0; )
407*b30d1939SAndy Fiddaman {
408*b30d1939SAndy Fiddaman nq = nv_namptr(dp->nodes,i);
409*b30d1939SAndy Fiddaman if(fixnode(dp,pp,i,nrp,NV_TYPE|(flags&NV_IARRAY)))
410*b30d1939SAndy Fiddaman {
411*b30d1939SAndy Fiddaman nrp++;
412*b30d1939SAndy Fiddaman nq = nq->nvalue.nrp->np;
413*b30d1939SAndy Fiddaman }
414*b30d1939SAndy Fiddaman if(flags==(NV_NOFREE|NV_ARRAY))
415*b30d1939SAndy Fiddaman continue;
416*b30d1939SAndy Fiddaman if(nq->nvalue.cp || !nv_isvtree(nq) || nv_isattr(nq,NV_RDONLY))
417*b30d1939SAndy Fiddaman {
418*b30d1939SAndy Fiddaman /* see if default value has been overwritten */
419*b30d1939SAndy Fiddaman if(!mp->nvname)
420*b30d1939SAndy Fiddaman continue;
421*b30d1939SAndy Fiddaman sh.last_table = last_table;
422*b30d1939SAndy Fiddaman if(pp->strsize<0)
423*b30d1939SAndy Fiddaman cp = nv_name(np);
424*b30d1939SAndy Fiddaman else
425*b30d1939SAndy Fiddaman cp = nv_name(mp);
426*b30d1939SAndy Fiddaman stakputs(cp);
427*b30d1939SAndy Fiddaman stakputc('.');
428*b30d1939SAndy Fiddaman stakputs(nq->nvname);
429*b30d1939SAndy Fiddaman stakputc(0);
430*b30d1939SAndy Fiddaman root = nv_dict(mp);
431*b30d1939SAndy Fiddaman save = fp->nofree;
432*b30d1939SAndy Fiddaman fp->nofree = 1;
433*b30d1939SAndy Fiddaman nr = nv_create(stakptr(offset),root,NV_VARNAME|NV_NOADD,fp);
434*b30d1939SAndy Fiddaman fp->nofree = save;
435*b30d1939SAndy Fiddaman stakseek(offset);
436*b30d1939SAndy Fiddaman if(nr)
437*b30d1939SAndy Fiddaman {
438*b30d1939SAndy Fiddaman if(nv_isattr(nq,NV_RDONLY) && (nq->nvalue.cp || nv_isattr(nq,NV_INTEGER)))
439*b30d1939SAndy Fiddaman errormsg(SH_DICT,ERROR_exit(1),e_readonly, nq->nvname);
440*b30d1939SAndy Fiddaman if(nv_isref(nq))
441*b30d1939SAndy Fiddaman nq = nv_refnode(nq);
442*b30d1939SAndy Fiddaman if((size = nv_datasize(nr,(size_t*)0)) && size==nv_datasize(nq,(size_t*)0))
443*b30d1939SAndy Fiddaman memcpy((char*)nq->nvalue.cp,nr->nvalue.cp,size);
444*b30d1939SAndy Fiddaman else if(ap=nv_arrayptr(nr))
445*b30d1939SAndy Fiddaman {
446*b30d1939SAndy Fiddaman nv_putsub(nr,NIL(char*),ARRAY_SCAN|ARRAY_NOSCOPE);
447*b30d1939SAndy Fiddaman do
448*b30d1939SAndy Fiddaman {
449*b30d1939SAndy Fiddaman if(array_assoc(ap))
450*b30d1939SAndy Fiddaman cp = (char*)((*ap->fun)(nr,NIL(char*),NV_ANAME));
451*b30d1939SAndy Fiddaman else
452*b30d1939SAndy Fiddaman cp = nv_getsub(nr);
453*b30d1939SAndy Fiddaman nv_putsub(nq,cp,ARRAY_ADD|ARRAY_NOSCOPE);
454*b30d1939SAndy Fiddaman if(array_assoc(ap))
455*b30d1939SAndy Fiddaman {
456*b30d1939SAndy Fiddaman Namval_t *mp = (Namval_t*)((*ap->fun)(nr,NIL(char*),NV_ACURRENT));
457*b30d1939SAndy Fiddaman Namval_t *mq = (Namval_t*)((*ap->fun)(nq,NIL(char*),NV_ACURRENT));
458*b30d1939SAndy Fiddaman nv_clone(mp,mq,NV_MOVE);
459*b30d1939SAndy Fiddaman ap->nelem--;
460*b30d1939SAndy Fiddaman nv_delete(mp,ap->table,0);
461*b30d1939SAndy Fiddaman }
462*b30d1939SAndy Fiddaman else
463*b30d1939SAndy Fiddaman {
464*b30d1939SAndy Fiddaman cp = nv_getval(nr);
465*b30d1939SAndy Fiddaman nv_putval(nq,cp,0);
466*b30d1939SAndy Fiddaman }
467*b30d1939SAndy Fiddaman }
468*b30d1939SAndy Fiddaman while(nv_nextsub(nr));
469*b30d1939SAndy Fiddaman }
470*b30d1939SAndy Fiddaman else
471*b30d1939SAndy Fiddaman nv_putval(nq,nv_getval(nr),NV_RDONLY);
472*b30d1939SAndy Fiddaman #if SHOPT_TYPEDEF
473*b30d1939SAndy Fiddaman if(sh.mktype)
474*b30d1939SAndy Fiddaman nv_addnode(nr,1);
475*b30d1939SAndy Fiddaman #endif /* SHOPT_TYPEDEF */
476*b30d1939SAndy Fiddaman if(pp->strsize<0)
477*b30d1939SAndy Fiddaman continue;
478*b30d1939SAndy Fiddaman _nv_unset(nr,0);
479*b30d1939SAndy Fiddaman if(!nv_isattr(nr,NV_MINIMAL))
480*b30d1939SAndy Fiddaman nv_delete(nr,sh.last_root,0);
481*b30d1939SAndy Fiddaman }
482*b30d1939SAndy Fiddaman else if(nv_isattr(nq,NV_RDONLY) && !nq->nvalue.cp && !nv_isattr(nq,NV_INTEGER))
483*b30d1939SAndy Fiddaman errormsg(SH_DICT,ERROR_exit(1),e_required,nq->nvname,nv_name(mp));
484*b30d1939SAndy Fiddaman }
485*b30d1939SAndy Fiddaman }
486*b30d1939SAndy Fiddaman if(nv_isattr(mp,NV_BINARY))
487*b30d1939SAndy Fiddaman mp->nvalue.cp = dp->data;
488*b30d1939SAndy Fiddaman if(pp->strsize<0)
489*b30d1939SAndy Fiddaman dp->strsize = -pp->strsize;
490*b30d1939SAndy Fiddaman return(&dp->fun);
491*b30d1939SAndy Fiddaman }
492*b30d1939SAndy Fiddaman
493*b30d1939SAndy Fiddaman
494*b30d1939SAndy Fiddaman /*
495*b30d1939SAndy Fiddaman * return Namval_t* corresponding to child <name> in <np>
496*b30d1939SAndy Fiddaman */
create_type(Namval_t * np,const char * name,int flag,Namfun_t * fp)497*b30d1939SAndy Fiddaman static Namval_t *create_type(Namval_t *np,const char *name,int flag,Namfun_t *fp)
498*b30d1939SAndy Fiddaman {
499*b30d1939SAndy Fiddaman Namtype_t *dp = (Namtype_t*)fp;
500*b30d1939SAndy Fiddaman register const char *cp=name;
501*b30d1939SAndy Fiddaman register int i=0,n;
502*b30d1939SAndy Fiddaman Namval_t *nq=0;
503*b30d1939SAndy Fiddaman if(!name)
504*b30d1939SAndy Fiddaman return(dp->parent);
505*b30d1939SAndy Fiddaman while((n=*cp++) && n != '=' && n != '+' && n!='[');
506*b30d1939SAndy Fiddaman n = (cp-1) -name;
507*b30d1939SAndy Fiddaman if(dp->numnodes && dp->strsize<0)
508*b30d1939SAndy Fiddaman {
509*b30d1939SAndy Fiddaman char *base = (char*)np-sizeof(Dtlink_t);
510*b30d1939SAndy Fiddaman int m=strlen(np->nvname);
511*b30d1939SAndy Fiddaman while((nq=nv_namptr(base,++i)) && memcmp(nq->nvname,np->nvname,m)==0)
512*b30d1939SAndy Fiddaman {
513*b30d1939SAndy Fiddaman if(nq->nvname[m]=='.' && memcmp(name,&nq->nvname[m+1],n)==0 && nq->nvname[m+n+1]==0)
514*b30d1939SAndy Fiddaman goto found;
515*b30d1939SAndy Fiddaman }
516*b30d1939SAndy Fiddaman nq = 0;
517*b30d1939SAndy Fiddaman }
518*b30d1939SAndy Fiddaman else for(i=0; i < dp->numnodes; i++)
519*b30d1939SAndy Fiddaman {
520*b30d1939SAndy Fiddaman nq = nv_namptr(dp->nodes,i);
521*b30d1939SAndy Fiddaman if((n==0||memcmp(name,nq->nvname,n)==0) && nq->nvname[n]==0)
522*b30d1939SAndy Fiddaman {
523*b30d1939SAndy Fiddaman while(nv_isref(nq))
524*b30d1939SAndy Fiddaman nq = nq->nvalue.nrp->np;
525*b30d1939SAndy Fiddaman goto found;
526*b30d1939SAndy Fiddaman }
527*b30d1939SAndy Fiddaman }
528*b30d1939SAndy Fiddaman nq = 0;
529*b30d1939SAndy Fiddaman found:
530*b30d1939SAndy Fiddaman if(nq)
531*b30d1939SAndy Fiddaman {
532*b30d1939SAndy Fiddaman fp->last = (char*)&name[n];
533*b30d1939SAndy Fiddaman sh.last_table = dp->parent;
534*b30d1939SAndy Fiddaman }
535*b30d1939SAndy Fiddaman else
536*b30d1939SAndy Fiddaman {
537*b30d1939SAndy Fiddaman if(name[n]!='=') for(i=0; i < dp->ndisc; i++)
538*b30d1939SAndy Fiddaman {
539*b30d1939SAndy Fiddaman if((memcmp(name,dp->names[i],n)==0) && dp->names[i][n]==0)
540*b30d1939SAndy Fiddaman return(nq);
541*b30d1939SAndy Fiddaman }
542*b30d1939SAndy Fiddaman errormsg(SH_DICT,ERROR_exit(1),e_notelem,n,name,nv_name(np));
543*b30d1939SAndy Fiddaman }
544*b30d1939SAndy Fiddaman return(nq);
545*b30d1939SAndy Fiddaman }
546*b30d1939SAndy Fiddaman
put_type(Namval_t * np,const char * val,int flag,Namfun_t * fp)547*b30d1939SAndy Fiddaman static void put_type(Namval_t* np, const char* val, int flag, Namfun_t* fp)
548*b30d1939SAndy Fiddaman {
549*b30d1939SAndy Fiddaman Namval_t *nq;
550*b30d1939SAndy Fiddaman if(val && (nq=nv_open(val,sh.var_tree,NV_VARNAME|NV_ARRAY|NV_NOADD|NV_NOFAIL)))
551*b30d1939SAndy Fiddaman {
552*b30d1939SAndy Fiddaman Namfun_t *pp;
553*b30d1939SAndy Fiddaman if((pp=nv_hasdisc(nq,fp->disc)) && pp->type==fp->type)
554*b30d1939SAndy Fiddaman
555*b30d1939SAndy Fiddaman {
556*b30d1939SAndy Fiddaman if(!nq->nvenv)
557*b30d1939SAndy Fiddaman flag |= NV_EXPORT;
558*b30d1939SAndy Fiddaman _nv_unset(np, flag);
559*b30d1939SAndy Fiddaman nv_clone(nq,np,NV_IARRAY);
560*b30d1939SAndy Fiddaman return;
561*b30d1939SAndy Fiddaman }
562*b30d1939SAndy Fiddaman }
563*b30d1939SAndy Fiddaman nv_putv(np,val,flag,fp);
564*b30d1939SAndy Fiddaman if(!val)
565*b30d1939SAndy Fiddaman {
566*b30d1939SAndy Fiddaman Namtype_t *dp = (Namtype_t*)fp;
567*b30d1939SAndy Fiddaman Namval_t *nq;
568*b30d1939SAndy Fiddaman Namarr_t *ap;
569*b30d1939SAndy Fiddaman int i;
570*b30d1939SAndy Fiddaman if(nv_isarray(np) && (ap=nv_arrayptr(np)) && ap->nelem>0)
571*b30d1939SAndy Fiddaman return;
572*b30d1939SAndy Fiddaman for(i=0; i < dp->numnodes; i++)
573*b30d1939SAndy Fiddaman {
574*b30d1939SAndy Fiddaman nq = nv_namptr(dp->nodes,i);
575*b30d1939SAndy Fiddaman if(ap=nv_arrayptr(nq))
576*b30d1939SAndy Fiddaman ap->nelem |= ARRAY_UNDEF;
577*b30d1939SAndy Fiddaman if(!nv_hasdisc(nq,&type_disc))
578*b30d1939SAndy Fiddaman _nv_unset(nq,flag|NV_TYPE|nv_isattr(nq,NV_RDONLY));
579*b30d1939SAndy Fiddaman }
580*b30d1939SAndy Fiddaman nv_disc(np,fp,NV_POP);
581*b30d1939SAndy Fiddaman if(!(fp->nofree&1))
582*b30d1939SAndy Fiddaman free((void*)fp);
583*b30d1939SAndy Fiddaman }
584*b30d1939SAndy Fiddaman }
585*b30d1939SAndy Fiddaman
next_type(register Namval_t * np,Dt_t * root,Namfun_t * fp)586*b30d1939SAndy Fiddaman static Namval_t *next_type(register Namval_t* np, Dt_t *root,Namfun_t *fp)
587*b30d1939SAndy Fiddaman {
588*b30d1939SAndy Fiddaman Namtype_t *dp = (Namtype_t*)fp;
589*b30d1939SAndy Fiddaman if(!root)
590*b30d1939SAndy Fiddaman {
591*b30d1939SAndy Fiddaman Namarr_t *ap = nv_arrayptr(np);
592*b30d1939SAndy Fiddaman if(ap && (ap->nelem&ARRAY_UNDEF))
593*b30d1939SAndy Fiddaman nv_putsub(np,(char*)0,ARRAY_SCAN);
594*b30d1939SAndy Fiddaman dp->current = 0;
595*b30d1939SAndy Fiddaman }
596*b30d1939SAndy Fiddaman else if(++dp->current>=dp->numnodes)
597*b30d1939SAndy Fiddaman return(0);
598*b30d1939SAndy Fiddaman return(nv_namptr(dp->nodes,dp->current));
599*b30d1939SAndy Fiddaman }
600*b30d1939SAndy Fiddaman
clone_inttype(Namval_t * np,Namval_t * mp,int flags,Namfun_t * fp)601*b30d1939SAndy Fiddaman static Namfun_t *clone_inttype(Namval_t* np, Namval_t *mp, int flags, Namfun_t *fp)
602*b30d1939SAndy Fiddaman {
603*b30d1939SAndy Fiddaman Namfun_t *pp= (Namfun_t*)malloc(fp->dsize);
604*b30d1939SAndy Fiddaman memcpy((void*)pp, (void*)fp, fp->dsize);
605*b30d1939SAndy Fiddaman fp->nofree &= ~1;
606*b30d1939SAndy Fiddaman if(nv_isattr(mp,NV_NOFREE) && mp->nvalue.cp)
607*b30d1939SAndy Fiddaman memcpy((void*)mp->nvalue.cp,np->nvalue.cp, fp->dsize-sizeof(*fp));
608*b30d1939SAndy Fiddaman else
609*b30d1939SAndy Fiddaman mp->nvalue.cp = (char*)(fp+1);
610*b30d1939SAndy Fiddaman if(!nv_isattr(mp,NV_MINIMAL))
611*b30d1939SAndy Fiddaman mp->nvenv = 0;
612*b30d1939SAndy Fiddaman nv_offattr(mp,NV_RDONLY);
613*b30d1939SAndy Fiddaman return(pp);
614*b30d1939SAndy Fiddaman }
615*b30d1939SAndy Fiddaman
typeinfo(Opt_t * op,Sfio_t * out,const char * str,Optdisc_t * fp)616*b30d1939SAndy Fiddaman static int typeinfo(Opt_t* op, Sfio_t *out, const char *str, Optdisc_t *fp)
617*b30d1939SAndy Fiddaman {
618*b30d1939SAndy Fiddaman char *cp,**help,buffer[256];
619*b30d1939SAndy Fiddaman Namtype_t *dp;
620*b30d1939SAndy Fiddaman Namval_t *np,*nq,*tp;
621*b30d1939SAndy Fiddaman int n, i, offset=staktell();
622*b30d1939SAndy Fiddaman Sfio_t *sp;
623*b30d1939SAndy Fiddaman
624*b30d1939SAndy Fiddaman np = *(Namval_t**)(fp+1);
625*b30d1939SAndy Fiddaman stakputs(NV_CLASS);
626*b30d1939SAndy Fiddaman stakputc('.');
627*b30d1939SAndy Fiddaman stakputs(np->nvname);
628*b30d1939SAndy Fiddaman stakputc(0);
629*b30d1939SAndy Fiddaman np = nv_open(cp=stakptr(offset), sh.var_tree, NV_NOADD|NV_VARNAME);
630*b30d1939SAndy Fiddaman stakseek(offset);
631*b30d1939SAndy Fiddaman if(!np)
632*b30d1939SAndy Fiddaman {
633*b30d1939SAndy Fiddaman sfprintf(sfstderr,"%s: no such variable\n",cp);
634*b30d1939SAndy Fiddaman return(-1);
635*b30d1939SAndy Fiddaman }
636*b30d1939SAndy Fiddaman if(!(dp=(Namtype_t*)nv_hasdisc(np,&type_disc)))
637*b30d1939SAndy Fiddaman {
638*b30d1939SAndy Fiddaman Namfun_t *fp;
639*b30d1939SAndy Fiddaman for(fp=np->nvfun;fp;fp=fp->next)
640*b30d1939SAndy Fiddaman {
641*b30d1939SAndy Fiddaman if(fp->disc && fp->disc->clonef==clone_inttype)
642*b30d1939SAndy Fiddaman break;
643*b30d1939SAndy Fiddaman }
644*b30d1939SAndy Fiddaman if(!fp)
645*b30d1939SAndy Fiddaman {
646*b30d1939SAndy Fiddaman sfprintf(sfstderr,"%s: not a type\n",np->nvname);
647*b30d1939SAndy Fiddaman return(-1);
648*b30d1939SAndy Fiddaman }
649*b30d1939SAndy Fiddaman if(strcmp(str,"other")==0)
650*b30d1939SAndy Fiddaman return(0);
651*b30d1939SAndy Fiddaman tp = fp->type;
652*b30d1939SAndy Fiddaman nv_offattr(np,NV_RDONLY);
653*b30d1939SAndy Fiddaman fp->type = 0;
654*b30d1939SAndy Fiddaman if(np->nvenv)
655*b30d1939SAndy Fiddaman sfprintf(out,"[+?\b%s\b is a %s.]\n", tp->nvname, np->nvenv);
656*b30d1939SAndy Fiddaman cp = (char*)out->_next;
657*b30d1939SAndy Fiddaman sfprintf(out,"[+?\b%s\b is a %n ", tp->nvname, &i);
658*b30d1939SAndy Fiddaman nv_attribute(np,out,(char*)0, 1);
659*b30d1939SAndy Fiddaman if(cp[i+1]=='i')
660*b30d1939SAndy Fiddaman cp[i-1]='n';
661*b30d1939SAndy Fiddaman fp->type = tp;
662*b30d1939SAndy Fiddaman nv_onattr(np,NV_RDONLY);
663*b30d1939SAndy Fiddaman sfprintf(out," with default value \b%s\b.]",nv_getval(np));
664*b30d1939SAndy Fiddaman return(0);
665*b30d1939SAndy Fiddaman }
666*b30d1939SAndy Fiddaman if(strcmp(str,"other")==0)
667*b30d1939SAndy Fiddaman {
668*b30d1939SAndy Fiddaman Nambfun_t *bp;
669*b30d1939SAndy Fiddaman if(bp=(Nambfun_t*)nv_hasdisc(np,nv_discfun(NV_DCADD)))
670*b30d1939SAndy Fiddaman {
671*b30d1939SAndy Fiddaman for(i=0; i < bp->num; i++)
672*b30d1939SAndy Fiddaman {
673*b30d1939SAndy Fiddaman if(nv_isattr(bp->bltins[i],NV_OPTGET))
674*b30d1939SAndy Fiddaman sfprintf(out,"\b%s.%s\b(3), ",np->nvname,bp->bnames[i]);
675*b30d1939SAndy Fiddaman }
676*b30d1939SAndy Fiddaman }
677*b30d1939SAndy Fiddaman return(0);
678*b30d1939SAndy Fiddaman }
679*b30d1939SAndy Fiddaman help = &dp->names[dp->ndisc];
680*b30d1939SAndy Fiddaman sp = sfnew((Sfio_t*)0,buffer,sizeof(buffer),-1,SF_STRING|SF_WRITE);
681*b30d1939SAndy Fiddaman sfprintf(out,"[+?\b%s\b defines the following fields:]{\n",np->nvname);
682*b30d1939SAndy Fiddaman for(i=0; i < dp->numnodes; i++)
683*b30d1939SAndy Fiddaman {
684*b30d1939SAndy Fiddaman nq = nv_namptr(dp->nodes,i);
685*b30d1939SAndy Fiddaman if(tp=nv_type(nq))
686*b30d1939SAndy Fiddaman {
687*b30d1939SAndy Fiddaman Namfun_t *pp = nv_hasdisc(nq,&type_disc);
688*b30d1939SAndy Fiddaman sfprintf(out,"\t[+%s?%s.\n",nq->nvname,tp->nvname);
689*b30d1939SAndy Fiddaman n = strlen(nq->nvname);
690*b30d1939SAndy Fiddaman while((cp=nv_namptr(dp->nodes,i+1)->nvname) && memcmp(cp,nq->nvname,n)==0 && cp[n]=='.')
691*b30d1939SAndy Fiddaman i++;
692*b30d1939SAndy Fiddaman }
693*b30d1939SAndy Fiddaman else
694*b30d1939SAndy Fiddaman {
695*b30d1939SAndy Fiddaman sfseek(sp,(Sfoff_t)0, SEEK_SET);
696*b30d1939SAndy Fiddaman nv_attribute(nq,sp,(char*)0,1);
697*b30d1939SAndy Fiddaman cp = 0;
698*b30d1939SAndy Fiddaman if(!nv_isattr(nq,NV_REF))
699*b30d1939SAndy Fiddaman cp = sh_fmtq(nv_getval(nq));
700*b30d1939SAndy Fiddaman sfputc(sp,0);
701*b30d1939SAndy Fiddaman for(n=strlen(buffer); n>0 && buffer[n-1]==' '; n--);
702*b30d1939SAndy Fiddaman buffer[n] = 0;
703*b30d1939SAndy Fiddaman if(cp)
704*b30d1939SAndy Fiddaman sfprintf(out,"\t[+%s?%s, default value is %s.\n",nq->nvname,*buffer?buffer:"string",cp);
705*b30d1939SAndy Fiddaman else
706*b30d1939SAndy Fiddaman sfprintf(out,"\t[+%s?%s.\n",nq->nvname,*buffer?buffer:"string");
707*b30d1939SAndy Fiddaman }
708*b30d1939SAndy Fiddaman if(help[i])
709*b30d1939SAndy Fiddaman sfprintf(out," %s.",help[i]);
710*b30d1939SAndy Fiddaman sfputc(out,']');
711*b30d1939SAndy Fiddaman }
712*b30d1939SAndy Fiddaman sfprintf(out,"}\n");
713*b30d1939SAndy Fiddaman if(dp->ndisc>0)
714*b30d1939SAndy Fiddaman {
715*b30d1939SAndy Fiddaman stakseek(offset);
716*b30d1939SAndy Fiddaman stakputs(NV_CLASS);
717*b30d1939SAndy Fiddaman stakputc('.');
718*b30d1939SAndy Fiddaman stakputs(np->nvname);
719*b30d1939SAndy Fiddaman stakputc('.');
720*b30d1939SAndy Fiddaman n = staktell();
721*b30d1939SAndy Fiddaman sfprintf(out,"[+?\b%s\b defines the following discipline functions:]{\n",np->nvname);
722*b30d1939SAndy Fiddaman for(i=0; i < dp->ndisc; i++)
723*b30d1939SAndy Fiddaman {
724*b30d1939SAndy Fiddaman stakputs(dp->names[i]);
725*b30d1939SAndy Fiddaman stakputc(0);
726*b30d1939SAndy Fiddaman cp = 0;
727*b30d1939SAndy Fiddaman if((nq = nv_search(stakptr(offset),sh.fun_tree,0)) && nq->nvalue.cp)
728*b30d1939SAndy Fiddaman cp = nq->nvalue.rp->help;
729*b30d1939SAndy Fiddaman if(nq && nv_isattr(nq,NV_STATICF))
730*b30d1939SAndy Fiddaman sfprintf(out,"\t[+%s?:static:%s]\n",dp->names[i],cp?cp:Empty);
731*b30d1939SAndy Fiddaman else
732*b30d1939SAndy Fiddaman sfprintf(out,"\t[+%s?%s]\n",dp->names[i],cp?cp:Empty);
733*b30d1939SAndy Fiddaman if(cp)
734*b30d1939SAndy Fiddaman sfputc(out,'.');
735*b30d1939SAndy Fiddaman stakseek(n);
736*b30d1939SAndy Fiddaman }
737*b30d1939SAndy Fiddaman sfprintf(out,"}\n");
738*b30d1939SAndy Fiddaman }
739*b30d1939SAndy Fiddaman stakseek(offset);
740*b30d1939SAndy Fiddaman sfclose(sp);
741*b30d1939SAndy Fiddaman return(0);
742*b30d1939SAndy Fiddaman }
743*b30d1939SAndy Fiddaman
std_disc(Namval_t * mp,Namtype_t * pp)744*b30d1939SAndy Fiddaman static int std_disc(Namval_t *mp, Namtype_t *pp)
745*b30d1939SAndy Fiddaman {
746*b30d1939SAndy Fiddaman register const char *sp, *cp = strrchr(mp->nvname,'.');
747*b30d1939SAndy Fiddaman register const char **argv;
748*b30d1939SAndy Fiddaman register int i;
749*b30d1939SAndy Fiddaman Namval_t *np=0,*nq;
750*b30d1939SAndy Fiddaman if(cp)
751*b30d1939SAndy Fiddaman cp++;
752*b30d1939SAndy Fiddaman else
753*b30d1939SAndy Fiddaman cp = mp->nvname;
754*b30d1939SAndy Fiddaman if(strcmp(cp,"create")==0)
755*b30d1939SAndy Fiddaman {
756*b30d1939SAndy Fiddaman if(pp)
757*b30d1939SAndy Fiddaman pp->cp = mp;
758*b30d1939SAndy Fiddaman return(0);
759*b30d1939SAndy Fiddaman }
760*b30d1939SAndy Fiddaman for(argv=nv_discnames; sp=*argv; argv++)
761*b30d1939SAndy Fiddaman {
762*b30d1939SAndy Fiddaman if(strcmp(cp,sp)==0)
763*b30d1939SAndy Fiddaman {
764*b30d1939SAndy Fiddaman if(!pp)
765*b30d1939SAndy Fiddaman return(1);
766*b30d1939SAndy Fiddaman goto found;
767*b30d1939SAndy Fiddaman }
768*b30d1939SAndy Fiddaman }
769*b30d1939SAndy Fiddaman return(0);
770*b30d1939SAndy Fiddaman found:
771*b30d1939SAndy Fiddaman if(memcmp(sp=mp->nvname,NV_CLASS,sizeof(NV_CLASS)-1)==0)
772*b30d1939SAndy Fiddaman sp += sizeof(NV_CLASS);
773*b30d1939SAndy Fiddaman sp += strlen(pp->fun.type->nvname)+1;
774*b30d1939SAndy Fiddaman if(sp == cp)
775*b30d1939SAndy Fiddaman np = pp->fun.type;
776*b30d1939SAndy Fiddaman else for(i=1; i < pp->numnodes; i++)
777*b30d1939SAndy Fiddaman {
778*b30d1939SAndy Fiddaman nq = nv_namptr(pp->nodes,i);
779*b30d1939SAndy Fiddaman if(memcmp(nq->nvname, sp, cp-sp-1)==0)
780*b30d1939SAndy Fiddaman {
781*b30d1939SAndy Fiddaman np = nq;
782*b30d1939SAndy Fiddaman break;
783*b30d1939SAndy Fiddaman }
784*b30d1939SAndy Fiddaman }
785*b30d1939SAndy Fiddaman if(np)
786*b30d1939SAndy Fiddaman {
787*b30d1939SAndy Fiddaman nv_onattr(mp,NV_NOFREE);
788*b30d1939SAndy Fiddaman if(!nv_setdisc(np,cp, mp, (Namfun_t*)np))
789*b30d1939SAndy Fiddaman sfprintf(sfstderr," nvsetdisc failed name=%s sp=%s cp=%s\n",np->nvname,sp,cp);
790*b30d1939SAndy Fiddaman }
791*b30d1939SAndy Fiddaman else
792*b30d1939SAndy Fiddaman sfprintf(sfstderr,"can't set discipline %s cp=%s \n",sp,cp);
793*b30d1939SAndy Fiddaman return(1);
794*b30d1939SAndy Fiddaman }
795*b30d1939SAndy Fiddaman
796*b30d1939SAndy Fiddaman
nv_addtype(Namval_t * np,const char * optstr,Optdisc_t * op,size_t optsz)797*b30d1939SAndy Fiddaman void nv_addtype(Namval_t *np, const char *optstr, Optdisc_t *op, size_t optsz)
798*b30d1939SAndy Fiddaman {
799*b30d1939SAndy Fiddaman Namdecl_t *cp = newof((Namdecl_t*)0,Namdecl_t,1,optsz);
800*b30d1939SAndy Fiddaman Optdisc_t *dp = (Optdisc_t*)(cp+1);
801*b30d1939SAndy Fiddaman Shell_t *shp = sh_getinterp();
802*b30d1939SAndy Fiddaman Namval_t *mp,*bp;
803*b30d1939SAndy Fiddaman char *name;
804*b30d1939SAndy Fiddaman if(optstr)
805*b30d1939SAndy Fiddaman cp->optstring = optstr;
806*b30d1939SAndy Fiddaman else
807*b30d1939SAndy Fiddaman cp->optstring = sh_opttype;
808*b30d1939SAndy Fiddaman memcpy((void*)dp,(void*)op, optsz);
809*b30d1939SAndy Fiddaman cp->optinfof = (void*)dp;
810*b30d1939SAndy Fiddaman cp->tp = np;
811*b30d1939SAndy Fiddaman mp = nv_search("typeset",shp->bltin_tree,0);
812*b30d1939SAndy Fiddaman if(name=strrchr(np->nvname,'.'))
813*b30d1939SAndy Fiddaman name++;
814*b30d1939SAndy Fiddaman else
815*b30d1939SAndy Fiddaman name = np->nvname;
816*b30d1939SAndy Fiddaman #if SHOPT_NAMESPACE
817*b30d1939SAndy Fiddaman if(bp=(Namval_t*)shp->namespace)
818*b30d1939SAndy Fiddaman {
819*b30d1939SAndy Fiddaman Namtype_t *tp = (Namtype_t*)nv_hasdisc(np, &type_disc);
820*b30d1939SAndy Fiddaman if(tp)
821*b30d1939SAndy Fiddaman tp->nsp = bp;
822*b30d1939SAndy Fiddaman if(!shp->strbuf2)
823*b30d1939SAndy Fiddaman shp->strbuf2 = sfstropen();
824*b30d1939SAndy Fiddaman sfprintf(shp->strbuf2,".%s.%s%c\n",nv_name(bp)+1,name,0);
825*b30d1939SAndy Fiddaman name = sfstruse(shp->strbuf2);
826*b30d1939SAndy Fiddaman }
827*b30d1939SAndy Fiddaman #endif /* SHOPT_NAMESPACE */
828*b30d1939SAndy Fiddaman if((bp=nv_search(name,shp->fun_tree,NV_NOSCOPE)) && !bp->nvalue.ip)
829*b30d1939SAndy Fiddaman nv_delete(bp,shp->fun_tree,0);
830*b30d1939SAndy Fiddaman bp = sh_addbuiltin(name, (Shbltin_f)mp->nvalue.bfp, (void*)cp);
831*b30d1939SAndy Fiddaman nv_onattr(bp,nv_isattr(mp,NV_PUBLIC));
832*b30d1939SAndy Fiddaman nv_onattr(np, NV_RDONLY);
833*b30d1939SAndy Fiddaman }
834*b30d1939SAndy Fiddaman
nv_newtype(Namval_t * mp)835*b30d1939SAndy Fiddaman void nv_newtype(Namval_t *mp)
836*b30d1939SAndy Fiddaman {
837*b30d1939SAndy Fiddaman struct {
838*b30d1939SAndy Fiddaman Optdisc_t opt;
839*b30d1939SAndy Fiddaman Namval_t *np;
840*b30d1939SAndy Fiddaman } optdisc;
841*b30d1939SAndy Fiddaman memset(&optdisc,0,sizeof(optdisc));
842*b30d1939SAndy Fiddaman optdisc.opt.infof = typeinfo;
843*b30d1939SAndy Fiddaman optdisc.np = mp;
844*b30d1939SAndy Fiddaman nv_addtype(mp,sh_opttype, &optdisc.opt, sizeof(optdisc));
845*b30d1939SAndy Fiddaman }
846*b30d1939SAndy Fiddaman
847*b30d1939SAndy Fiddaman /*
848*b30d1939SAndy Fiddaman * This function creates a type out of the <numnodes> nodes in the
849*b30d1939SAndy Fiddaman * array <nodes>. The first node is the name for the type
850*b30d1939SAndy Fiddaman */
nv_mktype(Namval_t ** nodes,int numnodes)851*b30d1939SAndy Fiddaman Namval_t *nv_mktype(Namval_t **nodes, int numnodes)
852*b30d1939SAndy Fiddaman {
853*b30d1939SAndy Fiddaman Namval_t *mp=nodes[0], *bp=0, *np, *nq, **mnodes=nodes;
854*b30d1939SAndy Fiddaman int i,j,k,m,n,nd=0,nref=0,iref=0,inherit=0;
855*b30d1939SAndy Fiddaman int size=sizeof(NV_DATA), dsize=0, nnodes;
856*b30d1939SAndy Fiddaman size_t offset=0;
857*b30d1939SAndy Fiddaman char *name=0, *cp, *sp, **help;
858*b30d1939SAndy Fiddaman Namtype_t *pp,*qp=0,*dp,*tp;
859*b30d1939SAndy Fiddaman Dt_t *root = nv_dict(mp);
860*b30d1939SAndy Fiddaman struct Namref *nrp = 0;
861*b30d1939SAndy Fiddaman Namfun_t *fp;
862*b30d1939SAndy Fiddaman m = strlen(mp->nvname)+1;
863*b30d1939SAndy Fiddaman if(numnodes < 2)
864*b30d1939SAndy Fiddaman {
865*b30d1939SAndy Fiddaman cp = nodes[0]->nvname;
866*b30d1939SAndy Fiddaman _nv_unset(nodes[0],NV_RDONLY);
867*b30d1939SAndy Fiddaman errormsg(SH_DICT,ERROR_exit(1),e_badtypedef,cp);
868*b30d1939SAndy Fiddaman }
869*b30d1939SAndy Fiddaman for(nnodes=1,i=1; i <numnodes; i++)
870*b30d1939SAndy Fiddaman {
871*b30d1939SAndy Fiddaman np=nodes[i];
872*b30d1939SAndy Fiddaman if(is_afunction(np))
873*b30d1939SAndy Fiddaman {
874*b30d1939SAndy Fiddaman if(!std_disc(np, (Namtype_t*)0))
875*b30d1939SAndy Fiddaman {
876*b30d1939SAndy Fiddaman size += strlen(np->nvname+m)+1;
877*b30d1939SAndy Fiddaman if(memcmp(np->nvname,NV_CLASS,sizeof(NV_CLASS)-1)==0)
878*b30d1939SAndy Fiddaman size -= sizeof(NV_CLASS);
879*b30d1939SAndy Fiddaman nd++;
880*b30d1939SAndy Fiddaman }
881*b30d1939SAndy Fiddaman continue;
882*b30d1939SAndy Fiddaman }
883*b30d1939SAndy Fiddaman if(nv_isattr(np,NV_REF))
884*b30d1939SAndy Fiddaman iref++;
885*b30d1939SAndy Fiddaman if(np->nvenv)
886*b30d1939SAndy Fiddaman size += strlen((char*)np->nvenv)+1;
887*b30d1939SAndy Fiddaman if(strcmp(&np->nvname[m],NV_DATA)==0 && !nv_type(np))
888*b30d1939SAndy Fiddaman continue;
889*b30d1939SAndy Fiddaman if(qp)
890*b30d1939SAndy Fiddaman { /* delete duplicates */
891*b30d1939SAndy Fiddaman for(j=0; j < qp->numnodes;j++)
892*b30d1939SAndy Fiddaman {
893*b30d1939SAndy Fiddaman nq = nv_namptr(qp->nodes,j);
894*b30d1939SAndy Fiddaman if(strcmp(nq->nvname,&np->nvname[m])==0)
895*b30d1939SAndy Fiddaman break;
896*b30d1939SAndy Fiddaman }
897*b30d1939SAndy Fiddaman if(j < qp->numnodes)
898*b30d1939SAndy Fiddaman continue;
899*b30d1939SAndy Fiddaman }
900*b30d1939SAndy Fiddaman nnodes++;
901*b30d1939SAndy Fiddaman if(name && memcmp(&name[m],&np->nvname[m],n)==0 && np->nvname[m+n]=='.')
902*b30d1939SAndy Fiddaman offset -= sizeof(char*);
903*b30d1939SAndy Fiddaman dsize = nv_datasize(np,&offset);
904*b30d1939SAndy Fiddaman if(!nv_isarray(np) && (dp=(Namtype_t*)nv_hasdisc(np, &type_disc)))
905*b30d1939SAndy Fiddaman {
906*b30d1939SAndy Fiddaman nnodes += dp->numnodes;
907*b30d1939SAndy Fiddaman if((n=dp->strsize)<0)
908*b30d1939SAndy Fiddaman n = -n;
909*b30d1939SAndy Fiddaman iref = nref += dp->nref;
910*b30d1939SAndy Fiddaman if(np->nvname[m]=='_' && np->nvname[m+1]==0 && (bp=nv_type(np)))
911*b30d1939SAndy Fiddaman {
912*b30d1939SAndy Fiddaman qp = dp;
913*b30d1939SAndy Fiddaman nd = dp->ndisc;
914*b30d1939SAndy Fiddaman nnodes = dp->numnodes;
915*b30d1939SAndy Fiddaman offset = 0;
916*b30d1939SAndy Fiddaman dsize = nv_size(np);
917*b30d1939SAndy Fiddaman size += n;
918*b30d1939SAndy Fiddaman }
919*b30d1939SAndy Fiddaman else
920*b30d1939SAndy Fiddaman size += n + dp->numnodes*(strlen(&np->nvname[m])+1);
921*b30d1939SAndy Fiddaman n = strlen(np->nvname);
922*b30d1939SAndy Fiddaman while((i+1) < numnodes && (cp=nodes[i+1]->nvname) && memcmp(cp,np->nvname,n)==0 && cp[n]=='.')
923*b30d1939SAndy Fiddaman i++;
924*b30d1939SAndy Fiddaman }
925*b30d1939SAndy Fiddaman else if(nv_isattr(np,NV_REF))
926*b30d1939SAndy Fiddaman nref++;
927*b30d1939SAndy Fiddaman offset += (dsize?dsize:4);
928*b30d1939SAndy Fiddaman size += (n=strlen(name=np->nvname)-m+1);
929*b30d1939SAndy Fiddaman }
930*b30d1939SAndy Fiddaman offset = roundof(offset,sizeof(char*));
931*b30d1939SAndy Fiddaman nv_setsize(mp,offset);
932*b30d1939SAndy Fiddaman k = roundof(sizeof(Namtype_t),sizeof(Sfdouble_t)) - sizeof(Namtype_t);
933*b30d1939SAndy Fiddaman pp = newof(NiL, Namtype_t, 1, nnodes*NV_MINSZ + offset + size + (nnodes+nd)*sizeof(char*) + iref*sizeof(struct Namref)+k);
934*b30d1939SAndy Fiddaman pp->fun.dsize = sizeof(Namtype_t)+nnodes*NV_MINSZ +offset+k;
935*b30d1939SAndy Fiddaman pp->fun.type = mp;
936*b30d1939SAndy Fiddaman pp->parent = nv_lastdict();
937*b30d1939SAndy Fiddaman pp->np = mp;
938*b30d1939SAndy Fiddaman pp->bp = bp;
939*b30d1939SAndy Fiddaman pp->childfun.fun.disc = &chtype_disc;
940*b30d1939SAndy Fiddaman pp->childfun.fun.nofree = 1;
941*b30d1939SAndy Fiddaman pp->childfun.ttype = pp;
942*b30d1939SAndy Fiddaman pp->childfun.ptype = pp;
943*b30d1939SAndy Fiddaman pp->fun.disc = &type_disc;
944*b30d1939SAndy Fiddaman pp->nodes = (char*)(pp+1);
945*b30d1939SAndy Fiddaman pp->numnodes = nnodes;
946*b30d1939SAndy Fiddaman pp->data = pp->nodes + nnodes*NV_MINSZ +k;
947*b30d1939SAndy Fiddaman pp->dsize = offset;
948*b30d1939SAndy Fiddaman nrp = (struct Namref*)(pp->data+offset);
949*b30d1939SAndy Fiddaman pp->names = (char**)(nrp+iref);
950*b30d1939SAndy Fiddaman help = &pp->names[nd];
951*b30d1939SAndy Fiddaman pp->strsize = size;
952*b30d1939SAndy Fiddaman cp = (char*)&pp->names[nd+nnodes];
953*b30d1939SAndy Fiddaman if(qp)
954*b30d1939SAndy Fiddaman mnodes = newof(NiL, Namval_t*, nd+1, 0);
955*b30d1939SAndy Fiddaman nd = 0;
956*b30d1939SAndy Fiddaman nq = nv_namptr(pp->nodes,0);
957*b30d1939SAndy Fiddaman nq->nvname = cp;
958*b30d1939SAndy Fiddaman nv_onattr(nq,NV_MINIMAL);
959*b30d1939SAndy Fiddaman cp = strcopy(cp,NV_DATA);
960*b30d1939SAndy Fiddaman *cp++ = 0;
961*b30d1939SAndy Fiddaman for(name=0, offset=0, k=i=1; i < numnodes; i++)
962*b30d1939SAndy Fiddaman {
963*b30d1939SAndy Fiddaman np=nodes[i];
964*b30d1939SAndy Fiddaman if(is_afunction(np))
965*b30d1939SAndy Fiddaman {
966*b30d1939SAndy Fiddaman sp = np->nvname+m;
967*b30d1939SAndy Fiddaman if(memcmp(np->nvname,NV_CLASS,sizeof(NV_CLASS)-1)==0)
968*b30d1939SAndy Fiddaman sp += sizeof(NV_CLASS);
969*b30d1939SAndy Fiddaman if(!std_disc(np, pp))
970*b30d1939SAndy Fiddaman {
971*b30d1939SAndy Fiddaman /* see if discipline already defined */
972*b30d1939SAndy Fiddaman for(j=0; j< nd; j++)
973*b30d1939SAndy Fiddaman {
974*b30d1939SAndy Fiddaman if(strcmp(sp,pp->names[j])==0)
975*b30d1939SAndy Fiddaman {
976*b30d1939SAndy Fiddaman mnodes[j] = nodes[i];
977*b30d1939SAndy Fiddaman break;
978*b30d1939SAndy Fiddaman }
979*b30d1939SAndy Fiddaman }
980*b30d1939SAndy Fiddaman if(j>=nd)
981*b30d1939SAndy Fiddaman {
982*b30d1939SAndy Fiddaman pp->names[nd] = cp;
983*b30d1939SAndy Fiddaman mnodes[nd++] = nodes[i];
984*b30d1939SAndy Fiddaman cp = strcopy(cp,sp);
985*b30d1939SAndy Fiddaman *cp++ = 0;
986*b30d1939SAndy Fiddaman }
987*b30d1939SAndy Fiddaman nv_onattr(mnodes[j],NV_NOFREE);
988*b30d1939SAndy Fiddaman }
989*b30d1939SAndy Fiddaman continue;
990*b30d1939SAndy Fiddaman }
991*b30d1939SAndy Fiddaman if(inherit)
992*b30d1939SAndy Fiddaman {
993*b30d1939SAndy Fiddaman for(j=0; j < k ; j++)
994*b30d1939SAndy Fiddaman {
995*b30d1939SAndy Fiddaman nq = nv_namptr(pp->nodes,j);
996*b30d1939SAndy Fiddaman if(strcmp(nq->nvname,&np->nvname[m])==0)
997*b30d1939SAndy Fiddaman break;
998*b30d1939SAndy Fiddaman }
999*b30d1939SAndy Fiddaman if(j < k)
1000*b30d1939SAndy Fiddaman {
1001*b30d1939SAndy Fiddaman sp = nv_getval(np);
1002*b30d1939SAndy Fiddaman if(nv_isvtree(np))
1003*b30d1939SAndy Fiddaman sfprintf(sfstderr,"initialization not implemented\n");
1004*b30d1939SAndy Fiddaman else if(sp)
1005*b30d1939SAndy Fiddaman nv_putval(nq,sp,0);
1006*b30d1939SAndy Fiddaman goto skip;
1007*b30d1939SAndy Fiddaman }
1008*b30d1939SAndy Fiddaman }
1009*b30d1939SAndy Fiddaman if(strcmp(&np->nvname[m],NV_DATA)==0 && !nv_type(np))
1010*b30d1939SAndy Fiddaman {
1011*b30d1939SAndy Fiddaman char *val=nv_getval(np);
1012*b30d1939SAndy Fiddaman nq = nv_namptr(pp->nodes,0);
1013*b30d1939SAndy Fiddaman nq->nvfun = 0;
1014*b30d1939SAndy Fiddaman nv_putval(nq,(val?val:0),nv_isattr(np,~(NV_IMPORT|NV_EXPORT|NV_ARRAY)));
1015*b30d1939SAndy Fiddaman nq->nvflag = np->nvflag|NV_NOFREE|NV_MINIMAL;
1016*b30d1939SAndy Fiddaman goto skip;
1017*b30d1939SAndy Fiddaman }
1018*b30d1939SAndy Fiddaman if(qp)
1019*b30d1939SAndy Fiddaman {
1020*b30d1939SAndy Fiddaman Nambfun_t *bp;
1021*b30d1939SAndy Fiddaman dp = (Namtype_t*)nv_hasdisc(nv_type(np), &type_disc);
1022*b30d1939SAndy Fiddaman memcpy(pp->nodes,dp->nodes,dp->numnodes*NV_MINSZ);
1023*b30d1939SAndy Fiddaman offset = nv_size(np);
1024*b30d1939SAndy Fiddaman memcpy(pp->data,dp->data,offset);
1025*b30d1939SAndy Fiddaman for(k=0;k < dp->numnodes; k++)
1026*b30d1939SAndy Fiddaman {
1027*b30d1939SAndy Fiddaman Namval_t *nr = nv_namptr(qp->nodes,k);
1028*b30d1939SAndy Fiddaman nq = nv_namptr(pp->nodes,k);
1029*b30d1939SAndy Fiddaman if(fixnode(pp,dp,k,nrp,0))
1030*b30d1939SAndy Fiddaman {
1031*b30d1939SAndy Fiddaman nrp++;
1032*b30d1939SAndy Fiddaman nq = nq->nvalue.nrp->np;
1033*b30d1939SAndy Fiddaman }
1034*b30d1939SAndy Fiddaman if(!nv_isattr(nr,NV_REF) && !nv_hasdisc(nr,&type_disc))
1035*b30d1939SAndy Fiddaman {
1036*b30d1939SAndy Fiddaman if(nr->nvsize)
1037*b30d1939SAndy Fiddaman memcpy((char*)nq->nvalue.cp,nr->nvalue.cp,size=nv_datasize(nr,(size_t*)0));
1038*b30d1939SAndy Fiddaman else
1039*b30d1939SAndy Fiddaman {
1040*b30d1939SAndy Fiddaman nq->nvalue.cp = nr->nvalue.cp;
1041*b30d1939SAndy Fiddaman nv_onattr(nq,NV_NOFREE);
1042*b30d1939SAndy Fiddaman }
1043*b30d1939SAndy Fiddaman }
1044*b30d1939SAndy Fiddaman }
1045*b30d1939SAndy Fiddaman if(bp=(Nambfun_t*)nv_hasdisc(np,nv_discfun(NV_DCADD)))
1046*b30d1939SAndy Fiddaman {
1047*b30d1939SAndy Fiddaman for(j=0; j < bp->num; j++)
1048*b30d1939SAndy Fiddaman {
1049*b30d1939SAndy Fiddaman pp->names[nd++] = (char*)bp->bnames[j];
1050*b30d1939SAndy Fiddaman mnodes[j] = bp->bltins[j];
1051*b30d1939SAndy Fiddaman }
1052*b30d1939SAndy Fiddaman }
1053*b30d1939SAndy Fiddaman qp = 0;
1054*b30d1939SAndy Fiddaman inherit=1;
1055*b30d1939SAndy Fiddaman goto skip;
1056*b30d1939SAndy Fiddaman }
1057*b30d1939SAndy Fiddaman nq = nv_namptr(pp->nodes,k);
1058*b30d1939SAndy Fiddaman if(np->nvenv)
1059*b30d1939SAndy Fiddaman {
1060*b30d1939SAndy Fiddaman /* need to save the string pointer */
1061*b30d1939SAndy Fiddaman nv_offattr(np,NV_EXPORT);
1062*b30d1939SAndy Fiddaman help[k] = cp;
1063*b30d1939SAndy Fiddaman cp = strcopy(cp,np->nvenv);
1064*b30d1939SAndy Fiddaman j = *help[k];
1065*b30d1939SAndy Fiddaman if(islower(j))
1066*b30d1939SAndy Fiddaman *help[k] = toupper(j);
1067*b30d1939SAndy Fiddaman *cp++ = 0;
1068*b30d1939SAndy Fiddaman np->nvenv = 0;
1069*b30d1939SAndy Fiddaman }
1070*b30d1939SAndy Fiddaman nq->nvname = cp;
1071*b30d1939SAndy Fiddaman if(name && memcmp(name,&np->nvname[m],n)==0 && np->nvname[m+n]=='.')
1072*b30d1939SAndy Fiddaman offset -= sizeof(char*);
1073*b30d1939SAndy Fiddaman dsize = nv_datasize(np,&offset);
1074*b30d1939SAndy Fiddaman cp = strcopy(name=cp, &np->nvname[m]);
1075*b30d1939SAndy Fiddaman n = cp-name;
1076*b30d1939SAndy Fiddaman *cp++ = 0;
1077*b30d1939SAndy Fiddaman nq->nvsize = np->nvsize;
1078*b30d1939SAndy Fiddaman nq->nvflag = (np->nvflag&~(NV_IMPORT|NV_EXPORT))|NV_NOFREE|NV_MINIMAL;
1079*b30d1939SAndy Fiddaman if(dp = (Namtype_t*)nv_hasdisc(np, &type_disc))
1080*b30d1939SAndy Fiddaman {
1081*b30d1939SAndy Fiddaman int r,kfirst=k;
1082*b30d1939SAndy Fiddaman char *cname = &np->nvname[m];
1083*b30d1939SAndy Fiddaman /*
1084*b30d1939SAndy Fiddaman * If field is a type, mark the type by setting
1085*b30d1939SAndy Fiddaman * strsize<0. This changes create_type()
1086*b30d1939SAndy Fiddaman */
1087*b30d1939SAndy Fiddaman clone_all_disc(np,nq,NV_RDONLY);
1088*b30d1939SAndy Fiddaman if(nv_isarray(np))
1089*b30d1939SAndy Fiddaman {
1090*b30d1939SAndy Fiddaman nv_disc(nq, &pp->childfun.fun, NV_LAST);
1091*b30d1939SAndy Fiddaman k++;
1092*b30d1939SAndy Fiddaman goto skip;
1093*b30d1939SAndy Fiddaman }
1094*b30d1939SAndy Fiddaman if(fp=nv_hasdisc(nq,&chtype_disc))
1095*b30d1939SAndy Fiddaman nv_disc(nq, &pp->childfun.fun, NV_LAST);
1096*b30d1939SAndy Fiddaman if(tp = (Namtype_t*)nv_hasdisc(nq, &type_disc))
1097*b30d1939SAndy Fiddaman tp->strsize = -tp->strsize;
1098*b30d1939SAndy Fiddaman else sfprintf(sfstderr,"tp==NULL\n");
1099*b30d1939SAndy Fiddaman for(r=0; r < dp->numnodes; r++)
1100*b30d1939SAndy Fiddaman {
1101*b30d1939SAndy Fiddaman Namval_t *nr = nv_namptr(dp->nodes,r);
1102*b30d1939SAndy Fiddaman nq = nv_namptr(pp->nodes,++k);
1103*b30d1939SAndy Fiddaman nq->nvname = cp;
1104*b30d1939SAndy Fiddaman dsize = nv_datasize(nr,&offset);
1105*b30d1939SAndy Fiddaman nq->nvflag = nr->nvflag;
1106*b30d1939SAndy Fiddaman if(nr->nvalue.cp)
1107*b30d1939SAndy Fiddaman {
1108*b30d1939SAndy Fiddaman Namchld_t *xp = (Namchld_t*)nv_hasdisc(nr,&chtype_disc);
1109*b30d1939SAndy Fiddaman if(xp && nr->nvalue.cp >= xp->ptype->data && nr->nvalue.cp < xp->ptype->data+xp->ptype->fun.dsize)
1110*b30d1939SAndy Fiddaman {
1111*b30d1939SAndy Fiddaman nq->nvalue.cp = pp->data+offset;
1112*b30d1939SAndy Fiddaman memcpy((char*)nq->nvalue.cp,nr->nvalue.cp,dsize);
1113*b30d1939SAndy Fiddaman nv_onattr(nq,NV_NOFREE);
1114*b30d1939SAndy Fiddaman }
1115*b30d1939SAndy Fiddaman else
1116*b30d1939SAndy Fiddaman nq->nvalue.cp = strdup(nr->nvalue.cp);
1117*b30d1939SAndy Fiddaman nv_disc(nq, &pp->childfun.fun, NV_LAST);
1118*b30d1939SAndy Fiddaman }
1119*b30d1939SAndy Fiddaman nq->nvsize = nr->nvsize;
1120*b30d1939SAndy Fiddaman offset += dsize;
1121*b30d1939SAndy Fiddaman if(*cname!='_' || cname[1])
1122*b30d1939SAndy Fiddaman {
1123*b30d1939SAndy Fiddaman cp = strcopy(cp,cname);
1124*b30d1939SAndy Fiddaman *cp++ = '.';
1125*b30d1939SAndy Fiddaman }
1126*b30d1939SAndy Fiddaman cp = strcopy(cp,nr->nvname);
1127*b30d1939SAndy Fiddaman *cp++ = 0;
1128*b30d1939SAndy Fiddaman }
1129*b30d1939SAndy Fiddaman while((i+1) < numnodes && (cname=&nodes[i+1]->nvname[m]) && memcmp(cname,&np->nvname[m],n)==0 && cname[n]=='.')
1130*b30d1939SAndy Fiddaman {
1131*b30d1939SAndy Fiddaman int j=kfirst;
1132*b30d1939SAndy Fiddaman nv_unset(np);
1133*b30d1939SAndy Fiddaman nv_delete(np,root,0);
1134*b30d1939SAndy Fiddaman np = nodes[++i];
1135*b30d1939SAndy Fiddaman while(j < k)
1136*b30d1939SAndy Fiddaman {
1137*b30d1939SAndy Fiddaman nq = nv_namptr(pp->nodes,++j);
1138*b30d1939SAndy Fiddaman if(strcmp(nq->nvname,cname)==0)
1139*b30d1939SAndy Fiddaman {
1140*b30d1939SAndy Fiddaman sfprintf(sfstderr,"%s found at k=%d\n",nq->nvname,k);
1141*b30d1939SAndy Fiddaman if(nq->nvalue.cp>=pp->data && nq->nvalue.cp< (char*)pp->names)
1142*b30d1939SAndy Fiddaman memcpy((char*)nq->nvalue.cp,np->nvalue.cp,nv_datasize(np,0));
1143*b30d1939SAndy Fiddaman break;
1144*b30d1939SAndy Fiddaman }
1145*b30d1939SAndy Fiddaman }
1146*b30d1939SAndy Fiddaman }
1147*b30d1939SAndy Fiddaman }
1148*b30d1939SAndy Fiddaman else
1149*b30d1939SAndy Fiddaman {
1150*b30d1939SAndy Fiddaman Namarr_t *ap;
1151*b30d1939SAndy Fiddaman j = nv_isattr(np,NV_NOFREE);
1152*b30d1939SAndy Fiddaman if(j==0 && (ap=nv_arrayptr(np)) && !ap->fun)
1153*b30d1939SAndy Fiddaman j = 1;
1154*b30d1939SAndy Fiddaman nq->nvfun = np->nvfun;
1155*b30d1939SAndy Fiddaman np->nvfun = 0;
1156*b30d1939SAndy Fiddaman nv_disc(nq, &pp->childfun.fun, NV_LAST);
1157*b30d1939SAndy Fiddaman if(nq->nvfun)
1158*b30d1939SAndy Fiddaman {
1159*b30d1939SAndy Fiddaman for(fp=nq->nvfun; fp; fp = fp->next)
1160*b30d1939SAndy Fiddaman fp->nofree |= 1;
1161*b30d1939SAndy Fiddaman }
1162*b30d1939SAndy Fiddaman nq->nvalue.cp = np->nvalue.cp;
1163*b30d1939SAndy Fiddaman if(dsize && (np->nvalue.cp || !nv_isarray(np)))
1164*b30d1939SAndy Fiddaman {
1165*b30d1939SAndy Fiddaman nq->nvalue.cp = pp->data+offset;
1166*b30d1939SAndy Fiddaman sp = (char*)np->nvalue.cp;
1167*b30d1939SAndy Fiddaman if(nv_isattr(np,NV_INT16P) ==NV_INT16)
1168*b30d1939SAndy Fiddaman {
1169*b30d1939SAndy Fiddaman sp= (char*)&np->nvalue;
1170*b30d1939SAndy Fiddaman nv_onattr(nq,NV_INT16P);
1171*b30d1939SAndy Fiddaman j = 1;
1172*b30d1939SAndy Fiddaman }
1173*b30d1939SAndy Fiddaman if(sp)
1174*b30d1939SAndy Fiddaman memcpy((char*)nq->nvalue.cp,sp,dsize);
1175*b30d1939SAndy Fiddaman else if(nv_isattr(np,NV_LJUST|NV_RJUST))
1176*b30d1939SAndy Fiddaman memset((char*)nq->nvalue.cp,' ',dsize);
1177*b30d1939SAndy Fiddaman if(!j)
1178*b30d1939SAndy Fiddaman free((void*)np->nvalue.cp);
1179*b30d1939SAndy Fiddaman }
1180*b30d1939SAndy Fiddaman if(!nq->nvalue.cp && nq->nvfun== &pp->childfun.fun)
1181*b30d1939SAndy Fiddaman nq->nvalue.cp = Empty;
1182*b30d1939SAndy Fiddaman np->nvalue.cp = 0;
1183*b30d1939SAndy Fiddaman #if 0
1184*b30d1939SAndy Fiddaman offset += dsize;
1185*b30d1939SAndy Fiddaman #else
1186*b30d1939SAndy Fiddaman offset += (dsize?dsize:4);
1187*b30d1939SAndy Fiddaman #endif
1188*b30d1939SAndy Fiddaman }
1189*b30d1939SAndy Fiddaman k++;
1190*b30d1939SAndy Fiddaman skip:
1191*b30d1939SAndy Fiddaman if(!nv_isnull(np))
1192*b30d1939SAndy Fiddaman _nv_unset(np,0);
1193*b30d1939SAndy Fiddaman nv_delete(np,root,0);
1194*b30d1939SAndy Fiddaman }
1195*b30d1939SAndy Fiddaman pp->ndisc = nd;
1196*b30d1939SAndy Fiddaman pp->nref = nref;
1197*b30d1939SAndy Fiddaman if(k>1)
1198*b30d1939SAndy Fiddaman {
1199*b30d1939SAndy Fiddaman nv_setsize(mp,offset);
1200*b30d1939SAndy Fiddaman mp->nvalue.cp = pp->data;
1201*b30d1939SAndy Fiddaman nv_onattr(mp,NV_NOFREE|NV_BINARY|NV_RAW);
1202*b30d1939SAndy Fiddaman }
1203*b30d1939SAndy Fiddaman else if(!mp->nvalue.cp)
1204*b30d1939SAndy Fiddaman mp->nvalue.cp = Empty;
1205*b30d1939SAndy Fiddaman nv_onattr(mp,NV_TAGGED);
1206*b30d1939SAndy Fiddaman nv_disc(mp, &pp->fun, NV_LAST);
1207*b30d1939SAndy Fiddaman if(nd>0)
1208*b30d1939SAndy Fiddaman {
1209*b30d1939SAndy Fiddaman pp->names[nd] = 0;
1210*b30d1939SAndy Fiddaman nv_adddisc(mp, (const char**)pp->names, mnodes);
1211*b30d1939SAndy Fiddaman }
1212*b30d1939SAndy Fiddaman if(mnodes!=nodes)
1213*b30d1939SAndy Fiddaman free((void*)mnodes);
1214*b30d1939SAndy Fiddaman nv_newtype(mp);
1215*b30d1939SAndy Fiddaman return(mp);
1216*b30d1939SAndy Fiddaman }
1217*b30d1939SAndy Fiddaman
nv_mkinttype(char * name,size_t size,int sign,const char * help,Namdisc_t * ep)1218*b30d1939SAndy Fiddaman Namval_t *nv_mkinttype(char *name, size_t size, int sign, const char *help, Namdisc_t *ep)
1219*b30d1939SAndy Fiddaman {
1220*b30d1939SAndy Fiddaman Namval_t *mp;
1221*b30d1939SAndy Fiddaman Namfun_t *fp;
1222*b30d1939SAndy Fiddaman Namdisc_t *dp;
1223*b30d1939SAndy Fiddaman int offset=staktell();
1224*b30d1939SAndy Fiddaman stakputs(NV_CLASS);
1225*b30d1939SAndy Fiddaman stakputc('.');
1226*b30d1939SAndy Fiddaman stakputs(name);
1227*b30d1939SAndy Fiddaman stakputc(0);
1228*b30d1939SAndy Fiddaman mp = nv_open(stakptr(offset), sh.var_tree, NV_VARNAME);
1229*b30d1939SAndy Fiddaman stakseek(offset);
1230*b30d1939SAndy Fiddaman offset = size + sizeof(Namdisc_t);
1231*b30d1939SAndy Fiddaman fp = newof(NiL, Namfun_t, 1, offset);
1232*b30d1939SAndy Fiddaman fp->type = mp;
1233*b30d1939SAndy Fiddaman fp->nofree |= 1;
1234*b30d1939SAndy Fiddaman fp->dsize = sizeof(Namfun_t)+size;
1235*b30d1939SAndy Fiddaman dp = (Namdisc_t*)(fp+1);
1236*b30d1939SAndy Fiddaman if(ep)
1237*b30d1939SAndy Fiddaman *dp = *ep;
1238*b30d1939SAndy Fiddaman dp->clonef = clone_inttype;
1239*b30d1939SAndy Fiddaman fp->disc = dp;
1240*b30d1939SAndy Fiddaman mp->nvalue.cp = (char*)(fp+1) + sizeof(Namdisc_t);
1241*b30d1939SAndy Fiddaman nv_setsize(mp,10);
1242*b30d1939SAndy Fiddaman mp->nvenv = (char*)help;
1243*b30d1939SAndy Fiddaman nv_onattr(mp,NV_NOFREE|NV_RDONLY|NV_INTEGER|NV_EXPORT);
1244*b30d1939SAndy Fiddaman if(size==16)
1245*b30d1939SAndy Fiddaman nv_onattr(mp,NV_INT16P);
1246*b30d1939SAndy Fiddaman else if(size==64)
1247*b30d1939SAndy Fiddaman nv_onattr(mp,NV_INT64);
1248*b30d1939SAndy Fiddaman if(!sign)
1249*b30d1939SAndy Fiddaman nv_onattr(mp,NV_UNSIGN);
1250*b30d1939SAndy Fiddaman nv_disc(mp, fp, NV_LAST);
1251*b30d1939SAndy Fiddaman nv_newtype(mp);
1252*b30d1939SAndy Fiddaman return(mp);
1253*b30d1939SAndy Fiddaman }
1254*b30d1939SAndy Fiddaman
nv_typename(Namval_t * tp,Sfio_t * out)1255*b30d1939SAndy Fiddaman void nv_typename(Namval_t *tp, Sfio_t *out)
1256*b30d1939SAndy Fiddaman {
1257*b30d1939SAndy Fiddaman char *v,*cp;
1258*b30d1939SAndy Fiddaman Namtype_t *dp;
1259*b30d1939SAndy Fiddaman cp = nv_name(tp);
1260*b30d1939SAndy Fiddaman if(v=strrchr(cp,'.'))
1261*b30d1939SAndy Fiddaman cp = v+1;
1262*b30d1939SAndy Fiddaman if((dp = (Namtype_t*)nv_hasdisc(tp,&type_disc)) && dp->bp)
1263*b30d1939SAndy Fiddaman {
1264*b30d1939SAndy Fiddaman nv_typename(dp->bp,out);
1265*b30d1939SAndy Fiddaman sfprintf(out,"%s.%s",sfstruse(out),cp);
1266*b30d1939SAndy Fiddaman }
1267*b30d1939SAndy Fiddaman else
1268*b30d1939SAndy Fiddaman sfputr(out,cp,-1);
1269*b30d1939SAndy Fiddaman }
1270*b30d1939SAndy Fiddaman
nv_type(Namval_t * np)1271*b30d1939SAndy Fiddaman Namval_t *nv_type(Namval_t *np)
1272*b30d1939SAndy Fiddaman {
1273*b30d1939SAndy Fiddaman Namfun_t *fp;
1274*b30d1939SAndy Fiddaman if(nv_isattr(np,NV_BLTIN|BLT_DCL)==(NV_BLTIN|BLT_DCL))
1275*b30d1939SAndy Fiddaman {
1276*b30d1939SAndy Fiddaman Namdecl_t *ntp = (Namdecl_t*)nv_context(np);
1277*b30d1939SAndy Fiddaman return(ntp?ntp->tp:0);
1278*b30d1939SAndy Fiddaman }
1279*b30d1939SAndy Fiddaman for(fp=np->nvfun; fp; fp=fp->next)
1280*b30d1939SAndy Fiddaman {
1281*b30d1939SAndy Fiddaman if(fp->type)
1282*b30d1939SAndy Fiddaman return(fp->type);
1283*b30d1939SAndy Fiddaman if(fp->disc && fp->disc->typef && (np= (*fp->disc->typef)(np,fp)))
1284*b30d1939SAndy Fiddaman return(np);
1285*b30d1939SAndy Fiddaman }
1286*b30d1939SAndy Fiddaman return(0);
1287*b30d1939SAndy Fiddaman }
1288*b30d1939SAndy Fiddaman
1289*b30d1939SAndy Fiddaman /*
1290*b30d1939SAndy Fiddaman * call any and all create functions
1291*b30d1939SAndy Fiddaman */
type_init(Namval_t * np)1292*b30d1939SAndy Fiddaman static void type_init(Namval_t *np)
1293*b30d1939SAndy Fiddaman {
1294*b30d1939SAndy Fiddaman int i;
1295*b30d1939SAndy Fiddaman Namtype_t *dp, *pp=(Namtype_t*)nv_hasdisc(np,&type_disc);
1296*b30d1939SAndy Fiddaman Namval_t *nq;
1297*b30d1939SAndy Fiddaman if(!pp)
1298*b30d1939SAndy Fiddaman return;
1299*b30d1939SAndy Fiddaman for(i=0; i < pp->numnodes; i++)
1300*b30d1939SAndy Fiddaman {
1301*b30d1939SAndy Fiddaman nq = nv_namptr(pp->nodes,i);
1302*b30d1939SAndy Fiddaman if((dp=(Namtype_t*)nv_hasdisc(nq,&type_disc)) && dp->cp)
1303*b30d1939SAndy Fiddaman sh_fun(dp->cp,nq, (char**)0);
1304*b30d1939SAndy Fiddaman }
1305*b30d1939SAndy Fiddaman if(pp->cp)
1306*b30d1939SAndy Fiddaman sh_fun(pp->cp, np, (char**)0);
1307*b30d1939SAndy Fiddaman }
1308*b30d1939SAndy Fiddaman
1309*b30d1939SAndy Fiddaman /*
1310*b30d1939SAndy Fiddaman * This function turns variable <np> to the type <tp>
1311*b30d1939SAndy Fiddaman */
nv_settype(Namval_t * np,Namval_t * tp,int flags)1312*b30d1939SAndy Fiddaman int nv_settype(Namval_t* np, Namval_t *tp, int flags)
1313*b30d1939SAndy Fiddaman {
1314*b30d1939SAndy Fiddaman int isnull = nv_isnull(np);
1315*b30d1939SAndy Fiddaman int rdonly = nv_isattr(np,NV_RDONLY);
1316*b30d1939SAndy Fiddaman char *val=0;
1317*b30d1939SAndy Fiddaman Namarr_t *ap=0;
1318*b30d1939SAndy Fiddaman Shell_t *shp = sh_getinterp();
1319*b30d1939SAndy Fiddaman int nelem=0,subshell=shp->subshell;
1320*b30d1939SAndy Fiddaman #if SHOPT_TYPEDEF
1321*b30d1939SAndy Fiddaman Namval_t *tq;
1322*b30d1939SAndy Fiddaman if(nv_type(np)==tp)
1323*b30d1939SAndy Fiddaman return(0);
1324*b30d1939SAndy Fiddaman if(nv_isarray(np) && (tq=nv_type(np)))
1325*b30d1939SAndy Fiddaman {
1326*b30d1939SAndy Fiddaman if(tp==tq)
1327*b30d1939SAndy Fiddaman return(0);
1328*b30d1939SAndy Fiddaman errormsg(SH_DICT,ERROR_exit(1),e_redef,nv_name(np));
1329*b30d1939SAndy Fiddaman }
1330*b30d1939SAndy Fiddaman if((ap=nv_arrayptr(np)) && ap->nelem>0)
1331*b30d1939SAndy Fiddaman {
1332*b30d1939SAndy Fiddaman nv_putsub(np,NIL(char*),ARRAY_SCAN);
1333*b30d1939SAndy Fiddaman ap->hdr.type = tp;
1334*b30d1939SAndy Fiddaman do
1335*b30d1939SAndy Fiddaman {
1336*b30d1939SAndy Fiddaman nv_arraysettype(np, tp, nv_getsub(np),flags);
1337*b30d1939SAndy Fiddaman }
1338*b30d1939SAndy Fiddaman while(nv_nextsub(np));
1339*b30d1939SAndy Fiddaman }
1340*b30d1939SAndy Fiddaman else if(ap || nv_isarray(np))
1341*b30d1939SAndy Fiddaman {
1342*b30d1939SAndy Fiddaman flags &= ~NV_APPEND;
1343*b30d1939SAndy Fiddaman if(!ap)
1344*b30d1939SAndy Fiddaman {
1345*b30d1939SAndy Fiddaman if(subshell)
1346*b30d1939SAndy Fiddaman {
1347*b30d1939SAndy Fiddaman sh_assignok(np,1);
1348*b30d1939SAndy Fiddaman shp->subshell = 0;
1349*b30d1939SAndy Fiddaman }
1350*b30d1939SAndy Fiddaman nv_putsub(np,"0",ARRAY_FILL);
1351*b30d1939SAndy Fiddaman ap = nv_arrayptr(np);
1352*b30d1939SAndy Fiddaman nelem = 1;
1353*b30d1939SAndy Fiddaman
1354*b30d1939SAndy Fiddaman }
1355*b30d1939SAndy Fiddaman }
1356*b30d1939SAndy Fiddaman else
1357*b30d1939SAndy Fiddaman #endif /*SHOPT_TYPEDEF */
1358*b30d1939SAndy Fiddaman {
1359*b30d1939SAndy Fiddaman if(isnull)
1360*b30d1939SAndy Fiddaman flags &= ~NV_APPEND;
1361*b30d1939SAndy Fiddaman else if(!nv_isvtree(np))
1362*b30d1939SAndy Fiddaman {
1363*b30d1939SAndy Fiddaman val = strdup(nv_getval(np));
1364*b30d1939SAndy Fiddaman if(!(flags&NV_APPEND))
1365*b30d1939SAndy Fiddaman _nv_unset(np, NV_RDONLY);
1366*b30d1939SAndy Fiddaman }
1367*b30d1939SAndy Fiddaman if(!nv_clone(tp,np,flags|NV_NOFREE))
1368*b30d1939SAndy Fiddaman return(0);
1369*b30d1939SAndy Fiddaman }
1370*b30d1939SAndy Fiddaman if(ap)
1371*b30d1939SAndy Fiddaman {
1372*b30d1939SAndy Fiddaman int nofree;
1373*b30d1939SAndy Fiddaman nv_disc(np,&ap->hdr,NV_POP);
1374*b30d1939SAndy Fiddaman np->nvalue.up = 0;
1375*b30d1939SAndy Fiddaman nv_clone(tp,np,flags|NV_NOFREE);
1376*b30d1939SAndy Fiddaman if(np->nvalue.cp && np->nvalue.cp!=Empty && !nv_isattr(np,NV_NOFREE))
1377*b30d1939SAndy Fiddaman free((void*)np->nvalue.cp);
1378*b30d1939SAndy Fiddaman np->nvalue.up = 0;
1379*b30d1939SAndy Fiddaman nofree = ap->hdr.nofree;
1380*b30d1939SAndy Fiddaman ap->hdr.nofree = 0;
1381*b30d1939SAndy Fiddaman ap->hdr.type = tp;
1382*b30d1939SAndy Fiddaman nv_disc(np, &ap->hdr, NV_FIRST);
1383*b30d1939SAndy Fiddaman ap->hdr.nofree = nofree;
1384*b30d1939SAndy Fiddaman nv_onattr(np,NV_ARRAY);
1385*b30d1939SAndy Fiddaman if(nelem)
1386*b30d1939SAndy Fiddaman {
1387*b30d1939SAndy Fiddaman ap->nelem++;
1388*b30d1939SAndy Fiddaman nv_putsub(np,"0",0);
1389*b30d1939SAndy Fiddaman _nv_unset(np,NV_RDONLY|NV_TYPE);
1390*b30d1939SAndy Fiddaman ap->nelem--;
1391*b30d1939SAndy Fiddaman shp->subshell = subshell;
1392*b30d1939SAndy Fiddaman }
1393*b30d1939SAndy Fiddaman }
1394*b30d1939SAndy Fiddaman type_init(np);
1395*b30d1939SAndy Fiddaman if(!rdonly)
1396*b30d1939SAndy Fiddaman nv_offattr(np,NV_RDONLY);
1397*b30d1939SAndy Fiddaman if(val)
1398*b30d1939SAndy Fiddaman {
1399*b30d1939SAndy Fiddaman nv_putval(np,val,NV_RDONLY);
1400*b30d1939SAndy Fiddaman free((void*)val);
1401*b30d1939SAndy Fiddaman }
1402*b30d1939SAndy Fiddaman return(0);
1403*b30d1939SAndy Fiddaman }
1404*b30d1939SAndy Fiddaman
1405*b30d1939SAndy Fiddaman #define S(x) #x
1406*b30d1939SAndy Fiddaman #define FIELD(x,y) { S(y##x), S(x##_t), offsetof(struct stat,st_##y##x) }
1407*b30d1939SAndy Fiddaman typedef struct _field_
1408*b30d1939SAndy Fiddaman {
1409*b30d1939SAndy Fiddaman char *name;
1410*b30d1939SAndy Fiddaman char *type;
1411*b30d1939SAndy Fiddaman int offset;
1412*b30d1939SAndy Fiddaman } Fields_t;
1413*b30d1939SAndy Fiddaman
1414*b30d1939SAndy Fiddaman Fields_t foo[]=
1415*b30d1939SAndy Fiddaman {
1416*b30d1939SAndy Fiddaman FIELD(dev,),
1417*b30d1939SAndy Fiddaman FIELD(ino,),
1418*b30d1939SAndy Fiddaman FIELD(nlink,),
1419*b30d1939SAndy Fiddaman FIELD(mode,),
1420*b30d1939SAndy Fiddaman FIELD(uid,),
1421*b30d1939SAndy Fiddaman FIELD(gid,),
1422*b30d1939SAndy Fiddaman FIELD(size,),
1423*b30d1939SAndy Fiddaman FIELD(time,a),
1424*b30d1939SAndy Fiddaman FIELD(time,m),
1425*b30d1939SAndy Fiddaman FIELD(time,c),
1426*b30d1939SAndy Fiddaman #if 0
1427*b30d1939SAndy Fiddaman FIELD(blksize,),
1428*b30d1939SAndy Fiddaman FIELD(blocks,),
1429*b30d1939SAndy Fiddaman #endif
1430*b30d1939SAndy Fiddaman 0
1431*b30d1939SAndy Fiddaman };
1432*b30d1939SAndy Fiddaman
1433*b30d1939SAndy Fiddaman
nv_mkstruct(const char * name,int rsize,Fields_t * fields)1434*b30d1939SAndy Fiddaman Namval_t *nv_mkstruct(const char *name, int rsize, Fields_t *fields)
1435*b30d1939SAndy Fiddaman {
1436*b30d1939SAndy Fiddaman Namval_t *mp, *nq, *nr, *tp;
1437*b30d1939SAndy Fiddaman Fields_t *fp;
1438*b30d1939SAndy Fiddaman Namtype_t *dp, *pp;
1439*b30d1939SAndy Fiddaman char *cp, *sp;
1440*b30d1939SAndy Fiddaman int nnodes=0, offset=staktell(), n, r, i, j;
1441*b30d1939SAndy Fiddaman size_t m, size=0;
1442*b30d1939SAndy Fiddaman stakputs(NV_CLASS);
1443*b30d1939SAndy Fiddaman stakputc('.');
1444*b30d1939SAndy Fiddaman r = staktell();
1445*b30d1939SAndy Fiddaman stakputs(name);
1446*b30d1939SAndy Fiddaman stakputc(0);
1447*b30d1939SAndy Fiddaman mp = nv_open(stakptr(offset), sh.var_tree, NV_VARNAME);
1448*b30d1939SAndy Fiddaman stakseek(r);
1449*b30d1939SAndy Fiddaman
1450*b30d1939SAndy Fiddaman for(fp=fields; fp->name; fp++)
1451*b30d1939SAndy Fiddaman {
1452*b30d1939SAndy Fiddaman m = strlen(fp->name)+1;
1453*b30d1939SAndy Fiddaman size += m;
1454*b30d1939SAndy Fiddaman nnodes++;
1455*b30d1939SAndy Fiddaman if(memcmp(fp->type,"typeset",7))
1456*b30d1939SAndy Fiddaman {
1457*b30d1939SAndy Fiddaman stakputs(fp->type);
1458*b30d1939SAndy Fiddaman stakputc(0);
1459*b30d1939SAndy Fiddaman tp = nv_open(stakptr(offset), sh.var_tree, NV_VARNAME|NV_NOADD|NV_NOFAIL);
1460*b30d1939SAndy Fiddaman stakseek(r);
1461*b30d1939SAndy Fiddaman if(!tp)
1462*b30d1939SAndy Fiddaman errormsg(SH_DICT,ERROR_exit(1),e_unknowntype,strlen(fp->type),fp->type);
1463*b30d1939SAndy Fiddaman if(dp = (Namtype_t*)nv_hasdisc(tp,&type_disc))
1464*b30d1939SAndy Fiddaman {
1465*b30d1939SAndy Fiddaman nnodes += dp->numnodes;
1466*b30d1939SAndy Fiddaman if((i=dp->strsize) < 0)
1467*b30d1939SAndy Fiddaman i = -i;
1468*b30d1939SAndy Fiddaman size += i + dp->numnodes*m;
1469*b30d1939SAndy Fiddaman }
1470*b30d1939SAndy Fiddaman }
1471*b30d1939SAndy Fiddaman }
1472*b30d1939SAndy Fiddaman pp = newof(NiL,Namtype_t, 1, nnodes*NV_MINSZ + rsize + size);
1473*b30d1939SAndy Fiddaman pp->fun.dsize = sizeof(Namtype_t)+nnodes*NV_MINSZ +rsize;
1474*b30d1939SAndy Fiddaman pp->fun.type = mp;
1475*b30d1939SAndy Fiddaman pp->np = mp;
1476*b30d1939SAndy Fiddaman pp->childfun.fun.disc = &chtype_disc;
1477*b30d1939SAndy Fiddaman pp->childfun.fun.nofree = 1;
1478*b30d1939SAndy Fiddaman pp->childfun.ttype = pp;
1479*b30d1939SAndy Fiddaman pp->childfun.ptype = pp;
1480*b30d1939SAndy Fiddaman pp->fun.disc = &type_disc;
1481*b30d1939SAndy Fiddaman pp->nodes = (char*)(pp+1);
1482*b30d1939SAndy Fiddaman pp->numnodes = nnodes;
1483*b30d1939SAndy Fiddaman pp->strsize = size;
1484*b30d1939SAndy Fiddaman pp->data = pp->nodes + nnodes*NV_MINSZ;
1485*b30d1939SAndy Fiddaman cp = pp->data + rsize;
1486*b30d1939SAndy Fiddaman for(i=0,fp=fields; fp->name; fp++)
1487*b30d1939SAndy Fiddaman {
1488*b30d1939SAndy Fiddaman nq = nv_namptr(pp->nodes,i++);
1489*b30d1939SAndy Fiddaman nq->nvname = cp;
1490*b30d1939SAndy Fiddaman nq->nvalue.cp = pp->data + fp->offset;
1491*b30d1939SAndy Fiddaman nv_onattr(nq,NV_MINIMAL|NV_NOFREE);
1492*b30d1939SAndy Fiddaman m = strlen(fp->name)+1;
1493*b30d1939SAndy Fiddaman memcpy(cp, fp->name, m);
1494*b30d1939SAndy Fiddaman cp += m;
1495*b30d1939SAndy Fiddaman if(memcmp(fp->type,"typeset",7))
1496*b30d1939SAndy Fiddaman {
1497*b30d1939SAndy Fiddaman stakputs(fp->type);
1498*b30d1939SAndy Fiddaman stakputc(0);
1499*b30d1939SAndy Fiddaman tp = nv_open(stakptr(offset), sh.var_tree, NV_VARNAME);
1500*b30d1939SAndy Fiddaman stakseek(r);
1501*b30d1939SAndy Fiddaman clone_all_disc(tp,nq,NV_RDONLY);
1502*b30d1939SAndy Fiddaman nq->nvflag = tp->nvflag|NV_MINIMAL|NV_NOFREE;
1503*b30d1939SAndy Fiddaman nq->nvsize = tp->nvsize;
1504*b30d1939SAndy Fiddaman if(dp = (Namtype_t*)nv_hasdisc(nq,&type_disc))
1505*b30d1939SAndy Fiddaman dp->strsize = -dp->strsize;
1506*b30d1939SAndy Fiddaman if(dp = (Namtype_t*)nv_hasdisc(tp,&type_disc))
1507*b30d1939SAndy Fiddaman {
1508*b30d1939SAndy Fiddaman if(nv_hasdisc(nq,&chtype_disc))
1509*b30d1939SAndy Fiddaman nv_disc(nq, &pp->childfun.fun, NV_LAST);
1510*b30d1939SAndy Fiddaman sp = (char*)nq->nvalue.cp;
1511*b30d1939SAndy Fiddaman memcpy(sp, dp->data, nv_size(tp));
1512*b30d1939SAndy Fiddaman for(j=0; j < dp->numnodes; j++)
1513*b30d1939SAndy Fiddaman {
1514*b30d1939SAndy Fiddaman nr = nv_namptr(dp->nodes,j);
1515*b30d1939SAndy Fiddaman nq = nv_namptr(pp->nodes,i++);
1516*b30d1939SAndy Fiddaman nq->nvname = cp;
1517*b30d1939SAndy Fiddaman memcpy(cp,fp->name,m);
1518*b30d1939SAndy Fiddaman cp[m-1] = '.';
1519*b30d1939SAndy Fiddaman cp += m;
1520*b30d1939SAndy Fiddaman n = strlen(nr->nvname)+1;
1521*b30d1939SAndy Fiddaman memcpy(cp,nr->nvname,n);
1522*b30d1939SAndy Fiddaman cp += n;
1523*b30d1939SAndy Fiddaman if(nr->nvalue.cp>=dp->data && nr->nvalue.cp < (char*)pp + pp->fun.dsize)
1524*b30d1939SAndy Fiddaman {
1525*b30d1939SAndy Fiddaman nq->nvalue.cp = sp + (nr->nvalue.cp-dp->data);
1526*b30d1939SAndy Fiddaman }
1527*b30d1939SAndy Fiddaman nq->nvflag = nr->nvflag;
1528*b30d1939SAndy Fiddaman nq->nvsize = nr->nvsize;
1529*b30d1939SAndy Fiddaman }
1530*b30d1939SAndy Fiddaman }
1531*b30d1939SAndy Fiddaman }
1532*b30d1939SAndy Fiddaman else if(strmatch(fp->type+7,"*-*i*")==0)
1533*b30d1939SAndy Fiddaman {
1534*b30d1939SAndy Fiddaman nv_onattr(nq,NV_NOFREE|NV_RDONLY|NV_INTEGER);
1535*b30d1939SAndy Fiddaman if(strmatch(fp->type+7,"*-*s*")==0)
1536*b30d1939SAndy Fiddaman nv_onattr(nq,NV_INT16P);
1537*b30d1939SAndy Fiddaman else if(strmatch(fp->type+7,"*-*l*")==0)
1538*b30d1939SAndy Fiddaman nv_onattr(nq,NV_INT64);
1539*b30d1939SAndy Fiddaman if(strmatch(fp->type+7,"*-*u*")==0)
1540*b30d1939SAndy Fiddaman nv_onattr(nq,NV_UNSIGN);
1541*b30d1939SAndy Fiddaman }
1542*b30d1939SAndy Fiddaman
1543*b30d1939SAndy Fiddaman }
1544*b30d1939SAndy Fiddaman stakseek(offset);
1545*b30d1939SAndy Fiddaman nv_onattr(mp,NV_RDONLY|NV_NOFREE|NV_BINARY);
1546*b30d1939SAndy Fiddaman nv_setsize(mp,rsize);
1547*b30d1939SAndy Fiddaman nv_disc(mp, &pp->fun, NV_LAST);
1548*b30d1939SAndy Fiddaman mp->nvalue.cp = pp->data;
1549*b30d1939SAndy Fiddaman nv_newtype(mp);
1550*b30d1939SAndy Fiddaman return(mp);
1551*b30d1939SAndy Fiddaman }
1552*b30d1939SAndy Fiddaman
put_stat(Namval_t * np,const char * val,int flag,Namfun_t * nfp)1553*b30d1939SAndy Fiddaman static void put_stat(Namval_t* np, const char* val, int flag, Namfun_t* nfp)
1554*b30d1939SAndy Fiddaman {
1555*b30d1939SAndy Fiddaman if(val)
1556*b30d1939SAndy Fiddaman {
1557*b30d1939SAndy Fiddaman if(stat(val,(struct stat*)np->nvalue.cp)<0)
1558*b30d1939SAndy Fiddaman sfprintf(sfstderr,"stat of %s failed\n",val);
1559*b30d1939SAndy Fiddaman return;
1560*b30d1939SAndy Fiddaman }
1561*b30d1939SAndy Fiddaman nv_putv(np,val,flag,nfp);
1562*b30d1939SAndy Fiddaman nv_disc(np,nfp,NV_POP);
1563*b30d1939SAndy Fiddaman if(!(nfp->nofree&1))
1564*b30d1939SAndy Fiddaman free((void*)nfp);
1565*b30d1939SAndy Fiddaman }
1566*b30d1939SAndy Fiddaman
1567*b30d1939SAndy Fiddaman static const Namdisc_t stat_disc =
1568*b30d1939SAndy Fiddaman {
1569*b30d1939SAndy Fiddaman 0,
1570*b30d1939SAndy Fiddaman put_stat
1571*b30d1939SAndy Fiddaman };
1572*b30d1939SAndy Fiddaman
1573*b30d1939SAndy Fiddaman
nv_mkstat(void)1574*b30d1939SAndy Fiddaman void nv_mkstat(void)
1575*b30d1939SAndy Fiddaman {
1576*b30d1939SAndy Fiddaman Namval_t *tp;
1577*b30d1939SAndy Fiddaman Namfun_t *fp;
1578*b30d1939SAndy Fiddaman tp = nv_mkstruct("stat_t", sizeof(struct stat), foo);
1579*b30d1939SAndy Fiddaman nv_offattr(tp,NV_RDONLY);
1580*b30d1939SAndy Fiddaman nv_setvtree(tp);
1581*b30d1939SAndy Fiddaman fp = newof(NiL,Namfun_t,1,0);
1582*b30d1939SAndy Fiddaman fp->type = tp;
1583*b30d1939SAndy Fiddaman fp->disc = &stat_disc;
1584*b30d1939SAndy Fiddaman nv_disc(tp,fp,NV_FIRST);
1585*b30d1939SAndy Fiddaman nv_putval(tp,e_devnull,0);
1586*b30d1939SAndy Fiddaman nv_onattr(tp,NV_RDONLY);
1587*b30d1939SAndy Fiddaman }
1588*b30d1939SAndy Fiddaman
write_indent(Sfio_t * out,char * str,int n,int indent)1589*b30d1939SAndy Fiddaman static void write_indent(Sfio_t *out,char *str,int n,int indent)
1590*b30d1939SAndy Fiddaman {
1591*b30d1939SAndy Fiddaman register int c, first=1;
1592*b30d1939SAndy Fiddaman register char *cp = str;
1593*b30d1939SAndy Fiddaman while(n-- && (c = *str++))
1594*b30d1939SAndy Fiddaman {
1595*b30d1939SAndy Fiddaman if(c=='\n')
1596*b30d1939SAndy Fiddaman {
1597*b30d1939SAndy Fiddaman if(!first)
1598*b30d1939SAndy Fiddaman sfnputc(out,'\t',indent);
1599*b30d1939SAndy Fiddaman first = 0;
1600*b30d1939SAndy Fiddaman sfwrite(out,cp,str-cp);
1601*b30d1939SAndy Fiddaman cp = str;
1602*b30d1939SAndy Fiddaman }
1603*b30d1939SAndy Fiddaman }
1604*b30d1939SAndy Fiddaman if(cp > str)
1605*b30d1939SAndy Fiddaman {
1606*b30d1939SAndy Fiddaman sfnputc(out,'\t',indent);
1607*b30d1939SAndy Fiddaman sfwrite(out,cp,str-cp);
1608*b30d1939SAndy Fiddaman }
1609*b30d1939SAndy Fiddaman }
1610*b30d1939SAndy Fiddaman
sh_outtype(Shell_t * shp,Sfio_t * out)1611*b30d1939SAndy Fiddaman int sh_outtype(Shell_t *shp,Sfio_t *out)
1612*b30d1939SAndy Fiddaman {
1613*b30d1939SAndy Fiddaman Namval_t node,*mp,*tp;
1614*b30d1939SAndy Fiddaman Dt_t *dp;
1615*b30d1939SAndy Fiddaman char *cp,*sp,*xp,nvtype[sizeof(NV_CLASS)];
1616*b30d1939SAndy Fiddaman Sfio_t *iop=0;
1617*b30d1939SAndy Fiddaman int n=0,indent = 0;
1618*b30d1939SAndy Fiddaman if(cp=shp->prefix)
1619*b30d1939SAndy Fiddaman {
1620*b30d1939SAndy Fiddaman indent=1;
1621*b30d1939SAndy Fiddaman while(*cp)
1622*b30d1939SAndy Fiddaman {
1623*b30d1939SAndy Fiddaman if(*cp++ =='.')
1624*b30d1939SAndy Fiddaman indent++;
1625*b30d1939SAndy Fiddaman }
1626*b30d1939SAndy Fiddaman n = cp-shp->prefix+1;
1627*b30d1939SAndy Fiddaman }
1628*b30d1939SAndy Fiddaman strcpy(nvtype,NV_CLASS);
1629*b30d1939SAndy Fiddaman if(!(mp = nv_open(nvtype, shp->var_base,NV_NOADD|NV_VARNAME)))
1630*b30d1939SAndy Fiddaman return(0);
1631*b30d1939SAndy Fiddaman memcpy(&node,L_ARGNOD,sizeof(node));
1632*b30d1939SAndy Fiddaman L_ARGNOD->nvfun = 0;
1633*b30d1939SAndy Fiddaman L_ARGNOD->nvalue.cp = 0;
1634*b30d1939SAndy Fiddaman dp = nv_dict(mp);
1635*b30d1939SAndy Fiddaman if(indent==0)
1636*b30d1939SAndy Fiddaman for(tp = (Namval_t*)dtfirst(dp); tp; tp = (Namval_t*)dtnext(dp,tp))
1637*b30d1939SAndy Fiddaman {
1638*b30d1939SAndy Fiddaman if(!nv_search(tp->nvname,shp->bltin_tree,0))
1639*b30d1939SAndy Fiddaman continue;
1640*b30d1939SAndy Fiddaman sfprintf(out,"typeset -T %s\n",tp->nvname);
1641*b30d1939SAndy Fiddaman }
1642*b30d1939SAndy Fiddaman for(tp = (Namval_t*)dtfirst(dp); tp; tp = (Namval_t*)dtnext(dp,tp))
1643*b30d1939SAndy Fiddaman {
1644*b30d1939SAndy Fiddaman if(nv_isnull(tp))
1645*b30d1939SAndy Fiddaman continue;
1646*b30d1939SAndy Fiddaman if(indent && (memcmp(tp->nvname,shp->prefix,n-1) || tp->nvname[n-1]!='.' || strchr(tp->nvname+n,'.')))
1647*b30d1939SAndy Fiddaman continue;
1648*b30d1939SAndy Fiddaman nv_settype(L_ARGNOD,tp,0);
1649*b30d1939SAndy Fiddaman if(indent)
1650*b30d1939SAndy Fiddaman sfnputc(out,'\t',indent);
1651*b30d1939SAndy Fiddaman sfprintf(out,"typeset -T %s=",tp->nvname+n);
1652*b30d1939SAndy Fiddaman shp->last_table = 0;
1653*b30d1939SAndy Fiddaman cp = nv_getval(L_ARGNOD);
1654*b30d1939SAndy Fiddaman if(indent)
1655*b30d1939SAndy Fiddaman write_indent(out,cp,strlen(cp)-1,indent);
1656*b30d1939SAndy Fiddaman else
1657*b30d1939SAndy Fiddaman sfprintf(out,"%.*s",strlen(cp)-1,cp);
1658*b30d1939SAndy Fiddaman _nv_unset(L_ARGNOD,NV_RDONLY);
1659*b30d1939SAndy Fiddaman for(sp=0; sp=nv_setdisc(tp,(char*)0,(Namval_t*)sp,(Namfun_t*)tp);)
1660*b30d1939SAndy Fiddaman {
1661*b30d1939SAndy Fiddaman mp = (Namval_t*)nv_setdisc(tp,sp,tp,(Namfun_t*)tp);
1662*b30d1939SAndy Fiddaman if(!mp || mp==tp)
1663*b30d1939SAndy Fiddaman continue;
1664*b30d1939SAndy Fiddaman if(cp=strrchr(mp->nvname,'.'))
1665*b30d1939SAndy Fiddaman cp++;
1666*b30d1939SAndy Fiddaman else
1667*b30d1939SAndy Fiddaman cp = mp->nvname;
1668*b30d1939SAndy Fiddaman if(indent)
1669*b30d1939SAndy Fiddaman sfnputc(out,'\t',indent);
1670*b30d1939SAndy Fiddaman if(nv_isattr(mp,NV_FPOSIX))
1671*b30d1939SAndy Fiddaman sfprintf(out,"\t%s()",cp);
1672*b30d1939SAndy Fiddaman else
1673*b30d1939SAndy Fiddaman sfprintf(out,"\tfunction %s",cp);
1674*b30d1939SAndy Fiddaman xp = 0;
1675*b30d1939SAndy Fiddaman if(mp->nvalue.ip && mp->nvalue.rp->hoffset>=0)
1676*b30d1939SAndy Fiddaman {
1677*b30d1939SAndy Fiddaman if(nv_isattr(mp,NV_FTMP))
1678*b30d1939SAndy Fiddaman iop = shp->heredocs;
1679*b30d1939SAndy Fiddaman else if(xp=mp->nvalue.rp->fname)
1680*b30d1939SAndy Fiddaman iop = sfopen(iop,xp,"r");
1681*b30d1939SAndy Fiddaman else if(shp->gd->hist_ptr)
1682*b30d1939SAndy Fiddaman iop = (shp->gd->hist_ptr)->histfp;
1683*b30d1939SAndy Fiddaman if(iop && sfseek(iop,(Sfoff_t)mp->nvalue.rp->hoffset,SEEK_SET)>=0)
1684*b30d1939SAndy Fiddaman sfmove(iop,out, nv_size(mp), -1);
1685*b30d1939SAndy Fiddaman else
1686*b30d1939SAndy Fiddaman sfputc(iop,'\n');
1687*b30d1939SAndy Fiddaman if(xp)
1688*b30d1939SAndy Fiddaman sfclose(iop);
1689*b30d1939SAndy Fiddaman if(nv_isattr(mp,NV_STATICF|NV_TAGGED))
1690*b30d1939SAndy Fiddaman {
1691*b30d1939SAndy Fiddaman if(indent)
1692*b30d1939SAndy Fiddaman sfnputc(out,'\t',indent);
1693*b30d1939SAndy Fiddaman sfwrite(out,"\ttypeset -f",11);
1694*b30d1939SAndy Fiddaman if(nv_isattr(mp,NV_STATICF))
1695*b30d1939SAndy Fiddaman sfputc(out,'S');
1696*b30d1939SAndy Fiddaman if(nv_isattr(mp,NV_TAGGED))
1697*b30d1939SAndy Fiddaman sfputc(out,'t');
1698*b30d1939SAndy Fiddaman if(mp->nvalue.rp->help)
1699*b30d1939SAndy Fiddaman sfprintf(out,"h '%s'",mp->nvalue.rp->help);
1700*b30d1939SAndy Fiddaman sfprintf(out," %s\n",cp);
1701*b30d1939SAndy Fiddaman }
1702*b30d1939SAndy Fiddaman iop = 0;
1703*b30d1939SAndy Fiddaman }
1704*b30d1939SAndy Fiddaman }
1705*b30d1939SAndy Fiddaman if(indent)
1706*b30d1939SAndy Fiddaman sfnputc(out,'\t',indent);
1707*b30d1939SAndy Fiddaman sfwrite(out,")\n",2);
1708*b30d1939SAndy Fiddaman }
1709*b30d1939SAndy Fiddaman dtdelete(shp->var_base,L_ARGNOD);
1710*b30d1939SAndy Fiddaman memcpy(L_ARGNOD,&node,sizeof(node));
1711*b30d1939SAndy Fiddaman dtinsert(shp->var_base,L_ARGNOD);
1712*b30d1939SAndy Fiddaman return(0);
1713*b30d1939SAndy Fiddaman }
1714