Skip to content
Stefano Zaghi edited this page Mar 23, 2016 · 4 revisions

FLAP fully supports nested (sub)commands or groups of command line arguments. For example git has many (sub)commands, git commit [commit-options], git tag [tag-options] .... In the FLAP nomenclature (sub)commands are named group (of Command Line Arguments).

Add a group of CLAs can be done with 2 ways (direct or indirect):

  • add explicitly a new group, call cli%add_group(...);
  • add a new CLA into a group not yet defined, call cli%add(group='new', switch='--mount', ...).

where cli is the defined command line interface, e.g. type(command_line_interface):: cli.

In the second case, if the group new is not yet defined it is created on the fly and the CLA is added to it.

Add a new group

  call cli%add_group(help, description, group)

where

  character(*), optional, intent(in) :: help        !< Help message.
  character(*), optional, intent(in) :: description !< Detailed description.
  character(*),           intent(in) :: group       !< Name of the grouped CLAs.

The dummy arguments should be auto-explicative. Note that the help dummy argument is used for printing a pretty help message explaining the group usage, thus should be always provided.

Add a CLA to a not yet defined group

call cli%add(self, pref, group, group_index, switch, switch_ab, help, required, &
             positional, position, hidden, act, def, nargs, choices, exclude, envvar, error)

where

character(*), optional, intent(in)  :: pref        !< Prefixing string.
character(*), optional, intent(in)  :: group       !< Name of the grouped CLAs.
integer(I4P), optional, intent(in)  :: group_index !< Index of the grouped CLAs.
character(*), optional, intent(in)  :: switch      !< Switch name.
character(*), optional, intent(in)  :: switch_ab   !< Abbreviated switch name.
character(*), optional, intent(in)  :: help        !< Help message describing the CLA.
logical,      optional, intent(in)  :: required    !< Flag for set required argument.
logical,      optional, intent(in)  :: positional  !< Flag for checking if CLA is a positional or a named CLA.
integer(I4P), optional, intent(in)  :: position    !< Position of positional CLA.
logical,      optional, intent(in)  :: hidden      !< Flag for hiding CLA, thus it does not compare into help.
character(*), optional, intent(in)  :: act         !< CLA value action.
character(*), optional, intent(in)  :: def         !< Default value.
character(*), optional, intent(in)  :: nargs       !< Number of arguments consumed by CLA.
character(*), optional, intent(in)  :: choices     !< List of allowable values for the argument.
character(*), optional, intent(in)  :: exclude     !< Switch name of the mutually exclusive CLA.
character(*), optional, intent(in)  :: envvar      !< Environment variable from which take value.
integer(I4P), optional, intent(out) :: error       !< Error trapping flag.

for more details see Adding-CLA-to-CLI.

Groups interaction

The following rules hold:

  • if no group is specified in adding a CLA, it is added to default group that has no name (standard, not nested CLI);

  • each group different from the default (not nested one), must have a name;

  • it is allowed to mix nested (named) group with the default (not named) one.

For example the following is a regular FLAP CLI:

! initializing Command Line Interface
call cli%init(progname    = 'Test_Driver_Nested',                                    &
              version     = 'v2.1.5',                                                &
              authors     = 'Stefano Zaghi',                                         &
              license     = 'MIT',                                                   &
              description = 'Toy program for testing FLAP with nested commands',     &
              examples    = ['Test_Driver_Nested                      ',&
                             'Test_Driver_Nested -h                   ',&
                             'Test_Driver_Nested init                 ',&
                             'Test_Driver_Nested commit -m "fix bug-1"',&
                             'Test_Driver_Nested tag -a "v2.1.5"      '])
! set a Command Line Argument without a group to trigger authors names printing
call cli%add(switch='--authors', switch_ab='-a', help='Print authors names', &
             required=.false., act='store_true', def='.false.')
! set Command Line Arguments Groups, i.e. commands
call cli%add_group(group='init', description='fake init versioning')
call cli%add_group(group='commit', description='fake commit changes to current branch')
call cli%add_group(group='tag', description='fake tag current commit')
! set Command Line Arguments of commit command
call cli%add(group='commit', switch='--message', switch_ab='-m', &
             help='Commit message', required=.false., act='store',def='')
! set Command Line Arguments of commit command
call cli%add(group='tag', switch='--annotate', switch_ab='-a', help='Tag annotation', &
             required=.false., act='store',def='')
! parsing Command Line Interface
call cli%parse(error=error)
if (error/=0) then
  print '(A)', 'Error code: '//trim(str(n=error))
  stop
endif
! using Command Line Interface data to trigger program behaviour
call cli%get(switch='-a', val=authors_print, error=error) ; if (error/=0) stop
if (authors_print) then
  print '(A)','Authors: '//cli%authors
elseif (cli%run_command('init')) then
  print '(A)','init (fake) versioning'
elseif (cli%run_command('commit')) then
  call cli%get(group='commit', switch='-m', val=message, error=error) ; if (error/=0) stop
  print '(A)','commit changes to current branch with message "'//trim(message)//'"'
elseif (cli%run_command('tag')) then
  call cli%get(group='tag', switch='-a', val=message, error=error) ; if (error/=0) stop
  print '(A)','tag current branch with message "'//trim(message)//'"'
else
  print '(A)','cowardly you are doing nothing... try at least "-h" option!'
endif

where the CLA --authors is added to the default not named group and the others CLAs have their own named group.

It is worth nothing that each group has its own detailed help automatically created by the group definition. For example the above code invoked with -h option gives:

usage: Test_Driver_Nested  [--authors] [--help] [--version] {init,commit,tag} ...

Toy program for testing FLAP with nested commands

Optional switches:
   --authors, -a
          default value .false.
          Print authors names
   --help, -h
          Print this help message
   --version, -v
          Print version

Commands:
  init
          fake init versioning
  commit
          fake commit changes to current branch
  tag
          fake tag current commit

For more detailed commands help try:
  Test_Driver_Nested init -h,--help
  Test_Driver_Nested commit -h,--help
  Test_Driver_Nested tag -h,--help

Examples:
   Test_Driver_Nested
   Test_Driver_Nested -h
   Test_Driver_Nested init
   Test_Driver_Nested commit -m "fix bug-1"
   Test_Driver_Nested tag -a "v2.1.5"

Note that the help message regard the CLAs of the default group and the groups themself, but the groups help is not printed. For printing detailed help of each group, you must invoked the code with:

  Test_Driver_Nested init -h

promting something like:

usage:  Test_Driver_Nested init [--help] [--version]

fake init versioning

Optional switches:
   --help, -h
          Print this help message
   --version, -v
          Print version

Examples:
   Test_Driver_Nested
   Test_Driver_Nested -h
   Test_Driver_Nested init
   Test_Driver_Nested commit -m "fix bug-1"
   Test_Driver_Nested tag -a "v2.1.5"

For more details, see the provided example.

Clone this wiki locally