106 |
char optlist[NOPTS]; |
char optlist[NOPTS]; |
107 |
|
|
108 |
|
|
109 |
STATIC void options(int); |
static int options(int); |
110 |
STATIC void minus_o(char *, int); |
STATIC void minus_o(char *, int); |
111 |
STATIC void setoption(int, int); |
STATIC void setoption(int, int); |
112 |
STATIC int getopts(char *, char *, char **, int *, int *); |
STATIC int getopts(char *, char *, char **); |
113 |
|
|
114 |
|
|
115 |
/* |
/* |
116 |
* Process the shell command line arguments. |
* Process the shell command line arguments. |
117 |
*/ |
*/ |
118 |
|
|
119 |
void |
int |
120 |
procargs(int argc, char **argv) |
procargs(int argc, char **argv) |
121 |
{ |
{ |
122 |
int i; |
int i; |
123 |
const char *xminusc; |
const char *xminusc; |
124 |
char **xargv; |
char **xargv; |
125 |
|
int login; |
126 |
|
|
127 |
xargv = argv; |
xargv = argv; |
128 |
|
login = xargv[0] && xargv[0][0] == '-'; |
129 |
arg0 = xargv[0]; |
arg0 = xargv[0]; |
130 |
if (argc > 0) |
if (argc > 0) |
131 |
xargv++; |
xargv++; |
132 |
for (i = 0; i < NOPTS; i++) |
for (i = 0; i < NOPTS; i++) |
133 |
optlist[i] = 2; |
optlist[i] = 2; |
134 |
argptr = xargv; |
argptr = xargv; |
135 |
options(1); |
login |= options(1); |
136 |
xargv = argptr; |
xargv = argptr; |
137 |
xminusc = minusc; |
xminusc = minusc; |
138 |
if (*xargv == NULL) { |
if (*xargv == NULL) { |
171 |
xargv++; |
xargv++; |
172 |
} |
} |
173 |
optschanged(); |
optschanged(); |
174 |
|
|
175 |
|
return login; |
176 |
} |
} |
177 |
|
|
178 |
|
|
194 |
* to the argument list; we advance it past the options. |
* to the argument list; we advance it past the options. |
195 |
*/ |
*/ |
196 |
|
|
197 |
STATIC void |
STATIC int |
198 |
options(int cmdline) |
options(int cmdline) |
199 |
{ |
{ |
200 |
char *p; |
char *p; |
201 |
int val; |
int val; |
202 |
int c; |
int c; |
203 |
|
int login = 0; |
204 |
|
|
205 |
if (cmdline) |
if (cmdline) |
206 |
minusc = NULL; |
minusc = NULL; |
228 |
while ((c = *p++) != '\0') { |
while ((c = *p++) != '\0') { |
229 |
if (c == 'c' && cmdline) { |
if (c == 'c' && cmdline) { |
230 |
minusc = p; /* command is after shell args*/ |
minusc = p; /* command is after shell args*/ |
231 |
|
} else if (c == 'l' && cmdline) { |
232 |
|
login = 1; |
233 |
} else if (c == 'o') { |
} else if (c == 'o') { |
234 |
minus_o(*argptr, val); |
minus_o(*argptr, val); |
235 |
if (*argptr) |
if (*argptr) |
239 |
} |
} |
240 |
} |
} |
241 |
} |
} |
242 |
|
|
243 |
|
return login; |
244 |
} |
} |
245 |
|
|
246 |
STATIC void |
STATIC void |
249 |
int i; |
int i; |
250 |
|
|
251 |
if (name == NULL) { |
if (name == NULL) { |
252 |
out1str("Current option settings\n"); |
if (val) { |
253 |
for (i = 0; i < NOPTS; i++) |
out1str("Current option settings\n"); |
254 |
out1fmt("%-16s%s\n", optnames[i], |
for (i = 0; i < NOPTS; i++) |
255 |
optlist[i] ? "on" : "off"); |
out1fmt("%-16s%s\n", optnames[i], |
256 |
|
optlist[i] ? "on" : "off"); |
257 |
|
} else { |
258 |
|
for (i = 0; i < NOPTS; i++) |
259 |
|
out1fmt("set %s %s\n", |
260 |
|
optlist[i] ? "-o" : "+o", |
261 |
|
optnames[i]); |
262 |
|
|
263 |
|
} |
264 |
} else { |
} else { |
265 |
for (i = 0; i < NOPTS; i++) |
for (i = 0; i < NOPTS; i++) |
266 |
if (equal(name, optnames[i])) { |
if (equal(name, optnames[i])) { |
394 |
getoptsreset(value) |
getoptsreset(value) |
395 |
const char *value; |
const char *value; |
396 |
{ |
{ |
397 |
shellparam.optind = number(value); |
shellparam.optind = number(value) ?: 1; |
398 |
shellparam.optoff = -1; |
shellparam.optoff = -1; |
399 |
} |
} |
400 |
|
|
414 |
sh_error("Usage: getopts optstring var [arg]"); |
sh_error("Usage: getopts optstring var [arg]"); |
415 |
else if (argc == 3) { |
else if (argc == 3) { |
416 |
optbase = shellparam.p; |
optbase = shellparam.p; |
417 |
if (shellparam.optind > shellparam.nparam + 1) { |
if ((unsigned)shellparam.optind > shellparam.nparam + 1) { |
418 |
shellparam.optind = 1; |
shellparam.optind = 1; |
419 |
shellparam.optoff = -1; |
shellparam.optoff = -1; |
420 |
} |
} |
421 |
} |
} |
422 |
else { |
else { |
423 |
optbase = &argv[3]; |
optbase = &argv[3]; |
424 |
if (shellparam.optind > argc - 2) { |
if ((unsigned)shellparam.optind > argc - 2) { |
425 |
shellparam.optind = 1; |
shellparam.optind = 1; |
426 |
shellparam.optoff = -1; |
shellparam.optoff = -1; |
427 |
} |
} |
428 |
} |
} |
429 |
|
|
430 |
return getopts(argv[1], argv[2], optbase, &shellparam.optind, |
return getopts(argv[1], argv[2], optbase); |
|
&shellparam.optoff); |
|
431 |
} |
} |
432 |
|
|
433 |
STATIC int |
STATIC int |
434 |
getopts(char *optstr, char *optvar, char **optfirst, int *optind, int *optoff) |
getopts(char *optstr, char *optvar, char **optfirst) |
435 |
{ |
{ |
436 |
char *p, *q; |
char *p, *q; |
437 |
char c = '?'; |
char c = '?'; |
438 |
int done = 0; |
int done = 0; |
439 |
int err = 0; |
char s[2]; |
|
char s[12]; |
|
440 |
char **optnext; |
char **optnext; |
441 |
|
int ind = shellparam.optind; |
442 |
|
int off = shellparam.optoff; |
443 |
|
|
444 |
if (*optind < 1) |
shellparam.optind = -1; |
445 |
return 1; |
optnext = optfirst + ind - 1; |
|
optnext = optfirst + *optind - 1; |
|
446 |
|
|
447 |
if (*optind <= 1 || *optoff < 0 || strlen(optnext[-1]) < *optoff) |
if (ind <= 1 || off < 0 || strlen(optnext[-1]) < off) |
448 |
p = NULL; |
p = NULL; |
449 |
else |
else |
450 |
p = optnext[-1] + *optoff; |
p = optnext[-1] + off; |
451 |
if (p == NULL || *p == '\0') { |
if (p == NULL || *p == '\0') { |
452 |
/* Current word is done, advance */ |
/* Current word is done, advance */ |
453 |
p = *optnext; |
p = *optnext; |
468 |
if (optstr[0] == ':') { |
if (optstr[0] == ':') { |
469 |
s[0] = c; |
s[0] = c; |
470 |
s[1] = '\0'; |
s[1] = '\0'; |
471 |
err |= setvarsafe("OPTARG", s, 0); |
setvar("OPTARG", s, 0); |
472 |
} else { |
} else { |
473 |
outfmt(&errout, "Illegal option -%c\n", c); |
outfmt(&errout, "Illegal option -%c\n", c); |
474 |
(void) unsetvar("OPTARG"); |
(void) unsetvar("OPTARG"); |
485 |
if (optstr[0] == ':') { |
if (optstr[0] == ':') { |
486 |
s[0] = c; |
s[0] = c; |
487 |
s[1] = '\0'; |
s[1] = '\0'; |
488 |
err |= setvarsafe("OPTARG", s, 0); |
setvar("OPTARG", s, 0); |
489 |
c = ':'; |
c = ':'; |
490 |
} else { |
} else { |
491 |
outfmt(&errout, "No arg for -%c option\n", c); |
outfmt(&errout, "No arg for -%c option\n", c); |
497 |
|
|
498 |
if (p == *optnext) |
if (p == *optnext) |
499 |
optnext++; |
optnext++; |
500 |
err |= setvarsafe("OPTARG", p, 0); |
setvar("OPTARG", p, 0); |
501 |
p = NULL; |
p = NULL; |
502 |
} else |
} else |
503 |
err |= setvarsafe("OPTARG", nullstr, 0); |
setvar("OPTARG", nullstr, 0); |
504 |
|
|
505 |
out: |
out: |
506 |
*optoff = p ? p - *(optnext - 1) : -1; |
ind = optnext - optfirst + 1; |
507 |
*optind = optnext - optfirst + 1; |
setvarint("OPTIND", ind, VNOFUNC); |
|
fmtstr(s, sizeof(s), "%d", *optind); |
|
|
err |= setvarsafe("OPTIND", s, VNOFUNC); |
|
508 |
s[0] = c; |
s[0] = c; |
509 |
s[1] = '\0'; |
s[1] = '\0'; |
510 |
err |= setvarsafe(optvar, s, 0); |
setvar(optvar, s, 0); |
511 |
if (err) { |
|
512 |
*optind = 1; |
shellparam.optoff = p ? p - *(optnext - 1) : -1; |
513 |
*optoff = -1; |
shellparam.optind = ind; |
514 |
flushall(); |
|
|
exraise(EXERROR); |
|
|
} |
|
515 |
return done; |
return done; |
516 |
} |
} |
517 |
|
|