def run
@running = true
while running?
e = @unprocessed_arguments_and_options.shift
break if e.nil?
if e == '--'
@no_more_options = true
elsif e =~ /^--./ and !@no_more_options
if e =~ /^--([^=]+)=(.+)$/
option_key = $1
option_value = $2
else
option_key = e[2..-1]
option_value = nil
end
definition = @definitions.find { |d| d[:long] == option_key }
raise IllegalOptionError.new(option_key) if definition.nil?
if [ :required, :optional ].include?(definition[:argument])
if option_value.nil?
option_value = @unprocessed_arguments_and_options.shift
if option_value.nil? || option_value =~ /^-/
if definition[:argument] == :required
raise OptionRequiresAnArgumentError.new(option_key)
else
@unprocessed_arguments_and_options.unshift(option_value)
option_value = true
end
end
end
add_option(definition[:long].to_sym, option_value)
else
add_option(definition[:long].to_sym, true)
end
elsif e =~ /^-./ and !@no_more_options
option_keys = e[1..-1].scan(/./)
option_keys.each do |option_key|
definition = @definitions.find { |d| d[:short] == option_key }
raise IllegalOptionError.new(option_key) if definition.nil?
if option_keys.length > 1 and definition[:argument] == :required
raise OptionRequiresAnArgumentError.new(option_key)
elsif [ :required, :optional ].include?(definition[:argument])
option_value = @unprocessed_arguments_and_options.shift
if option_value.nil? || option_value =~ /^-/
if definition[:argument] == :required
raise OptionRequiresAnArgumentError.new(option_key)
else
@unprocessed_arguments_and_options.unshift(option_value)
option_value = true
end
end
add_option(definition[:long].to_sym, option_value)
else
add_option(definition[:long].to_sym, true)
end
end
else
add_argument(e)
end
end
self
ensure
@running = false
end