xref: /illumos-gate/usr/src/contrib/ast/src/cmd/ksh93/sh/nvtype.c (revision b30d193948be5a7794d7ae3ba0ed9c2f72c88e0f)
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