4 # Copyright (C) 1998, 1999, 2000 Motoyuki Kasahara.
6 # You may redistribute and/or modify this library under the same license
9 # See GetoptLong for documentation.
11 # Additional documents and the latest version of `getoptlong.rb' can be
12 # found at http://www.sra.co.jp/people/m-kasahr/ruby/getoptlong/
14 # The GetoptLong class allows you to parse command line options similarly to
15 # the GNU getopt_long() C library call. Note, however, that GetoptLong is a
16 # pure Ruby implementation.
18 # GetoptLong allows for POSIX-style options like <tt>--file</tt> as well
19 # as single letter options like <tt>-f</tt>
21 # The empty option <tt>--</tt> (two minus symbols) is used to end option
22 # processing. This can be particularly important if options have optional
25 # Here is a simple example of usage:
27 # require 'getoptlong'
28 # require 'rdoc/usage'
30 # opts = GetoptLong.new(
31 # [ '--help', '-h', GetoptLong::NO_ARGUMENT ],
32 # [ '--repeat', '-n', GetoptLong::REQUIRED_ARGUMENT ],
33 # [ '--name', GetoptLong::OPTIONAL_ARGUMENT ]
39 # opts.each do |opt, arg|
43 # hello [OPTION] ... DIR
52 # greet user by name, if name not supplied default is John
54 # DIR: The directory in which to issue the greeting.
57 # repetitions = arg.to_i
68 # puts "Missing dir argument (try --help)"
75 # for i in (1..repetitions)
83 # Example command line:
85 # hello -n 6 --name -- /tmp
91 ORDERINGS = [REQUIRE_ORDER = 0, PERMUTE = 1, RETURN_IN_ORDER = 2]
96 ARGUMENT_FLAGS = [NO_ARGUMENT = 0, REQUIRED_ARGUMENT = 1,
97 OPTIONAL_ARGUMENT = 2]
102 STATUS_YET, STATUS_STARTED, STATUS_TERMINATED = 0, 1, 2
107 class Error < StandardError; end
108 class AmbiguousOption < Error; end
109 class NeedlessArgument < Error; end
110 class MissingArgument < Error; end
111 class InvalidOption < Error; end
114 # Set up option processing.
116 # The options to support are passed to new() as an array of arrays.
117 # Each sub-array contains any number of String option names which carry
118 # the same meaning, and one of the following flags:
120 # GetoptLong::NO_ARGUMENT :: Option does not take an argument.
122 # GetoptLong::REQUIRED_ARGUMENT :: Option always takes an argument.
124 # GetoptLong::OPTIONAL_ARGUMENT :: Option may or may not take an argument.
126 # The first option name is considered to be the preferred (canonical) name.
127 # Other than that, the elements of each sub-array can be in any order.
129 def initialize(*arguments)
133 if ENV.include?('POSIXLY_CORRECT')
134 @ordering = REQUIRE_ORDER
140 # Hash table of option names.
141 # Keys of the table are option names, and their values are canonical
142 # names of the options.
144 @canonical_names = Hash.new
147 # Hash table of argument flags.
148 # Keys of the table are option names, and their values are argument
149 # flags of the options.
151 @argument_flags = Hash.new
154 # Whether error messages are output to $stderr.
174 # Rest of catenated short options.
179 # List of non-option-arguments.
180 # Append them to ARGV when option processing is terminated.
182 @non_option_arguments = Array.new
184 if 0 < arguments.length
185 set_options(*arguments)
190 # Set the handling of the ordering of options and arguments.
191 # A RuntimeError is raised if option processing has already started.
193 # The supplied value must be a member of GetoptLong::ORDERINGS. It alters
194 # the processing of options as follows:
196 # <b>REQUIRE_ORDER</b> :
198 # Options are required to occur before non-options.
200 # Processing of options ends as soon as a word is encountered that has not
201 # been preceded by an appropriate option flag.
203 # For example, if -a and -b are options which do not take arguments,
204 # parsing command line arguments of '-a one -b two' would result in
205 # 'one', '-b', 'two' being left in ARGV, and only ('-a', '') being
206 # processed as an option/arg pair.
208 # This is the default ordering, if the environment variable
209 # POSIXLY_CORRECT is set. (This is for compatibility with GNU getopt_long.)
213 # Options can occur anywhere in the command line parsed. This is the
216 # Every sequence of words which can be interpreted as an option (with or
217 # without argument) is treated as an option; non-option words are skipped.
219 # For example, if -a does not require an argument and -b optionally takes
220 # an argument, parsing '-a one -b two three' would result in ('-a','') and
221 # ('-b', 'two') being processed as option/arg pairs, and 'one','three'
222 # being left in ARGV.
224 # If the ordering is set to PERMUTE but the environment variable
225 # POSIXLY_CORRECT is set, REQUIRE_ORDER is used instead. This is for
226 # compatibility with GNU getopt_long.
228 # <b>RETURN_IN_ORDER</b> :
230 # All words on the command line are processed as options. Words not
231 # preceded by a short or long option flag are passed as arguments
232 # with an option of '' (empty string).
234 # For example, if -a requires an argument but -b does not, a command line
235 # of '-a one -b two three' would result in option/arg pairs of ('-a', 'one')
236 # ('-b', ''), ('', 'two'), ('', 'three') being processed.
238 def ordering=(ordering)
240 # The method is failed if option processing has already started.
242 if @status != STATUS_YET
243 set_error(ArgumentError, "argument error")
245 "invoke ordering=, but option processing has already started"
251 if !ORDERINGS.include?(ordering)
252 raise ArgumentError, "invalid ordering `#{ordering}'"
254 if ordering == PERMUTE && ENV.include?('POSIXLY_CORRECT')
255 @ordering = REQUIRE_ORDER
264 attr_reader :ordering
267 # Set options. Takes the same argument as GetoptLong.new.
269 # Raises a RuntimeError if option processing has already started.
271 def set_options(*arguments)
273 # The method is failed if option processing has already started.
275 if @status != STATUS_YET
277 "invoke set_options, but option processing has already started"
281 # Clear tables of option names and argument flags.
283 @canonical_names.clear
284 @argument_flags.clear
286 arguments.each do |*arg|
287 arg = arg.first # TODO: YARV Hack
289 # Find an argument flag and it set to `argument_flag'.
293 if ARGUMENT_FLAGS.include?(i)
294 if argument_flag != nil
295 raise ArgumentError, "too many argument-flags"
301 raise ArgumentError, "no argument-flag" if argument_flag == nil
306 # Check an option name.
308 next if i == argument_flag
310 if !i.is_a?(String) || i !~ /^-([^-]|-.+)$/
311 raise ArgumentError, "an invalid option `#{i}'"
313 if (@canonical_names.include?(i))
314 raise ArgumentError, "option redefined `#{i}'"
317 @canonical_names.clear
318 @argument_flags.clear
323 # Register the option (`i') to the `@canonical_names' and
324 # `@canonical_names' Hashes.
326 if canonical_name == nil
329 @canonical_names[i] = canonical_name
330 @argument_flags[i] = argument_flag
332 raise ArgumentError, "no option name" if canonical_name == nil
338 # Set/Unset `quiet' mode.
343 # Return the flag of `quiet' mode.
348 # `quiet?' is an alias of `quiet'.
353 # Explicitly terminate option processing.
356 return nil if @status == STATUS_TERMINATED
357 raise RuntimeError, "an error has occured" if @error != nil
359 @status = STATUS_TERMINATED
360 @non_option_arguments.reverse_each do |argument|
361 ARGV.unshift(argument)
364 @canonical_names = nil
365 @argument_flags = nil
367 @non_option_arguments = nil
373 # Returns true if option processing has terminated, false otherwise.
376 return @status == STATUS_TERMINATED
380 # Set an error (a protected method).
382 def set_error(type, message)
383 $stderr.print("#{$0}: #{message}\n") if !@quiet
386 @error_message = message
387 @canonical_names = nil
388 @argument_flags = nil
390 @non_option_arguments = nil
397 # Examine whether an option processing is failed.
402 # `error?' is an alias of `error'.
406 # Return the appropriate error message in POSIX-defined format.
407 # If no error has occurred, returns nil.
410 return @error_message
414 # Get next option name and its argument, as an Array of two elements.
416 # The option name is always converted to the first (preferred)
417 # name given in the original options to GetoptLong.new.
419 # Example: ['--option', 'value']
421 # Returns nil if the processing is complete (as determined by
422 # STATUS_TERMINATED).
425 option_name, option_argument = nil, ''
430 return nil if @error != nil
433 @status = STATUS_STARTED
434 when STATUS_TERMINATED
439 # Get next option argument.
441 if 0 < @rest_singles.length
442 argument = '-' + @rest_singles
443 elsif (ARGV.length == 0)
446 elsif @ordering == PERMUTE
447 while 0 < ARGV.length && ARGV[0] !~ /^-./
448 @non_option_arguments.push(ARGV.shift)
454 argument = ARGV.shift
455 elsif @ordering == REQUIRE_ORDER
456 if (ARGV[0] !~ /^-./)
460 argument = ARGV.shift
462 argument = ARGV.shift
466 # Check the special argument `--'.
467 # `--' indicates the end of the option list.
469 if argument == '--' && @rest_singles.length == 0
475 # Check for long and short options.
477 if argument =~ /^(--[^=]+)/ && @rest_singles.length == 0
479 # This is a long style option, which start with `--'.
482 if @canonical_names.include?(pattern)
483 option_name = pattern
486 # The option `option_name' is not registered in `@canonical_names'.
487 # It may be an abbreviated.
490 @canonical_names.each_key do |key|
491 if key.index(pattern) == 0
496 if 2 <= matches.length
497 set_error(AmbiguousOption, "option `#{argument}' is ambiguous between #{matches.join(', ')}")
498 elsif matches.length == 0
499 set_error(InvalidOption, "unrecognized option `#{argument}'")
504 # Check an argument to the option.
506 if @argument_flags[option_name] == REQUIRED_ARGUMENT
507 if argument =~ /=(.*)$/
509 elsif 0 < ARGV.length
510 option_argument = ARGV.shift
512 set_error(MissingArgument,
513 "option `#{argument}' requires an argument")
515 elsif @argument_flags[option_name] == OPTIONAL_ARGUMENT
516 if argument =~ /=(.*)$/
518 elsif 0 < ARGV.length && ARGV[0] !~ /^-./
519 option_argument = ARGV.shift
523 elsif argument =~ /=(.*)$/
524 set_error(NeedlessArgument,
525 "option `#{option_name}' doesn't allow an argument")
528 elsif argument =~ /^(-(.))(.*)/
530 # This is a short style option, which start with `-' (not `--').
531 # Short options may be catenated (e.g. `-l -g' is equivalent to
534 option_name, ch, @rest_singles = $1, $2, $3
536 if @canonical_names.include?(option_name)
538 # The option `option_name' is found in `@canonical_names'.
539 # Check its argument.
541 if @argument_flags[option_name] == REQUIRED_ARGUMENT
542 if 0 < @rest_singles.length
543 option_argument = @rest_singles
545 elsif 0 < ARGV.length
546 option_argument = ARGV.shift
548 # 1003.2 specifies the format of this message.
549 set_error(MissingArgument, "option requires an argument -- #{ch}")
551 elsif @argument_flags[option_name] == OPTIONAL_ARGUMENT
552 if 0 < @rest_singles.length
553 option_argument = @rest_singles
555 elsif 0 < ARGV.length && ARGV[0] !~ /^-./
556 option_argument = ARGV.shift
563 # This is an invalid option.
564 # 1003.2 specifies the format of this message.
566 if ENV.include?('POSIXLY_CORRECT')
567 set_error(InvalidOption, "invalid option -- #{ch}")
569 set_error(InvalidOption, "invalid option -- #{ch}")
574 # This is a non-option argument.
575 # Only RETURN_IN_ORDER falled into here.
580 return @canonical_names[option_name], option_argument
584 # `get_option' is an alias of `get'.
588 # Iterator version of `get'.
590 # The block is called repeatedly with two arguments:
591 # The first is the option name.
592 # The second is the argument which followed it (if any).
593 # Example: ('--opt', 'value')
595 # The option name is always converted to the first (preferred)
596 # name given in the original options to GetoptLong.new.
600 option_name, option_argument = get_option
601 break if option_name == nil
602 yield option_name, option_argument
607 # `each_option' is an alias of `each'.
609 alias each_option each