Command line option parser module

Introduction

This is a command line option parser for Fortran 90/95 programs. It can handle integer, real, complex, logical and character (len=256) options. It was inspired by opt_parse, (one of the) command line option modules of Python.

Limitations

The Fortran 2003 procedures COMMAND_ARGUMENT_COUNT, GET_ARGUMENT_COUNT and GET_COMMAND are used, so you'll need a fairly recent compiler (it works with recent version of ifort, gfortran and g95).
To set options and get their values, the module uses generic interfaces (SET_OPTION & GET_OPTION_VALUE).

The real and complex options can be of size single, double or quadruple. That last one is only supported on Intel fortran, as quadruple precision is not a mandatory part of the Fortran standard and therefore not supported by the two GNU fortran compilers.

Quick Overview

All public procedures and data can be made available in the program by USEing the module:

use m_option_parser

Options are defined by calling SET_OPTION as follows:

call set_option ( program_options , "--long-name" , "-l" , default_value , "help message" )

Where the first argument is the derived type holding all program option related data. It must be defined and allocated at the beginning of the program:

type(option_t) , allocatable :: program_options(:)
allocate( program_options(10) ) ! as much as the number of options

The above subroutine can take an additional sixth (string) option that sets the group to which this option belongs. This is only important if you want to provide a help message explaining all options to the user and group the options that belong together:

call set_option ( program_options ,   &
      "--long-name" ,  & ! long option name
      "-l" ,           & ! short option name
      default_value ,  & ! default value
      "help message" , & ! option explanation
      "group_name" )     ! group to which the option belongs (optional)

Every option needs a non-empty long name and may have an empty short name.

The actual command line parsing is done with a call to PARSE_OPTIONS:

call parse_options ( program_options )

To tie the value of a supplied option to a variable, the variable must first be declared in the program, after which it can be tied to the value supplied on the command line (or, in case it was not supplied, the default value) using a call to GET_OPTION_VALUE:

call get_option_value ( program_options , "-l" , variable_name )

Here, the second argument is one of the keys (short or long) defined earlier.

To print a help message explaining all options, call PRINT_HELP_MESSAGE as follows:

call print_help_message ( program_options , "My Program" , "1.0" , "Wim Van Hoydonck" , "2007" )

Only the first argument is mandatory, the second to fifth arguments can be used to show the name of the program, the version of the program, the author and the (copyright) year(s), respectively.

A complete example can be found at the end of this page.

Supported Option Styles

The options follow the GNU style of short and long keys, where the following examples are valid short and valid long keys:

$ ./prog -v 10.0
$ ./prog --airspeed 10.0
$ ./prog -v=10.0
$ ./prog --airspeed=10.0

Short keys can be combined as follows:

$ ./prog -iv .true.

will set the both logical options to true. If they are combined, they share the same value (meaning that if two or more values follow a short key combination, only the first value will be used). So, in the following example, a and b both get the value 1:

$ ./prog -ab 1 2

Logical keys do not need a value, if they are present, their value is automatically set to true. So,

$ ./prog -iv

will both set i and v to true.

A complex value on the command line must be given as in the following example:

$ ./prog -p "(-1.,2.)"

If a key was not found on the command line, its variable gets the default value that is the fourth input to SET_OPTION (see below for an example).

Sources

The module and a test program can be downloaded here as a compressed tar archive. This archive does not contain build files, but using g95, the module library and program can be build as follows:

$ wget http://users.telenet.be/tuinbels/fortran/m_option_parser-2.0.tgz
$ tar -xzf m_option_parser-2.0.tgz
$ cd m_option_parser
$ g95 -c -o m_option_parser.o m_option_parser.F90
$ g95 -o test_option_parser test_option_parser.F90 m_option_parser.o

License

The module is licensed under a 3-clause BSD license.

API docs

The API docs can be viewed here. They were created using ROBODoc

Public module name, subroutine names and derived types

m_option_parser
option parser module
option_t
derived type holding all data for an option
set_parser_options
set some parser options
set_option
set arguments of any option
check_options
check short & long keys for doubles
parse_options
parse command line and filter out valid options
get_option_value
get the value of a key
print_help_message
display help message explaining all options

Example

program test_option_parser
  
  use m_option_parser ! load public derived types and procedures

  implicit none

  ! create allocatable instance of option_t
  type(option_t) , allocatable :: program_options(:)

  integer                      :: err

  ! the local variables that need values
  real                         :: incidence
  complex                      :: pole
  logical                      :: version , help
  integer                      :: file_unit
  character(len=256)           :: file_name

  ! allocate as much space for this instance of option_t as there are options (6 in this case)
  allocate( program_options(6) )

  ! set logical, real, integer, character, logical command-line options
  ! option number - long key - short key - default value - help text
  call set_option ( program_options , "--version" , "-v" , .false. , "print version info to screen" )
  call set_option ( program_options , "--incidence" , "-i" , 15.0 , "set incidence" )
  call set_option ( program_options , "--file-unit" , "-u" , 4 , "set file unit" )
  call set_option ( program_options , "--file-name" , "-f" , "myfile.xml" , "set output file name" )
  call set_option ( program_options , "--help" , "-h" , .false. , "print help message and quit" )
  call set_option ( program_options , "--pole" , "-p" , cmplx(-1.1,1.0) , "set complex pole" )

  ! check that (short) keys are not set double
  call check_options ( program_options , err )
  if (err /= 0) stop

  ! now parse the command line by which this program was invoked
  call parse_options ( program_options )

  ! attach cmdline/default options to variables
  call get_option_value ( program_options , "-i" , incidence )
  call get_option_value ( program_options , "-h" , help )
  call get_option_value ( program_options , "-v" , version )
  call get_option_value ( program_options , "-u" , file_unit )
  call get_option_value ( program_options , "-f" , file_name )
  call get_option_value ( program_options , "-p" , pole )

  if ( help ) then ! if help flag was supplied, display a help message and quit
    call print_help_message ( program_options , "My Program" , "1.0" , "Wim Van Hoydonck" , "2007" )
    stop
  end if

  ! the following is just to check that the values are correct
  print *, "incidence : " , incidence
  print *, "help      : " , help
  print *, "version   : " , version
  print *, "file_unit : " , file_unit
  print *, "file_name : " , file_name
  print *, "pole      : " , pole

end program