diff options
-rw-r--r-- | bin/sh/eval.c | 1 | ||||
-rw-r--r-- | bin/sh/options.c | 31 | ||||
-rw-r--r-- | bin/sh/options.h | 1 | ||||
-rw-r--r-- | bin/sh/tests/builtins/getopts9.0 | 9 | ||||
-rw-r--r-- | bin/sh/tests/builtins/getopts9.0.stdout | 3 |
5 files changed, 39 insertions, 6 deletions
diff --git a/bin/sh/eval.c b/bin/sh/eval.c index 38e227c..c1a9cdb 100644 --- a/bin/sh/eval.c +++ b/bin/sh/eval.c @@ -1039,6 +1039,7 @@ evalcommand(union node *cmd, int flags, struct backcmd *backcmd) shellparam.reset = 1; shellparam.nparam = argc - 1; shellparam.p = argv + 1; + shellparam.optp = NULL; shellparam.optnext = NULL; INTOFF; savelocalvars = localvars; diff --git a/bin/sh/options.c b/bin/sh/options.c index bf00a4e..860cf6c 100644 --- a/bin/sh/options.c +++ b/bin/sh/options.c @@ -325,6 +325,7 @@ setparam(char **argv) shellparam.malloc = 1; shellparam.nparam = nparam; shellparam.p = newparam; + shellparam.optp = NULL; shellparam.reset = 1; shellparam.optnext = NULL; } @@ -344,6 +345,11 @@ freeparam(struct shparam *param) ckfree(*ap); ckfree(param->p); } + if (param->optp) { + for (ap = param->optp ; *ap ; ap++) + ckfree(*ap); + ckfree(param->optp); + } } @@ -417,20 +423,33 @@ getoptsreset(const char *value) int getoptscmd(int argc, char **argv) { - char **optbase = NULL; + char **optbase = NULL, **ap; + int i; if (argc < 3) error("usage: getopts optstring var [arg]"); - else if (argc == 3) - optbase = shellparam.p; - else - optbase = &argv[3]; if (shellparam.reset == 1) { + INTOFF; + if (shellparam.optp) { + for (ap = shellparam.optp ; *ap ; ap++) + ckfree(*ap); + ckfree(shellparam.optp); + shellparam.optp = NULL; + } + if (argc > 3) { + shellparam.optp = ckmalloc((argc - 2) * sizeof *ap); + memset(shellparam.optp, '\0', (argc - 2) * sizeof *ap); + for (i = 0; i < argc - 3; i++) + shellparam.optp[i] = savestr(argv[i + 3]); + } + INTON; + optbase = argc == 3 ? shellparam.p : shellparam.optp; shellparam.optnext = optbase; shellparam.optptr = NULL; shellparam.reset = 0; - } + } else + optbase = shellparam.optp ? shellparam.optp : shellparam.p; return getopts(argv[1], argv[2], optbase, &shellparam.optnext, &shellparam.optptr); diff --git a/bin/sh/options.h b/bin/sh/options.h index acc2a11..0994862 100644 --- a/bin/sh/options.h +++ b/bin/sh/options.h @@ -38,6 +38,7 @@ struct shparam { unsigned char malloc; /* if parameter list dynamically allocated */ unsigned char reset; /* if getopts has been reset */ char **p; /* parameter list */ + char **optp; /* parameter list for getopts */ char **optnext; /* next parameter to be processed by getopts */ char *optptr; /* used by getopts */ }; diff --git a/bin/sh/tests/builtins/getopts9.0 b/bin/sh/tests/builtins/getopts9.0 new file mode 100644 index 0000000..d23fc43 --- /dev/null +++ b/bin/sh/tests/builtins/getopts9.0 @@ -0,0 +1,9 @@ +# $FreeBSD$ + +args='-ab' +getopts ab opt $args +echo $?:$opt:$OPTARG +for dummy in dummy1 dummy2; do + getopts ab opt $args + echo $?:$opt:$OPTARG +done diff --git a/bin/sh/tests/builtins/getopts9.0.stdout b/bin/sh/tests/builtins/getopts9.0.stdout new file mode 100644 index 0000000..4d32063 --- /dev/null +++ b/bin/sh/tests/builtins/getopts9.0.stdout @@ -0,0 +1,3 @@ +0:a: +0:b: +1:?: |