@@ -1643,93 +1643,109 @@ def sym_set(name, val)
1643
1643
end
1644
1644
end
1645
1645
1646
+ def parse_option ( arg , argv , setter = nil )
1647
+ case arg
1648
+ when /\A --([^=]*)(?:=(.*))?/m
1649
+ opt , rest = $1, $2
1650
+ opt . tr! ( '_' , '-' )
1651
+ begin
1652
+ sw , = complete ( :long , opt , true )
1653
+ if require_exact && !sw . long . include? ( arg )
1654
+ throw :terminate , arg unless raise_unknown
1655
+ raise InvalidOption , arg
1656
+ end
1657
+ rescue ParseError
1658
+ throw :terminate , arg unless raise_unknown
1659
+ raise $!. set_option ( arg , true )
1660
+ end
1661
+ begin
1662
+ opt , cb , val = sw . parse ( rest , argv ) { |*exc | raise ( *exc ) }
1663
+ val = cb . call ( val ) if cb
1664
+ setter . call ( sw . switch_name , val ) if setter
1665
+ rescue ParseError
1666
+ raise $!. set_option ( arg , rest )
1667
+ end
1668
+
1669
+ when /\A -(.)((=).*|.+)?/m
1670
+ eq , rest , opt = $3, $2, $1
1671
+ has_arg , val = eq , rest
1672
+ begin
1673
+ sw , = search ( :short , opt )
1674
+ unless sw
1675
+ begin
1676
+ sw , = complete ( :short , opt )
1677
+ # short option matched.
1678
+ val = arg . delete_prefix ( '-' )
1679
+ has_arg = true
1680
+ rescue InvalidOption
1681
+ raise if require_exact
1682
+ # if no short options match, try completion with long
1683
+ # options.
1684
+ sw , = complete ( :long , opt )
1685
+ eq ||= !rest
1686
+ end
1687
+ end
1688
+ rescue ParseError
1689
+ throw :terminate , arg unless raise_unknown
1690
+ raise $!. set_option ( arg , true )
1691
+ end
1692
+ begin
1693
+ opt , cb , val = sw . parse ( val , argv ) { |*exc | raise ( *exc ) if eq }
1694
+ rescue ParseError
1695
+ raise $!. set_option ( arg , arg . length > 2 )
1696
+ else
1697
+ raise InvalidOption , arg if has_arg and !eq and arg == "-#{ opt } "
1698
+ end
1699
+ begin
1700
+ argv . unshift ( opt ) if opt and ( !rest or ( opt = opt . sub ( /\A -*/ , '-' ) ) != '-' )
1701
+ val = cb . call ( val ) if cb
1702
+ setter . call ( sw . switch_name , val ) if setter
1703
+ rescue ParseError
1704
+ raise $!. set_option ( arg , arg . length > 2 )
1705
+ end
1706
+
1707
+ else
1708
+ return false
1709
+ end
1710
+
1711
+ true
1712
+ end
1713
+
1646
1714
def parse_in_order ( argv = default_argv , setter = nil , raise_unknown : self . raise_unknown , &nonopt ) # :nodoc:
1647
1715
opt , arg , val , rest , sub = nil
1648
1716
nonopt ||= proc { |a | throw :terminate , a }
1649
1717
argv . unshift ( arg ) if arg = catch ( :terminate ) {
1650
1718
while arg = argv . shift
1651
- case arg
1652
- # long option
1653
- when /\A --([^=]*)(?:=(.*))?/m
1654
- opt , rest = $1, $2
1655
- opt . tr! ( '_' , '-' )
1656
- begin
1657
- sw , = complete ( :long , opt , true )
1658
- if require_exact && !sw . long . include? ( arg )
1659
- throw :terminate , arg unless raise_unknown
1660
- raise InvalidOption , arg
1661
- end
1662
- rescue ParseError
1663
- throw :terminate , arg unless raise_unknown
1664
- raise $!. set_option ( arg , true )
1719
+ next if parse_option ( arg , argv , setter )
1720
+
1721
+ # sub-command
1722
+ if ( key , ( sub , block ) = @subparsers &.complete ( arg ) )
1723
+ block . call if block
1724
+ if setter
1725
+ into = setter . receiver . class . new . extend ( SymSetter )
1726
+ setter . call ( key , into )
1727
+ subsetter = into . method ( :sym_set )
1665
1728
end
1666
1729
begin
1667
- opt , cb , val = sw . parse ( rest , argv ) { |*exc | raise ( *exc ) }
1668
- val = cb . call ( val ) if cb
1669
- setter . call ( sw . switch_name , val ) if setter
1670
- rescue ParseError
1671
- raise $!. set_option ( arg , rest )
1672
- end
1673
-
1674
- # short option
1675
- when /\A -(.)((=).*|.+)?/m
1676
- eq , rest , opt = $3, $2, $1
1677
- has_arg , val = eq , rest
1678
- begin
1679
- sw , = search ( :short , opt )
1680
- unless sw
1681
- begin
1682
- sw , = complete ( :short , opt )
1683
- # short option matched.
1684
- val = arg . delete_prefix ( '-' )
1685
- has_arg = true
1686
- rescue InvalidOption
1687
- raise if require_exact
1688
- # if no short options match, try completion with long
1689
- # options.
1690
- sw , = complete ( :long , opt )
1691
- eq ||= !rest
1692
- end
1730
+ pp argv : argv
1731
+ sub . parse_in_order ( argv , subsetter , raise_unknown : true ) do |a |
1732
+ pp arg : arg , a : a , argv : argv
1733
+ nonopt . call ( a ) unless parse_option ( a , argv )
1693
1734
end
1694
- rescue ParseError
1695
- throw :terminate , arg unless raise_unknown
1696
- raise $!. set_option ( arg , true )
1697
- end
1698
- begin
1699
- opt , cb , val = sw . parse ( val , argv ) { |*exc | raise ( *exc ) if eq }
1700
- rescue ParseError
1701
- raise $!. set_option ( arg , arg . length > 2 )
1702
- else
1703
- raise InvalidOption , arg if has_arg and !eq and arg == "-#{ opt } "
1704
- end
1705
- begin
1706
- argv . unshift ( opt ) if opt and ( !rest or ( opt = opt . sub ( /\A -*/ , '-' ) ) != '-' )
1707
- val = cb . call ( val ) if cb
1708
- setter . call ( sw . switch_name , val ) if setter
1709
- rescue ParseError
1710
- raise $!. set_option ( arg , arg . length > 2 )
1711
- end
1712
-
1713
- # non-option argument
1714
- else
1715
- # sub-command
1716
- if ( key , ( sub , block ) = @subparsers &.complete ( arg ) )
1717
- block . call if block
1718
- if setter
1719
- into = setter . receiver . class . new . extend ( SymSetter )
1720
- setter . call ( key , into )
1721
- setter = into . method ( :sym_set )
1722
- end
1723
- return sub . parse_in_order ( argv , setter , &nonopt )
1735
+ rescue InvalidOption => e
1736
+ e . recover ( argv )
1737
+ arg = argv . shift
1738
+ retry if parse_option ( arg , argv , setter )
1739
+ raise
1724
1740
end
1741
+ end
1725
1742
1726
- catch ( :prune ) do
1727
- visit ( :each_option ) do |sw0 |
1728
- sw = sw0
1729
- sw . block . call ( arg ) if Switch === sw and sw . match_nonswitch? ( arg )
1730
- end
1731
- nonopt . call ( arg )
1743
+ catch ( :prune ) do
1744
+ visit ( :each_option ) do |sw0 |
1745
+ sw = sw0
1746
+ sw . block . call ( arg ) if Switch === sw and sw . match_nonswitch? ( arg )
1732
1747
end
1748
+ nonopt . call ( arg )
1733
1749
end
1734
1750
end
1735
1751
0 commit comments