Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: bug in getopts
- X-seq: zsh-workers 3167
- From: Bernd Eggink <eggink@xxxxxxxxxxxxxxxxxx>
- To: zsh workers mailing list <zsh-workers@xxxxxxxxxxxxxxx>
- Subject: Re: bug in getopts
- Date: Sun, 25 May 1997 23:57:16 +0200
- Cc: "Christopher T. White" <chris@xxxxxxxx>
- Organization: Regionales Rechenzentrum der Uni Hamburg
- References: <3.0.1.32.19970523124527.0068bae4@xxxxxxxxxxxx>
- Sender: rz2a022@xxxxxxxxxxxxxxxxxx
Christopher T. White wrote:
>
> Dear ZSH users and workers,
>
> Forgive me if this has been addressed previously, but I haven't run into
> this particular situation before.
>
> Getops seems to be broken in zsh version 3.1.0.
It's broken in 3.0.2, too.
I looked into the sources and think I found the bug(s). Edit the file
zsh-3.1.0/Src/buitin.c, look for the function 'bin_getopts' and replace
that function by the attached version. I marked the changes with /*!!
(sorry, I'm not yet familiar with the patch utility).
After rebuild ingand reinstalling zsh, getopts should work correctly.
Regards,
Bernd
---
Bernd Eggink
Regionales Rechenzentrum der Universitaet Hamburg
eggink@xxxxxxxxxxxxxxxxxx
http://www.rrz.uni-hamburg.de/eggink/BEggink.html
int
bin_getopts(char *name, char **argv, char *ops, int func)
{
int lenstr, lenoptstr, i;
char *optstr = unmetafy(*argv++, &lenoptstr), *var = *argv++;
char **args = (*argv) ? argv : pparams;
static int optcind = 1, quiet;
char *str, optbuf[2], *opch = optbuf + 1;
/* zoptind keeps count of the current argument number */
if (zoptind < 1)
/* first call */
zoptind = 1;
if (zoptind == 1)
{ /*!! added*/
quiet = 0;
optbuf[0] = '+';
zsfree(zoptarg);
zoptarg = ztrdup("");
setsparam(var, ztrdup(""));
if (*optstr == ':') {
quiet = 1;
optstr++;
}
} /*!! added*/
if (zoptind > arrlen(args))
return 1;
str = unmetafy(args[zoptind - 1], &lenstr);
if ((*str != '+' && *str != '-') || optcind >= lenstr ||
(lenstr == 2 && str[0] == '-' && str[1] == '-')) {
/* current argument doesn't contain options, or optcind is impossibly
large */
if (*str == '+' || *str == '-')
zoptind++;
optcind = 0;
return 1;
}
/* Get the option character. optcind records the current position within
the argument. */
if (!optcind)
optcind = 1;
*opch = str[optcind++];
if (optcind == lenstr) {
if(args[zoptind++])
str = unmetafy(args[zoptind - 1], &lenstr);
optcind = 0;
}
/* look for option in the provided optstr */
for (i = 0; i != lenoptstr; i++)
if (*opch == optstr[i])
break;
if (i == lenoptstr) {
/* not a valid option */
setsparam(var, ztrdup("?"));
if (quiet) {
zsfree(zoptarg);
zoptarg = metafy(opch, 1, META_DUP);
return 0;
}
zerr("bad option: -%c", NULL, *opch);
errflag = 0;
return 0;
}
/* copy option into specified parameter, with + if required */
setsparam(var, metafy(opch - (*str == '+'), 1 + (*str == '+'), META_DUP));
/* handle case of an expected extra argument */
if (optstr[i + 1] == ':') { /*!! changed 1 to i + 1 */
if (!args[zoptind - 1]) {
/* no extra argument was provided */
if (quiet) {
zsfree(zoptarg);
zoptarg = metafy(opch, 1, META_DUP);
setsparam(var, ztrdup(":"));
return 0;
}
setsparam(var, ztrdup("?"));
zerr("argument expected after -%c option", NULL, *opch);
errflag = 0;
return 0;
}
/* skip over the extra argument */
zsfree(zoptarg);
zoptarg = metafy(str + optcind, lenstr - optcind, META_DUP);
zoptind++;
optcind = 0;
}
return 0;
}
Messages sorted by:
Reverse Date,
Date,
Thread,
Author