xref: /illumos-gate/usr/src/contrib/ast/src/cmd/ksh93/bltins/typeset.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  * export [-p] [arg...]
23*b30d1939SAndy Fiddaman  * readonly [-p] [arg...]
24*b30d1939SAndy Fiddaman  * typeset [options]  [arg...]
25*b30d1939SAndy Fiddaman  * alias [-ptx] [arg...]
26*b30d1939SAndy Fiddaman  * unalias [arg...]
27*b30d1939SAndy Fiddaman  * builtin [-sd] [-f file] [name...]
28*b30d1939SAndy Fiddaman  * set [options] [name...]
29*b30d1939SAndy Fiddaman  * unset [-fnv] [name...]
30*b30d1939SAndy Fiddaman  *
31*b30d1939SAndy Fiddaman  *   David Korn
32*b30d1939SAndy Fiddaman  *   AT&T Labs
33*b30d1939SAndy Fiddaman  *
34*b30d1939SAndy Fiddaman  */
35*b30d1939SAndy Fiddaman 
36*b30d1939SAndy Fiddaman #include	"defs.h"
37*b30d1939SAndy Fiddaman #include	<error.h>
38*b30d1939SAndy Fiddaman #include	"path.h"
39*b30d1939SAndy Fiddaman #include	"name.h"
40*b30d1939SAndy Fiddaman #include	"history.h"
41*b30d1939SAndy Fiddaman #include	"builtins.h"
42*b30d1939SAndy Fiddaman #include	"variables.h"
43*b30d1939SAndy Fiddaman #include	"FEATURE/dynamic"
44*b30d1939SAndy Fiddaman 
45*b30d1939SAndy Fiddaman struct tdata
46*b30d1939SAndy Fiddaman {
47*b30d1939SAndy Fiddaman 	Shell_t 	*sh;
48*b30d1939SAndy Fiddaman 	Namval_t	*tp;
49*b30d1939SAndy Fiddaman 	const char	*wctname;
50*b30d1939SAndy Fiddaman 	Sfio_t  	*outfile;
51*b30d1939SAndy Fiddaman 	char    	*prefix;
52*b30d1939SAndy Fiddaman 	char    	*tname;
53*b30d1939SAndy Fiddaman 	char		*help;
54*b30d1939SAndy Fiddaman 	short     	aflag;
55*b30d1939SAndy Fiddaman 	short     	pflag;
56*b30d1939SAndy Fiddaman 	int     	argnum;
57*b30d1939SAndy Fiddaman 	int     	scanmask;
58*b30d1939SAndy Fiddaman 	Dt_t 		*scanroot;
59*b30d1939SAndy Fiddaman 	char    	**argnam;
60*b30d1939SAndy Fiddaman 	int		indent;
61*b30d1939SAndy Fiddaman 	int		noref;
62*b30d1939SAndy Fiddaman };
63*b30d1939SAndy Fiddaman 
64*b30d1939SAndy Fiddaman 
65*b30d1939SAndy Fiddaman static int	print_namval(Sfio_t*, Namval_t*, int, struct tdata*);
66*b30d1939SAndy Fiddaman static void	print_attribute(Namval_t*,void*);
67*b30d1939SAndy Fiddaman static void	print_all(Sfio_t*, Dt_t*, struct tdata*);
68*b30d1939SAndy Fiddaman static void	print_scan(Sfio_t*, int, Dt_t*, int, struct tdata*);
69*b30d1939SAndy Fiddaman static int	unall(int, char**, Dt_t*, Shell_t*);
70*b30d1939SAndy Fiddaman static int	setall(char**, int, Dt_t*, struct tdata*);
71*b30d1939SAndy Fiddaman static void	pushname(Namval_t*,void*);
72*b30d1939SAndy Fiddaman static void(*nullscan)(Namval_t*,void*);
73*b30d1939SAndy Fiddaman 
load_class(const char * name)74*b30d1939SAndy Fiddaman static Namval_t *load_class(const char *name)
75*b30d1939SAndy Fiddaman {
76*b30d1939SAndy Fiddaman 	errormsg(SH_DICT,ERROR_exit(1),"%s: type not loadable",name);
77*b30d1939SAndy Fiddaman 	return(0);
78*b30d1939SAndy Fiddaman }
79*b30d1939SAndy Fiddaman 
80*b30d1939SAndy Fiddaman /*
81*b30d1939SAndy Fiddaman  * Note export and readonly are the same
82*b30d1939SAndy Fiddaman  */
83*b30d1939SAndy Fiddaman #if 0
84*b30d1939SAndy Fiddaman     /* for the dictionary generator */
85*b30d1939SAndy Fiddaman     int    b_export(int argc,char *argv[],Shbltin_t *context){}
86*b30d1939SAndy Fiddaman #endif
b_readonly(int argc,char * argv[],Shbltin_t * context)87*b30d1939SAndy Fiddaman int    b_readonly(int argc,char *argv[],Shbltin_t *context)
88*b30d1939SAndy Fiddaman {
89*b30d1939SAndy Fiddaman 	register int flag;
90*b30d1939SAndy Fiddaman 	char *command = argv[0];
91*b30d1939SAndy Fiddaman 	struct tdata tdata;
92*b30d1939SAndy Fiddaman 	NOT_USED(argc);
93*b30d1939SAndy Fiddaman 	memset((void*)&tdata,0,sizeof(tdata));
94*b30d1939SAndy Fiddaman 	tdata.sh = context->shp;
95*b30d1939SAndy Fiddaman 	tdata.aflag = '-';
96*b30d1939SAndy Fiddaman 	while((flag = optget(argv,*command=='e'?sh_optexport:sh_optreadonly))) switch(flag)
97*b30d1939SAndy Fiddaman 	{
98*b30d1939SAndy Fiddaman 		case 'p':
99*b30d1939SAndy Fiddaman 			tdata.prefix = command;
100*b30d1939SAndy Fiddaman 			break;
101*b30d1939SAndy Fiddaman 		case ':':
102*b30d1939SAndy Fiddaman 			errormsg(SH_DICT,2, "%s", opt_info.arg);
103*b30d1939SAndy Fiddaman 			break;
104*b30d1939SAndy Fiddaman 		case '?':
105*b30d1939SAndy Fiddaman 			errormsg(SH_DICT,ERROR_usage(0), "%s", opt_info.arg);
106*b30d1939SAndy Fiddaman 			return(2);
107*b30d1939SAndy Fiddaman 	}
108*b30d1939SAndy Fiddaman 	if(error_info.errors)
109*b30d1939SAndy Fiddaman 		errormsg(SH_DICT,ERROR_usage(2),optusage(NIL(char*)));
110*b30d1939SAndy Fiddaman 	argv += (opt_info.index-1);
111*b30d1939SAndy Fiddaman 	if(*command=='r')
112*b30d1939SAndy Fiddaman 		flag = (NV_ASSIGN|NV_RDONLY|NV_VARNAME);
113*b30d1939SAndy Fiddaman #ifdef _ENV_H
114*b30d1939SAndy Fiddaman 	else if(!argv[1])
115*b30d1939SAndy Fiddaman 	{
116*b30d1939SAndy Fiddaman 		char *cp,**env=env_get(tdata.sh->env);
117*b30d1939SAndy Fiddaman 		while(cp = *env++)
118*b30d1939SAndy Fiddaman 		{
119*b30d1939SAndy Fiddaman 			if(tdata.prefix)
120*b30d1939SAndy Fiddaman 				sfputr(sfstdout,tdata.prefix,' ');
121*b30d1939SAndy Fiddaman 			sfprintf(sfstdout,"%s\n",sh_fmtq(cp));
122*b30d1939SAndy Fiddaman 		}
123*b30d1939SAndy Fiddaman 		return(0);
124*b30d1939SAndy Fiddaman 	}
125*b30d1939SAndy Fiddaman #endif
126*b30d1939SAndy Fiddaman 	else
127*b30d1939SAndy Fiddaman 	{
128*b30d1939SAndy Fiddaman 		flag = (NV_ASSIGN|NV_EXPORT|NV_IDENT);
129*b30d1939SAndy Fiddaman 		if(!tdata.sh->prefix)
130*b30d1939SAndy Fiddaman 			tdata.sh->prefix = "";
131*b30d1939SAndy Fiddaman 	}
132*b30d1939SAndy Fiddaman 	return(setall(argv,flag,tdata.sh->var_tree, &tdata));
133*b30d1939SAndy Fiddaman }
134*b30d1939SAndy Fiddaman 
135*b30d1939SAndy Fiddaman 
b_alias(int argc,register char * argv[],Shbltin_t * context)136*b30d1939SAndy Fiddaman int    b_alias(int argc,register char *argv[],Shbltin_t *context)
137*b30d1939SAndy Fiddaman {
138*b30d1939SAndy Fiddaman 	register unsigned flag = NV_NOARRAY|NV_NOSCOPE|NV_ASSIGN;
139*b30d1939SAndy Fiddaman 	register Dt_t *troot;
140*b30d1939SAndy Fiddaman 	register int n;
141*b30d1939SAndy Fiddaman 	struct tdata tdata;
142*b30d1939SAndy Fiddaman 	NOT_USED(argc);
143*b30d1939SAndy Fiddaman 	memset((void*)&tdata,0,sizeof(tdata));
144*b30d1939SAndy Fiddaman 	tdata.sh = context->shp;
145*b30d1939SAndy Fiddaman 	troot = tdata.sh->alias_tree;
146*b30d1939SAndy Fiddaman 	if(*argv[0]=='h')
147*b30d1939SAndy Fiddaman 		flag = NV_TAGGED;
148*b30d1939SAndy Fiddaman 	if(argv[1])
149*b30d1939SAndy Fiddaman 	{
150*b30d1939SAndy Fiddaman 		opt_info.offset = 0;
151*b30d1939SAndy Fiddaman 		opt_info.index = 1;
152*b30d1939SAndy Fiddaman 		*opt_info.option = 0;
153*b30d1939SAndy Fiddaman 		tdata.argnum = 0;
154*b30d1939SAndy Fiddaman 		tdata.aflag = *argv[1];
155*b30d1939SAndy Fiddaman 		while((n = optget(argv,sh_optalias))) switch(n)
156*b30d1939SAndy Fiddaman 		{
157*b30d1939SAndy Fiddaman 		    case 'p':
158*b30d1939SAndy Fiddaman 			tdata.prefix = argv[0];
159*b30d1939SAndy Fiddaman 			break;
160*b30d1939SAndy Fiddaman 		    case 't':
161*b30d1939SAndy Fiddaman 			flag |= NV_TAGGED;
162*b30d1939SAndy Fiddaman 			break;
163*b30d1939SAndy Fiddaman 		    case 'x':
164*b30d1939SAndy Fiddaman 			flag |= NV_EXPORT;
165*b30d1939SAndy Fiddaman 			break;
166*b30d1939SAndy Fiddaman 		    case ':':
167*b30d1939SAndy Fiddaman 			errormsg(SH_DICT,2, "%s", opt_info.arg);
168*b30d1939SAndy Fiddaman 			break;
169*b30d1939SAndy Fiddaman 		    case '?':
170*b30d1939SAndy Fiddaman 			errormsg(SH_DICT,ERROR_usage(0), "%s", opt_info.arg);
171*b30d1939SAndy Fiddaman 			return(2);
172*b30d1939SAndy Fiddaman 		}
173*b30d1939SAndy Fiddaman 		if(error_info.errors)
174*b30d1939SAndy Fiddaman 			errormsg(SH_DICT,ERROR_usage(2),"%s",optusage(NIL(char*)));
175*b30d1939SAndy Fiddaman 		argv += (opt_info.index-1);
176*b30d1939SAndy Fiddaman 		if(flag&NV_TAGGED)
177*b30d1939SAndy Fiddaman 		{
178*b30d1939SAndy Fiddaman 			/* hacks to handle hash -r | -- */
179*b30d1939SAndy Fiddaman 			if(argv[1] && argv[1][0]=='-')
180*b30d1939SAndy Fiddaman 			{
181*b30d1939SAndy Fiddaman 				if(argv[1][1]=='r' && argv[1][2]==0)
182*b30d1939SAndy Fiddaman 				{
183*b30d1939SAndy Fiddaman 					Namval_t *np = nv_search((char*)PATHNOD,tdata.sh->var_tree,HASH_BUCKET);
184*b30d1939SAndy Fiddaman 					nv_putval(np,nv_getval(np),NV_RDONLY);
185*b30d1939SAndy Fiddaman 					argv++;
186*b30d1939SAndy Fiddaman 					if(!argv[1])
187*b30d1939SAndy Fiddaman 						return(0);
188*b30d1939SAndy Fiddaman 				}
189*b30d1939SAndy Fiddaman 				if(argv[1][0]=='-')
190*b30d1939SAndy Fiddaman 				{
191*b30d1939SAndy Fiddaman 					if(argv[1][1]=='-' && argv[1][2]==0)
192*b30d1939SAndy Fiddaman 						argv++;
193*b30d1939SAndy Fiddaman 					else
194*b30d1939SAndy Fiddaman 						errormsg(SH_DICT, ERROR_exit(1), e_option, argv[1]);
195*b30d1939SAndy Fiddaman 		}
196*b30d1939SAndy Fiddaman 			}
197*b30d1939SAndy Fiddaman 			troot = tdata.sh->track_tree;
198*b30d1939SAndy Fiddaman 		}
199*b30d1939SAndy Fiddaman 	}
200*b30d1939SAndy Fiddaman 	return(setall(argv,flag,troot,&tdata));
201*b30d1939SAndy Fiddaman }
202*b30d1939SAndy Fiddaman 
203*b30d1939SAndy Fiddaman 
204*b30d1939SAndy Fiddaman #if 0
205*b30d1939SAndy Fiddaman     /* for the dictionary generator */
206*b30d1939SAndy Fiddaman     int    b_local(int argc,char *argv[],Shbltin_t *context){}
207*b30d1939SAndy Fiddaman #endif
b_typeset(int argc,register char * argv[],Shbltin_t * context)208*b30d1939SAndy Fiddaman int    b_typeset(int argc,register char *argv[],Shbltin_t *context)
209*b30d1939SAndy Fiddaman {
210*b30d1939SAndy Fiddaman 	register int	n, flag = NV_VARNAME|NV_ASSIGN;
211*b30d1939SAndy Fiddaman 	struct tdata	tdata;
212*b30d1939SAndy Fiddaman 	const char	*optstring = sh_opttypeset;
213*b30d1939SAndy Fiddaman 	Namdecl_t 	*ntp = (Namdecl_t*)context->ptr;
214*b30d1939SAndy Fiddaman 	Dt_t		*troot;
215*b30d1939SAndy Fiddaman 	int		isfloat=0, shortint=0, sflag=0;
216*b30d1939SAndy Fiddaman 	NOT_USED(argc);
217*b30d1939SAndy Fiddaman 	memset((void*)&tdata,0,sizeof(tdata));
218*b30d1939SAndy Fiddaman 	tdata.sh = context->shp;
219*b30d1939SAndy Fiddaman 	if(ntp)
220*b30d1939SAndy Fiddaman 	{
221*b30d1939SAndy Fiddaman 		tdata.tp = ntp->tp;
222*b30d1939SAndy Fiddaman 		opt_info.disc = (Optdisc_t*)ntp->optinfof;
223*b30d1939SAndy Fiddaman 		optstring = ntp->optstring;
224*b30d1939SAndy Fiddaman 	}
225*b30d1939SAndy Fiddaman 	troot = tdata.sh->var_tree;
226*b30d1939SAndy Fiddaman 	while((n = optget(argv,optstring)))
227*b30d1939SAndy Fiddaman 	{
228*b30d1939SAndy Fiddaman 		if(tdata.aflag==0)
229*b30d1939SAndy Fiddaman 			tdata.aflag = *opt_info.option;
230*b30d1939SAndy Fiddaman 		switch(n)
231*b30d1939SAndy Fiddaman 		{
232*b30d1939SAndy Fiddaman 			case 'a':
233*b30d1939SAndy Fiddaman 				flag |= NV_IARRAY;
234*b30d1939SAndy Fiddaman 				if(opt_info.arg && *opt_info.arg!='[')
235*b30d1939SAndy Fiddaman 				{
236*b30d1939SAndy Fiddaman 					opt_info.index--;
237*b30d1939SAndy Fiddaman 					goto endargs;
238*b30d1939SAndy Fiddaman 				}
239*b30d1939SAndy Fiddaman 				tdata.tname = opt_info.arg;
240*b30d1939SAndy Fiddaman 				break;
241*b30d1939SAndy Fiddaman 			case 'A':
242*b30d1939SAndy Fiddaman 				flag |= NV_ARRAY;
243*b30d1939SAndy Fiddaman 				break;
244*b30d1939SAndy Fiddaman 			case 'C':
245*b30d1939SAndy Fiddaman 				flag |= NV_COMVAR;
246*b30d1939SAndy Fiddaman 				break;
247*b30d1939SAndy Fiddaman 			case 'E':
248*b30d1939SAndy Fiddaman 				/* The following is for ksh88 compatibility */
249*b30d1939SAndy Fiddaman 				if(opt_info.offset && !strchr(argv[opt_info.index],'E'))
250*b30d1939SAndy Fiddaman 				{
251*b30d1939SAndy Fiddaman 					tdata.argnum = (int)opt_info.num;
252*b30d1939SAndy Fiddaman 					break;
253*b30d1939SAndy Fiddaman 				}
254*b30d1939SAndy Fiddaman 				/* FALLTHROUGH */
255*b30d1939SAndy Fiddaman 			case 'F':
256*b30d1939SAndy Fiddaman 			case 'X':
257*b30d1939SAndy Fiddaman 				if(!opt_info.arg || (tdata.argnum = opt_info.num) <0)
258*b30d1939SAndy Fiddaman 					tdata.argnum = (n=='X'?2*sizeof(Sfdouble_t):10);
259*b30d1939SAndy Fiddaman 				isfloat = 1;
260*b30d1939SAndy Fiddaman 				if(n=='E')
261*b30d1939SAndy Fiddaman 				{
262*b30d1939SAndy Fiddaman 					flag &= ~NV_HEXFLOAT;
263*b30d1939SAndy Fiddaman 					flag |= NV_EXPNOTE;
264*b30d1939SAndy Fiddaman 				}
265*b30d1939SAndy Fiddaman 				else if(n=='X')
266*b30d1939SAndy Fiddaman 				{
267*b30d1939SAndy Fiddaman 					flag &= ~NV_EXPNOTE;
268*b30d1939SAndy Fiddaman 					flag |= NV_HEXFLOAT;
269*b30d1939SAndy Fiddaman 				}
270*b30d1939SAndy Fiddaman 				break;
271*b30d1939SAndy Fiddaman 			case 'b':
272*b30d1939SAndy Fiddaman 				flag |= NV_BINARY;
273*b30d1939SAndy Fiddaman 				break;
274*b30d1939SAndy Fiddaman 			case 'm':
275*b30d1939SAndy Fiddaman 				flag |= NV_MOVE;
276*b30d1939SAndy Fiddaman 				break;
277*b30d1939SAndy Fiddaman 			case 'n':
278*b30d1939SAndy Fiddaman 				flag &= ~NV_VARNAME;
279*b30d1939SAndy Fiddaman 				flag |= (NV_REF|NV_IDENT);
280*b30d1939SAndy Fiddaman 				break;
281*b30d1939SAndy Fiddaman 			case 'H':
282*b30d1939SAndy Fiddaman 				flag |= NV_HOST;
283*b30d1939SAndy Fiddaman 				break;
284*b30d1939SAndy Fiddaman 			case 'T':
285*b30d1939SAndy Fiddaman 				flag |= NV_TYPE;
286*b30d1939SAndy Fiddaman 				tdata.prefix = opt_info.arg;
287*b30d1939SAndy Fiddaman 				break;
288*b30d1939SAndy Fiddaman 			case 'L': case 'Z': case 'R':
289*b30d1939SAndy Fiddaman 				if(tdata.argnum==0)
290*b30d1939SAndy Fiddaman 					tdata.argnum = (int)opt_info.num;
291*b30d1939SAndy Fiddaman 				if(tdata.argnum < 0)
292*b30d1939SAndy Fiddaman 					errormsg(SH_DICT,ERROR_exit(1), e_badfield, tdata.argnum);
293*b30d1939SAndy Fiddaman 				if(n=='Z')
294*b30d1939SAndy Fiddaman 					flag |= NV_ZFILL;
295*b30d1939SAndy Fiddaman 				else
296*b30d1939SAndy Fiddaman 				{
297*b30d1939SAndy Fiddaman 					flag &= ~(NV_LJUST|NV_RJUST);
298*b30d1939SAndy Fiddaman 					flag |= (n=='L'?NV_LJUST:NV_RJUST);
299*b30d1939SAndy Fiddaman 				}
300*b30d1939SAndy Fiddaman 				break;
301*b30d1939SAndy Fiddaman 			case 'M':
302*b30d1939SAndy Fiddaman 				if((tdata.wctname = opt_info.arg) && !nv_mapchar((Namval_t*)0,tdata.wctname))
303*b30d1939SAndy Fiddaman 					errormsg(SH_DICT, ERROR_exit(1),e_unknownmap, tdata.wctname);
304*b30d1939SAndy Fiddaman 				if(tdata.wctname && strcmp(tdata.wctname,e_tolower)==0)
305*b30d1939SAndy Fiddaman 					flag |= NV_UTOL;
306*b30d1939SAndy Fiddaman 				else
307*b30d1939SAndy Fiddaman 					flag |= NV_LTOU;
308*b30d1939SAndy Fiddaman 				if(!tdata.wctname)
309*b30d1939SAndy Fiddaman 					flag |= NV_UTOL;
310*b30d1939SAndy Fiddaman 				break;
311*b30d1939SAndy Fiddaman 			case 'f':
312*b30d1939SAndy Fiddaman 				flag &= ~(NV_VARNAME|NV_ASSIGN);
313*b30d1939SAndy Fiddaman 				troot = tdata.sh->fun_tree;
314*b30d1939SAndy Fiddaman 				break;
315*b30d1939SAndy Fiddaman 			case 'i':
316*b30d1939SAndy Fiddaman 				if(!opt_info.arg || (tdata.argnum = opt_info.num) <0)
317*b30d1939SAndy Fiddaman 					tdata.argnum = 10;
318*b30d1939SAndy Fiddaman 				flag |= NV_INTEGER;
319*b30d1939SAndy Fiddaman 				break;
320*b30d1939SAndy Fiddaman 			case 'l':
321*b30d1939SAndy Fiddaman 				tdata.wctname = e_tolower;
322*b30d1939SAndy Fiddaman 				flag |= NV_UTOL;
323*b30d1939SAndy Fiddaman 				break;
324*b30d1939SAndy Fiddaman 			case 'p':
325*b30d1939SAndy Fiddaman 				tdata.prefix = argv[0];
326*b30d1939SAndy Fiddaman 				tdata.pflag = 1;
327*b30d1939SAndy Fiddaman 				flag &= ~NV_ASSIGN;
328*b30d1939SAndy Fiddaman 				break;
329*b30d1939SAndy Fiddaman 			case 'r':
330*b30d1939SAndy Fiddaman 				flag |= NV_RDONLY;
331*b30d1939SAndy Fiddaman 				break;
332*b30d1939SAndy Fiddaman #ifdef SHOPT_TYPEDEF
333*b30d1939SAndy Fiddaman 			case 'S':
334*b30d1939SAndy Fiddaman 				sflag=1;
335*b30d1939SAndy Fiddaman 				break;
336*b30d1939SAndy Fiddaman 			case 'h':
337*b30d1939SAndy Fiddaman 				tdata.help = opt_info.arg;
338*b30d1939SAndy Fiddaman 				break;
339*b30d1939SAndy Fiddaman #endif /*SHOPT_TYPEDEF*/
340*b30d1939SAndy Fiddaman 			case 's':
341*b30d1939SAndy Fiddaman 				shortint=1;
342*b30d1939SAndy Fiddaman 				break;
343*b30d1939SAndy Fiddaman 			case 't':
344*b30d1939SAndy Fiddaman 				flag |= NV_TAGGED;
345*b30d1939SAndy Fiddaman 				break;
346*b30d1939SAndy Fiddaman 			case 'u':
347*b30d1939SAndy Fiddaman 				tdata.wctname = e_toupper;
348*b30d1939SAndy Fiddaman 				flag |= NV_LTOU;
349*b30d1939SAndy Fiddaman 				break;
350*b30d1939SAndy Fiddaman 			case 'x':
351*b30d1939SAndy Fiddaman 				flag &= ~NV_VARNAME;
352*b30d1939SAndy Fiddaman 				flag |= (NV_EXPORT|NV_IDENT);
353*b30d1939SAndy Fiddaman 				break;
354*b30d1939SAndy Fiddaman 			case ':':
355*b30d1939SAndy Fiddaman 				errormsg(SH_DICT,2, "%s", opt_info.arg);
356*b30d1939SAndy Fiddaman 				break;
357*b30d1939SAndy Fiddaman 			case '?':
358*b30d1939SAndy Fiddaman 				errormsg(SH_DICT,ERROR_usage(0), "%s", opt_info.arg);
359*b30d1939SAndy Fiddaman 				opt_info.disc = 0;
360*b30d1939SAndy Fiddaman 				return(2);
361*b30d1939SAndy Fiddaman 		}
362*b30d1939SAndy Fiddaman 	}
363*b30d1939SAndy Fiddaman endargs:
364*b30d1939SAndy Fiddaman 	argv += opt_info.index;
365*b30d1939SAndy Fiddaman 	opt_info.disc = 0;
366*b30d1939SAndy Fiddaman 	/* handle argument of + and - specially */
367*b30d1939SAndy Fiddaman 	if(*argv && argv[0][1]==0 && (*argv[0]=='+' || *argv[0]=='-'))
368*b30d1939SAndy Fiddaman 		tdata.aflag = *argv[0];
369*b30d1939SAndy Fiddaman 	else
370*b30d1939SAndy Fiddaman 		argv--;
371*b30d1939SAndy Fiddaman 	if((flag&NV_ZFILL) && !(flag&NV_LJUST))
372*b30d1939SAndy Fiddaman 		flag |= NV_RJUST;
373*b30d1939SAndy Fiddaman 	if((flag&NV_INTEGER) && (flag&(NV_LJUST|NV_RJUST|NV_ZFILL)))
374*b30d1939SAndy Fiddaman 		error_info.errors++;
375*b30d1939SAndy Fiddaman 	if((flag&NV_BINARY) && (flag&(NV_LJUST|NV_UTOL|NV_LTOU)))
376*b30d1939SAndy Fiddaman 		error_info.errors++;
377*b30d1939SAndy Fiddaman 	if((flag&NV_MOVE) && (flag&~(NV_MOVE|NV_VARNAME|NV_ASSIGN)))
378*b30d1939SAndy Fiddaman 		error_info.errors++;
379*b30d1939SAndy Fiddaman 	if((flag&NV_REF) && (flag&~(NV_REF|NV_IDENT|NV_ASSIGN)))
380*b30d1939SAndy Fiddaman 		error_info.errors++;
381*b30d1939SAndy Fiddaman 	if((flag&NV_TYPE) && (flag&~(NV_TYPE|NV_VARNAME|NV_ASSIGN)))
382*b30d1939SAndy Fiddaman 		error_info.errors++;
383*b30d1939SAndy Fiddaman 	if(troot==tdata.sh->fun_tree && ((isfloat || flag&~(NV_FUNCT|NV_TAGGED|NV_EXPORT|NV_LTOU))))
384*b30d1939SAndy Fiddaman 		error_info.errors++;
385*b30d1939SAndy Fiddaman 	if(sflag && troot==tdata.sh->fun_tree)
386*b30d1939SAndy Fiddaman 	{
387*b30d1939SAndy Fiddaman 		/* static function */
388*b30d1939SAndy Fiddaman 		sflag = 0;
389*b30d1939SAndy Fiddaman 		flag |= NV_STATICF;
390*b30d1939SAndy Fiddaman 	}
391*b30d1939SAndy Fiddaman 	if(error_info.errors)
392*b30d1939SAndy Fiddaman 		errormsg(SH_DICT,ERROR_usage(2),"%s", optusage(NIL(char*)));
393*b30d1939SAndy Fiddaman 	if(sizeof(char*)<8 && tdata.argnum > SHRT_MAX)
394*b30d1939SAndy Fiddaman 		errormsg(SH_DICT,ERROR_exit(2),"option argument cannot be greater than %d",SHRT_MAX);
395*b30d1939SAndy Fiddaman 	if(isfloat)
396*b30d1939SAndy Fiddaman 		flag |= NV_DOUBLE;
397*b30d1939SAndy Fiddaman 	if(shortint)
398*b30d1939SAndy Fiddaman 	{
399*b30d1939SAndy Fiddaman 		flag &= ~NV_LONG;
400*b30d1939SAndy Fiddaman 		flag |= NV_SHORT|NV_INTEGER;
401*b30d1939SAndy Fiddaman 	}
402*b30d1939SAndy Fiddaman 	if(sflag)
403*b30d1939SAndy Fiddaman 	{
404*b30d1939SAndy Fiddaman 		if(tdata.sh->mktype)
405*b30d1939SAndy Fiddaman 			flag |= NV_REF|NV_TAGGED;
406*b30d1939SAndy Fiddaman 		else if(!tdata.sh->typeinit)
407*b30d1939SAndy Fiddaman 			flag |= NV_STATIC|NV_IDENT;
408*b30d1939SAndy Fiddaman 	}
409*b30d1939SAndy Fiddaman 	if(tdata.sh->fn_depth && !tdata.pflag)
410*b30d1939SAndy Fiddaman 		flag |= NV_NOSCOPE;
411*b30d1939SAndy Fiddaman 	if(tdata.help)
412*b30d1939SAndy Fiddaman 		tdata.help = strdup(tdata.help);
413*b30d1939SAndy Fiddaman 	if(flag&NV_TYPE)
414*b30d1939SAndy Fiddaman 	{
415*b30d1939SAndy Fiddaman 		Stk_t *stkp = tdata.sh->stk;
416*b30d1939SAndy Fiddaman 		int off=0,offset = stktell(stkp);
417*b30d1939SAndy Fiddaman 		if(!tdata.prefix)
418*b30d1939SAndy Fiddaman 			return(sh_outtype(tdata.sh,sfstdout));
419*b30d1939SAndy Fiddaman 		sfputr(stkp,NV_CLASS,-1);
420*b30d1939SAndy Fiddaman #if SHOPT_NAMESPACE
421*b30d1939SAndy Fiddaman 		if(tdata.sh->namespace)
422*b30d1939SAndy Fiddaman 		{
423*b30d1939SAndy Fiddaman 			off = stktell(stkp)+1;
424*b30d1939SAndy Fiddaman 			sfputr(stkp,nv_name(tdata.sh->namespace),'.');
425*b30d1939SAndy Fiddaman 		}
426*b30d1939SAndy Fiddaman 		else
427*b30d1939SAndy Fiddaman #endif /* SHOPT_NAMESPACE */
428*b30d1939SAndy Fiddaman 		if(NV_CLASS[sizeof(NV_CLASS)-2]!='.')
429*b30d1939SAndy Fiddaman 			sfputc(stkp,'.');
430*b30d1939SAndy Fiddaman 		sfputr(stkp,tdata.prefix,0);
431*b30d1939SAndy Fiddaman 		tdata.tp = nv_open(stkptr(stkp,offset),tdata.sh->var_tree,NV_VARNAME|NV_NOARRAY|NV_NOASSIGN);
432*b30d1939SAndy Fiddaman #if SHOPT_NAMESPACE
433*b30d1939SAndy Fiddaman 		if(!tdata.tp && off)
434*b30d1939SAndy Fiddaman 		{
435*b30d1939SAndy Fiddaman 			*stkptr(stkp,off)=0;
436*b30d1939SAndy Fiddaman 			tdata.tp = nv_open(stkptr(stkp,offset),tdata.sh->var_tree,NV_VARNAME|NV_NOARRAY|NV_NOASSIGN);
437*b30d1939SAndy Fiddaman 		}
438*b30d1939SAndy Fiddaman #endif /* SHOPT_NAMESPACE */
439*b30d1939SAndy Fiddaman 		stkseek(stkp,offset);
440*b30d1939SAndy Fiddaman 		if(!tdata.tp)
441*b30d1939SAndy Fiddaman 			errormsg(SH_DICT,ERROR_exit(1),"%s: unknown type",tdata.prefix);
442*b30d1939SAndy Fiddaman 		else if(nv_isnull(tdata.tp))
443*b30d1939SAndy Fiddaman 			nv_newtype(tdata.tp);
444*b30d1939SAndy Fiddaman 		tdata.tp->nvenv = tdata.help;
445*b30d1939SAndy Fiddaman 		flag &= ~NV_TYPE;
446*b30d1939SAndy Fiddaman 		if(nv_isattr(tdata.tp,NV_TAGGED))
447*b30d1939SAndy Fiddaman 		{
448*b30d1939SAndy Fiddaman 			nv_offattr(tdata.tp,NV_TAGGED);
449*b30d1939SAndy Fiddaman 			return(0);
450*b30d1939SAndy Fiddaman 		}
451*b30d1939SAndy Fiddaman 	}
452*b30d1939SAndy Fiddaman 	else if(tdata.aflag==0 && ntp && ntp->tp)
453*b30d1939SAndy Fiddaman 		tdata.aflag = '-';
454*b30d1939SAndy Fiddaman 	if(!tdata.sh->mktype)
455*b30d1939SAndy Fiddaman 		tdata.help = 0;
456*b30d1939SAndy Fiddaman 	if(tdata.aflag=='+' && (flag&(NV_ARRAY|NV_IARRAY|NV_COMVAR)) && argv[1])
457*b30d1939SAndy Fiddaman 		errormsg(SH_DICT,ERROR_exit(1),e_nounattr);
458*b30d1939SAndy Fiddaman 	return(setall(argv,flag,troot,&tdata));
459*b30d1939SAndy Fiddaman }
460*b30d1939SAndy Fiddaman 
print_value(Sfio_t * iop,Namval_t * np,struct tdata * tp)461*b30d1939SAndy Fiddaman static void print_value(Sfio_t *iop, Namval_t *np, struct tdata *tp)
462*b30d1939SAndy Fiddaman {
463*b30d1939SAndy Fiddaman 	char	 *name;
464*b30d1939SAndy Fiddaman 	int	aflag=tp->aflag;
465*b30d1939SAndy Fiddaman 	if(nv_isnull(np))
466*b30d1939SAndy Fiddaman 	{
467*b30d1939SAndy Fiddaman 		if(!np->nvflag)
468*b30d1939SAndy Fiddaman 			return;
469*b30d1939SAndy Fiddaman 		aflag = '+';
470*b30d1939SAndy Fiddaman 	}
471*b30d1939SAndy Fiddaman 	else if(nv_istable(np))
472*b30d1939SAndy Fiddaman 	{
473*b30d1939SAndy Fiddaman 		Dt_t	*root = tp->sh->last_root;
474*b30d1939SAndy Fiddaman 		Namval_t *nsp = tp->sh->namespace;
475*b30d1939SAndy Fiddaman 		char *cp;
476*b30d1939SAndy Fiddaman 		if(!tp->pflag)
477*b30d1939SAndy Fiddaman 			return;
478*b30d1939SAndy Fiddaman 		cp = name = nv_name(np);
479*b30d1939SAndy Fiddaman 		if(*name=='.')
480*b30d1939SAndy Fiddaman 			name++;
481*b30d1939SAndy Fiddaman 		if(tp->indent)
482*b30d1939SAndy Fiddaman 			sfnputc(iop,'\t',tp->indent);
483*b30d1939SAndy Fiddaman 		sfprintf(iop,"namespace %s\n", name);
484*b30d1939SAndy Fiddaman 		if(tp->indent)
485*b30d1939SAndy Fiddaman 			sfnputc(iop,'\t',tp->indent);
486*b30d1939SAndy Fiddaman 		sfprintf(iop,"{\n", name);
487*b30d1939SAndy Fiddaman 		tp->indent++;
488*b30d1939SAndy Fiddaman 		/* output types from namespace */
489*b30d1939SAndy Fiddaman 		tp->sh->namespace = 0;
490*b30d1939SAndy Fiddaman 		tp->sh->prefix = nv_name(np)+1;
491*b30d1939SAndy Fiddaman 		sh_outtype(tp->sh,iop);
492*b30d1939SAndy Fiddaman 		tp->sh->prefix = 0;
493*b30d1939SAndy Fiddaman 		tp->sh->namespace = np;
494*b30d1939SAndy Fiddaman 		tp->sh->last_root = root;
495*b30d1939SAndy Fiddaman 		/* output variables from namespace */
496*b30d1939SAndy Fiddaman 		print_scan(iop,NV_NOSCOPE,nv_dict(np),aflag=='+',tp);
497*b30d1939SAndy Fiddaman 		tp->wctname = cp;
498*b30d1939SAndy Fiddaman 		tp->sh->namespace = 0;
499*b30d1939SAndy Fiddaman 		/* output functions from namespace */
500*b30d1939SAndy Fiddaman 		print_scan(iop,NV_FUNCTION|NV_NOSCOPE,tp->sh->fun_tree,aflag=='+',tp);
501*b30d1939SAndy Fiddaman 		tp->wctname = 0;
502*b30d1939SAndy Fiddaman 		tp->sh->namespace = nsp;
503*b30d1939SAndy Fiddaman 		if(--tp->indent)
504*b30d1939SAndy Fiddaman 			sfnputc(iop,'\t',tp->indent);
505*b30d1939SAndy Fiddaman 		sfwrite(iop,"}\n",2);
506*b30d1939SAndy Fiddaman 		return;
507*b30d1939SAndy Fiddaman 	}
508*b30d1939SAndy Fiddaman 	sfputr(iop,nv_name(np),aflag=='+'?'\n':'=');
509*b30d1939SAndy Fiddaman 	if(aflag=='+')
510*b30d1939SAndy Fiddaman 		return;
511*b30d1939SAndy Fiddaman 	if(nv_isarray(np) && nv_arrayptr(np))
512*b30d1939SAndy Fiddaman 	{
513*b30d1939SAndy Fiddaman 		nv_outnode(np,iop,-1,0);
514*b30d1939SAndy Fiddaman 		sfwrite(iop,")\n",2);
515*b30d1939SAndy Fiddaman 	}
516*b30d1939SAndy Fiddaman 	else
517*b30d1939SAndy Fiddaman 	{
518*b30d1939SAndy Fiddaman 		if(nv_isvtree(np))
519*b30d1939SAndy Fiddaman 			nv_onattr(np,NV_EXPORT);
520*b30d1939SAndy Fiddaman 		if(!(name = nv_getval(np)))
521*b30d1939SAndy Fiddaman 			name = Empty;
522*b30d1939SAndy Fiddaman 		if(!nv_isvtree(np))
523*b30d1939SAndy Fiddaman 			name = sh_fmtq(name);
524*b30d1939SAndy Fiddaman 		sfputr(iop,name,'\n');
525*b30d1939SAndy Fiddaman 	}
526*b30d1939SAndy Fiddaman }
527*b30d1939SAndy Fiddaman 
setall(char ** argv,register int flag,Dt_t * troot,struct tdata * tp)528*b30d1939SAndy Fiddaman static int     setall(char **argv,register int flag,Dt_t *troot,struct tdata *tp)
529*b30d1939SAndy Fiddaman {
530*b30d1939SAndy Fiddaman 	register char *name;
531*b30d1939SAndy Fiddaman 	char *last = 0;
532*b30d1939SAndy Fiddaman 	int nvflags=(flag&(NV_ARRAY|NV_NOARRAY|NV_VARNAME|NV_IDENT|NV_ASSIGN|NV_STATIC|NV_MOVE));
533*b30d1939SAndy Fiddaman 	int r=0, ref=0, comvar=(flag&NV_COMVAR),iarray=(flag&NV_IARRAY);
534*b30d1939SAndy Fiddaman 	Shell_t *shp =tp->sh;
535*b30d1939SAndy Fiddaman 	if(!shp->prefix)
536*b30d1939SAndy Fiddaman 	{
537*b30d1939SAndy Fiddaman 		if(!tp->pflag)
538*b30d1939SAndy Fiddaman 			nvflags |= NV_NOSCOPE;
539*b30d1939SAndy Fiddaman 	}
540*b30d1939SAndy Fiddaman 	else if(*shp->prefix==0)
541*b30d1939SAndy Fiddaman 		shp->prefix = 0;
542*b30d1939SAndy Fiddaman 	if(*argv[0]=='+')
543*b30d1939SAndy Fiddaman 		nvflags |= NV_NOADD;
544*b30d1939SAndy Fiddaman 	flag &= ~(NV_NOARRAY|NV_NOSCOPE|NV_VARNAME|NV_IDENT|NV_STATIC|NV_COMVAR|NV_IARRAY);
545*b30d1939SAndy Fiddaman 	if(argv[1])
546*b30d1939SAndy Fiddaman 	{
547*b30d1939SAndy Fiddaman 		if(flag&NV_REF)
548*b30d1939SAndy Fiddaman 		{
549*b30d1939SAndy Fiddaman 			flag &= ~NV_REF;
550*b30d1939SAndy Fiddaman 			ref=1;
551*b30d1939SAndy Fiddaman 			if(tp->aflag!='-')
552*b30d1939SAndy Fiddaman 				nvflags |= NV_NOREF;
553*b30d1939SAndy Fiddaman 		}
554*b30d1939SAndy Fiddaman 		if(tp->pflag)
555*b30d1939SAndy Fiddaman 			nvflags |= (NV_NOREF|NV_NOADD|NV_NOFAIL);
556*b30d1939SAndy Fiddaman 		while(name = *++argv)
557*b30d1939SAndy Fiddaman 		{
558*b30d1939SAndy Fiddaman 			register unsigned newflag;
559*b30d1939SAndy Fiddaman 			register Namval_t *np;
560*b30d1939SAndy Fiddaman 			Namarr_t	*ap;
561*b30d1939SAndy Fiddaman 			Namval_t	*mp;
562*b30d1939SAndy Fiddaman 			unsigned curflag;
563*b30d1939SAndy Fiddaman 			if(troot == shp->fun_tree)
564*b30d1939SAndy Fiddaman 			{
565*b30d1939SAndy Fiddaman 				/*
566*b30d1939SAndy Fiddaman 				 *functions can be exported or
567*b30d1939SAndy Fiddaman 				 * traced but not set
568*b30d1939SAndy Fiddaman 				 */
569*b30d1939SAndy Fiddaman 				flag &= ~NV_ASSIGN;
570*b30d1939SAndy Fiddaman 				if(flag&NV_LTOU)
571*b30d1939SAndy Fiddaman 				{
572*b30d1939SAndy Fiddaman 					/* Function names cannot be special builtin */
573*b30d1939SAndy Fiddaman 					if((np=nv_search(name,shp->bltin_tree,0)) && nv_isattr(np,BLT_SPC))
574*b30d1939SAndy Fiddaman 						errormsg(SH_DICT,ERROR_exit(1),e_badfun,name);
575*b30d1939SAndy Fiddaman #if SHOPT_NAMESPACE
576*b30d1939SAndy Fiddaman 					if(shp->namespace)
577*b30d1939SAndy Fiddaman 						np = sh_fsearch(shp,name,NV_ADD|HASH_NOSCOPE);
578*b30d1939SAndy Fiddaman 					else
579*b30d1939SAndy Fiddaman #endif /* SHOPT_NAMESPACE */
580*b30d1939SAndy Fiddaman 					np = nv_open(name,sh_subfuntree(1),NV_NOARRAY|NV_IDENT|NV_NOSCOPE);
581*b30d1939SAndy Fiddaman 				}
582*b30d1939SAndy Fiddaman 				else
583*b30d1939SAndy Fiddaman 				{
584*b30d1939SAndy Fiddaman 					if(shp->prefix)
585*b30d1939SAndy Fiddaman 					{
586*b30d1939SAndy Fiddaman 						sfprintf(shp->strbuf,"%s.%s%c",shp->prefix,name,0);
587*b30d1939SAndy Fiddaman 						name = sfstruse(shp->strbuf);
588*b30d1939SAndy Fiddaman 					}
589*b30d1939SAndy Fiddaman #if SHOPT_NAMESPACE
590*b30d1939SAndy Fiddaman 					np = 0;
591*b30d1939SAndy Fiddaman 					if(shp->namespace)
592*b30d1939SAndy Fiddaman 						np = sh_fsearch(shp,name,HASH_NOSCOPE);
593*b30d1939SAndy Fiddaman 					if(!np)
594*b30d1939SAndy Fiddaman #endif /* SHOPT_NAMESPACE */
595*b30d1939SAndy Fiddaman 					if(np=nv_search(name,troot,0))
596*b30d1939SAndy Fiddaman 					{
597*b30d1939SAndy Fiddaman 						if(!is_afunction(np))
598*b30d1939SAndy Fiddaman 							np = 0;
599*b30d1939SAndy Fiddaman 					}
600*b30d1939SAndy Fiddaman 					else if(memcmp(name,".sh.math.",9)==0 && sh_mathstd(name+9))
601*b30d1939SAndy Fiddaman 						continue;
602*b30d1939SAndy Fiddaman 				}
603*b30d1939SAndy Fiddaman 				if(np && ((flag&NV_LTOU) || !nv_isnull(np) || nv_isattr(np,NV_LTOU)))
604*b30d1939SAndy Fiddaman 				{
605*b30d1939SAndy Fiddaman 					if(flag==0 && !tp->help)
606*b30d1939SAndy Fiddaman 					{
607*b30d1939SAndy Fiddaman 						print_namval(sfstdout,np,tp->aflag=='+',tp);
608*b30d1939SAndy Fiddaman 						continue;
609*b30d1939SAndy Fiddaman 					}
610*b30d1939SAndy Fiddaman 					if(shp->subshell && !shp->subshare)
611*b30d1939SAndy Fiddaman 						sh_subfork();
612*b30d1939SAndy Fiddaman 					if(tp->aflag=='-')
613*b30d1939SAndy Fiddaman 						nv_onattr(np,flag|NV_FUNCTION);
614*b30d1939SAndy Fiddaman 					else if(tp->aflag=='+')
615*b30d1939SAndy Fiddaman 						nv_offattr(np,flag);
616*b30d1939SAndy Fiddaman 				}
617*b30d1939SAndy Fiddaman 				else
618*b30d1939SAndy Fiddaman 					r++;
619*b30d1939SAndy Fiddaman 				if(tp->help)
620*b30d1939SAndy Fiddaman 				{
621*b30d1939SAndy Fiddaman 					int offset = stktell(shp->stk);
622*b30d1939SAndy Fiddaman 					if(!np)
623*b30d1939SAndy Fiddaman 					{
624*b30d1939SAndy Fiddaman 						sfputr(shp->stk,shp->prefix,'.');
625*b30d1939SAndy Fiddaman 						sfputr(shp->stk,name,0);
626*b30d1939SAndy Fiddaman 						np = nv_search(stkptr(shp->stk,offset),troot,0);
627*b30d1939SAndy Fiddaman 						stkseek(shp->stk,offset);
628*b30d1939SAndy Fiddaman 					}
629*b30d1939SAndy Fiddaman 					if(np && np->nvalue.cp)
630*b30d1939SAndy Fiddaman 						np->nvalue.rp->help = tp->help;
631*b30d1939SAndy Fiddaman 				}
632*b30d1939SAndy Fiddaman 				continue;
633*b30d1939SAndy Fiddaman 			}
634*b30d1939SAndy Fiddaman 			/* tracked alias */
635*b30d1939SAndy Fiddaman 			if(troot==shp->track_tree && tp->aflag=='-')
636*b30d1939SAndy Fiddaman 			{
637*b30d1939SAndy Fiddaman 				np = nv_search(name,troot,NV_ADD);
638*b30d1939SAndy Fiddaman 				path_alias(np,path_absolute(shp,nv_name(np),NIL(Pathcomp_t*)));
639*b30d1939SAndy Fiddaman 				continue;
640*b30d1939SAndy Fiddaman 			}
641*b30d1939SAndy Fiddaman 			np = nv_open(name,troot,nvflags|((nvflags&NV_ASSIGN)?0:NV_ARRAY)|((iarray|(nvflags&(NV_REF|NV_NOADD)==NV_REF))?NV_FARRAY:0));
642*b30d1939SAndy Fiddaman 			if(!np)
643*b30d1939SAndy Fiddaman 				continue;
644*b30d1939SAndy Fiddaman 			if(nv_isnull(np) && !nv_isarray(np) && nv_isattr(np,NV_NOFREE))
645*b30d1939SAndy Fiddaman 				nv_offattr(np,NV_NOFREE);
646*b30d1939SAndy Fiddaman 			else if(tp->tp && !nv_isattr(np,NV_MINIMAL|NV_EXPORT) && (mp=(Namval_t*)np->nvenv) && (ap=nv_arrayptr(mp)) && (ap->nelem&ARRAY_TREE))
647*b30d1939SAndy Fiddaman 				errormsg(SH_DICT,ERROR_exit(1),e_typecompat,nv_name(np));
648*b30d1939SAndy Fiddaman 			else if((ap=nv_arrayptr(np)) && nv_aindex(np)>0 && ap->nelem==1 && nv_getval(np)==Empty)
649*b30d1939SAndy Fiddaman 			{
650*b30d1939SAndy Fiddaman 				ap->nelem++;
651*b30d1939SAndy Fiddaman 				_nv_unset(np,0);
652*b30d1939SAndy Fiddaman 				ap->nelem--;
653*b30d1939SAndy Fiddaman 			}
654*b30d1939SAndy Fiddaman 			else if(iarray && ap && ap->fun)
655*b30d1939SAndy Fiddaman 				errormsg(SH_DICT,ERROR_exit(1),"cannot change associative array %s to index array",nv_name(np));
656*b30d1939SAndy Fiddaman 			else if( (iarray||(flag&NV_ARRAY)) && nv_isvtree(np) && !nv_type(np))
657*b30d1939SAndy Fiddaman 				_nv_unset(np,NV_EXPORT);
658*b30d1939SAndy Fiddaman 			if(tp->pflag)
659*b30d1939SAndy Fiddaman 			{
660*b30d1939SAndy Fiddaman 				if(!nv_istable(np))
661*b30d1939SAndy Fiddaman 					nv_attribute(np,sfstdout,tp->prefix,1);
662*b30d1939SAndy Fiddaman 				print_value(sfstdout,np,tp);
663*b30d1939SAndy Fiddaman 				continue;
664*b30d1939SAndy Fiddaman 			}
665*b30d1939SAndy Fiddaman 			if(flag==NV_ASSIGN && !ref && tp->aflag!='-' && !strchr(name,'='))
666*b30d1939SAndy Fiddaman 			{
667*b30d1939SAndy Fiddaman 				if(troot!=shp->var_tree && (nv_isnull(np) || !print_namval(sfstdout,np,0,tp)))
668*b30d1939SAndy Fiddaman 				{
669*b30d1939SAndy Fiddaman 					sfprintf(sfstderr,sh_translate(e_noalias),name);
670*b30d1939SAndy Fiddaman 					r++;
671*b30d1939SAndy Fiddaman 				}
672*b30d1939SAndy Fiddaman 				if(!comvar && !iarray)
673*b30d1939SAndy Fiddaman 					continue;
674*b30d1939SAndy Fiddaman 			}
675*b30d1939SAndy Fiddaman 			if(!nv_isarray(np) && !strchr(name,'=') && !(shp->envlist  && nv_onlist(shp->envlist,name)))
676*b30d1939SAndy Fiddaman 			{
677*b30d1939SAndy Fiddaman 				if(comvar || (shp->last_root==shp->var_tree && (tp->tp || (!shp->st.real_fun && (nvflags&NV_STATIC)) || (!(flag&(NV_EXPORT|NV_RDONLY)) && nv_isattr(np,(NV_EXPORT|NV_IMPORT))==(NV_EXPORT|NV_IMPORT)))))
678*b30d1939SAndy Fiddaman {
679*b30d1939SAndy Fiddaman 					_nv_unset(np,0);
680*b30d1939SAndy Fiddaman }
681*b30d1939SAndy Fiddaman 			}
682*b30d1939SAndy Fiddaman 			if(troot==shp->var_tree)
683*b30d1939SAndy Fiddaman 			{
684*b30d1939SAndy Fiddaman 				if(iarray)
685*b30d1939SAndy Fiddaman 				{
686*b30d1939SAndy Fiddaman 					if(tp->tname)
687*b30d1939SAndy Fiddaman 						nv_atypeindex(np,tp->tname+1);
688*b30d1939SAndy Fiddaman 					else if(nv_isnull(np))
689*b30d1939SAndy Fiddaman 						nv_onattr(np,NV_ARRAY|(comvar?NV_NOFREE:0));
690*b30d1939SAndy Fiddaman 					else
691*b30d1939SAndy Fiddaman 					{
692*b30d1939SAndy Fiddaman 						if(ap && comvar)
693*b30d1939SAndy Fiddaman 							ap->nelem |= ARRAY_TREE;
694*b30d1939SAndy Fiddaman 						nv_putsub(np, (char*)0, 0);
695*b30d1939SAndy Fiddaman 					}
696*b30d1939SAndy Fiddaman 				}
697*b30d1939SAndy Fiddaman 				else if(nvflags&NV_ARRAY)
698*b30d1939SAndy Fiddaman 				{
699*b30d1939SAndy Fiddaman 					if(comvar)
700*b30d1939SAndy Fiddaman 					{
701*b30d1939SAndy Fiddaman 						Namarr_t *ap=nv_arrayptr(np);
702*b30d1939SAndy Fiddaman 						if(ap)
703*b30d1939SAndy Fiddaman 							ap->nelem |= ARRAY_TREE;
704*b30d1939SAndy Fiddaman 						else
705*b30d1939SAndy Fiddaman 						{
706*b30d1939SAndy Fiddaman 							_nv_unset(np,NV_RDONLY);
707*b30d1939SAndy Fiddaman 							nv_onattr(np,NV_NOFREE);
708*b30d1939SAndy Fiddaman 						}
709*b30d1939SAndy Fiddaman 					}
710*b30d1939SAndy Fiddaman 					nv_setarray(np,nv_associative);
711*b30d1939SAndy Fiddaman 				}
712*b30d1939SAndy Fiddaman 				else if(comvar && !nv_isvtree(np) && !nv_rename(np,flag|NV_COMVAR))
713*b30d1939SAndy Fiddaman 					nv_setvtree(np);
714*b30d1939SAndy Fiddaman 			}
715*b30d1939SAndy Fiddaman 			if(flag&NV_MOVE)
716*b30d1939SAndy Fiddaman 			{
717*b30d1939SAndy Fiddaman 				nv_rename(np, flag);
718*b30d1939SAndy Fiddaman 				nv_close(np);
719*b30d1939SAndy Fiddaman 				continue;
720*b30d1939SAndy Fiddaman 			}
721*b30d1939SAndy Fiddaman 			if(tp->tp && nv_type(np)!=tp->tp)
722*b30d1939SAndy Fiddaman 			{
723*b30d1939SAndy Fiddaman 				nv_settype(np,tp->tp,tp->aflag=='-'?0:NV_APPEND);
724*b30d1939SAndy Fiddaman 				flag = (np->nvflag&NV_NOCHANGE);
725*b30d1939SAndy Fiddaman 			}
726*b30d1939SAndy Fiddaman 			flag &= ~NV_ASSIGN;
727*b30d1939SAndy Fiddaman 			if(last=strchr(name,'='))
728*b30d1939SAndy Fiddaman 				*last = 0;
729*b30d1939SAndy Fiddaman 			if (shp->typeinit)
730*b30d1939SAndy Fiddaman 				continue;
731*b30d1939SAndy Fiddaman 			curflag = np->nvflag;
732*b30d1939SAndy Fiddaman 			if(!(flag&NV_INTEGER) && (flag&(NV_LTOU|NV_UTOL)))
733*b30d1939SAndy Fiddaman 			{
734*b30d1939SAndy Fiddaman 				Namfun_t *fp;
735*b30d1939SAndy Fiddaman 				char  *cp;
736*b30d1939SAndy Fiddaman 				if(!tp->wctname)
737*b30d1939SAndy Fiddaman 					errormsg(SH_DICT,ERROR_exit(1),e_mapchararg,nv_name(np));
738*b30d1939SAndy Fiddaman 				cp = (char*)nv_mapchar(np,0);
739*b30d1939SAndy Fiddaman 				if(fp=nv_mapchar(np,tp->wctname))
740*b30d1939SAndy Fiddaman 				{
741*b30d1939SAndy Fiddaman 					if(tp->aflag=='+')
742*b30d1939SAndy Fiddaman 					{
743*b30d1939SAndy Fiddaman 						if(cp && strcmp(cp,tp->wctname)==0)
744*b30d1939SAndy Fiddaman 						{
745*b30d1939SAndy Fiddaman 							nv_disc(np,fp,NV_POP);
746*b30d1939SAndy Fiddaman 							if(!(fp->nofree&1))
747*b30d1939SAndy Fiddaman 								free((void*)fp);
748*b30d1939SAndy Fiddaman 							nv_offattr(np,flag&(NV_LTOU|NV_UTOL));
749*b30d1939SAndy Fiddaman 						}
750*b30d1939SAndy Fiddaman 					}
751*b30d1939SAndy Fiddaman 					else if(!cp || strcmp(cp,tp->wctname))
752*b30d1939SAndy Fiddaman 					{
753*b30d1939SAndy Fiddaman 						nv_disc(np,fp,NV_LAST);
754*b30d1939SAndy Fiddaman 						nv_onattr(np,flag&(NV_LTOU|NV_UTOL));
755*b30d1939SAndy Fiddaman 					}
756*b30d1939SAndy Fiddaman 				}
757*b30d1939SAndy Fiddaman 			}
758*b30d1939SAndy Fiddaman 			if (tp->aflag == '-')
759*b30d1939SAndy Fiddaman 			{
760*b30d1939SAndy Fiddaman 				if((flag&NV_EXPORT) && (strchr(name,'.') || nv_isvtree(np)))
761*b30d1939SAndy Fiddaman 					errormsg(SH_DICT,ERROR_exit(1),e_badexport,name);
762*b30d1939SAndy Fiddaman #if SHOPT_BSH
763*b30d1939SAndy Fiddaman 				if(flag&NV_EXPORT)
764*b30d1939SAndy Fiddaman 					nv_offattr(np,NV_IMPORT);
765*b30d1939SAndy Fiddaman #endif /* SHOPT_BSH */
766*b30d1939SAndy Fiddaman 				newflag = curflag;
767*b30d1939SAndy Fiddaman 				if(flag&~NV_NOCHANGE)
768*b30d1939SAndy Fiddaman 					newflag &= NV_NOCHANGE;
769*b30d1939SAndy Fiddaman 				newflag |= flag;
770*b30d1939SAndy Fiddaman 				if (flag & (NV_LJUST|NV_RJUST))
771*b30d1939SAndy Fiddaman 				{
772*b30d1939SAndy Fiddaman 					if(!(flag&NV_RJUST))
773*b30d1939SAndy Fiddaman 						newflag &= ~NV_RJUST;
774*b30d1939SAndy Fiddaman 
775*b30d1939SAndy Fiddaman 					else if(!(flag&NV_LJUST))
776*b30d1939SAndy Fiddaman 						newflag &= ~NV_LJUST;
777*b30d1939SAndy Fiddaman 				}
778*b30d1939SAndy Fiddaman 			}
779*b30d1939SAndy Fiddaman 			else
780*b30d1939SAndy Fiddaman 			{
781*b30d1939SAndy Fiddaman 				if((flag&NV_RDONLY) && (curflag&NV_RDONLY))
782*b30d1939SAndy Fiddaman 					errormsg(SH_DICT,ERROR_exit(1),e_readonly,nv_name(np));
783*b30d1939SAndy Fiddaman 				newflag = curflag & ~flag;
784*b30d1939SAndy Fiddaman 			}
785*b30d1939SAndy Fiddaman 			if (tp->aflag && (tp->argnum>0 || (curflag!=newflag)))
786*b30d1939SAndy Fiddaman 			{
787*b30d1939SAndy Fiddaman 				if(shp->subshell)
788*b30d1939SAndy Fiddaman 					sh_assignok(np,1);
789*b30d1939SAndy Fiddaman 				if(troot!=shp->var_tree)
790*b30d1939SAndy Fiddaman 					nv_setattr(np,newflag&~NV_ASSIGN);
791*b30d1939SAndy Fiddaman 				else
792*b30d1939SAndy Fiddaman 				{
793*b30d1939SAndy Fiddaman 					char *oldname=0;
794*b30d1939SAndy Fiddaman 					int len=strlen(name);
795*b30d1939SAndy Fiddaman 					if(tp->argnum==1 && newflag==NV_INTEGER && nv_isattr(np,NV_INTEGER))
796*b30d1939SAndy Fiddaman 						tp->argnum = 10;
797*b30d1939SAndy Fiddaman 					if(np->nvfun && !nv_isarray(np) && name[len-1]=='.')
798*b30d1939SAndy Fiddaman 						newflag |= NV_NODISC;
799*b30d1939SAndy Fiddaman 					nv_newattr (np, newflag&~NV_ASSIGN,tp->argnum);
800*b30d1939SAndy Fiddaman 					if(oldname)
801*b30d1939SAndy Fiddaman 						np->nvname = oldname;
802*b30d1939SAndy Fiddaman 				}
803*b30d1939SAndy Fiddaman 			}
804*b30d1939SAndy Fiddaman 			if(tp->help && !nv_isattr(np,NV_MINIMAL|NV_EXPORT))
805*b30d1939SAndy Fiddaman 			{
806*b30d1939SAndy Fiddaman 				np->nvenv = tp->help;
807*b30d1939SAndy Fiddaman 				nv_onattr(np,NV_EXPORT);
808*b30d1939SAndy Fiddaman 			}
809*b30d1939SAndy Fiddaman 			if(last)
810*b30d1939SAndy Fiddaman 				*last = '=';
811*b30d1939SAndy Fiddaman 			/* set or unset references */
812*b30d1939SAndy Fiddaman 			if(ref)
813*b30d1939SAndy Fiddaman 			{
814*b30d1939SAndy Fiddaman 				if(tp->aflag=='-')
815*b30d1939SAndy Fiddaman 				{
816*b30d1939SAndy Fiddaman 					Dt_t *hp=0;
817*b30d1939SAndy Fiddaman 					if(nv_isattr(np,NV_PARAM) && shp->st.prevst)
818*b30d1939SAndy Fiddaman 					{
819*b30d1939SAndy Fiddaman 						if(!(hp=(Dt_t*)shp->st.prevst->save_tree))
820*b30d1939SAndy Fiddaman 							hp = dtvnext(shp->var_tree);
821*b30d1939SAndy Fiddaman 					}
822*b30d1939SAndy Fiddaman 					if(tp->sh->mktype)
823*b30d1939SAndy Fiddaman 						nv_onattr(np,NV_REF|NV_FUNCT);
824*b30d1939SAndy Fiddaman 					else
825*b30d1939SAndy Fiddaman 						nv_setref(np,hp,NV_VARNAME);
826*b30d1939SAndy Fiddaman 				}
827*b30d1939SAndy Fiddaman 				else
828*b30d1939SAndy Fiddaman 					nv_unref(np);
829*b30d1939SAndy Fiddaman 			}
830*b30d1939SAndy Fiddaman 			nv_close(np);
831*b30d1939SAndy Fiddaman 		}
832*b30d1939SAndy Fiddaman 	}
833*b30d1939SAndy Fiddaman 	else
834*b30d1939SAndy Fiddaman 	{
835*b30d1939SAndy Fiddaman 		if(shp->prefix)
836*b30d1939SAndy Fiddaman 			errormsg(SH_DICT,2, e_subcomvar,shp->prefix);
837*b30d1939SAndy Fiddaman 		if(tp->aflag)
838*b30d1939SAndy Fiddaman 		{
839*b30d1939SAndy Fiddaman 			if(troot==shp->fun_tree)
840*b30d1939SAndy Fiddaman 			{
841*b30d1939SAndy Fiddaman 				flag |= NV_FUNCTION;
842*b30d1939SAndy Fiddaman 				tp->prefix = 0;
843*b30d1939SAndy Fiddaman 			}
844*b30d1939SAndy Fiddaman 			else if(troot==shp->var_tree)
845*b30d1939SAndy Fiddaman 			{
846*b30d1939SAndy Fiddaman 				flag |= (nvflags&NV_ARRAY);
847*b30d1939SAndy Fiddaman 				if(iarray)
848*b30d1939SAndy Fiddaman 					flag |= NV_ARRAY|NV_IARRAY;
849*b30d1939SAndy Fiddaman 				if(comvar)
850*b30d1939SAndy Fiddaman 					flag |= NV_TABLE;
851*b30d1939SAndy Fiddaman 				if(!(flag&~NV_ASSIGN))
852*b30d1939SAndy Fiddaman 					tp->noref = 1;
853*b30d1939SAndy Fiddaman 			}
854*b30d1939SAndy Fiddaman 			if((flag&(NV_UTOL|NV_LTOU)) ==(NV_UTOL|NV_LTOU))
855*b30d1939SAndy Fiddaman 			{
856*b30d1939SAndy Fiddaman 				print_scan(sfstdout,flag&~NV_UTOL,troot,tp->aflag=='+',tp);
857*b30d1939SAndy Fiddaman 				flag &= ~NV_LTOU;
858*b30d1939SAndy Fiddaman 			}
859*b30d1939SAndy Fiddaman 			print_scan(sfstdout,flag,troot,tp->aflag=='+',tp);
860*b30d1939SAndy Fiddaman 			if(tp->noref)
861*b30d1939SAndy Fiddaman 			{
862*b30d1939SAndy Fiddaman 				tp->noref = 0;
863*b30d1939SAndy Fiddaman 				print_scan(sfstdout,flag|NV_REF,troot,tp->aflag=='+',tp);
864*b30d1939SAndy Fiddaman 			}
865*b30d1939SAndy Fiddaman 		}
866*b30d1939SAndy Fiddaman 		else if(troot==shp->alias_tree)
867*b30d1939SAndy Fiddaman 			print_scan(sfstdout,0,troot,0,tp);
868*b30d1939SAndy Fiddaman 		else
869*b30d1939SAndy Fiddaman 			print_all(sfstdout,troot,tp);
870*b30d1939SAndy Fiddaman 		sfsync(sfstdout);
871*b30d1939SAndy Fiddaman 	}
872*b30d1939SAndy Fiddaman 	return(r);
873*b30d1939SAndy Fiddaman }
874*b30d1939SAndy Fiddaman 
875*b30d1939SAndy Fiddaman #if SHOPT_DYNAMIC
876*b30d1939SAndy Fiddaman 
877*b30d1939SAndy Fiddaman typedef void (*Libinit_f)(int,void*);
878*b30d1939SAndy Fiddaman 
879*b30d1939SAndy Fiddaman typedef struct Libcomp_s
880*b30d1939SAndy Fiddaman {
881*b30d1939SAndy Fiddaman 	void*		dll;
882*b30d1939SAndy Fiddaman 	char*		lib;
883*b30d1939SAndy Fiddaman 	dev_t		dev;
884*b30d1939SAndy Fiddaman 	ino_t		ino;
885*b30d1939SAndy Fiddaman 	unsigned int	attr;
886*b30d1939SAndy Fiddaman } Libcomp_t;
887*b30d1939SAndy Fiddaman 
888*b30d1939SAndy Fiddaman #define GROWLIB	4
889*b30d1939SAndy Fiddaman 
890*b30d1939SAndy Fiddaman static Libcomp_t	*liblist;
891*b30d1939SAndy Fiddaman static int		nlib;
892*b30d1939SAndy Fiddaman static int		maxlib;
893*b30d1939SAndy Fiddaman 
894*b30d1939SAndy Fiddaman /*
895*b30d1939SAndy Fiddaman  * add library to loaded list
896*b30d1939SAndy Fiddaman  * call (*lib_init)() on first load if defined
897*b30d1939SAndy Fiddaman  * always move to head of search list
898*b30d1939SAndy Fiddaman  * return: 0: already loaded 1: first load
899*b30d1939SAndy Fiddaman  */
900*b30d1939SAndy Fiddaman 
sh_addlib(Shell_t * shp,void * dll,char * name,Pathcomp_t * pp)901*b30d1939SAndy Fiddaman int sh_addlib(Shell_t* shp, void* dll, char* name, Pathcomp_t* pp)
902*b30d1939SAndy Fiddaman {
903*b30d1939SAndy Fiddaman 	register int	n;
904*b30d1939SAndy Fiddaman 	register int	r;
905*b30d1939SAndy Fiddaman 	Libinit_f	initfn;
906*b30d1939SAndy Fiddaman 	Shbltin_t	*sp = &shp->bltindata;
907*b30d1939SAndy Fiddaman 
908*b30d1939SAndy Fiddaman 	sp->nosfio = 0;
909*b30d1939SAndy Fiddaman 	for (n = r = 0; n < nlib; n++)
910*b30d1939SAndy Fiddaman 	{
911*b30d1939SAndy Fiddaman 		if (r)
912*b30d1939SAndy Fiddaman 			liblist[n-1] = liblist[n];
913*b30d1939SAndy Fiddaman 		else if (liblist[n].dll == dll)
914*b30d1939SAndy Fiddaman 			r++;
915*b30d1939SAndy Fiddaman 	}
916*b30d1939SAndy Fiddaman 	if (r)
917*b30d1939SAndy Fiddaman 		nlib--;
918*b30d1939SAndy Fiddaman 	else if ((initfn = (Libinit_f)dlllook(dll, "lib_init")))
919*b30d1939SAndy Fiddaman 		(*initfn)(0,sp);
920*b30d1939SAndy Fiddaman 	if (nlib >= maxlib)
921*b30d1939SAndy Fiddaman 	{
922*b30d1939SAndy Fiddaman 		maxlib += GROWLIB;
923*b30d1939SAndy Fiddaman 		liblist = newof(liblist, Libcomp_t, maxlib+1, 0);
924*b30d1939SAndy Fiddaman 	}
925*b30d1939SAndy Fiddaman 	liblist[nlib].dll = dll;
926*b30d1939SAndy Fiddaman 	liblist[nlib].attr = (sp->nosfio?BLT_NOSFIO:0);
927*b30d1939SAndy Fiddaman 	if (name)
928*b30d1939SAndy Fiddaman 		liblist[nlib].lib = strdup(name);
929*b30d1939SAndy Fiddaman 	if (pp)
930*b30d1939SAndy Fiddaman 	{
931*b30d1939SAndy Fiddaman 		liblist[nlib].dev = pp->dev;
932*b30d1939SAndy Fiddaman 		liblist[nlib].ino = pp->ino;
933*b30d1939SAndy Fiddaman 	}
934*b30d1939SAndy Fiddaman 	nlib++;
935*b30d1939SAndy Fiddaman 	return !r;
936*b30d1939SAndy Fiddaman }
937*b30d1939SAndy Fiddaman 
sh_getlib(Shell_t * shp,char * sym,Pathcomp_t * pp)938*b30d1939SAndy Fiddaman Shbltin_f sh_getlib(Shell_t* shp, char* sym, Pathcomp_t* pp)
939*b30d1939SAndy Fiddaman {
940*b30d1939SAndy Fiddaman 	register int	n;
941*b30d1939SAndy Fiddaman 
942*b30d1939SAndy Fiddaman 	for (n = 0; n < nlib; n++)
943*b30d1939SAndy Fiddaman 		if (liblist[n].ino == pp->ino && liblist[n].dev == pp->dev)
944*b30d1939SAndy Fiddaman 			return (Shbltin_f)dlllook(liblist[n].dll, sym);
945*b30d1939SAndy Fiddaman 	return 0;
946*b30d1939SAndy Fiddaman }
947*b30d1939SAndy Fiddaman 
948*b30d1939SAndy Fiddaman #else
949*b30d1939SAndy Fiddaman 
sh_addlib(Shell_t * shp,void * library,char * name,Pathcomp_t * pp)950*b30d1939SAndy Fiddaman int sh_addlib(Shell_t* shp, void* library, char* name, Pathcomp_t* pp)
951*b30d1939SAndy Fiddaman {
952*b30d1939SAndy Fiddaman 	return 0;
953*b30d1939SAndy Fiddaman }
954*b30d1939SAndy Fiddaman 
sh_getlib(Shell_t * shp,char * name,Pathcomp_t * pp)955*b30d1939SAndy Fiddaman Shbltin_f sh_getlib(Shell_t* shp, char* name, Pathcomp_t* pp)
956*b30d1939SAndy Fiddaman {
957*b30d1939SAndy Fiddaman 	return 0;
958*b30d1939SAndy Fiddaman }
959*b30d1939SAndy Fiddaman 
960*b30d1939SAndy Fiddaman #endif /* SHOPT_DYNAMIC */
961*b30d1939SAndy Fiddaman 
962*b30d1939SAndy Fiddaman /*
963*b30d1939SAndy Fiddaman  * add change or list built-ins
964*b30d1939SAndy Fiddaman  * adding builtins requires dlopen() interface
965*b30d1939SAndy Fiddaman  */
b_builtin(int argc,char * argv[],Shbltin_t * context)966*b30d1939SAndy Fiddaman int	b_builtin(int argc,char *argv[],Shbltin_t *context)
967*b30d1939SAndy Fiddaman {
968*b30d1939SAndy Fiddaman 	register char *arg=0, *name;
969*b30d1939SAndy Fiddaman 	register int n, r=0, flag=0;
970*b30d1939SAndy Fiddaman 	register Namval_t *np;
971*b30d1939SAndy Fiddaman 	long dlete=0;
972*b30d1939SAndy Fiddaman 	struct tdata tdata;
973*b30d1939SAndy Fiddaman 	Shbltin_f addr;
974*b30d1939SAndy Fiddaman 	Stk_t	*stkp;
975*b30d1939SAndy Fiddaman 	void *library=0;
976*b30d1939SAndy Fiddaman 	char *errmsg;
977*b30d1939SAndy Fiddaman #ifdef SH_PLUGIN_VERSION
978*b30d1939SAndy Fiddaman 	unsigned long ver;
979*b30d1939SAndy Fiddaman 	int list = 0;
980*b30d1939SAndy Fiddaman 	char path[1024];
981*b30d1939SAndy Fiddaman #endif
982*b30d1939SAndy Fiddaman 	NOT_USED(argc);
983*b30d1939SAndy Fiddaman 	memset(&tdata,0,sizeof(tdata));
984*b30d1939SAndy Fiddaman 	tdata.sh = context->shp;
985*b30d1939SAndy Fiddaman 	stkp = tdata.sh->stk;
986*b30d1939SAndy Fiddaman 	if(!tdata.sh->pathlist)
987*b30d1939SAndy Fiddaman 		path_absolute(tdata.sh,argv[0],NIL(Pathcomp_t*));
988*b30d1939SAndy Fiddaman 	while (n = optget(argv,sh_optbuiltin)) switch (n)
989*b30d1939SAndy Fiddaman 	{
990*b30d1939SAndy Fiddaman 	    case 's':
991*b30d1939SAndy Fiddaman 		flag = BLT_SPC;
992*b30d1939SAndy Fiddaman 		break;
993*b30d1939SAndy Fiddaman 	    case 'd':
994*b30d1939SAndy Fiddaman 		dlete=1;
995*b30d1939SAndy Fiddaman 		break;
996*b30d1939SAndy Fiddaman 	    case 'f':
997*b30d1939SAndy Fiddaman #if SHOPT_DYNAMIC
998*b30d1939SAndy Fiddaman 		arg = opt_info.arg;
999*b30d1939SAndy Fiddaman #else
1000*b30d1939SAndy Fiddaman 		errormsg(SH_DICT,2, "adding built-ins not supported");
1001*b30d1939SAndy Fiddaman 		error_info.errors++;
1002*b30d1939SAndy Fiddaman #endif /* SHOPT_DYNAMIC */
1003*b30d1939SAndy Fiddaman 		break;
1004*b30d1939SAndy Fiddaman 	    case 'l':
1005*b30d1939SAndy Fiddaman #ifdef SH_PLUGIN_VERSION
1006*b30d1939SAndy Fiddaman 		list = 1;
1007*b30d1939SAndy Fiddaman #endif
1008*b30d1939SAndy Fiddaman 	        break;
1009*b30d1939SAndy Fiddaman 	    case ':':
1010*b30d1939SAndy Fiddaman 		errormsg(SH_DICT,2, "%s", opt_info.arg);
1011*b30d1939SAndy Fiddaman 		break;
1012*b30d1939SAndy Fiddaman 	    case '?':
1013*b30d1939SAndy Fiddaman 		errormsg(SH_DICT,ERROR_usage(2), "%s", opt_info.arg);
1014*b30d1939SAndy Fiddaman 		break;
1015*b30d1939SAndy Fiddaman 	}
1016*b30d1939SAndy Fiddaman 	argv += opt_info.index;
1017*b30d1939SAndy Fiddaman 	if(error_info.errors)
1018*b30d1939SAndy Fiddaman 		errormsg(SH_DICT,ERROR_usage(2),"%s", optusage(NIL(char*)));
1019*b30d1939SAndy Fiddaman 	if(arg || *argv)
1020*b30d1939SAndy Fiddaman 	{
1021*b30d1939SAndy Fiddaman 		if(sh_isoption(SH_RESTRICTED))
1022*b30d1939SAndy Fiddaman 			errormsg(SH_DICT,ERROR_exit(1),e_restricted,argv[-opt_info.index]);
1023*b30d1939SAndy Fiddaman 		if(sh_isoption(SH_PFSH))
1024*b30d1939SAndy Fiddaman 			errormsg(SH_DICT,ERROR_exit(1),e_pfsh,argv[-opt_info.index]);
1025*b30d1939SAndy Fiddaman 		if(tdata.sh->subshell && !tdata.sh->subshare)
1026*b30d1939SAndy Fiddaman 			sh_subfork();
1027*b30d1939SAndy Fiddaman 	}
1028*b30d1939SAndy Fiddaman #if SHOPT_DYNAMIC
1029*b30d1939SAndy Fiddaman 	if(arg)
1030*b30d1939SAndy Fiddaman 	{
1031*b30d1939SAndy Fiddaman #ifdef SH_PLUGIN_VERSION
1032*b30d1939SAndy Fiddaman 		if(!(library = dllplugin(SH_ID, arg, NiL, SH_PLUGIN_VERSION, &ver, RTLD_LAZY, path, sizeof(path))))
1033*b30d1939SAndy Fiddaman 		{
1034*b30d1939SAndy Fiddaman 			errormsg(SH_DICT,ERROR_exit(0),"%s: %s",arg,dllerror(0));
1035*b30d1939SAndy Fiddaman 			return(1);
1036*b30d1939SAndy Fiddaman 		}
1037*b30d1939SAndy Fiddaman 		if(list)
1038*b30d1939SAndy Fiddaman 			sfprintf(sfstdout, "%s %08lu %s\n", arg, ver, path);
1039*b30d1939SAndy Fiddaman #else
1040*b30d1939SAndy Fiddaman #if (_AST_VERSION>=20040404)
1041*b30d1939SAndy Fiddaman 		if(!(library = dllplug(SH_ID,arg,NIL(char*),RTLD_LAZY,NIL(char*),0)))
1042*b30d1939SAndy Fiddaman #else
1043*b30d1939SAndy Fiddaman 		if(!(library = dllfind(arg,NIL(char*),RTLD_LAZY,NIL(char*),0)))
1044*b30d1939SAndy Fiddaman #endif
1045*b30d1939SAndy Fiddaman 		{
1046*b30d1939SAndy Fiddaman 			errormsg(SH_DICT,ERROR_exit(0),"%s: %s",arg,dlerror());
1047*b30d1939SAndy Fiddaman 			return(1);
1048*b30d1939SAndy Fiddaman 		}
1049*b30d1939SAndy Fiddaman #endif
1050*b30d1939SAndy Fiddaman 		sh_addlib(tdata.sh,library,arg,NiL);
1051*b30d1939SAndy Fiddaman 	}
1052*b30d1939SAndy Fiddaman 	else
1053*b30d1939SAndy Fiddaman #endif /* SHOPT_DYNAMIC */
1054*b30d1939SAndy Fiddaman 	if(*argv==0 && !dlete)
1055*b30d1939SAndy Fiddaman 	{
1056*b30d1939SAndy Fiddaman 		print_scan(sfstdout, flag, tdata.sh->bltin_tree, 1, &tdata);
1057*b30d1939SAndy Fiddaman 		return(0);
1058*b30d1939SAndy Fiddaman 	}
1059*b30d1939SAndy Fiddaman 	r = 0;
1060*b30d1939SAndy Fiddaman 	flag = stktell(stkp);
1061*b30d1939SAndy Fiddaman 	while(arg = *argv)
1062*b30d1939SAndy Fiddaman 	{
1063*b30d1939SAndy Fiddaman 		name = path_basename(arg);
1064*b30d1939SAndy Fiddaman 		sfwrite(stkp,"b_",2);
1065*b30d1939SAndy Fiddaman 		sfputr(stkp,name,0);
1066*b30d1939SAndy Fiddaman 		errmsg = 0;
1067*b30d1939SAndy Fiddaman 		addr = 0;
1068*b30d1939SAndy Fiddaman 		if(dlete || liblist)
1069*b30d1939SAndy Fiddaman 			for(n=(nlib?nlib:dlete); --n>=0;)
1070*b30d1939SAndy Fiddaman 			{
1071*b30d1939SAndy Fiddaman #if SHOPT_DYNAMIC
1072*b30d1939SAndy Fiddaman 				if(!dlete && !liblist[n].dll)
1073*b30d1939SAndy Fiddaman 					continue;
1074*b30d1939SAndy Fiddaman 				if(dlete || (addr = (Shbltin_f)dlllook(liblist[n].dll,stkptr(stkp,flag))))
1075*b30d1939SAndy Fiddaman #else
1076*b30d1939SAndy Fiddaman 				if(dlete)
1077*b30d1939SAndy Fiddaman #endif /* SHOPT_DYNAMIC */
1078*b30d1939SAndy Fiddaman 				{
1079*b30d1939SAndy Fiddaman 					if(np = sh_addbuiltin(arg, addr,pointerof(dlete)))
1080*b30d1939SAndy Fiddaman 					{
1081*b30d1939SAndy Fiddaman 						if(dlete || nv_isattr(np,BLT_SPC))
1082*b30d1939SAndy Fiddaman 							errmsg = "restricted name";
1083*b30d1939SAndy Fiddaman #if SHOPT_DYNAMIC
1084*b30d1939SAndy Fiddaman 						else
1085*b30d1939SAndy Fiddaman 							nv_onattr(np,liblist[n].attr);
1086*b30d1939SAndy Fiddaman #endif /* SHOPT_DYNAMIC */
1087*b30d1939SAndy Fiddaman 					}
1088*b30d1939SAndy Fiddaman 					break;
1089*b30d1939SAndy Fiddaman 				}
1090*b30d1939SAndy Fiddaman 			}
1091*b30d1939SAndy Fiddaman 		if(!addr && (np = nv_search(arg,context->shp->bltin_tree,0)))
1092*b30d1939SAndy Fiddaman 		{
1093*b30d1939SAndy Fiddaman 			if(nv_isattr(np,BLT_SPC))
1094*b30d1939SAndy Fiddaman 				errmsg = "restricted name";
1095*b30d1939SAndy Fiddaman 			addr = (Shbltin_f)np->nvalue.bfp;
1096*b30d1939SAndy Fiddaman 		}
1097*b30d1939SAndy Fiddaman 		if(!dlete && !addr && !(np=sh_addbuiltin(arg,(Shbltin_f)0 ,0)))
1098*b30d1939SAndy Fiddaman 			errmsg = "not found";
1099*b30d1939SAndy Fiddaman 		if(errmsg)
1100*b30d1939SAndy Fiddaman 		{
1101*b30d1939SAndy Fiddaman 			errormsg(SH_DICT,ERROR_exit(0),"%s: %s",*argv,errmsg);
1102*b30d1939SAndy Fiddaman 			r = 1;
1103*b30d1939SAndy Fiddaman 		}
1104*b30d1939SAndy Fiddaman 		stkseek(stkp,flag);
1105*b30d1939SAndy Fiddaman 		argv++;
1106*b30d1939SAndy Fiddaman 	}
1107*b30d1939SAndy Fiddaman 	return(r);
1108*b30d1939SAndy Fiddaman }
1109*b30d1939SAndy Fiddaman 
b_set(int argc,register char * argv[],Shbltin_t * context)1110*b30d1939SAndy Fiddaman int    b_set(int argc,register char *argv[],Shbltin_t *context)
1111*b30d1939SAndy Fiddaman {
1112*b30d1939SAndy Fiddaman 	struct tdata tdata;
1113*b30d1939SAndy Fiddaman 	int was_monitor = sh_isoption(SH_MONITOR);
1114*b30d1939SAndy Fiddaman 	memset(&tdata,0,sizeof(tdata));
1115*b30d1939SAndy Fiddaman 	tdata.sh = context->shp;
1116*b30d1939SAndy Fiddaman 	tdata.prefix=0;
1117*b30d1939SAndy Fiddaman 	if(argv[1])
1118*b30d1939SAndy Fiddaman 	{
1119*b30d1939SAndy Fiddaman 		if(sh_argopts(argc,argv,tdata.sh) < 0)
1120*b30d1939SAndy Fiddaman 			return(2);
1121*b30d1939SAndy Fiddaman 		if(sh_isoption(SH_VERBOSE))
1122*b30d1939SAndy Fiddaman 			sh_onstate(SH_VERBOSE);
1123*b30d1939SAndy Fiddaman 		else
1124*b30d1939SAndy Fiddaman 			sh_offstate(SH_VERBOSE);
1125*b30d1939SAndy Fiddaman 		if(sh_isoption(SH_MONITOR) && !was_monitor)
1126*b30d1939SAndy Fiddaman 			sh_onstate(SH_MONITOR);
1127*b30d1939SAndy Fiddaman 		else if(!sh_isoption(SH_MONITOR)  && was_monitor)
1128*b30d1939SAndy Fiddaman 			sh_offstate(SH_MONITOR);
1129*b30d1939SAndy Fiddaman 	}
1130*b30d1939SAndy Fiddaman 	else
1131*b30d1939SAndy Fiddaman 		/*scan name chain and print*/
1132*b30d1939SAndy Fiddaman 		print_scan(sfstdout,0,tdata.sh->var_tree,0,&tdata);
1133*b30d1939SAndy Fiddaman 	return(0);
1134*b30d1939SAndy Fiddaman }
1135*b30d1939SAndy Fiddaman 
1136*b30d1939SAndy Fiddaman /*
1137*b30d1939SAndy Fiddaman  * The removing of Shell variable names, aliases, and functions
1138*b30d1939SAndy Fiddaman  * is performed here.
1139*b30d1939SAndy Fiddaman  * Unset functions with unset -f
1140*b30d1939SAndy Fiddaman  * Non-existent items being deleted give non-zero exit status
1141*b30d1939SAndy Fiddaman  */
1142*b30d1939SAndy Fiddaman 
b_unalias(int argc,register char * argv[],Shbltin_t * context)1143*b30d1939SAndy Fiddaman int    b_unalias(int argc,register char *argv[],Shbltin_t *context)
1144*b30d1939SAndy Fiddaman {
1145*b30d1939SAndy Fiddaman 	Shell_t *shp = context->shp;
1146*b30d1939SAndy Fiddaman 	return(unall(argc,argv,shp->alias_tree,shp));
1147*b30d1939SAndy Fiddaman }
1148*b30d1939SAndy Fiddaman 
b_unset(int argc,register char * argv[],Shbltin_t * context)1149*b30d1939SAndy Fiddaman int    b_unset(int argc,register char *argv[],Shbltin_t *context)
1150*b30d1939SAndy Fiddaman {
1151*b30d1939SAndy Fiddaman 	Shell_t *shp = context->shp;
1152*b30d1939SAndy Fiddaman 	return(unall(argc,argv,shp->var_tree,shp));
1153*b30d1939SAndy Fiddaman }
1154*b30d1939SAndy Fiddaman 
unall(int argc,char ** argv,register Dt_t * troot,Shell_t * shp)1155*b30d1939SAndy Fiddaman static int unall(int argc, char **argv, register Dt_t *troot, Shell_t* shp)
1156*b30d1939SAndy Fiddaman {
1157*b30d1939SAndy Fiddaman 	register Namval_t *np;
1158*b30d1939SAndy Fiddaman 	register const char *name;
1159*b30d1939SAndy Fiddaman 	volatile int r;
1160*b30d1939SAndy Fiddaman 	Dt_t	*dp;
1161*b30d1939SAndy Fiddaman 	int nflag=0,all=0,isfun,jmpval;
1162*b30d1939SAndy Fiddaman 	struct checkpt buff;
1163*b30d1939SAndy Fiddaman 	NOT_USED(argc);
1164*b30d1939SAndy Fiddaman 	if(troot==shp->alias_tree)
1165*b30d1939SAndy Fiddaman 	{
1166*b30d1939SAndy Fiddaman 		name = sh_optunalias;
1167*b30d1939SAndy Fiddaman 		if(shp->subshell)
1168*b30d1939SAndy Fiddaman 			troot = sh_subaliastree(0);
1169*b30d1939SAndy Fiddaman 	}
1170*b30d1939SAndy Fiddaman 	else
1171*b30d1939SAndy Fiddaman 		name = sh_optunset;
1172*b30d1939SAndy Fiddaman 	while(r = optget(argv,name)) switch(r)
1173*b30d1939SAndy Fiddaman 	{
1174*b30d1939SAndy Fiddaman 		case 'f':
1175*b30d1939SAndy Fiddaman 			troot = sh_subfuntree(1);
1176*b30d1939SAndy Fiddaman 			break;
1177*b30d1939SAndy Fiddaman 		case 'a':
1178*b30d1939SAndy Fiddaman 			all=1;
1179*b30d1939SAndy Fiddaman 			break;
1180*b30d1939SAndy Fiddaman 		case 'n':
1181*b30d1939SAndy Fiddaman 			nflag = NV_NOREF;
1182*b30d1939SAndy Fiddaman 			/* FALLTHROUGH */
1183*b30d1939SAndy Fiddaman 		case 'v':
1184*b30d1939SAndy Fiddaman 			troot = shp->var_tree;
1185*b30d1939SAndy Fiddaman 			break;
1186*b30d1939SAndy Fiddaman 		case ':':
1187*b30d1939SAndy Fiddaman 			errormsg(SH_DICT,2, "%s", opt_info.arg);
1188*b30d1939SAndy Fiddaman 			break;
1189*b30d1939SAndy Fiddaman 		case '?':
1190*b30d1939SAndy Fiddaman 			errormsg(SH_DICT,ERROR_usage(0), "%s", opt_info.arg);
1191*b30d1939SAndy Fiddaman 			return(2);
1192*b30d1939SAndy Fiddaman 	}
1193*b30d1939SAndy Fiddaman 	argv += opt_info.index;
1194*b30d1939SAndy Fiddaman 	if(error_info.errors || (*argv==0 &&!all))
1195*b30d1939SAndy Fiddaman 		errormsg(SH_DICT,ERROR_usage(2),"%s",optusage(NIL(char*)));
1196*b30d1939SAndy Fiddaman 	if(!troot)
1197*b30d1939SAndy Fiddaman 		return(1);
1198*b30d1939SAndy Fiddaman 	r = 0;
1199*b30d1939SAndy Fiddaman 	if(troot==shp->var_tree)
1200*b30d1939SAndy Fiddaman 		nflag |= NV_VARNAME;
1201*b30d1939SAndy Fiddaman 	else
1202*b30d1939SAndy Fiddaman 		nflag = NV_NOSCOPE;
1203*b30d1939SAndy Fiddaman 	if(all)
1204*b30d1939SAndy Fiddaman 	{
1205*b30d1939SAndy Fiddaman 		dtclear(troot);
1206*b30d1939SAndy Fiddaman 		return(r);
1207*b30d1939SAndy Fiddaman 	}
1208*b30d1939SAndy Fiddaman 	sh_pushcontext(shp,&buff,1);
1209*b30d1939SAndy Fiddaman 	while(name = *argv++)
1210*b30d1939SAndy Fiddaman 	{
1211*b30d1939SAndy Fiddaman 		jmpval = sigsetjmp(buff.buff,0);
1212*b30d1939SAndy Fiddaman 		np = 0;
1213*b30d1939SAndy Fiddaman 		if(jmpval==0)
1214*b30d1939SAndy Fiddaman 		{
1215*b30d1939SAndy Fiddaman #if SHOPT_NAMESPACE
1216*b30d1939SAndy Fiddaman 			if(shp->namespace && troot!=shp->var_tree)
1217*b30d1939SAndy Fiddaman 				np = sh_fsearch(shp,name,nflag?HASH_NOSCOPE:0);
1218*b30d1939SAndy Fiddaman 			if(!np)
1219*b30d1939SAndy Fiddaman #endif /* SHOPT_NAMESPACE */
1220*b30d1939SAndy Fiddaman 			np=nv_open(name,troot,NV_NOADD|nflag);
1221*b30d1939SAndy Fiddaman 		}
1222*b30d1939SAndy Fiddaman 		else
1223*b30d1939SAndy Fiddaman 		{
1224*b30d1939SAndy Fiddaman 			r = 1;
1225*b30d1939SAndy Fiddaman 			continue;
1226*b30d1939SAndy Fiddaman 		}
1227*b30d1939SAndy Fiddaman 		if(np)
1228*b30d1939SAndy Fiddaman 		{
1229*b30d1939SAndy Fiddaman 			if(is_abuiltin(np) || nv_isattr(np,NV_RDONLY))
1230*b30d1939SAndy Fiddaman 			{
1231*b30d1939SAndy Fiddaman 				if(nv_isattr(np,NV_RDONLY))
1232*b30d1939SAndy Fiddaman 					errormsg(SH_DICT,ERROR_warn(0),e_readonly, nv_name(np));
1233*b30d1939SAndy Fiddaman 				r = 1;
1234*b30d1939SAndy Fiddaman 				continue;
1235*b30d1939SAndy Fiddaman 			}
1236*b30d1939SAndy Fiddaman 			isfun = is_afunction(np);
1237*b30d1939SAndy Fiddaman 			if(troot==shp->var_tree)
1238*b30d1939SAndy Fiddaman 			{
1239*b30d1939SAndy Fiddaman 				Namarr_t *ap;
1240*b30d1939SAndy Fiddaman #if SHOPT_FIXEDARRAY
1241*b30d1939SAndy Fiddaman 				if((ap=nv_arrayptr(np)) && !ap->fixed  && name[strlen(name)-1]==']' && !nv_getsub(np))
1242*b30d1939SAndy Fiddaman #else
1243*b30d1939SAndy Fiddaman 				if(nv_isarray(np) && name[strlen(name)-1]==']' && !nv_getsub(np))
1244*b30d1939SAndy Fiddaman #endif /* SHOPT_FIXEDARRAY */
1245*b30d1939SAndy Fiddaman 				{
1246*b30d1939SAndy Fiddaman 					r=1;
1247*b30d1939SAndy Fiddaman 					continue;
1248*b30d1939SAndy Fiddaman 				}
1249*b30d1939SAndy Fiddaman 
1250*b30d1939SAndy Fiddaman 				if(shp->subshell)
1251*b30d1939SAndy Fiddaman 					np=sh_assignok(np,0);
1252*b30d1939SAndy Fiddaman 			}
1253*b30d1939SAndy Fiddaman 			if(!nv_isnull(np) || nv_size(np) || nv_isattr(np,~(NV_MINIMAL|NV_NOFREE)))
1254*b30d1939SAndy Fiddaman 				_nv_unset(np,0);
1255*b30d1939SAndy Fiddaman 			if(troot==shp->var_tree && shp->st.real_fun && (dp=shp->var_tree->walk) && dp==shp->st.real_fun->sdict)
1256*b30d1939SAndy Fiddaman 				nv_delete(np,dp,NV_NOFREE);
1257*b30d1939SAndy Fiddaman 			else if(isfun && !(np->nvalue.rp && np->nvalue.rp->running))
1258*b30d1939SAndy Fiddaman 				nv_delete(np,troot,0);
1259*b30d1939SAndy Fiddaman #if 0
1260*b30d1939SAndy Fiddaman 			/* causes unsetting local variable to expose global */
1261*b30d1939SAndy Fiddaman 			else if(shp->var_tree==troot && shp->var_tree!=shp->var_base && nv_search((char*)np,shp->var_tree,HASH_BUCKET|HASH_NOSCOPE))
1262*b30d1939SAndy Fiddaman 				nv_delete(np,shp->var_tree,0);
1263*b30d1939SAndy Fiddaman #endif
1264*b30d1939SAndy Fiddaman 			else
1265*b30d1939SAndy Fiddaman 				nv_close(np);
1266*b30d1939SAndy Fiddaman 
1267*b30d1939SAndy Fiddaman 		}
1268*b30d1939SAndy Fiddaman 		else if(troot==shp->alias_tree)
1269*b30d1939SAndy Fiddaman 			r = 1;
1270*b30d1939SAndy Fiddaman 	}
1271*b30d1939SAndy Fiddaman 	sh_popcontext(shp,&buff);
1272*b30d1939SAndy Fiddaman 	return(r);
1273*b30d1939SAndy Fiddaman }
1274*b30d1939SAndy Fiddaman 
1275*b30d1939SAndy Fiddaman /*
1276*b30d1939SAndy Fiddaman  * print out the name and value of a name-value pair <np>
1277*b30d1939SAndy Fiddaman  */
1278*b30d1939SAndy Fiddaman 
print_namval(Sfio_t * file,register Namval_t * np,register int flag,struct tdata * tp)1279*b30d1939SAndy Fiddaman static int print_namval(Sfio_t *file,register Namval_t *np,register int flag, struct tdata *tp)
1280*b30d1939SAndy Fiddaman {
1281*b30d1939SAndy Fiddaman 	register char *cp;
1282*b30d1939SAndy Fiddaman 	int	indent=tp->indent, outname=0, isfun;
1283*b30d1939SAndy Fiddaman 	sh_sigcheck(tp->sh);
1284*b30d1939SAndy Fiddaman 	if(flag)
1285*b30d1939SAndy Fiddaman 		flag = '\n';
1286*b30d1939SAndy Fiddaman 	if(tp->noref && nv_isref(np))
1287*b30d1939SAndy Fiddaman 		return(0);
1288*b30d1939SAndy Fiddaman 	if(nv_isattr(np,NV_NOPRINT|NV_INTEGER)==NV_NOPRINT)
1289*b30d1939SAndy Fiddaman 	{
1290*b30d1939SAndy Fiddaman 		if(is_abuiltin(np) && strcmp(np->nvname,".sh.tilde"))
1291*b30d1939SAndy Fiddaman 			sfputr(file,nv_name(np),'\n');
1292*b30d1939SAndy Fiddaman 		return(0);
1293*b30d1939SAndy Fiddaman 	}
1294*b30d1939SAndy Fiddaman 	if(nv_istable(np))
1295*b30d1939SAndy Fiddaman 	{
1296*b30d1939SAndy Fiddaman 		print_value(file,np,tp);
1297*b30d1939SAndy Fiddaman 		return(0);
1298*b30d1939SAndy Fiddaman 	}
1299*b30d1939SAndy Fiddaman 	isfun = is_afunction(np);
1300*b30d1939SAndy Fiddaman 	if(tp->prefix)
1301*b30d1939SAndy Fiddaman 	{
1302*b30d1939SAndy Fiddaman 		outname = (*tp->prefix=='t' &&  (!nv_isnull(np) || nv_isattr(np,NV_FLOAT|NV_RDONLY|NV_BINARY|NV_RJUST|NV_NOPRINT)));
1303*b30d1939SAndy Fiddaman 		if(indent && (isfun || outname || *tp->prefix!='t'))
1304*b30d1939SAndy Fiddaman 		{
1305*b30d1939SAndy Fiddaman 			sfnputc(file,'\t',indent);
1306*b30d1939SAndy Fiddaman 			indent = 0;
1307*b30d1939SAndy Fiddaman 		}
1308*b30d1939SAndy Fiddaman 		if(!isfun)
1309*b30d1939SAndy Fiddaman 		{
1310*b30d1939SAndy Fiddaman 			if(*tp->prefix=='t')
1311*b30d1939SAndy Fiddaman 			nv_attribute(np,tp->outfile,tp->prefix,tp->aflag);
1312*b30d1939SAndy Fiddaman 			else
1313*b30d1939SAndy Fiddaman 				sfputr(file,tp->prefix,' ');
1314*b30d1939SAndy Fiddaman 		}
1315*b30d1939SAndy Fiddaman 	}
1316*b30d1939SAndy Fiddaman 	if(isfun)
1317*b30d1939SAndy Fiddaman 	{
1318*b30d1939SAndy Fiddaman 		Sfio_t *iop=0;
1319*b30d1939SAndy Fiddaman 		char *fname=0;
1320*b30d1939SAndy Fiddaman 		if(nv_isattr(np,NV_NOFREE))
1321*b30d1939SAndy Fiddaman 			return(0);
1322*b30d1939SAndy Fiddaman 		if(!flag && !np->nvalue.ip)
1323*b30d1939SAndy Fiddaman 			sfputr(file,"typeset -fu",' ');
1324*b30d1939SAndy Fiddaman 		else if(!flag && !nv_isattr(np,NV_FPOSIX))
1325*b30d1939SAndy Fiddaman 			sfputr(file,"function",' ');
1326*b30d1939SAndy Fiddaman 		cp = nv_name(np);
1327*b30d1939SAndy Fiddaman 		if(tp->wctname)
1328*b30d1939SAndy Fiddaman 			cp += strlen(tp->wctname)+1;
1329*b30d1939SAndy Fiddaman 		sfputr(file,cp,-1);
1330*b30d1939SAndy Fiddaman 		if(nv_isattr(np,NV_FPOSIX))
1331*b30d1939SAndy Fiddaman 			sfwrite(file,"()",2);
1332*b30d1939SAndy Fiddaman 		if(np->nvalue.ip && np->nvalue.rp->hoffset>=0)
1333*b30d1939SAndy Fiddaman 			fname = np->nvalue.rp->fname;
1334*b30d1939SAndy Fiddaman 		else
1335*b30d1939SAndy Fiddaman 			flag = '\n';
1336*b30d1939SAndy Fiddaman 		if(flag)
1337*b30d1939SAndy Fiddaman 		{
1338*b30d1939SAndy Fiddaman 			if(tp->pflag && np->nvalue.ip && np->nvalue.rp->hoffset>=0)
1339*b30d1939SAndy Fiddaman 				sfprintf(file," #line %d %s\n",np->nvalue.rp->lineno,fname?sh_fmtq(fname):"");
1340*b30d1939SAndy Fiddaman 			else
1341*b30d1939SAndy Fiddaman 				sfputc(file, '\n');
1342*b30d1939SAndy Fiddaman 		}
1343*b30d1939SAndy Fiddaman 		else
1344*b30d1939SAndy Fiddaman 		{
1345*b30d1939SAndy Fiddaman 			if(nv_isattr(np,NV_FTMP))
1346*b30d1939SAndy Fiddaman 			{
1347*b30d1939SAndy Fiddaman 				fname = 0;
1348*b30d1939SAndy Fiddaman 				iop = tp->sh->heredocs;
1349*b30d1939SAndy Fiddaman 			}
1350*b30d1939SAndy Fiddaman 			else if(fname)
1351*b30d1939SAndy Fiddaman 				iop = sfopen(iop,fname,"r");
1352*b30d1939SAndy Fiddaman 			else if(tp->sh->gd->hist_ptr)
1353*b30d1939SAndy Fiddaman 				iop = (tp->sh->gd->hist_ptr)->histfp;
1354*b30d1939SAndy Fiddaman 			if(iop && sfseek(iop,(Sfoff_t)np->nvalue.rp->hoffset,SEEK_SET)>=0)
1355*b30d1939SAndy Fiddaman 				sfmove(iop,file, nv_size(np), -1);
1356*b30d1939SAndy Fiddaman 			else
1357*b30d1939SAndy Fiddaman 				flag = '\n';
1358*b30d1939SAndy Fiddaman 			if(fname)
1359*b30d1939SAndy Fiddaman 				sfclose(iop);
1360*b30d1939SAndy Fiddaman 		}
1361*b30d1939SAndy Fiddaman 		return(nv_size(np)+1);
1362*b30d1939SAndy Fiddaman 	}
1363*b30d1939SAndy Fiddaman 	if(nv_arrayptr(np))
1364*b30d1939SAndy Fiddaman 	{
1365*b30d1939SAndy Fiddaman 		if(indent)
1366*b30d1939SAndy Fiddaman 			sfnputc(file,'\t',indent);
1367*b30d1939SAndy Fiddaman 		print_value(file,np,tp);
1368*b30d1939SAndy Fiddaman 		return(0);
1369*b30d1939SAndy Fiddaman 	}
1370*b30d1939SAndy Fiddaman 	if(nv_isvtree(np))
1371*b30d1939SAndy Fiddaman 		nv_onattr(np,NV_EXPORT);
1372*b30d1939SAndy Fiddaman 	if(cp=nv_getval(np))
1373*b30d1939SAndy Fiddaman 	{
1374*b30d1939SAndy Fiddaman 		if(indent)
1375*b30d1939SAndy Fiddaman 			sfnputc(file,'\t',indent);
1376*b30d1939SAndy Fiddaman 		sfputr(file,nv_name(np),-1);
1377*b30d1939SAndy Fiddaman 		if(!flag)
1378*b30d1939SAndy Fiddaman 			flag = '=';
1379*b30d1939SAndy Fiddaman 		sfputc(file,flag);
1380*b30d1939SAndy Fiddaman 		if(flag != '\n')
1381*b30d1939SAndy Fiddaman 		{
1382*b30d1939SAndy Fiddaman 			if(nv_isref(np) && nv_refsub(np))
1383*b30d1939SAndy Fiddaman 			{
1384*b30d1939SAndy Fiddaman 				sfputr(file,sh_fmtq(cp),-1);
1385*b30d1939SAndy Fiddaman 				sfprintf(file,"[%s]\n", sh_fmtq(nv_refsub(np)));
1386*b30d1939SAndy Fiddaman 			}
1387*b30d1939SAndy Fiddaman 			else
1388*b30d1939SAndy Fiddaman #if SHOPT_TYPEDEF
1389*b30d1939SAndy Fiddaman 				sfputr(file,nv_isvtree(np)?cp:sh_fmtq(cp),'\n');
1390*b30d1939SAndy Fiddaman #else
1391*b30d1939SAndy Fiddaman 				sfputr(file,sh_fmtq(cp),'\n');
1392*b30d1939SAndy Fiddaman #endif /* SHOPT_TYPEDEF */
1393*b30d1939SAndy Fiddaman 		}
1394*b30d1939SAndy Fiddaman 		return(1);
1395*b30d1939SAndy Fiddaman 	}
1396*b30d1939SAndy Fiddaman 	else if(outname || (tp->scanmask && tp->scanroot==tp->sh->var_tree))
1397*b30d1939SAndy Fiddaman 		sfputr(file,nv_name(np),'\n');
1398*b30d1939SAndy Fiddaman 	return(0);
1399*b30d1939SAndy Fiddaman }
1400*b30d1939SAndy Fiddaman 
1401*b30d1939SAndy Fiddaman /*
1402*b30d1939SAndy Fiddaman  * print attributes at all nodes
1403*b30d1939SAndy Fiddaman  */
print_all(Sfio_t * file,Dt_t * root,struct tdata * tp)1404*b30d1939SAndy Fiddaman static void	print_all(Sfio_t *file,Dt_t *root, struct tdata *tp)
1405*b30d1939SAndy Fiddaman {
1406*b30d1939SAndy Fiddaman 	tp->outfile = file;
1407*b30d1939SAndy Fiddaman 	nv_scan(root, print_attribute, (void*)tp, 0, 0);
1408*b30d1939SAndy Fiddaman }
1409*b30d1939SAndy Fiddaman 
1410*b30d1939SAndy Fiddaman /*
1411*b30d1939SAndy Fiddaman  * print the attributes of name value pair give by <np>
1412*b30d1939SAndy Fiddaman  */
print_attribute(register Namval_t * np,void * data)1413*b30d1939SAndy Fiddaman static void	print_attribute(register Namval_t *np,void *data)
1414*b30d1939SAndy Fiddaman {
1415*b30d1939SAndy Fiddaman 	register struct tdata *dp = (struct tdata*)data;
1416*b30d1939SAndy Fiddaman 	nv_attribute(np,dp->outfile,dp->prefix,dp->aflag);
1417*b30d1939SAndy Fiddaman }
1418*b30d1939SAndy Fiddaman 
1419*b30d1939SAndy Fiddaman /*
1420*b30d1939SAndy Fiddaman  * print the nodes in tree <root> which have attributes <flag> set
1421*b30d1939SAndy Fiddaman  * of <option> is non-zero, no subscript or value is printed.
1422*b30d1939SAndy Fiddaman  */
1423*b30d1939SAndy Fiddaman 
print_scan(Sfio_t * file,int flag,Dt_t * root,int option,struct tdata * tp)1424*b30d1939SAndy Fiddaman static void print_scan(Sfio_t *file, int flag, Dt_t *root, int option,struct tdata *tp)
1425*b30d1939SAndy Fiddaman {
1426*b30d1939SAndy Fiddaman 	register char **argv;
1427*b30d1939SAndy Fiddaman 	register Namval_t *np;
1428*b30d1939SAndy Fiddaman 	register int namec;
1429*b30d1939SAndy Fiddaman 	Namval_t *onp = 0;
1430*b30d1939SAndy Fiddaman 	char	*name=0;
1431*b30d1939SAndy Fiddaman 	int	len;
1432*b30d1939SAndy Fiddaman 	tp->sh->last_table=0;
1433*b30d1939SAndy Fiddaman 	flag &= ~NV_ASSIGN;
1434*b30d1939SAndy Fiddaman 	tp->scanmask = flag&~NV_NOSCOPE;
1435*b30d1939SAndy Fiddaman 	tp->scanroot = root;
1436*b30d1939SAndy Fiddaman 	tp->outfile = file;
1437*b30d1939SAndy Fiddaman #if SHOPT_TYPEDEF
1438*b30d1939SAndy Fiddaman 	if(!tp->prefix && tp->tp)
1439*b30d1939SAndy Fiddaman 		tp->prefix = nv_name(tp->tp);
1440*b30d1939SAndy Fiddaman #endif /* SHOPT_TYPEDEF */
1441*b30d1939SAndy Fiddaman 	if(flag&NV_INTEGER)
1442*b30d1939SAndy Fiddaman 		tp->scanmask |= (NV_DOUBLE|NV_EXPNOTE);
1443*b30d1939SAndy Fiddaman 	if(flag==NV_LTOU || flag==NV_UTOL)
1444*b30d1939SAndy Fiddaman 		tp->scanmask |= NV_UTOL|NV_LTOU;
1445*b30d1939SAndy Fiddaman 	namec = nv_scan(root,nullscan,(void*)tp,tp->scanmask,flag);
1446*b30d1939SAndy Fiddaman 	argv = tp->argnam  = (char**)stkalloc(tp->sh->stk,(namec+1)*sizeof(char*));
1447*b30d1939SAndy Fiddaman 	namec = nv_scan(root, pushname, (void*)tp, tp->scanmask, flag&~NV_IARRAY);
1448*b30d1939SAndy Fiddaman 	if(mbcoll())
1449*b30d1939SAndy Fiddaman 		strsort(argv,namec,strcoll);
1450*b30d1939SAndy Fiddaman 	if(namec==0 && tp->sh->namespace && nv_dict(tp->sh->namespace)==root)
1451*b30d1939SAndy Fiddaman 	{
1452*b30d1939SAndy Fiddaman 		sfnputc(file,'\t',tp->indent);
1453*b30d1939SAndy Fiddaman 		sfwrite(file,":\n",2);
1454*b30d1939SAndy Fiddaman 	}
1455*b30d1939SAndy Fiddaman 	else while(namec--)
1456*b30d1939SAndy Fiddaman 	{
1457*b30d1939SAndy Fiddaman 		if((np=nv_search(*argv++,root,0)) && np!=onp && (!nv_isnull(np) || np->nvfun || nv_isattr(np,~NV_NOFREE)))
1458*b30d1939SAndy Fiddaman 		{
1459*b30d1939SAndy Fiddaman 			onp = np;
1460*b30d1939SAndy Fiddaman 			if(name)
1461*b30d1939SAndy Fiddaman 			{
1462*b30d1939SAndy Fiddaman 				char *newname = nv_name(np);
1463*b30d1939SAndy Fiddaman 				if(memcmp(name,newname,len)==0 && newname[len]== '.')
1464*b30d1939SAndy Fiddaman 					continue;
1465*b30d1939SAndy Fiddaman 				name = 0;
1466*b30d1939SAndy Fiddaman 			}
1467*b30d1939SAndy Fiddaman 			if(flag&NV_ARRAY)
1468*b30d1939SAndy Fiddaman 			{
1469*b30d1939SAndy Fiddaman 				if(nv_aindex(np)>=0)
1470*b30d1939SAndy Fiddaman 				{
1471*b30d1939SAndy Fiddaman 					if(!(flag&NV_IARRAY))
1472*b30d1939SAndy Fiddaman 						continue;
1473*b30d1939SAndy Fiddaman 				}
1474*b30d1939SAndy Fiddaman 				else if((flag&NV_IARRAY))
1475*b30d1939SAndy Fiddaman 					continue;
1476*b30d1939SAndy Fiddaman 
1477*b30d1939SAndy Fiddaman 			}
1478*b30d1939SAndy Fiddaman 			tp->scanmask = flag&~NV_NOSCOPE;
1479*b30d1939SAndy Fiddaman 			tp->scanroot = root;
1480*b30d1939SAndy Fiddaman 			print_namval(file,np,option,tp);
1481*b30d1939SAndy Fiddaman 			if(!is_abuiltin(np) && nv_isvtree(np))
1482*b30d1939SAndy Fiddaman 			{
1483*b30d1939SAndy Fiddaman 				name = nv_name(np);
1484*b30d1939SAndy Fiddaman 				len = strlen(name);
1485*b30d1939SAndy Fiddaman 			}
1486*b30d1939SAndy Fiddaman 		}
1487*b30d1939SAndy Fiddaman 	}
1488*b30d1939SAndy Fiddaman }
1489*b30d1939SAndy Fiddaman 
1490*b30d1939SAndy Fiddaman /*
1491*b30d1939SAndy Fiddaman  * add the name of the node to the argument list argnam
1492*b30d1939SAndy Fiddaman  */
1493*b30d1939SAndy Fiddaman 
pushname(Namval_t * np,void * data)1494*b30d1939SAndy Fiddaman static void pushname(Namval_t *np,void *data)
1495*b30d1939SAndy Fiddaman {
1496*b30d1939SAndy Fiddaman 	struct tdata *tp = (struct tdata*)data;
1497*b30d1939SAndy Fiddaman 	*tp->argnam++ = nv_name(np);
1498*b30d1939SAndy Fiddaman }
1499*b30d1939SAndy Fiddaman 
1500