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