1da2e3ebdSchin /***********************************************************************
2da2e3ebdSchin *                                                                      *
3da2e3ebdSchin *               This software is part of the ast package               *
4*b30d1939SAndy Fiddaman *          Copyright (c) 1982-2012 AT&T Intellectual Property          *
5da2e3ebdSchin *                      and is licensed under the                       *
6*b30d1939SAndy Fiddaman *                 Eclipse Public License, Version 1.0                  *
77c2fbfb3SApril Chin *                    by AT&T Intellectual Property                     *
8da2e3ebdSchin *                                                                      *
9da2e3ebdSchin *                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)         *
12da2e3ebdSchin *                                                                      *
13da2e3ebdSchin *              Information and Software Systems Research               *
14da2e3ebdSchin *                            AT&T Research                             *
15da2e3ebdSchin *                           Florham Park NJ                            *
16da2e3ebdSchin *                                                                      *
17da2e3ebdSchin *                  David Korn <dgk@research.att.com>                   *
18da2e3ebdSchin *                                                                      *
19da2e3ebdSchin ***********************************************************************/
20da2e3ebdSchin #pragma prototyped
21da2e3ebdSchin /*
22da2e3ebdSchin  * getopts  optstring name [arg...]
23da2e3ebdSchin  *
24da2e3ebdSchin  *   David Korn
25da2e3ebdSchin  *   AT&T Labs
26da2e3ebdSchin  *   research!dgk
27da2e3ebdSchin  *
28da2e3ebdSchin  */
29da2e3ebdSchin 
30da2e3ebdSchin #include	"defs.h"
31da2e3ebdSchin #include	"variables.h"
32da2e3ebdSchin #include	<error.h>
33da2e3ebdSchin #include	<nval.h>
34da2e3ebdSchin #include	"builtins.h"
35da2e3ebdSchin 
infof(Opt_t * op,Sfio_t * sp,const char * s,Optdisc_t * dp)36da2e3ebdSchin static int infof(Opt_t* op, Sfio_t* sp, const char* s, Optdisc_t* dp)
37da2e3ebdSchin {
387c2fbfb3SApril Chin 	Shell_t	*shp = *(Shell_t**)(dp+1);
397c2fbfb3SApril Chin 	Stk_t	*stkp = shp->stk;
40*b30d1939SAndy Fiddaman #if SHOPT_NAMESPACE
41*b30d1939SAndy Fiddaman 	if((shp->namespace && sh_fsearch(shp,s,0)) || nv_search(s,shp->fun_tree,0))
42*b30d1939SAndy Fiddaman #else
43*b30d1939SAndy Fiddaman 	if(nv_search(s,shp->fun_tree,0))
44*b30d1939SAndy Fiddaman #endif /* SHOPT_NAMESPACE */
45da2e3ebdSchin 	{
467c2fbfb3SApril Chin 		int savtop = stktell(stkp);
477c2fbfb3SApril Chin 		char *savptr = stkfreeze(stkp,0);
487c2fbfb3SApril Chin 		sfputc(stkp,'$');
497c2fbfb3SApril Chin 		sfputc(stkp,'(');
507c2fbfb3SApril Chin 		sfputr(stkp,s,')');
517c2fbfb3SApril Chin 		sfputr(sp,sh_mactry(shp,stkfreeze(stkp,1)),-1);
527c2fbfb3SApril Chin 		stkset(stkp,savptr,savtop);
53da2e3ebdSchin 	}
54da2e3ebdSchin         return(1);
55da2e3ebdSchin }
56da2e3ebdSchin 
b_getopts(int argc,char * argv[],Shbltin_t * context)57*b30d1939SAndy Fiddaman int	b_getopts(int argc,char *argv[],Shbltin_t *context)
58da2e3ebdSchin {
59da2e3ebdSchin 	register char *options=error_info.context->id;
60da2e3ebdSchin 	register Namval_t *np;
61*b30d1939SAndy Fiddaman 	register int flag, mode;
62*b30d1939SAndy Fiddaman 	register Shell_t *shp = context->shp;
63da2e3ebdSchin 	char value[2], key[2];
64*b30d1939SAndy Fiddaman 	int jmpval;
65*b30d1939SAndy Fiddaman 	volatile int extended, r= -1;
66da2e3ebdSchin 	struct checkpt buff, *pp;
677c2fbfb3SApril Chin 	struct {
687c2fbfb3SApril Chin 	        Optdisc_t	hdr;
697c2fbfb3SApril Chin 		Shell_t		*sh;
707c2fbfb3SApril Chin 	} disc;
71da2e3ebdSchin         memset(&disc, 0, sizeof(disc));
727c2fbfb3SApril Chin         disc.hdr.version = OPT_VERSION;
737c2fbfb3SApril Chin         disc.hdr.infof = infof;
747c2fbfb3SApril Chin 	disc.sh = shp;
75da2e3ebdSchin 	value[1] = 0;
76da2e3ebdSchin 	key[1] = 0;
77da2e3ebdSchin 	while((flag = optget(argv,sh_optgetopts))) switch(flag)
78da2e3ebdSchin 	{
79da2e3ebdSchin 	    case 'a':
80da2e3ebdSchin 		options = opt_info.arg;
81da2e3ebdSchin 		break;
82da2e3ebdSchin 	    case ':':
83da2e3ebdSchin 		errormsg(SH_DICT,2, "%s", opt_info.arg);
84da2e3ebdSchin 		break;
85da2e3ebdSchin 	    case '?':
86da2e3ebdSchin 		errormsg(SH_DICT,ERROR_usage(2), "%s", opt_info.arg);
87da2e3ebdSchin 		break;
88da2e3ebdSchin 	}
89da2e3ebdSchin 	argv += opt_info.index;
90da2e3ebdSchin 	argc -= opt_info.index;
91da2e3ebdSchin 	if(error_info.errors || argc<2)
92da2e3ebdSchin 		errormsg(SH_DICT,ERROR_usage(2), "%s", optusage((char*)0));
93da2e3ebdSchin 	error_info.context->flags |= ERROR_SILENT;
94da2e3ebdSchin 	error_info.id = options;
95da2e3ebdSchin 	options = argv[0];
96da2e3ebdSchin 	np = nv_open(argv[1],shp->var_tree,NV_NOASSIGN|NV_VARNAME);
97da2e3ebdSchin 	if(argc>2)
98da2e3ebdSchin 	{
99da2e3ebdSchin 		argv +=1;
100da2e3ebdSchin 		argc -=1;
101da2e3ebdSchin 	}
102da2e3ebdSchin 	else
103da2e3ebdSchin 	{
104da2e3ebdSchin 		argv = shp->st.dolv;
105da2e3ebdSchin 		argc = shp->st.dolc;
106da2e3ebdSchin 	}
107da2e3ebdSchin 	opt_info.index = shp->st.optindex;
108da2e3ebdSchin 	opt_info.offset = shp->st.optchar;
109da2e3ebdSchin 	if(mode= (*options==':'))
110da2e3ebdSchin 		options++;
1117c2fbfb3SApril Chin 	extended = *options=='\n' && *(options+1)=='[' || *options=='[' && *(options+1)=='-';
112*b30d1939SAndy Fiddaman 	sh_pushcontext(shp,&buff,1);
113da2e3ebdSchin 	jmpval = sigsetjmp(buff.buff,0);
114da2e3ebdSchin 	if(jmpval)
115da2e3ebdSchin 	{
116*b30d1939SAndy Fiddaman 		sh_popcontext(shp,&buff);
117*b30d1939SAndy Fiddaman 		shp->st.opterror = 1;
118*b30d1939SAndy Fiddaman 		if(r==0)
119*b30d1939SAndy Fiddaman 			return(2);
120da2e3ebdSchin 		pp = (struct checkpt*)shp->jmplist;
121da2e3ebdSchin 		pp->mode = SH_JMPERREXIT;
122da2e3ebdSchin 		sh_exit(2);
123da2e3ebdSchin 	}
1247c2fbfb3SApril Chin         opt_info.disc = &disc.hdr;
125da2e3ebdSchin 	switch(opt_info.index>=0 && opt_info.index<=argc?(opt_info.num= LONG_MIN,flag=optget(argv,options)):0)
126da2e3ebdSchin 	{
127da2e3ebdSchin 	    case '?':
128da2e3ebdSchin 		if(mode==0)
129da2e3ebdSchin 			errormsg(SH_DICT,ERROR_usage(2), "%s", opt_info.arg);
130da2e3ebdSchin 		opt_info.option[1] = '?';
131da2e3ebdSchin 		/* FALL THRU */
132da2e3ebdSchin 	    case ':':
133da2e3ebdSchin 		key[0] = opt_info.option[1];
134da2e3ebdSchin 		if(strmatch(opt_info.arg,"*unknown*"))
135da2e3ebdSchin 			flag = '?';
136da2e3ebdSchin 		if(mode)
137da2e3ebdSchin 			opt_info.arg = key;
138da2e3ebdSchin 		else
139da2e3ebdSchin 		{
140da2e3ebdSchin 			errormsg(SH_DICT,2, "%s", opt_info.arg);
141da2e3ebdSchin 			opt_info.arg = 0;
142da2e3ebdSchin 			flag = '?';
143da2e3ebdSchin 		}
144da2e3ebdSchin 		*(options = value) = flag;
145da2e3ebdSchin 		shp->st.opterror = 1;
146da2e3ebdSchin 		if (opt_info.offset != 0 && !argv[opt_info.index][opt_info.offset])
147da2e3ebdSchin 		{
148da2e3ebdSchin 			opt_info.offset = 0;
149da2e3ebdSchin 			opt_info.index++;
150da2e3ebdSchin 		}
151da2e3ebdSchin 		break;
152da2e3ebdSchin 	    case 0:
153da2e3ebdSchin 		if(shp->st.opterror)
154da2e3ebdSchin 		{
155da2e3ebdSchin 			char *com[2];
156da2e3ebdSchin 			com[0] = "-?";
157da2e3ebdSchin 			com[1] = 0;
158da2e3ebdSchin 			flag = opt_info.index;
159da2e3ebdSchin 			opt_info.index = 0;
160da2e3ebdSchin 			optget(com,options);
161da2e3ebdSchin 			opt_info.index = flag;
162da2e3ebdSchin 			if(!mode && strchr(options,' '))
163da2e3ebdSchin 				errormsg(SH_DICT,ERROR_usage(2), "%s", optusage((char*)0));
164da2e3ebdSchin 		}
165da2e3ebdSchin 		opt_info.arg = 0;
166da2e3ebdSchin 		options = value;
167da2e3ebdSchin 		*options = '?';
168da2e3ebdSchin 		r=1;
169da2e3ebdSchin 		opt_info.offset = 0;
170da2e3ebdSchin 		break;
171da2e3ebdSchin 	    default:
172da2e3ebdSchin 		options = opt_info.option + (*opt_info.option!='+');
173da2e3ebdSchin 	}
174*b30d1939SAndy Fiddaman 	if(r<0)
175*b30d1939SAndy Fiddaman 		r = 0;
176da2e3ebdSchin 	error_info.context->flags &= ~ERROR_SILENT;
177da2e3ebdSchin 	shp->st.optindex = opt_info.index;
178da2e3ebdSchin 	shp->st.optchar = opt_info.offset;
179da2e3ebdSchin 	nv_putval(np, options, 0);
180da2e3ebdSchin 	nv_close(np);
181*b30d1939SAndy Fiddaman 	np = nv_open(nv_name(OPTARGNOD),shp->var_tree,0);
182da2e3ebdSchin 	if(opt_info.num == LONG_MIN)
183da2e3ebdSchin 		nv_putval(np, opt_info.arg, NV_RDONLY);
1847c2fbfb3SApril Chin 	else if (opt_info.arg && opt_info.num > 0 && isalpha((char)opt_info.num) && !isdigit(opt_info.arg[0]) && opt_info.arg[0] != '-' && opt_info.arg[0] != '+')
185da2e3ebdSchin 	{
186da2e3ebdSchin 		key[0] = (char)opt_info.num;
187da2e3ebdSchin 		key[1] = 0;
188da2e3ebdSchin 		nv_putval(np, key, NV_RDONLY);
189da2e3ebdSchin 	}
1907c2fbfb3SApril Chin 	else if(extended)
191da2e3ebdSchin 	{
192da2e3ebdSchin 		Sfdouble_t d;
193da2e3ebdSchin 		d = opt_info.number;
194da2e3ebdSchin 		nv_putval(np, (char*)&d, NV_LDOUBLE|NV_RDONLY);
195da2e3ebdSchin 	}
1967c2fbfb3SApril Chin 	else
1977c2fbfb3SApril Chin 		nv_putval(np, opt_info.arg, NV_RDONLY);
198da2e3ebdSchin 	nv_close(np);
199*b30d1939SAndy Fiddaman 	sh_popcontext(shp,&buff);
200da2e3ebdSchin         opt_info.disc = 0;
201da2e3ebdSchin 	return(r);
202da2e3ebdSchin }
203da2e3ebdSchin 
204