getopt 1.6.0 → 1.7.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/CHANGES.md +9 -2
- data/Gemfile +2 -3
- data/MANIFEST.md +2 -2
- data/README.md +5 -2
- data/Rakefile +12 -2
- data/getopt.gemspec +12 -7
- data/lib/getopt/long.rb +246 -224
- data/lib/getopt/std.rb +91 -91
- data/lib/getopt/version.rb +3 -1
- data/spec/getopt_long_spec.rb +213 -121
- data/spec/getopt_std_spec.rb +79 -71
- data.tar.gz.sig +0 -0
- metadata +36 -8
- metadata.gz.sig +0 -0
data/lib/getopt/std.rb
CHANGED
|
@@ -1,108 +1,108 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require_relative 'version'
|
|
2
4
|
|
|
3
5
|
# The Getopt module serves as a namespace only
|
|
4
6
|
module Getopt
|
|
7
|
+
# The Getopt::Std class serves as a base class for the getopts method.
|
|
8
|
+
class Std
|
|
9
|
+
include Getopt::Version
|
|
5
10
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
# The Getopt::Std::Error class is raised if there are any illegal
|
|
11
|
-
# command line arguments.
|
|
12
|
-
#
|
|
13
|
-
class Error < StandardError; end
|
|
11
|
+
# The Getopt::Std::Error class is raised if there are any illegal
|
|
12
|
+
# command line arguments.
|
|
13
|
+
#
|
|
14
|
+
class Error < StandardError; end
|
|
14
15
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
#
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
16
|
+
# Processes single character command line options with option
|
|
17
|
+
# clustering. This information is parsed from ARGV and returned
|
|
18
|
+
# as a hash, with the switch (minus the "-") as the key. The value
|
|
19
|
+
# for that key is either true/false (boolean switches) or the argument
|
|
20
|
+
# that was passed to the switch.
|
|
21
|
+
#
|
|
22
|
+
# Characters followed by a ":" require an argument. The rest are
|
|
23
|
+
# considered boolean switches. If a switch that accepts an argument
|
|
24
|
+
# appears more than once, the value for that key becomes an array
|
|
25
|
+
# of values.
|
|
26
|
+
#
|
|
27
|
+
# Example:
|
|
28
|
+
#
|
|
29
|
+
# # Look for -o with argument, and -I and -D boolean arguments
|
|
30
|
+
# opt = Getopt::Std.getopts("o:ID")
|
|
31
|
+
#
|
|
32
|
+
# if opt["I"]
|
|
33
|
+
# # Do something if -I passed
|
|
34
|
+
# end
|
|
35
|
+
#
|
|
36
|
+
# if opt["D"]
|
|
37
|
+
# # Do something if -D passed
|
|
38
|
+
# end
|
|
39
|
+
#
|
|
40
|
+
# if opt["o"]
|
|
41
|
+
# case opt["o"]
|
|
42
|
+
# # Do something
|
|
43
|
+
# end
|
|
44
|
+
# end
|
|
45
|
+
#
|
|
46
|
+
def self.getopts(switches)
|
|
47
|
+
args = switches.split(/ */)
|
|
48
|
+
hash = {}
|
|
49
|
+
regex = /^-([^\s-])\s*(\S*)/s
|
|
48
50
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
51
|
+
while !ARGV.empty? && regex.match(ARGV.first)
|
|
52
|
+
first, rest = Regexp.last_match(1), Regexp.last_match(2)
|
|
53
|
+
pos = switches.index(first)
|
|
52
54
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
55
|
+
# Switches on the command line must appear among the characters
|
|
56
|
+
# declared in +switches+.
|
|
57
|
+
raise Error, "invalid option '#{first}'" unless pos
|
|
56
58
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
59
|
+
if args[pos + 1] == ':'
|
|
60
|
+
ARGV.shift
|
|
61
|
+
if rest.empty?
|
|
62
|
+
rest = ARGV.shift
|
|
61
63
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
64
|
+
# Ensure that switches requiring arguments actually
|
|
65
|
+
# receive a (non-switch) argument.
|
|
66
|
+
if rest.nil? || rest.empty?
|
|
67
|
+
raise Error, "missing argument for '-#{args[pos]}'"
|
|
68
|
+
end
|
|
67
69
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
70
|
+
# Do not permit switches that require arguments to be
|
|
71
|
+
# followed immediately by another switch.
|
|
72
|
+
temp_args = args.map{ |e| "-#{e}" }
|
|
71
73
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
end
|
|
74
|
+
if temp_args.include?(rest) || temp_args.include?(rest[1..])
|
|
75
|
+
err = "cannot use switch '#{rest}' as argument to another switch"
|
|
76
|
+
raise Error, err
|
|
77
|
+
end
|
|
77
78
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
else
|
|
84
|
-
hash[first] = rest
|
|
85
|
-
end
|
|
86
|
-
else
|
|
87
|
-
# Do not permit switches that require arguments to be
|
|
88
|
-
# followed immediately by another switch.
|
|
89
|
-
if args.include?(rest) || args.include?(rest[1..-1])
|
|
90
|
-
err = "cannot use switch '#{rest}' as argument "
|
|
91
|
-
err += "to another switch"
|
|
92
|
-
raise Error, err
|
|
93
|
-
end
|
|
94
|
-
end
|
|
79
|
+
# For non boolean switches, arguments that appear multiple
|
|
80
|
+
# times are converted to an array (or pushed onto an already
|
|
81
|
+
# existant array).
|
|
82
|
+
if hash.key?(first)
|
|
83
|
+
hash[first] = [hash[first], rest].flatten
|
|
95
84
|
else
|
|
96
|
-
|
|
97
|
-
if rest.empty?
|
|
98
|
-
ARGV.shift
|
|
99
|
-
else
|
|
100
|
-
ARGV[0] = "-#{rest}"
|
|
101
|
-
end
|
|
85
|
+
hash[first] = rest
|
|
102
86
|
end
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
87
|
+
else
|
|
88
|
+
# Do not permit switches that require arguments to be
|
|
89
|
+
# followed immediately by another switch.
|
|
90
|
+
if args.include?(rest) || args.include?(rest[1..])
|
|
91
|
+
err = "cannot use switch '#{rest}' as argument to another switch"
|
|
92
|
+
raise Error, err
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
else
|
|
96
|
+
hash[first] = true # Boolean switch
|
|
97
|
+
if rest.empty?
|
|
98
|
+
ARGV.shift
|
|
99
|
+
else
|
|
100
|
+
ARGV[0] = "-#{rest}"
|
|
101
|
+
end
|
|
102
|
+
end
|
|
106
103
|
end
|
|
107
|
-
|
|
104
|
+
|
|
105
|
+
hash
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
108
|
end
|