X-Git-Url: http://nitlanguage.org diff --git a/lib/opts.nit b/lib/opts.nit index 06fe44e..f383a32 100644 --- a/lib/opts.nit +++ b/lib/opts.nit @@ -5,7 +5,7 @@ # # This file is free software, which comes along with NIT. This software is # distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; -# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# without even the implied warranty of MERCHANTABILITY or FITNESS FOR A # PARTICULAR PURPOSE. You can modify it is you want, provided this header # is kept unaltered, and a notification of the changes is added. # You are allowed to redistribute it and sell it, alone or is a part of @@ -17,50 +17,49 @@ module opts # Super class of all option's class abstract class Option # Names for the option (including long and short ones) - readable var _names: Array[String] + var names: Array[String] # Type of the value of the option type VALUE: nullable Object # Human readable description of the option - readable var _helptext: String + var helptext: String # Gathering errors during parsing - readable var _errors: Array[String] + var errors: Array[String] = new Array[String] # Is this option mandatory? - readable writable var _mandatory: Bool + var mandatory: Bool writable = false # Has this option been read? - readable var _read:Bool + var read: Bool writable = false # Current value of this option - writable var _value: nullable VALUE - - # Current value of this option - fun value: VALUE do return _value.as(VALUE) + var value: VALUE writable # Default value of this option - readable writable var _default_value: nullable VALUE + var default_value: VALUE writable # Create a new option - init init_opt(help: String, default: nullable VALUE, names: nullable Array[String]) + init(help: String, default: VALUE, names: nullable Array[String]) + do + init_opt(help, default, names) + end + + fun init_opt(help: String, default: VALUE, names: nullable Array[String]) do if names == null then - _names = new Array[String] + self.names = new Array[String] else - _names = names.to_a + self.names = names.to_a end - _helptext = help - _mandatory = false - _read = false - _default_value = default - _value = default - _errors = new Array[String] + helptext = help + default_value = default + value = default end # Add new aliases for this option - fun add_aliases(names: String...) do _names.add_all(names) + fun add_aliases(names: String...) do names.add_all(names) # An help text for this option with default settings redef fun to_s do return pretty(2) @@ -68,8 +67,8 @@ abstract class Option # A pretty print for this help fun pretty(off: Int): String do - var text = new Buffer.from(" ") - text.append(_names.join(", ")) + var text = new FlatBuffer.from(" ") + text.append(names.join(", ")) text.append(" ") var rest = off - text.length if rest > 0 then text.append(" " * rest) @@ -88,13 +87,13 @@ abstract class Option # Consume parameters for this option protected fun read_param(it: Iterator[String]) do - _read = true + read = true end end class OptionText super Option - init(text: String) do init_opt(text, null, null) + init(text: String) do super(text, null, null) redef fun pretty(off) do return to_s @@ -105,7 +104,7 @@ class OptionBool super Option redef type VALUE: Bool - init(help: String, names: String...) do init_opt(help, false, names) + init(help: String, names: String...) do super(help, false, names) redef fun read_param(it) do @@ -118,7 +117,7 @@ class OptionCount super Option redef type VALUE: Int - init(help: String, names: String...) do init_opt(help, 0, names) + init(help: String, names: String...) do super(help, 0, names) redef fun read_param(it) do @@ -133,33 +132,27 @@ abstract class OptionParameter protected fun convert(str: String): VALUE is abstract # Is the parameter mandatory? - readable writable var _parameter_mandatory: Bool + var parameter_mandatory: Bool writable = true redef fun read_param(it) do super - if it.is_ok and it.item.first != '-' then + if it.is_ok and it.item.chars.first != '-' then value = convert(it.item) it.next else - if _parameter_mandatory then - _errors.add("parameter expected for option {names.first}") + if parameter_mandatory then + errors.add("Parameter expected for option {names.first}.") end end end - - init init_opt(h, d, n) - do - super - _parameter_mandatory = true - end end class OptionString super OptionParameter redef type VALUE: nullable String - init(help: String, names: String...) do init_opt(help, null, names) + init(help: String, names: String...) do super(help, null, names) redef fun convert(str) do return str end @@ -167,32 +160,32 @@ end class OptionEnum super OptionParameter redef type VALUE: Int - var _values: Array[String] + var values: Array[String] init(values: Array[String], help: String, default: Int, names: String...) do assert values.length > 0 - _values = values.to_a - init_opt("{help} <{values.join(", ")}>", default, names) + self.values = values.to_a + super("{help} <{values.join(", ")}>", default, names) end redef fun convert(str) do - var id = _values.index_of(str) + var id = values.index_of(str) if id == -1 then - var e = "Unrecognized value for option {_names.join(", ")}.\n" - e += "Expected values are: {_values.join(", ")}." - _errors.add(e) + var e = "Unrecognized value for option {names.join(", ")}.\n" + e += "Expected values are: {values.join(", ")}." + errors.add(e) end return id end - fun value_name: String = _values[value] + fun value_name: String do return values[value] redef fun pretty_default do if default_value != null then - return " ({_values[default_value.as(not null)]})" + return " ({values[default_value.as(not null)]})" else return "" end @@ -203,40 +196,49 @@ class OptionInt super OptionParameter redef type VALUE: Int - init(help: String, default: Int, names: String...) do init_opt(help, default, names) + init(help: String, default: Int, names: String...) do super(help, default, names) redef fun convert(str) do return str.to_i end +class OptionFloat + super OptionParameter + redef type VALUE: Float + + init(help: String, default: Float, names: String...) do super(help, default, names) + + redef fun convert(str) do return str.to_f +end + class OptionArray super OptionParameter redef type VALUE: Array[String] init(help: String, names: String...) do - _values = new Array[String] - init_opt(help, _values, names) + values = new Array[String] + super(help, values, names) end - var _values: Array[String] + private var values: Array[String] redef fun convert(str) do - _values.add(str) - return _values + values.add(str) + return values end end class OptionContext - readable var _options: Array[Option] - readable var _rest: Array[String] - readable var _errors: Array[String] + var options: Array[Option] + var rest: Array[String] + var errors: Array[String] - var _optmap: Map[String, Option] + private var optmap: Map[String, Option] fun usage do var lmax = 1 - for i in _options do + for i in options do var l = 3 for n in i.names do l += n.length + 2 @@ -244,7 +246,7 @@ class OptionContext if lmax < l then lmax = l end - for i in _options do + for i in options do print(i.pretty(lmax)) end end @@ -260,21 +262,22 @@ class OptionContext do var parseargs = true build - var rest = _rest + var rest = rest while parseargs and it.is_ok do var str = it.item if str == "--" then + it.next rest.add_all(it.to_a) parseargs = false else # We're looking for packed short options - if str.last_index_of('-') == 0 and str.length > 2 then + if str.chars.last_index_of('-') == 0 and str.length > 2 then var next_called = false for i in [1..str.length] do - var short_opt = "-" + str[i].to_s - if _optmap.has_key(short_opt) then - var option = _optmap[short_opt] + var short_opt = "-" + str.chars[i].to_s + if optmap.has_key(short_opt) then + var option = optmap[short_opt] if option isa OptionParameter then it.next next_called = true @@ -284,8 +287,8 @@ class OptionContext end if not next_called then it.next else - if _optmap.has_key(str) then - var opt = _optmap[str] + if optmap.has_key(str) then + var opt = optmap[str] it.next opt.read_param(it) else @@ -296,53 +299,49 @@ class OptionContext end end - for opt in _options do + for opt in options do if opt.mandatory and not opt.read then - _errors.add("mandatory option {opt.names.join(", ")} not found") + errors.add("Mandatory option {opt.names.join(", ")} not found.") end end - - check_errors end fun add_option(opts: Option...) do for opt in opts do - _options.add(opt) + options.add(opt) end end init do - _options = new Array[Option] - _optmap = new HashMap[String, Option] - _rest = new Array[String] - _errors = new Array[String] + options = new Array[Option] + optmap = new HashMap[String, Option] + rest = new Array[String] + errors = new Array[String] end private fun build do - for o in _options do + for o in options do for n in o.names do - _optmap[n] = o + optmap[n] = o end end end - private fun check_errors + fun get_errors: Array[String] do - for o in _options do + var errors: Array[String] = new Array[String] + + errors.add_all(errors) + + for o in options do for e in o.errors do - _errors.add(e) + errors.add(e) end end - if _errors.length > 0 then - stderr.write("Errors occured during parsing:\n") - for e in _errors do - stderr.write(" - " + e + "\n") - end - exit(1) - end + return errors end end