Class | CommandLine::Option |
In: |
lib/commandline/optionparser/CVS/Base/option.rb
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, :opt_not_found => false | You get these without asking for them | |
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] | |
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/CVS/Base/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
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/CVS/Base/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 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/CVS/Base/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[2..-1]} to true." 140: end 141: end
# File lib/commandline/optionparser/CVS/Base/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 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/CVS/Base/option.rb, line 179 179: def to_hash 180: Marshal.load(Marshal.dump(@properties)) 181: 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
# File lib/commandline/optionparser/CVS/Base/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