Skip to content

Commit

Permalink
bee/beegetopt: fix major option handling bug
Browse files Browse the repository at this point in the history
we need to preserve the location of '--' option ending when pre parsing
commandline arguments in bee.

so beegetopt was changed to be able to do so if the new option
--keep-option-end is used.

there was an API-breaking change in bee_getopt() since flags are now
set in optctl and not via the third argument of (bee_getopt()).

since we also need the new flag in lower option parsing this was
the cleanest way to do so at the moment.

since this is new nobody should get hurt after we release this 8)

i'm really sorry for changing the API 8)
  • Loading branch information
mariux committed Mar 23, 2012
1 parent afa0f4d commit cc9c507
Show file tree
Hide file tree
Showing 4 changed files with 23 additions and 9 deletions.
2 changes: 2 additions & 0 deletions src/bee.sh.in
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ function search_tool_cmd {
}

options=$(${BEE_BINDIR}/beegetopt --name=bee \
--keep-option-end \
--option=destdir/d= \
-- "${@}")

Expand All @@ -105,6 +106,7 @@ done
options=$(${BEE_BINDIR}/beegetopt --name=bee \
--stop-on-no-option \
--no-skip-unknown-option \
--keep-option-end \
--option=print-config \
--option=help/h \
--option=version/V \
Expand Down
13 changes: 8 additions & 5 deletions src/bee_getopt.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ int bee_getopt_init(struct bee_getopt_ctl *ctl, int argc, char **argv, struct be
ctl->_argc = argc;
ctl->_unhandled_shortopts = NULL;

ctl->flags = 0;

return err?0:1;
}

Expand Down Expand Up @@ -353,7 +355,8 @@ static int _bee_getopt_long(struct bee_getopt_ctl *optctl, int *optindex)
/* match & skip '--' and pop all remaining arguments */

if(maybe_long && (optctl->argv[this][2] == '\0')) {
optctl->optind++;
if(!(optctl->flags & BEE_FLAG_KEEPOPTIONEND))
optctl->optind++;
bee_getopt_pop_all_arguments(optctl);
return BEE_GETOPT_END;
}
Expand Down Expand Up @@ -394,7 +397,7 @@ int bee_getopt_long(struct bee_getopt_ctl *optctl, int *optindex)
return _bee_getopt_long(optctl, optindex);
}

int bee_getopt(struct bee_getopt_ctl *optctl, int *optindex, int flags)
int bee_getopt(struct bee_getopt_ctl *optctl, int *optindex)
{
int opt;

Expand All @@ -404,7 +407,7 @@ int bee_getopt(struct bee_getopt_ctl *optctl, int *optindex, int flags)
return BEE_GETOPT_NOVALUE;

case BEE_GETOPT_NOOPT:
if (flags & BEE_FLAG_STOPONNOOPT) {
if (optctl->flags & BEE_FLAG_STOPONNOOPT) {
bee_getopt_pop_all_arguments(optctl);
return BEE_GETOPT_END;
}
Expand All @@ -417,11 +420,11 @@ int bee_getopt(struct bee_getopt_ctl *optctl, int *optindex, int flags)
return BEE_GETOPT_ERROR;

case BEE_GETOPT_OPTUNKNOWN:
if (flags & BEE_FLAG_STOPONUNKNOWN) {
if (optctl->flags & BEE_FLAG_STOPONUNKNOWN) {
bee_getopt_pop_all_arguments(optctl);
return BEE_GETOPT_END;
}
if (!(flags & BEE_FLAG_SKIPUNKNOWN)) {
if (!(optctl->flags & BEE_FLAG_SKIPUNKNOWN)) {
if (optctl->program)
fprintf(stderr, "%s: ", optctl->program);
fprintf(stderr, "unrecognized option '%s'.\n", optctl->argv[optctl->optind]);
Expand Down
5 changes: 4 additions & 1 deletion src/bee_getopt.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
#define BEE_FLAG_SKIPUNKNOWN (1<<0)
#define BEE_FLAG_STOPONNOOPT (1<<1)
#define BEE_FLAG_STOPONUNKNOWN (1<<2)
#define BEE_FLAG_KEEPOPTIONEND (1<<3)

#define BEE_OPT_LONG(name) .long_opt = (name)
#define BEE_OPT_SHORT(short) .short_opt = (short)
Expand Down Expand Up @@ -165,13 +166,15 @@ struct bee_getopt_ctl {
int _argc;
int _optcnt;
char *_unhandled_shortopts;

int flags;
};

void bee_getopt_pop_current_argument(struct bee_getopt_ctl *optctl);

int bee_getopt_init(struct bee_getopt_ctl *ctl, int argc, char **argv, struct bee_option *optv);
int bee_getopt_long(struct bee_getopt_ctl *optctl, int *optindex);
int bee_getopt(struct bee_getopt_ctl *optctl, int *optindex, int flags);
int bee_getopt(struct bee_getopt_ctl *optctl, int *optindex);

void bee_getopt_print_quoted(char *s);

Expand Down
12 changes: 9 additions & 3 deletions src/beegetopt.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ void usage(void)
" by default unknown options are skipped\n"
" and handled as non-option argument.\n"
" -S is ignored if -U is given.\n"
" -k | --keep-option-end respect but keep '--' at it's position\n"
"\n"
" -h | --help print this little help\n"
" -V | --version print version\n"
Expand Down Expand Up @@ -81,6 +82,7 @@ int main(int argc, char *argv[])
BEE_OPTION_REQUIRED_ARG("name", 'n'),
BEE_OPTION_NO_ARG("stop-on-unknown-option", 'U'),
BEE_OPTION_NO_ARG("stop-on-no-option", 'N'),
BEE_OPTION_NO_ARG("keep-option-end", 'k'),
BEE_OPTION_NO_ARG("no-skip-unknown-option", 'S'),
BEE_OPTION_END
};
Expand All @@ -105,7 +107,7 @@ int main(int argc, char *argv[])

optctl.program = "beegetopt";

while((opt=bee_getopt(&optctl, &i, 0)) != BEE_GETOPT_END) {
while((opt=bee_getopt(&optctl, &i)) != BEE_GETOPT_END) {

if (opt == BEE_GETOPT_ERROR) {
exit(1);
Expand All @@ -131,6 +133,10 @@ int main(int argc, char *argv[])
flags |= BEE_FLAG_STOPONUNKNOWN;
break;

case 'k':
flags |= BEE_FLAG_KEEPOPTIONEND;
break;

case 'S':
flags &= ~BEE_FLAG_SKIPUNKNOWN;
break;
Expand Down Expand Up @@ -236,9 +242,9 @@ int main(int argc, char *argv[])
bee_getopt_init(&optctl, optctl.argc-optctl.optind, &argv[optctl.optind+1], beeopts);

optctl.program = name?name:"program";
optctl.flags = flags;

while((opt=bee_getopt(&optctl, &i, flags)) != BEE_GETOPT_END) {

while((opt=bee_getopt(&optctl, &i)) != BEE_GETOPT_END) {
if (opt == BEE_GETOPT_ERROR) {
exit(1);
}
Expand Down

0 comments on commit cc9c507

Please sign in to comment.