1 # This file is part of NIT ( http://www.nitlanguage.org ).
3 # Copyright 2008 Floréal Morandat <morandat@lirmm.fr>
4 # Copyright 2008 Jean Privat <jean@pryen.org>
6 # This file is free software, which comes along with NIT. This software is
7 # distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
8 # without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
9 # PARTICULAR PURPOSE. You can modify it is you want, provided this header
10 # is kept unaltered, and a notification of the changes is added.
11 # You are allowed to redistribute it and sell it, alone or is a part of
14 # Management of options on the command line
17 # Super class of all option's class
19 # Names for the option (including long and short ones)
20 readable var _names
: Array[String]
22 # Type of the value of the option
23 type VALUE: nullable Object
25 # Human readable description of the option
26 readable var _helptext
: String
28 # Gathering errors during parsing
29 readable var _errors
: Array[String]
31 # Is this option mandatory?
32 readable writable var _mandatory
: Bool
34 # Has this option been read?
35 readable var _read
:Bool
37 # Current value of this option
38 writable var _value
: nullable VALUE
40 # Current value of this option
41 fun value
: VALUE do return _value
.as(VALUE)
43 # Default value of this option
44 readable writable var _default_value
: nullable VALUE
47 init init_opt
(help
: String, default
: nullable VALUE, names
: nullable Array[String])
50 _names
= new Array[String]
57 _default_value
= default
59 _errors
= new Array[String]
62 # Add new aliases for this option
63 fun add_aliases
(names
: String...) do _names
.add_all
(names
)
65 # An help text for this option with default settings
66 redef fun to_s
do return pretty
(2)
68 # A pretty print for this help
69 fun pretty
(off
: Int): String
71 var text
= new Buffer.from
(" ")
72 text
.append
(_names
.join
(", "))
74 var rest
= off
- text
.length
75 if rest
> 0 then text
.append
(" " * rest
)
77 #text.append(pretty_default)
81 fun pretty_default
: String
83 var dv
= default_value
84 if dv
!= null then return " ({dv})"
88 # Consume parameters for this option
89 protected fun read_param
(it
: Iterator[String])
97 init(text
: String) do init_opt
(text
, null, null)
99 redef fun pretty
(off
) do return to_s
101 redef fun to_s
do return helptext
106 redef type VALUE: Bool
108 init(help
: String, names
: String...) do init_opt
(help
, false, names
)
110 redef fun read_param
(it
)
119 redef type VALUE: Int
121 init(help
: String, names
: String...) do init_opt
(help
, 0, names
)
123 redef fun read_param
(it
)
130 # Option with one parameter (mandatory by default)
131 abstract class OptionParameter
133 protected fun convert
(str
: String): VALUE is abstract
135 # Is the parameter mandatory?
136 readable writable var _parameter_mandatory
: Bool
138 redef fun read_param
(it
)
141 if it
.is_ok
and it
.item
.first
!= '-' then
142 value
= convert
(it
.item
)
145 if _parameter_mandatory
then
146 _errors
.add
("Parameter expected for option {names.first}.")
151 init init_opt
(h
, d
, n
)
154 _parameter_mandatory
= true
159 super OptionParameter
160 redef type VALUE: nullable String
162 init(help
: String, names
: String...) do init_opt
(help
, null, names
)
164 redef fun convert
(str
) do return str
168 super OptionParameter
169 redef type VALUE: Int
170 var _values
: Array[String]
172 init(values
: Array[String], help
: String, default
: Int, names
: String...)
174 assert values
.length
> 0
175 _values
= values
.to_a
176 init_opt
("{help} <{values.join(", ")}>", default
, names
)
179 redef fun convert
(str
)
181 var id
= _values
.index_of
(str
)
183 var e
= "Unrecognized value for option {_names.join(", ")}.\n"
184 e
+= "Expected values are: {_values.join(", ")}."
190 fun value_name
: String = _values
[value
]
192 redef fun pretty_default
194 if default_value
!= null then
195 return " ({_values[default_value.as(not null)]})"
203 super OptionParameter
204 redef type VALUE: Int
206 init(help
: String, default
: Int, names
: String...) do init_opt
(help
, default
, names
)
208 redef fun convert
(str
) do return str
.to_i
212 super OptionParameter
213 redef type VALUE: Array[String]
215 init(help
: String, names
: String...)
217 _values
= new Array[String]
218 init_opt
(help
, _values
, names
)
221 var _values
: Array[String]
222 redef fun convert
(str
)
230 readable var _options
: Array[Option]
231 readable var _rest
: Array[String]
232 readable var _errors
: Array[String]
234 var _optmap
: Map[String, Option]
244 if lmax
< l
then lmax
= l
248 print
(i
.pretty
(lmax
))
252 # Parse ans assign options everywhere is the argument list
253 fun parse
(argv
: Collection[String])
255 var it
= argv
.iterator
259 protected fun parse_intern
(it
: Iterator[String])
265 while parseargs
and it
.is_ok
do
269 rest
.add_all
(it
.to_a
)
272 # We're looking for packed short options
273 if str
.last_index_of
('-') == 0 and str
.length
> 2 then
274 var next_called
= false
275 for i
in [1..str
.length
] do
276 var short_opt
= "-" + str
[i
].to_s
277 if _optmap
.has_key
(short_opt
) then
278 var option
= _optmap
[short_opt
]
279 if option
isa OptionParameter then
283 option
.read_param
(it
)
286 if not next_called
then it
.next
288 if _optmap
.has_key
(str
) then
289 var opt
= _optmap
[str
]
300 for opt
in _options
do
301 if opt
.mandatory
and not opt
.read
then
302 _errors
.add
("Mandatory option {opt.names.join(", ")} not found.")
307 fun add_option
(opts
: Option...)
316 _options
= new Array[Option]
317 _optmap
= new HashMap[String, Option]
318 _rest
= new Array[String]
319 _errors
= new Array[String]
331 fun get_errors
: Array[String]
333 var errors
: Array[String] = new Array[String]
335 errors
.add_all
(_errors
)