1da2e3ebdSchin /***********************************************************************
2da2e3ebdSchin * *
3da2e3ebdSchin * This software is part of the ast package *
4*3e14f97fSRoger A. Faulkner * Copyright (c) 1982-2010 AT&T Intellectual Property *
5da2e3ebdSchin * and is licensed under the *
6da2e3ebdSchin * Common Public License, Version 1.0 *
77c2fbfb3SApril Chin * by AT&T Intellectual Property *
8da2e3ebdSchin * *
9da2e3ebdSchin * A copy of the License is available at *
10da2e3ebdSchin * http://www.opensource.org/licenses/cpl1.0.txt *
11da2e3ebdSchin * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
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;
40da2e3ebdSchin if(nv_search(s,sh.fun_tree,0))
41da2e3ebdSchin {
427c2fbfb3SApril Chin int savtop = stktell(stkp);
437c2fbfb3SApril Chin char *savptr = stkfreeze(stkp,0);
447c2fbfb3SApril Chin sfputc(stkp,'$');
457c2fbfb3SApril Chin sfputc(stkp,'(');
467c2fbfb3SApril Chin sfputr(stkp,s,')');
477c2fbfb3SApril Chin sfputr(sp,sh_mactry(shp,stkfreeze(stkp,1)),-1);
487c2fbfb3SApril Chin stkset(stkp,savptr,savtop);
49da2e3ebdSchin }
50da2e3ebdSchin return(1);
51da2e3ebdSchin }
52da2e3ebdSchin
b_getopts(int argc,char * argv[],void * extra)53da2e3ebdSchin int b_getopts(int argc,char *argv[],void *extra)
54da2e3ebdSchin {
55da2e3ebdSchin register char *options=error_info.context->id;
56da2e3ebdSchin register Namval_t *np;
57da2e3ebdSchin register int flag, mode, r=0;
587c2fbfb3SApril Chin register Shell_t *shp = ((Shbltin_t*)extra)->shp;
59da2e3ebdSchin char value[2], key[2];
607c2fbfb3SApril Chin int jmpval,extended;
61da2e3ebdSchin struct checkpt buff, *pp;
627c2fbfb3SApril Chin struct {
637c2fbfb3SApril Chin Optdisc_t hdr;
647c2fbfb3SApril Chin Shell_t *sh;
657c2fbfb3SApril Chin } disc;
66da2e3ebdSchin memset(&disc, 0, sizeof(disc));
677c2fbfb3SApril Chin disc.hdr.version = OPT_VERSION;
687c2fbfb3SApril Chin disc.hdr.infof = infof;
697c2fbfb3SApril Chin disc.sh = shp;
70da2e3ebdSchin value[1] = 0;
71da2e3ebdSchin key[1] = 0;
72da2e3ebdSchin while((flag = optget(argv,sh_optgetopts))) switch(flag)
73da2e3ebdSchin {
74da2e3ebdSchin case 'a':
75da2e3ebdSchin options = opt_info.arg;
76da2e3ebdSchin break;
77da2e3ebdSchin case ':':
78da2e3ebdSchin errormsg(SH_DICT,2, "%s", opt_info.arg);
79da2e3ebdSchin break;
80da2e3ebdSchin case '?':
81da2e3ebdSchin errormsg(SH_DICT,ERROR_usage(2), "%s", opt_info.arg);
82da2e3ebdSchin break;
83da2e3ebdSchin }
84da2e3ebdSchin argv += opt_info.index;
85da2e3ebdSchin argc -= opt_info.index;
86da2e3ebdSchin if(error_info.errors || argc<2)
87da2e3ebdSchin errormsg(SH_DICT,ERROR_usage(2), "%s", optusage((char*)0));
88da2e3ebdSchin error_info.context->flags |= ERROR_SILENT;
89da2e3ebdSchin error_info.id = options;
90da2e3ebdSchin options = argv[0];
91da2e3ebdSchin np = nv_open(argv[1],shp->var_tree,NV_NOASSIGN|NV_VARNAME);
92da2e3ebdSchin if(argc>2)
93da2e3ebdSchin {
94da2e3ebdSchin argv +=1;
95da2e3ebdSchin argc -=1;
96da2e3ebdSchin }
97da2e3ebdSchin else
98da2e3ebdSchin {
99da2e3ebdSchin argv = shp->st.dolv;
100da2e3ebdSchin argc = shp->st.dolc;
101da2e3ebdSchin }
102da2e3ebdSchin opt_info.index = shp->st.optindex;
103da2e3ebdSchin opt_info.offset = shp->st.optchar;
104da2e3ebdSchin if(mode= (*options==':'))
105da2e3ebdSchin options++;
1067c2fbfb3SApril Chin extended = *options=='\n' && *(options+1)=='[' || *options=='[' && *(options+1)=='-';
107da2e3ebdSchin sh_pushcontext(&buff,1);
108da2e3ebdSchin jmpval = sigsetjmp(buff.buff,0);
109da2e3ebdSchin if(jmpval)
110da2e3ebdSchin {
111da2e3ebdSchin sh_popcontext(&buff);
112da2e3ebdSchin pp = (struct checkpt*)shp->jmplist;
113da2e3ebdSchin pp->mode = SH_JMPERREXIT;
114da2e3ebdSchin sh_exit(2);
115da2e3ebdSchin }
1167c2fbfb3SApril Chin opt_info.disc = &disc.hdr;
117da2e3ebdSchin switch(opt_info.index>=0 && opt_info.index<=argc?(opt_info.num= LONG_MIN,flag=optget(argv,options)):0)
118da2e3ebdSchin {
119da2e3ebdSchin case '?':
120da2e3ebdSchin if(mode==0)
121da2e3ebdSchin errormsg(SH_DICT,ERROR_usage(2), "%s", opt_info.arg);
122da2e3ebdSchin opt_info.option[1] = '?';
123da2e3ebdSchin /* FALL THRU */
124da2e3ebdSchin case ':':
125da2e3ebdSchin key[0] = opt_info.option[1];
126da2e3ebdSchin if(strmatch(opt_info.arg,"*unknown*"))
127da2e3ebdSchin flag = '?';
128da2e3ebdSchin if(mode)
129da2e3ebdSchin opt_info.arg = key;
130da2e3ebdSchin else
131da2e3ebdSchin {
132da2e3ebdSchin errormsg(SH_DICT,2, "%s", opt_info.arg);
133da2e3ebdSchin opt_info.arg = 0;
134da2e3ebdSchin flag = '?';
135da2e3ebdSchin }
136da2e3ebdSchin *(options = value) = flag;
137da2e3ebdSchin shp->st.opterror = 1;
138da2e3ebdSchin if (opt_info.offset != 0 && !argv[opt_info.index][opt_info.offset])
139da2e3ebdSchin {
140da2e3ebdSchin opt_info.offset = 0;
141da2e3ebdSchin opt_info.index++;
142da2e3ebdSchin }
143da2e3ebdSchin break;
144da2e3ebdSchin case 0:
145da2e3ebdSchin if(shp->st.opterror)
146da2e3ebdSchin {
147da2e3ebdSchin char *com[2];
148da2e3ebdSchin com[0] = "-?";
149da2e3ebdSchin com[1] = 0;
150da2e3ebdSchin flag = opt_info.index;
151da2e3ebdSchin opt_info.index = 0;
152da2e3ebdSchin optget(com,options);
153da2e3ebdSchin opt_info.index = flag;
154da2e3ebdSchin if(!mode && strchr(options,' '))
155da2e3ebdSchin errormsg(SH_DICT,ERROR_usage(2), "%s", optusage((char*)0));
156da2e3ebdSchin }
157da2e3ebdSchin opt_info.arg = 0;
158da2e3ebdSchin options = value;
159da2e3ebdSchin *options = '?';
160da2e3ebdSchin r=1;
161da2e3ebdSchin opt_info.offset = 0;
162da2e3ebdSchin break;
163da2e3ebdSchin default:
164da2e3ebdSchin options = opt_info.option + (*opt_info.option!='+');
165da2e3ebdSchin }
166da2e3ebdSchin error_info.context->flags &= ~ERROR_SILENT;
167da2e3ebdSchin shp->st.optindex = opt_info.index;
168da2e3ebdSchin shp->st.optchar = opt_info.offset;
169da2e3ebdSchin nv_putval(np, options, 0);
170da2e3ebdSchin nv_close(np);
171da2e3ebdSchin np = nv_open(nv_name(OPTARGNOD),shp->var_tree,NV_NOSCOPE);
172da2e3ebdSchin if(opt_info.num == LONG_MIN)
173da2e3ebdSchin nv_putval(np, opt_info.arg, NV_RDONLY);
1747c2fbfb3SApril 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] != '+')
175da2e3ebdSchin {
176da2e3ebdSchin key[0] = (char)opt_info.num;
177da2e3ebdSchin key[1] = 0;
178da2e3ebdSchin nv_putval(np, key, NV_RDONLY);
179da2e3ebdSchin }
1807c2fbfb3SApril Chin else if(extended)
181da2e3ebdSchin {
182da2e3ebdSchin Sfdouble_t d;
183da2e3ebdSchin d = opt_info.number;
184da2e3ebdSchin nv_putval(np, (char*)&d, NV_LDOUBLE|NV_RDONLY);
185da2e3ebdSchin }
1867c2fbfb3SApril Chin else
1877c2fbfb3SApril Chin nv_putval(np, opt_info.arg, NV_RDONLY);
188da2e3ebdSchin nv_close(np);
189da2e3ebdSchin sh_popcontext(&buff);
190da2e3ebdSchin opt_info.disc = 0;
191da2e3ebdSchin return(r);
192da2e3ebdSchin }
193da2e3ebdSchin
194