Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: Replacing getopts with zparseopts
- X-seq: zsh-users 16032
- From: Bart Schaefer <schaefer@xxxxxxxxxxxxxxxx>
- To: zsh-users@xxxxxxx
- Subject: Re: Replacing getopts with zparseopts
- Date: Mon, 16 May 2011 11:44:46 -0700
- In-reply-to: <iqp77h$veu$2@dough.gmane.org>
- List-help: <mailto:zsh-users-help@zsh.org>
- List-id: Zsh Users List <zsh-users.zsh.org>
- List-post: <mailto:zsh-users@zsh.org>
- Mailing-list: contact zsh-users-help@xxxxxxx; run by ezmlm
- References: <iqooau$tdf$1@dough.gmane.org> <110515110005.ZM8306@torch.brasslantern.com> <iqp77h$veu$2@dough.gmane.org>
On May 15, 8:49pm, Thorsten Kampe wrote:
}
} So zparseopts is not a "better getopts". So what do people use to be
} able to use (and parse) long options??
This might be helpful. With the patch below, one can e.g. do
zparseopts -M d=opt_d -debug=d
and have both the -d and the --debug options stashed in the $opt_d
array. There's a remaining buglet here that I haven't decided how
to handle: Given the above spec, the $d array is also created (or
reset) but is always empty. The most straightforward fix for this
would be simply to assert that -M always implies -K.
The patch also fixes this bug:
torch% zparseopts -- -debug=d
zparseopts: missing option descriptions
The problem is that the generic command parser handles "--" natively,
removing it from the arguments passed to bin_zparseopts(), which
then caused "-debug=d" to be ignored.
Index: Doc/Zsh/mod_zutil.yo
===================================================================
diff -c -r1.6 mod_zutil.yo
--- Doc/Zsh/mod_zutil.yo 26 Nov 2007 17:38:13 -0000 1.6
+++ Doc/Zsh/mod_zutil.yo 16 May 2011 17:39:16 -0000
@@ -178,7 +178,7 @@
This implements some internals of the tt(_regex_arguments) function.
)
findex(zparseopts)
-item(tt(zparseopts) [ tt(-D) ] [ tt(-K) ] [ tt(-E) ] [ tt(-a) var(array) ] [
tt(-A) var(assoc) ] var(specs))(
+item(tt(zparseopts) [ tt(-D) ] [ tt(-K) ] [ tt(-M) ] [ tt(-E) ] [ tt(-a)
var(array) ] [ tt(-A) var(assoc) ] var(specs))(
This builtin simplifies the parsing of options in positional parameters,
i.e. the set of arguments given by tt($*). Each var(spec) describes one
option and must be of the form `var(opt)[tt(=)var(array)]'. If an option
@@ -255,6 +255,15 @@
of the var(specs) for them is used. This allows assignment of default
values to them before calling tt(zparseopts).
)
+item(tt(-M))(
+This changes the assignment rules to implement a map among equivalent
+option names. If any var(spec) uses the `tt(=)var(array)' form, the
+string var(array) is interpreted as the name of another var(spec),
+which is used to choose where to store the values. If no other var(spec)
+is found, the values are stored as usual. This changes only the way the
+values are stored, not the way tt($*) is parsed, so results may be
+unpredicable if the `var(name)tt(+)' specifier is used inconsistently.
+)
item(tt(-E))(
This changes the parsing rules to em(not) stop at the first string
that isn't described by one of the var(spec)s. It can be used to test
@@ -288,5 +297,15 @@
I.e., the option tt(-b) and its arguments are taken from the
positional parameters and put into the array tt(bar).
+
+The tt(-M) option can be used like this:
+
+example(set -- -a -bx -c y -cz baz -cend
+zparseopts -A bar -M a=foo b+: c:=b)
+
+to have the effect of
+
+example(foo=(-a)
+bar=(-a '' -b xyz))
)
enditem()
Index: Src/Modules/zutil.c
===================================================================
diff -c -r1.11 zutil.c
--- Src/Modules/zutil.c 21 Dec 2010 16:41:16 -0000 1.11
+++ Src/Modules/zutil.c 16 May 2011 18:15:53 -0000
@@ -1405,6 +1405,7 @@
#define ZOF_OPT 2
#define ZOF_MULT 4
#define ZOF_SAME 8
+#define ZOF_MAP 16
struct zoptarr {
Zoptarr next;
@@ -1466,6 +1467,12 @@
char *n = dyncat("-", d->name);
int new = 0;
+ while (d->flags & ZOF_MAP) {
+ Zoptdesc map = get_opt_desc(d->arr->name);
+ if (!map || !strcmp(map->name, n+1))
+ break;
+ d = map;
+ }
if (!(d->flags & ZOF_MULT))
v = d->vals;
if (!v) {
@@ -1513,7 +1520,7 @@
bin_zparseopts(char *nam, char **args, UNUSED(Options ops), UNUSED(int func))
{
char *o, *p, *n, **pp, **aval, **ap, *assoc = NULL, **cp, **np;
- int del = 0, f, extract = 0, keep = 0;
+ int del = 0, flags = 0, extract = 0, keep = 0;
Zoptdesc sopts[256], d;
Zoptarr a, defarr = NULL;
Zoptval v;
@@ -1531,6 +1538,7 @@
case '-':
if (o[2])
args--;
+ /* else unreachable, default parsing removes "--" */
o = NULL;
break;
case 'D':
@@ -1557,6 +1565,14 @@
}
keep = 1;
break;
+ case 'M':
+ if (o[2]) {
+ args--;
+ o = NULL;
+ break;
+ }
+ flags |= ZOF_MAP;
+ break;
case 'a':
if (defarr) {
zwarnnam(nam, "default array given more than once");
@@ -1578,6 +1594,10 @@
opt_arrs = defarr;
break;
case 'A':
+ if (assoc) {
+ zwarnnam(nam, "associative array given more than once");
+ return 1;
+ }
if (o[2])
assoc = o + 2;
else if (*args)
@@ -1587,6 +1607,11 @@
return 1;
}
break;
+ default:
+ /* Anything else is an option description */
+ args--;
+ o = NULL;
+ break;
}
if (!o) {
o = "";
@@ -1602,11 +1627,11 @@
return 1;
}
while ((o = dupstring(*args++))) {
+ int f = 0;
if (!*o) {
zwarnnam(nam, "invalid option description: %s", o);
return 1;
}
- f = 0;
for (p = o; *p; p++) {
if (*p == '\\' && p[1])
p++;
@@ -1633,6 +1658,7 @@
a = NULL;
if (*p == '=') {
*p++ = '\0';
+ f |= flags;
if (!(a = get_opt_arr(p))) {
a = (Zoptarr) zhalloc(sizeof(*a));
a->name = p;
Messages sorted by:
Reverse Date,
Date,
Thread,
Author