Class: Rex::Parser::Arguments
- Inherits:
-
Object
- Object
- Rex::Parser::Arguments
- Defined in:
- lib/rex/parser/arguments.rb
Overview
This class parses arguments in a getopt style format, kind of. Unfortunately, the default ruby getopt implementation will only work on ARGV, so we can’t use it.
Class Method Summary collapse
-
.from_s(str) ⇒ Object
Takes a string and converts it into an array of arguments.
Instance Method Summary collapse
- #arg_required?(opt) ⇒ Boolean
- #include?(search) ⇒ Boolean
-
#initialize(fmt) ⇒ Arguments
constructor
Initializes the format list with an array of formats like:.
-
#merge(to_merge) ⇒ Object
Return new Parser object featuring options from the base object and including the options hash that was passed in.
- #option_keys ⇒ Object
-
#parse(args, &_block) ⇒ Object
Parses the supplied arguments into a set of options.
-
#usage ⇒ Object
Returns usage information for this parsing context.
Constructor Details
#initialize(fmt) ⇒ Arguments
Initializes the format list with an array of formats like:
Arguments.new(
'-z' => [ has_argument, "some text", "<argument_description>" ],
'-b' => [ false, "some text" ],
['-b'] => [ false, "some text" ],
['-x', '--execute'] => [ true, "mixing long and short args" ],
['-t', '--test'] => [ true, "testing custom <opt> value", "<arg_to_test>" ],
['--long-flag'] => [ false, "sample long flag" ]
)
34 35 36 37 38 |
# File 'lib/rex/parser/arguments.rb', line 34 def initialize(fmt) normalised_fmt = fmt.map { |key, | [Array(key), ] }.to_h self.fmt = normalised_fmt self.longest = normalised_fmt.each_pair.map { |key, value| key.flatten.join(', ') + (value[0] ? ' ' + value[2].to_s : '') }.max_by(&:length) end |
Class Method Details
.from_s(str) ⇒ Object
Takes a string and converts it into an array of arguments.
43 44 45 |
# File 'lib/rex/parser/arguments.rb', line 43 def self.from_s(str) Shellwords.shellwords(str) end |
Instance Method Details
#arg_required?(opt) ⇒ Boolean
123 124 125 126 127 128 |
# File 'lib/rex/parser/arguments.rb', line 123 def arg_required?(opt) value = select_value_from_fmt_option(opt) return false if value.nil? value.first end |
#include?(search) ⇒ Boolean
119 120 121 |
# File 'lib/rex/parser/arguments.rb', line 119 def include?(search) fmt.keys.flatten.include?(search) end |
#merge(to_merge) ⇒ Object
Return new Parser object featuring options from the base object and including the options hash that was passed in
135 136 137 138 139 |
# File 'lib/rex/parser/arguments.rb', line 135 def merge(to_merge) return fmt unless to_merge.is_a?(Hash) Rex::Parser::Arguments.new(fmt.clone.merge(to_merge)) end |
#option_keys ⇒ Object
130 131 132 |
# File 'lib/rex/parser/arguments.rb', line 130 def option_keys fmt.keys.flatten end |
#parse(args, &_block) ⇒ Object
Parses the supplied arguments into a set of options.
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/rex/parser/arguments.rb', line 50 def parse(args, &_block) skip_next = 0 args.each_with_index do |arg, idx| if skip_next > 0 skip_next -= 1 next end param = nil if arg =~ SHORT_FLAG # parsing needs to take into account a couple requirements # 1. longest `short` flag found in 'arg' should be extracted first # * consider passing the short flag to a tokenizer that returns a list of tokens in order with any invalid tokens # 2. any short flag arguments that need an option will consume the next option from the list short_args_from_token(arg).each do |letter| next unless include?("-#{letter}") if arg_required?("-#{letter}") skip_next += 1 param = args[idx + skip_next] end yield "-#{letter}", idx, param end elsif arg =~ LONG_FLAG && include?(arg) if arg_required?(arg) skip_next = 1 param = args[idx + skip_next] end # Try to yield the short hand version of our argument if possible # This will result in less areas of code that would need to be changed to_return = short_arg_from_long_arg(arg) if to_return.nil? yield arg, idx, param else yield to_return, idx, param end else # else treat the passed in flag as argument yield nil, idx, arg end end end |
#usage ⇒ Object
Returns usage information for this parsing context.
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
# File 'lib/rex/parser/arguments.rb', line 99 def usage txt = ["\nOPTIONS:\n"] fmt.sort_by { |key, | key.to_s.downcase }.each do |key, val| # if the arg takes in a parameter, get parameter string opt = val[0] ? " #{val[2]}" : '' # Get all arguments for a command output = key.join(', ') output += opt # Left align the fmt options and <opt> string aligned_option = " #{output.ljust(longest.length)}" txt << "#{aligned_option} #{val[1]}" end txt << "" txt.join("\n") end |