| | 558 | |
|---|
| | 559 | /************************************************************************* |
|---|
| | 560 | * vlc_parse_cmdline: Command line parsing into elements. |
|---|
| | 561 | * |
|---|
| | 562 | * The command line is composed of space/tab separated arguments. |
|---|
| | 563 | * Quotes can be used as argument delimiters and a backslash can be used to |
|---|
| | 564 | * escape a quote. |
|---|
| | 565 | *************************************************************************/ |
|---|
| | 566 | static void find_end_quote( char **s, char **ppsz_parser, int i_quote ) |
|---|
| | 567 | { |
|---|
| | 568 | int i_bcount = 0; |
|---|
| | 569 | |
|---|
| | 570 | while( **s ) |
|---|
| | 571 | { |
|---|
| | 572 | if( **s == '\\' ) |
|---|
| | 573 | { |
|---|
| | 574 | **ppsz_parser = **s; |
|---|
| | 575 | (*ppsz_parser)++; (*s)++; |
|---|
| | 576 | i_bcount++; |
|---|
| | 577 | } |
|---|
| | 578 | else if( **s == '"' || **s == '\'' ) |
|---|
| | 579 | { |
|---|
| | 580 | /* Preceeded by a number of '\' which we erase. */ |
|---|
| | 581 | *ppsz_parser -= i_bcount / 2; |
|---|
| | 582 | if( i_bcount & 1 ) |
|---|
| | 583 | { |
|---|
| | 584 | /* '\\' followed by a '"' or '\'' */ |
|---|
| | 585 | *ppsz_parser -= 1; |
|---|
| | 586 | **ppsz_parser = **s; |
|---|
| | 587 | (*ppsz_parser)++; (*s)++; |
|---|
| | 588 | i_bcount = 0; |
|---|
| | 589 | continue; |
|---|
| | 590 | } |
|---|
| | 591 | |
|---|
| | 592 | if( **s == i_quote ) |
|---|
| | 593 | { |
|---|
| | 594 | /* End */ |
|---|
| | 595 | return; |
|---|
| | 596 | } |
|---|
| | 597 | else |
|---|
| | 598 | { |
|---|
| | 599 | /* Different quoting */ |
|---|
| | 600 | int i_quote = **s; |
|---|
| | 601 | **ppsz_parser = **s; |
|---|
| | 602 | (*ppsz_parser)++; (*s)++; |
|---|
| | 603 | find_end_quote( s, ppsz_parser, i_quote ); |
|---|
| | 604 | **ppsz_parser = **s; |
|---|
| | 605 | (*ppsz_parser)++; (*s)++; |
|---|
| | 606 | } |
|---|
| | 607 | |
|---|
| | 608 | i_bcount = 0; |
|---|
| | 609 | } |
|---|
| | 610 | else |
|---|
| | 611 | { |
|---|
| | 612 | /* A regular character */ |
|---|
| | 613 | **ppsz_parser = **s; |
|---|
| | 614 | (*ppsz_parser)++; (*s)++; |
|---|
| | 615 | i_bcount = 0; |
|---|
| | 616 | } |
|---|
| | 617 | } |
|---|
| | 618 | } |
|---|
| | 619 | |
|---|
| | 620 | char **vlc_parse_cmdline( const char *psz_cmdline, int *i_args ) |
|---|
| | 621 | { |
|---|
| | 622 | int argc = 0; |
|---|
| | 623 | char **argv = 0; |
|---|
| | 624 | char *s, *psz_parser, *psz_arg; |
|---|
| | 625 | int i_bcount = 0; |
|---|
| | 626 | |
|---|
| | 627 | if( !psz_cmdline ) return 0; |
|---|
| | 628 | psz_cmdline = strdup( psz_cmdline ); |
|---|
| | 629 | psz_arg = psz_parser = s = psz_cmdline; |
|---|
| | 630 | |
|---|
| | 631 | while( *s ) |
|---|
| | 632 | { |
|---|
| | 633 | if( *s == '\t' || *s == ' ' ) |
|---|
| | 634 | { |
|---|
| | 635 | /* We have a complete argument */ |
|---|
| | 636 | *psz_parser = 0; |
|---|
| | 637 | TAB_APPEND( argc, argv, strdup(psz_arg) ); |
|---|
| | 638 | |
|---|
| | 639 | /* Skip trailing spaces/tabs */ |
|---|
| | 640 | do{ s++; } while( *s == '\t' || *s == ' ' ); |
|---|
| | 641 | |
|---|
| | 642 | /* New argument */ |
|---|
| | 643 | psz_arg = psz_parser = s; |
|---|
| | 644 | i_bcount = 0; |
|---|
| | 645 | } |
|---|
| | 646 | else if( *s == '\\' ) |
|---|
| | 647 | { |
|---|
| | 648 | *psz_parser++ = *s++; |
|---|
| | 649 | i_bcount++; |
|---|
| | 650 | } |
|---|
| | 651 | else if( *s == '"' || *s == '\'' ) |
|---|
| | 652 | { |
|---|
| | 653 | if( ( i_bcount & 1 ) == 0 ) |
|---|
| | 654 | { |
|---|
| | 655 | /* Preceeded by an even number of '\', this is half that |
|---|
| | 656 | * number of '\', plus a quote which we erase. */ |
|---|
| | 657 | int i_quote = *s; |
|---|
| | 658 | psz_parser -= i_bcount / 2; |
|---|
| | 659 | s++; |
|---|
| | 660 | find_end_quote( &s, &psz_parser, i_quote ); |
|---|
| | 661 | s++; |
|---|
| | 662 | } |
|---|
| | 663 | else |
|---|
| | 664 | { |
|---|
| | 665 | /* Preceeded by an odd number of '\', this is half that |
|---|
| | 666 | * number of '\' followed by a '"' */ |
|---|
| | 667 | psz_parser = psz_parser - i_bcount/2 - 1; |
|---|
| | 668 | *psz_parser++ = '"'; |
|---|
| | 669 | s++; |
|---|
| | 670 | } |
|---|
| | 671 | i_bcount = 0; |
|---|
| | 672 | } |
|---|
| | 673 | else |
|---|
| | 674 | { |
|---|
| | 675 | /* A regular character */ |
|---|
| | 676 | *psz_parser++ = *s++; |
|---|
| | 677 | i_bcount = 0; |
|---|
| | 678 | } |
|---|
| | 679 | } |
|---|
| | 680 | |
|---|
| | 681 | /* Take care of the last arg */ |
|---|
| | 682 | if( *psz_arg ) |
|---|
| | 683 | { |
|---|
| | 684 | *psz_parser = '\0'; |
|---|
| | 685 | TAB_APPEND( argc, argv, strdup(psz_arg) ); |
|---|
| | 686 | } |
|---|
| | 687 | |
|---|
| | 688 | if( i_args ) *i_args = argc; |
|---|
| | 689 | free( psz_cmdline ); |
|---|
| | 690 | return argv; |
|---|
| | 691 | } |
|---|