Project

General

Profile

prelude-option.diff

Experimental patch: avoid unhandled arguments deletion, handle special "--" option code - Yoann VANDOORSELAERE, 01/02/2006 10:30 PM

Download (6.32 KB)

View differences:

src/prelude-option.c (local)
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