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 var names
: Array[String]
22 # Type of the value of the option
23 type VALUE: nullable Object
25 # Human readable description of the option
28 # Gathering errors during parsing
29 var errors
: Array[String] = new Array[String]
31 # Is this option mandatory?
32 var mandatory
: Bool writable = false
34 # Has this option been read?
35 var read
: Bool writable = false
37 # Current value of this option
38 var value
: VALUE writable
40 # Default value of this option
41 var default_value
: VALUE writable
44 init(help
: String, default
: VALUE, names
: nullable Array[String])
46 init_opt
(help
, default
, names
)
49 fun init_opt
(help
: String, default
: VALUE, names
: nullable Array[String])
52 self.names
= new Array[String]
54 self.names
= names
.to_a
57 default_value
= default
61 # Add new aliases for this option
62 fun add_aliases
(names
: String...) do names
.add_all
(names
)
64 # An help text for this option with default settings
65 redef fun to_s
do return pretty
(2)
67 # A pretty print for this help
68 fun pretty
(off
: Int): String
70 var text
= new FlatBuffer.from
(" ")
71 text
.append
(names
.join
(", "))
73 var rest
= off
- text
.length
74 if rest
> 0 then text
.append
(" " * rest
)
76 #text.append(pretty_default)
80 fun pretty_default
: String
82 var dv
= default_value
83 if dv
!= null then return " ({dv.to_s})"
87 # Consume parameters for this option
88 protected fun read_param
(it
: Iterator[String])
96 init(text
: String) do super(text
, null, null)
98 redef fun pretty
(off
) do return to_s
100 redef fun to_s
do return helptext
105 redef type VALUE: Bool
107 init(help
: String, names
: String...) do super(help
, false, names
)
109 redef fun read_param
(it
)
118 redef type VALUE: Int
120 init(help
: String, names
: String...) do super(help
, 0, names
)
122 redef fun read_param
(it
)
129 # Option with one parameter (mandatory by default)
130 abstract class OptionParameter
132 protected fun convert
(str
: String): VALUE is abstract
134 # Is the parameter mandatory?
135 var parameter_mandatory
: Bool writable = true
137 redef fun read_param
(it
)
140 if it
.is_ok
and it
.item
.chars
.first
!= '-' then
141 value
= convert
(it
.item
)
144 if parameter_mandatory
then
145 errors
.add
("Parameter expected for option {names.first}.")
152 super OptionParameter
153 redef type VALUE: nullable String
155 init(help
: String, names
: String...) do super(help
, null, names
)
157 redef fun convert
(str
) do return str
161 super OptionParameter
162 redef type VALUE: Int
163 var values
: Array[String]
165 init(values
: Array[String], help
: String, default
: Int, names
: String...)
167 assert values
.length
> 0
168 self.values
= values
.to_a
169 super("{help} <{values.join(", ")}>", default
, names
)
172 redef fun convert
(str
)
174 var id
= values
.index_of
(str
)
176 var e
= "Unrecognized value for option {names.join(", ")}.\n"
177 e
+= "Expected values are: {values.join(", ")}."
183 fun value_name
: String do return values
[value
]
185 redef fun pretty_default
187 if default_value
!= null then
188 return " ({values[default_value]})"
196 super OptionParameter
197 redef type VALUE: Int
199 init(help
: String, default
: Int, names
: String...) do super(help
, default
, names
)
201 redef fun convert
(str
) do return str
.to_i
205 super OptionParameter
206 redef type VALUE: Float
208 init(help
: String, default
: Float, names
: String...) do super(help
, default
, names
)
210 redef fun convert
(str
) do return str
.to_f
214 super OptionParameter
215 redef type VALUE: Array[String]
217 init(help
: String, names
: String...)
219 values
= new Array[String]
220 super(help
, values
, names
)
223 private var values
: Array[String]
224 redef fun convert
(str
)
232 var options
: Array[Option]
233 var rest
: Array[String]
234 var errors
: Array[String]
236 private var optmap
: Map[String, Option]
246 if lmax
< l
then lmax
= l
250 print
(i
.pretty
(lmax
))
254 # Parse ans assign options everywhere is the argument list
255 fun parse
(argv
: Collection[String])
257 var it
= argv
.iterator
261 protected fun parse_intern
(it
: Iterator[String])
267 while parseargs
and it
.is_ok
do
271 rest
.add_all
(it
.to_a
)
274 # We're looking for packed short options
275 if str
.chars
.last_index_of
('-') == 0 and str
.length
> 2 then
276 var next_called
= false
277 for i
in [1..str
.length
] do
278 var short_opt
= "-" + str
.chars
[i
].to_s
279 if optmap
.has_key
(short_opt
) then
280 var option
= optmap
[short_opt
]
281 if option
isa OptionParameter then
285 option
.read_param
(it
)
288 if not next_called
then it
.next
290 if optmap
.has_key
(str
) then
291 var opt
= optmap
[str
]
302 for opt
in options
do
303 if opt
.mandatory
and not opt
.read
then
304 errors
.add
("Mandatory option {opt.names.join(", ")} not found.")
309 fun add_option
(opts
: Option...)
318 options
= new Array[Option]
319 optmap
= new HashMap[String, Option]
320 rest
= new Array[String]
321 errors
= new Array[String]
333 fun get_errors
: Array[String]
335 var errors
: Array[String] = new Array[String]
337 errors
.add_all
(errors
)