X-Git-Url: http://nitlanguage.org diff --git a/lib/opts.nit b/lib/opts.nit index db931d6..14e28fa 100644 --- a/lib/opts.nit +++ b/lib/opts.nit @@ -25,6 +25,9 @@ abstract class Option # Human readable description of the option readable var _helptext: String + # Gathering errors during parsing + readable var _errors: Array[String] + # Is this option mandatory? readable writable var _mandatory: Bool @@ -53,6 +56,7 @@ abstract class Option _read = false _default_value = default _value = default + _errors = new Array[String] end # Add new aliases for this option @@ -64,7 +68,7 @@ abstract class Option # A pretty print for this help fun pretty(off: Int): String do - var text = new Buffer.from(" ") + var text = new FlatBuffer.from(" ") text.append(_names.join(", ")) text.append(" ") var rest = off - text.length @@ -123,23 +127,32 @@ class OptionCount end end -# Option with one mandatory parameter +# Option with one parameter (mandatory by default) abstract class OptionParameter super Option protected fun convert(str: String): VALUE is abstract + # Is the parameter mandatory? + readable writable var _parameter_mandatory: Bool + redef fun read_param(it) do super - if it.is_ok then + if it.is_ok and it.item.chars.first != '-' then value = convert(it.item) it.next else - # TODO: What to do? + if _parameter_mandatory then + _errors.add("Parameter expected for option {names.first}.") + end end end - init init_opt(h, d, n) do super + init init_opt(h, d, n) + do + super + _parameter_mandatory = true + end end class OptionString @@ -166,6 +179,11 @@ class OptionEnum redef fun convert(str) do 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) + end return id end @@ -211,6 +229,7 @@ end class OptionContext readable var _options: Array[Option] readable var _rest: Array[String] + readable var _errors: Array[String] var _optmap: Map[String, Option] @@ -242,7 +261,7 @@ class OptionContext var parseargs = true build var rest = _rest - + while parseargs and it.is_ok do var str = it.item if str == "--" then @@ -250,21 +269,37 @@ class OptionContext rest.add_all(it.to_a) parseargs = false else - if _optmap.has_key(str) then - var opt = _optmap[str] - it.next - opt.read_param(it) + # We're looking for packed short options + if str.last_index_of('-') == 0 and str.length > 2 then + var next_called = false + for i in [1..str.length] do + 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 + end + option.read_param(it) + end + end + if not next_called then it.next else - rest.add(it.item) - it.next + if _optmap.has_key(str) then + var opt = _optmap[str] + it.next + opt.read_param(it) + else + rest.add(it.item) + it.next + end end end end for opt in _options do if opt.mandatory and not opt.read then - stderr.write("Error: mandatory option {opt.names.join(", ")} not found\n") - exit(1) + _errors.add("Mandatory option {opt.names.join(", ")} not found.") end end end @@ -281,6 +316,7 @@ class OptionContext _options = new Array[Option] _optmap = new HashMap[String, Option] _rest = new Array[String] + _errors = new Array[String] end private fun build @@ -291,4 +327,19 @@ class OptionContext end end end + + fun get_errors: Array[String] + 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) + end + end + + return errors + end end