Parse command-line arguments: Difference between revisions

From Rosetta Code
Content added Content deleted
(J: something of a joke, given lack of any specified task... or maybe just really concise?)
(Add Ruby with 'optparse'. With Ruby, there is more than one way to parse options.)
Line 23: Line 23:
{{libheader|Icon Programming Library}}
{{libheader|Icon Programming Library}}
[http://www.cs.arizona.edu/icon/library/src/procs/options.icn options.icn supports getting command-line options]
[http://www.cs.arizona.edu/icon/library/src/procs/options.icn options.icn supports getting command-line options]

=={{header|J}}==


=={{header|PicoLisp}}==
=={{header|PicoLisp}}==
Line 41: Line 39:


=={{header|Ruby}}==
=={{header|Ruby}}==
Ruby's standard library provides two different packages to parse command-line arguments.
<lang shell>$ ./pargs.rb -h


* 'getoptlong' resembles the libraries from other languages.
Usage
* 'optparse' has more features.
-----
pargs [OPTIONS]

--help, -h:

show usage

--eddy, -e <message>

call eddy

--daniel, -d <message>

call daniel

--test, -t

run unit tests

$ ./pargs.rb -e Yo!
Calling eddy...
Yo!
$ ./pargs.rb --test
Calling Barry...
Hi!
Calling Cindy...
Hello!</lang>


=== Ruby with 'getoptlong' ===
<lang ruby>#!/usr/bin/env ruby
<lang ruby>#!/usr/bin/env ruby


Line 154: Line 127:
end
end
end</lang>
end</lang>

<pre>$ ./pargs.rb -h

Usage
-----
pargs [OPTIONS]

--help, -h:

show usage

--eddy, -e <message>

call eddy

--daniel, -d <message>

call daniel

--test, -t

run unit tests

$ ./pargs.rb -e Yo!
Calling eddy...
Yo!
$ ./pargs.rb --test
Calling Barry...
Hi!
Calling Cindy...
Hello!</pre>

=== Ruby with 'optparse' ===
<lang ruby>require 'optparse'

sflag = false
longflag = false
count = 0
percent = 50
fruit = nil

OptionParser.new do |opts|
# Default banner is "Usage: #{opts.program_name} [options]".
opts.banner += " [arguments...]"
opts.separator "This demo prints the results of parsing the options."
opts.version = "0.0.1"

opts.on("-s", "Enable short flag") {sflag = true}
opts.on("--long", "Enable long flag") {longflag = true}
opts.on("-b", "--both", "Enable both -s and --long"
) {sflag = true; longflag = true}
opts.on("-c", "--count", "Add 1 to count") {count += 1}

# Argument must match a regular expression.
opts.on("-p", "--percent PERCENT", /[0-9]+%?/i,
"Percent [50%]") {|arg| percent = arg.to_i}

# Argument must match a list of symbols.
opts.on("-f", "--fruit FRUIT",
[:apple, :banana, :orange, :pear],
"Fruit (apple, banana, orange, pear)"
) {|arg| fruit = arg}

begin
# Parse and remove options from ARGV.
opts.parse!
rescue OptionParser::ParseError => error
# Without this rescue, Ruby would print the stack trace
# of the error. Instead, we want to show the error message,
# suggest -h or --help, and exit 1.

$stderr.puts error
$stderr.puts "(-h or --help will show valid options)"
exit 1
end
end

print <<EOF
Short flag: #{sflag}
Long flag: #{longflag}
Count: #{count}
Percent: #{percent}%
Fruit: #{fruit}
Arguments: #{ARGV.inspect}
EOF</lang>

<pre>$ ruby takeopts.rb -h
Usage: takeopts [options] [arguments...]
This demo prints the results of parsing the options.
-s Enable short flag
--long Enable long flag
-b, --both Enable both -s and --long
-c, --count Add 1 to count
-p, --percent PERCENT Percent [50%]
-f, --fruit FRUIT Fruit (apple, banana, orange, pear)
$ ruby takeopts.rb -v
takeopts 0.0.1
$ ruby takeopts.rb -b -c
Short flag: true
Long flag: true
Count: 1
Percent: 50%
Fruit:
Arguments: []
$ ruby takeopts.rb -ccccp90% -f oran -- -arg
Short flag: false
Long flag: false
Count: 4
Percent: 90%
Fruit: orange
Arguments: ["-arg"]</pre>

Revision as of 16:42, 13 September 2011

Parse command-line arguments is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

Command-line arguments can be quite complicated, as in "nc -v -n -z -w 1 192.168.1.2 1-1000". Many languages provide a library (getopt or GetOpt) to parse the raw command line options in an intelligent way.

Icon and Unicon

The Icon Programming Library provides a procedure for processing command line options. See the library reference for detailed documentation. The code below is an example.

<lang Icon>link options

procedure main(ARGLIST) /errproc := stop # special error procedure or stop() opstring := "f!s:i+r.flag!string:integer+real." # example opttable := options(ARGLIST,optstring,errproc)

if \opttable[flag] then ... # test a flag r  := opttable(real) # assign a real r2 := opttable(r) # assign another real s  := opttable(s) # assign a string i  := opttable(i) # assign an integer ... end</lang>

options.icn supports getting command-line options

PicoLisp

PicoLisp doesn't have a library to get options. Instead, the command line is parsed at startup and handled in the following way: Each command line argument is executed (interpreted) as a Lisp source file, except that if the first character is a hypen '-', then that arguments is taken as a Lisp function call (without the surrounding parentheses). For example, the command line <lang shell>$ ./pil abc.l -foo def.l -"bar 3 4" -'mumble "hello"' -bye</lang> has the effect that

  1. The file "abc.l" is executed
  2. (foo) is called
  3. The file "def.l" is executed
  4. (bar 3 4) is called
  5. (mumble "hello") is called
  6. (bye) is called, resulting in program termination

Command line arguments like "-v", "-n" and "-z" can be implemented simply by defining three functions 'v', 'n' and 'z'.

In addition to the above mechanism, the command line can also be handled "manually", by either processing the list of arguments returned by 'argv', or by fetching arguments individually with 'opt'.

Ruby

Ruby's standard library provides two different packages to parse command-line arguments.

  • 'getoptlong' resembles the libraries from other languages.
  • 'optparse' has more features.

Ruby with 'getoptlong'

<lang ruby>#!/usr/bin/env ruby

  1. == Synopsis
  2. pargs: Phone a friend
  3. == Usage
  4. pargs [OPTIONS]
  5. --help, -h:
  6. show usage
  7. --eddy, -e <message>
  8. call eddy
  9. --danial, -d <message>
  10. call daniel
  11. --test, -t
  12. run unit tests

require "getoptlong" require "rdoc/usage"

def phone(name, message) puts "Calling #{name}..." puts message end

def test phone("Barry", "Hi!") phone("Cindy", "Hello!") end

def main mode = :usage

name = "" message = ""

opts=GetoptLong.new( ["--help", "-h", GetoptLong::NO_ARGUMENT], ["--eddy", "-e", GetoptLong::REQUIRED_ARGUMENT], ["--daniel", "-d", GetoptLong::REQUIRED_ARGUMENT], ["--test", "-t", GetoptLong::NO_ARGUMENT] )

opts.each { |option, value| case option when "--help" RDoc::usage("Usage") when "--eddy" mode = :call name = "eddy" message = value when "--daniel" mode = :call name = "daniel" message = value when "--test" mode = :test end }

case mode when :usage RDoc::usage("Usage") when :call phone(name, message) when :test test end end

if __FILE__==$0 begin main rescue Interrupt => e nil end end</lang>

$ ./pargs.rb -h

Usage
-----
pargs [OPTIONS]

--help, -h:

   show usage

--eddy, -e <message>

   call eddy

--daniel, -d <message>

   call daniel

--test, -t

   run unit tests

$ ./pargs.rb -e Yo!
Calling eddy...
Yo!
$ ./pargs.rb --test
Calling Barry...
Hi!
Calling Cindy...
Hello!

Ruby with 'optparse'

<lang ruby>require 'optparse'

sflag = false longflag = false count = 0 percent = 50 fruit = nil

OptionParser.new do |opts|

 # Default banner is "Usage: #{opts.program_name} [options]".
 opts.banner += " [arguments...]"
 opts.separator "This demo prints the results of parsing the options."
 opts.version = "0.0.1"
 opts.on("-s", "Enable short flag") {sflag = true}
 opts.on("--long", "Enable long flag") {longflag = true}
 opts.on("-b", "--both", "Enable both -s and --long"
         ) {sflag = true; longflag = true}
 opts.on("-c", "--count", "Add 1 to count") {count += 1}
 # Argument must match a regular expression.
 opts.on("-p", "--percent PERCENT", /[0-9]+%?/i,
         "Percent [50%]") {|arg| percent = arg.to_i}
 # Argument must match a list of symbols.
 opts.on("-f", "--fruit FRUIT",
         [:apple, :banana, :orange, :pear],
         "Fruit (apple, banana, orange, pear)"
         ) {|arg| fruit = arg}
 begin
   # Parse and remove options from ARGV.
   opts.parse!
 rescue OptionParser::ParseError => error
   # Without this rescue, Ruby would print the stack trace
   # of the error. Instead, we want to show the error message,
   # suggest -h or --help, and exit 1.
   $stderr.puts error
   $stderr.puts "(-h or --help will show valid options)"
   exit 1
 end

end

print <<EOF Short flag: #{sflag} Long flag: #{longflag} Count: #{count} Percent: #{percent}% Fruit: #{fruit} Arguments: #{ARGV.inspect} EOF</lang>

$ ruby takeopts.rb -h
Usage: takeopts [options] [arguments...]
This demo prints the results of parsing the options.
    -s                               Enable short flag
        --long                       Enable long flag
    -b, --both                       Enable both -s and --long
    -c, --count                      Add 1 to count
    -p, --percent PERCENT            Percent [50%]
    -f, --fruit FRUIT                Fruit (apple, banana, orange, pear)
$ ruby takeopts.rb -v 
takeopts 0.0.1
$ ruby takeopts.rb -b -c
Short flag: true
Long flag: true
Count: 1
Percent: 50%
Fruit: 
Arguments: []
$ ruby takeopts.rb -ccccp90% -f oran -- -arg
Short flag: false
Long flag: false
Count: 4
Percent: 90%
Fruit: orange
Arguments: ["-arg"]