201 |
201 |
|
202 |
202 |
|
203 |
203 |
|
204 |
|
static void reorder_argv(int *argc, char **argv, int removed, int *argv_index)
|
205 |
|
{
|
206 |
|
int i;
|
207 |
|
|
208 |
|
for ( i = removed; (i + 1) < *argc; i++ )
|
209 |
|
argv[i] = argv[i + 1];
|
210 |
|
|
211 |
|
(*argc)--;
|
212 |
|
(*argv_index)--;
|
213 |
|
}
|
214 |
|
|
215 |
|
|
216 |
|
|
217 |
|
|
218 |
204 |
static int check_option_optarg(const char **outptr, const char *option, const char *arg)
|
219 |
205 |
{
|
220 |
206 |
if ( arg && is_an_argument(arg) )
|
... | ... | |
234 |
220 |
}
|
235 |
221 |
|
236 |
222 |
*outptr = arg;
|
237 |
|
|
|
223 |
|
238 |
224 |
return 0;
|
239 |
225 |
}
|
240 |
226 |
|
... | ... | |
516 |
502 |
}
|
517 |
503 |
|
518 |
504 |
|
|
505 |
static void remove_argv(int argc, char **argv, char **unhandled, int *unhandled_index, int removed)
|
|
506 |
{
|
|
507 |
int i;
|
|
508 |
|
|
509 |
unhandled[(*unhandled_index)++] = argv[removed];
|
|
510 |
|
|
511 |
for ( i = removed; (i + 1) < argc; i++ )
|
|
512 |
argv[i] = argv[i + 1];
|
|
513 |
}
|
519 |
514 |
|
520 |
|
static int parse_argument(void *context, prelude_list_t *cb_list, prelude_option_t *optlist,
|
521 |
|
int *argc, char **argv, int *argv_index, int depth, prelude_string_t *err)
|
|
515 |
|
|
516 |
|
|
517 |
static int parse_argument(void *context, prelude_list_t *cb_list,
|
|
518 |
prelude_option_t *root_optlist, prelude_option_t *optlist,
|
|
519 |
int *argc, char **argv, int *argv_index,
|
|
520 |
char **unhandled, int *unhandled_index,
|
|
521 |
int depth, prelude_string_t *err, prelude_bool_t ignore)
|
522 |
522 |
{
|
523 |
523 |
int ret;
|
524 |
|
prelude_option_t *opt;
|
|
524 |
prelude_option_t *opt, *tmp;
|
525 |
525 |
struct cb_list *cbitem;
|
526 |
526 |
const char *arg, *old, *argptr;
|
527 |
527 |
|
528 |
|
while ( *argv_index < *argc ) {
|
529 |
|
|
|
528 |
while ( *argv_index < (*argc - *unhandled_index) ) {
|
|
529 |
|
530 |
530 |
old = arg = argv[(*argv_index)++];
|
|
531 |
if ( *arg != '-' ) {
|
|
532 |
remove_argv(*argc, argv, unhandled, unhandled_index, --(*argv_index));
|
|
533 |
continue;
|
|
534 |
}
|
531 |
535 |
|
532 |
|
if ( *arg != '-' )
|
533 |
|
continue;
|
534 |
|
|
|
536 |
if ( strcmp(arg, "--") == 0 )
|
|
537 |
return 0;
|
|
538 |
|
535 |
539 |
while ( *arg == '-' ) arg++;
|
536 |
540 |
|
537 |
541 |
if ( ! isalnum((int) *arg) )
|
538 |
542 |
continue;
|
539 |
|
|
|
543 |
|
540 |
544 |
opt = search_option(optlist, arg, PRELUDE_OPTION_TYPE_CLI, 0);
|
541 |
|
if ( ! opt ) {
|
|
545 |
if ( root_optlist != _prelude_generic_optlist && (tmp = search_option(_prelude_generic_optlist, arg, ~0, TRUE)) ) {
|
|
546 |
opt = tmp;
|
|
547 |
ignore = TRUE;
|
|
548 |
}
|
|
549 |
|
|
550 |
if ( ! opt ) {
|
|
551 |
|
542 |
552 |
if ( depth ) {
|
543 |
553 |
(*argv_index)--;
|
544 |
554 |
return 0;
|
545 |
555 |
}
|
546 |
|
|
|
556 |
|
|
557 |
remove_argv(*argc, argv, unhandled, unhandled_index, --(*argv_index));
|
547 |
558 |
option_err(PRELUDE_OPTION_WARNING_OPTION, "invalid option -- \"%s\" (%d).\n", arg, depth);
|
548 |
559 |
continue;
|
549 |
560 |
}
|
550 |
561 |
|
551 |
|
reorder_argv(argc, argv, *argv_index - 1, argv_index);
|
552 |
|
|
553 |
562 |
ret = check_option(opt, &argptr, (*argv_index < *argc) ? argv[*argv_index] : NULL);
|
554 |
563 |
if ( ret < 0 )
|
555 |
564 |
return -1;
|
556 |
565 |
|
557 |
|
if ( argptr )
|
558 |
|
reorder_argv(argc, argv, *argv_index, argv_index);
|
|
566 |
if ( argptr )
|
|
567 |
(*argv_index)++;
|
559 |
568 |
|
560 |
|
ret = call_option_cb(context, &cbitem, cb_list, opt, argptr, err, SET_FROM_CLI);
|
561 |
|
if ( ret < 0 )
|
562 |
|
return ret;
|
|
569 |
if ( ! ignore ) {
|
|
570 |
ret = call_option_cb(context, &cbitem, cb_list, opt, argptr, err, SET_FROM_CLI);
|
|
571 |
if ( ret < 0 )
|
|
572 |
return ret;
|
|
573 |
}
|
563 |
574 |
|
564 |
575 |
/*
|
565 |
576 |
* If the option we just found have sub-option.
|
... | ... | |
567 |
578 |
*/
|
568 |
579 |
if ( ! prelude_list_is_empty(&opt->optlist) ) {
|
569 |
580 |
|
570 |
|
ret = parse_argument(context, &cbitem->children, opt,
|
571 |
|
argc, argv, argv_index, depth + 1, err);
|
|
581 |
ret = parse_argument(context, &cbitem->children, root_optlist, opt,
|
|
582 |
argc, argv, argv_index, unhandled, unhandled_index, depth + 1, err, ignore);
|
572 |
583 |
|
573 |
584 |
if ( ret < 0 )
|
574 |
585 |
return ret;
|
575 |
586 |
}
|
|
587 |
|
|
588 |
ignore = FALSE;
|
576 |
589 |
}
|
577 |
590 |
|
578 |
591 |
return 0;
|
... | ... | |
585 |
598 |
const char **filename, int *argc, char **argv, prelude_string_t **err)
|
586 |
599 |
{
|
587 |
600 |
prelude_list_t cblist;
|
588 |
|
int argv_index = 1, ret = 0;
|
|
601 |
char *unhandled[*argc];
|
|
602 |
int i, unhandled_index = 0, argv_index = 1, ret = 0;
|
589 |
603 |
|
590 |
604 |
prelude_list_init(&cblist);
|
591 |
605 |
|
592 |
|
if ( argc ) {
|
593 |
|
ret = parse_argument(context, &cblist, optlist, argc, argv, &argv_index, 0, *err);
|
|
606 |
if ( argc ) {
|
|
607 |
ret = parse_argument(context, &cblist, optlist, optlist, argc, argv, &argv_index,
|
|
608 |
unhandled, &unhandled_index, 0, *err, FALSE);
|
594 |
609 |
if ( ret < 0 )
|
595 |
610 |
return ret;
|
|
611 |
|
|
612 |
for ( i = 0; i < unhandled_index; i++)
|
|
613 |
argv[*argc - unhandled_index + i] = unhandled[i];
|
596 |
614 |
}
|
597 |
615 |
|
598 |
616 |
if ( filename && *filename ) {
|
... | ... | |
605 |
623 |
if ( ret < 0 )
|
606 |
624 |
return ret;
|
607 |
625 |
|
608 |
|
return ret;
|
|
626 |
return *argc - unhandled_index;
|
609 |
627 |
}
|
610 |
628 |
|
611 |
629 |
|
... | ... | |
658 |
676 |
*err = NULL;
|
659 |
677 |
}
|
660 |
678 |
|
661 |
|
if ( ret < 0 )
|
662 |
|
return ret;
|
663 |
|
|
664 |
|
return 0;
|
|
679 |
return ret;
|
665 |
680 |
}
|
666 |
681 |
|
667 |
682 |
|