1 /***********************************************************************
3 * This software is part of the ast package *
4 * Copyright (c) 1982-2010 AT&T Intellectual Property *
5 * and is licensed under the *
6 * Common Public License, Version 1.0 *
7 * by AT&T Intellectual Property *
9 * A copy of the License is available at *
10 * http://www.opensource.org/licenses/cpl1.0.txt *
11 * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
13 * Information and Software Systems Research *
17 * David Korn <dgk@research.att.com> *
19 ***********************************************************************/
22 * getopts optstring name [arg...]
31 #include "variables.h"
36 static int infof(Opt_t
* op
, Sfio_t
* sp
, const char* s
, Optdisc_t
* dp
)
38 Shell_t
*shp
= *(Shell_t
**)(dp
+1);
39 Stk_t
*stkp
= shp
->stk
;
40 if(nv_search(s
,sh
.fun_tree
,0))
42 int savtop
= stktell(stkp
);
43 char *savptr
= stkfreeze(stkp
,0);
47 sfputr(sp
,sh_mactry(shp
,stkfreeze(stkp
,1)),-1);
48 stkset(stkp
,savptr
,savtop
);
53 int b_getopts(int argc
,char *argv
[],void *extra
)
55 register char *options
=error_info
.context
->id
;
56 register Namval_t
*np
;
57 register int flag
, mode
, r
=0;
58 register Shell_t
*shp
= ((Shbltin_t
*)extra
)->shp
;
59 char value
[2], key
[2];
61 struct checkpt buff
, *pp
;
66 memset(&disc
, 0, sizeof(disc
));
67 disc
.hdr
.version
= OPT_VERSION
;
68 disc
.hdr
.infof
= infof
;
72 while((flag
= optget(argv
,sh_optgetopts
))) switch(flag
)
75 options
= opt_info
.arg
;
78 errormsg(SH_DICT
,2, "%s", opt_info
.arg
);
81 errormsg(SH_DICT
,ERROR_usage(2), "%s", opt_info
.arg
);
84 argv
+= opt_info
.index
;
85 argc
-= opt_info
.index
;
86 if(error_info
.errors
|| argc
<2)
87 errormsg(SH_DICT
,ERROR_usage(2), "%s", optusage((char*)0));
88 error_info
.context
->flags
|= ERROR_SILENT
;
89 error_info
.id
= options
;
91 np
= nv_open(argv
[1],shp
->var_tree
,NV_NOASSIGN
|NV_VARNAME
);
102 opt_info
.index
= shp
->st
.optindex
;
103 opt_info
.offset
= shp
->st
.optchar
;
104 if(mode
= (*options
==':'))
106 extended
= *options
=='\n' && *(options
+1)=='[' || *options
=='[' && *(options
+1)=='-';
107 sh_pushcontext(&buff
,1);
108 jmpval
= sigsetjmp(buff
.buff
,0);
111 sh_popcontext(&buff
);
112 pp
= (struct checkpt
*)shp
->jmplist
;
113 pp
->mode
= SH_JMPERREXIT
;
116 opt_info
.disc
= &disc
.hdr
;
117 switch(opt_info
.index
>=0 && opt_info
.index
<=argc
?(opt_info
.num
= LONG_MIN
,flag
=optget(argv
,options
)):0)
121 errormsg(SH_DICT
,ERROR_usage(2), "%s", opt_info
.arg
);
122 opt_info
.option
[1] = '?';
125 key
[0] = opt_info
.option
[1];
126 if(strmatch(opt_info
.arg
,"*unknown*"))
132 errormsg(SH_DICT
,2, "%s", opt_info
.arg
);
136 *(options
= value
) = flag
;
137 shp
->st
.opterror
= 1;
138 if (opt_info
.offset
!= 0 && !argv
[opt_info
.index
][opt_info
.offset
])
150 flag
= opt_info
.index
;
153 opt_info
.index
= flag
;
154 if(!mode
&& strchr(options
,' '))
155 errormsg(SH_DICT
,ERROR_usage(2), "%s", optusage((char*)0));
164 options
= opt_info
.option
+ (*opt_info
.option
!='+');
166 error_info
.context
->flags
&= ~ERROR_SILENT
;
167 shp
->st
.optindex
= opt_info
.index
;
168 shp
->st
.optchar
= opt_info
.offset
;
169 nv_putval(np
, options
, 0);
171 np
= nv_open(nv_name(OPTARGNOD
),shp
->var_tree
,NV_NOSCOPE
);
172 if(opt_info
.num
== LONG_MIN
)
173 nv_putval(np
, opt_info
.arg
, NV_RDONLY
);
174 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] != '+')
176 key
[0] = (char)opt_info
.num
;
178 nv_putval(np
, key
, NV_RDONLY
);
184 nv_putval(np
, (char*)&d
, NV_LDOUBLE
|NV_RDONLY
);
187 nv_putval(np
, opt_info
.arg
, NV_RDONLY
);
189 sh_popcontext(&buff
);