| Class | CommandLine::Option |
| In: |
lib/commandline/optionparser/option.rb
|
| Parent: | Object |
| GNU_OPT_EQ_ARG_RE | = | /^(--[a-zA-Z]+[-_a-zA-Z0-9]*)=(.*)$/ | ||
| POSIX_OPTION_RE | = | /^-[a-zA-Z]?$/ | OPTION_RE = /^-{1,2}([a-zA-Z]+\w*)(.*)/ UNIX_OPT_EQ_ARG_RE = /^(-[a-zA-Z])=(.*)$/ UNIX_OPT_EQorSP_ARG_RE = /^(-[a-zA-Z])(=|\s+)(.*)$/ | |
| NON_POSIX_OPTION_RE | = | /^(-|-{1,2}[a-zA-Z_]+[-_a-zA-Z0-9]*)/ | need to change this to support - and — | |
| PROPERTIES | = | [ :names, :arity, :opt_description, :arg_description, :opt_found, :opt_not_found, :posix | ||
| FLAG_BASE_OPTS | = | { :arity => [0,0], # :opt_description => nil, :arg_description => "", :opt_found => true, :opt_not_found => false | ||
| DEFAULT_OPTS | = | { :arity => [1,1], :opt_description => "", :arg_description => "", :opt_found => true, #TODO: Should be get_args? :opt_not_found => false | You get these without asking for them |
| posix | [RW] |
Option.new(:flag, :posix => true, :names => %w(—opt))
TODO: Should we test and raise key is not one of :names, opt_description, … This will prevent typos. Can users add properties to an Option that are their own?
# File lib/commandline/optionparser/option.rb, line 65
65: def initialize(*all)
66: @posix = false
67:
68: raise(MissingPropertyError,
69: "No properties specified for new #{self.class}.") if all.empty?
70:
71: until Hash === all[0]
72: case (prop = all.shift)
73: when :flag then @flag = true
74: when :posix then @posix = true
75: else
76: raise(InvalidPropertyError, "Unknown option setting '#{prop}'.")
77: end
78: end
79:
80: unknown_keys = all[0].keys.find_all { |k| !PROPERTIES.include?(k) && /^use?r_/ !~ "#{k}" }
81: raise(InvalidPropertyError,
82: "The key #{unknown_keys.inspect} is not known and is not a user key.") unless
83: unknown_keys.empty?
84:
85: @flag = nil unless defined?(@flag)
86: type = @flag.nil? ? :default : :flag
87: merge_hash =
88: case type
89: when :flag then FLAG_BASE_OPTS
90: when :default then DEFAULT_OPTS
91: else raise(InvalidConstructionError,
92: "Invalid arguments to Option.new. Must be a property hash with "+
93: "keys [:names, :arity, :opt_description, :arg_description, "+
94: ":opt_found, :opt_not_found] or "+
95: "an option type [:flag, :default].")
96: end
97:
98: @properties = {}.merge(merge_hash)
99: all.each { |properties|
100: raise(InvalidPropertyError,
101: "Don't understand argument of type '#{properties.class}' => "+
102: "#{properties.inspect} passed to #{self.class}.new. Looking "+
103: "for type Hash.") unless properties.kind_of?(Hash)
104:
105: @properties.merge!(properties)
106: }
107:
108: @properties[:names] = [@properties[:names]].flatten.compact
109:
110: arg_arity = @properties[:arity]
111: @properties[:arity] = [arg_arity, arg_arity] unless
112: arg_arity.kind_of?(Array)
113:
114: raise "Invalid value for arity '#{arg_arity}'." unless
115: arg_arity.kind_of?(Array) || arg_arity.kind_of?(Fixnum)
116:
117: raise(InvalidArgumentArityError,
118: "Conflicting value given to new option: :flag "+
119: "and :arity = #{@properties[:arity].inspect}.") if
120: :flag == type && [0,0] != @properties[:arity]
121:
122: names = @properties[:names]
123: raise(MissingOptionNameError,
124: "Attempt to create an Option without :names defined.") if
125: names.nil? || names.empty?
126:
127: names.each { |name| check_option_name(name) }
128: validate_arity @properties[:arity]
129:
130: create_opt_description if :flag == type
131: end
# File lib/commandline/optionparser/option.rb, line 143
143: def check_option_name(name)
144: raise(InvalidOptionNameError,
145: "Option name '#{name}' contains invalid space.") if /\s+/.match(name)
146:
147: if @posix
148: raise(InvalidOptionNameError,
149: "Option name '#{name}' is invalid.") unless POSIX_OPTION_RE.match(name)
150: else
151: raise(InvalidOptionNameError,
152: "Option name '#{name}' is invalid.") unless NON_POSIX_OPTION_RE.match(name)
153: end
154: end
# File lib/commandline/optionparser/option.rb, line 133
133: def create_opt_description
134: return if @properties.has_key?(:opt_description)
135: word = @properties[:names].grep(/^--\w.+/)
136: if word.empty?
137: @properties[:opt_description] = ""
138: else
139: @properties[:opt_description] = "Sets #{word.first} to true."
140: end
141: end
# File lib/commandline/optionparser/option.rb, line 172
172: def method_missing(sym, *args)
173: raise "Unknown property '#{sym}' for option
174: #{@properties[:names].inspect unless @properties[:names].nil?}." unless
175: @properties.has_key?(sym) || PROPERTIES.include?(sym)
176: @properties[sym, *args]
177: end
# File lib/commandline/optionparser/option.rb, line 179
179: def to_hash
180: Marshal.load(Marshal.dump(@properties))
181: end
# File lib/commandline/optionparser/option.rb, line 156
156: def validate_arity(arity)
157: raise ":arity is nil" if arity.nil?
158: min, max = *arity
159:
160: raise(InvalidArgumentArityError, "Minimum argument arity '#{min}' must be "+
161: "greater than or equal to 0.") unless min >= 0
162: raise(InvalidArgumentArityError, "Maximum argument arity '#{max}' must be "+
163: "greater than or equal to -1.") if max < -1
164: raise(InvalidArgumentArityError, "Maximum argument arity '#{max}' must be "+
165: "greater than minimum arity '#{min}'.") if max < min && max != -1
166: if @posix
167: raise(InvalidArgumentArityError, "Posix options only support :arity "+
168: "of [0,0] or [1,1].") unless ([0,0] == arity) || ([1,1] == arity)
169: end
170: end