-
Notifications
You must be signed in to change notification settings - Fork 5
Get Started
In your project make use of f90getopt by adding use f90getopt
in the head of your Fortran main file. Then decide if you want to use long options as "--alpha" (GNU extension) or just short options as "-a" (POSIX-compliant) or both.
Your development tree for a short option program is just:
- Add
use f90getopt
statement - Handle no options
-
Process options one by one in a do-loop with character function
getopt()
- Done
You have to specify what to do if no option was committed. Check for zero options and specify the action if true:
if (command_argument_count() .eq. 0) then
print*, "ERROR: No options committed"
end if
2.) Then call the function getopt()
in a do-loop and process the short options one by one by a select-cas-statement. Place just one character-array argument in getopt()
. The character-array should contain all single-character option names in a line without space. If you want that some characters should ask for arguments, add a trailing colon (:) to the character.
If you want to have 3 options in your program, e.g. "-a", "-b" and "-h" and you want to commit an argument to the option "-b" your character array is "ab:h". The argument of "-b" (or others) is stored in the global character variable optarg
. It is not an array, it pulls the argument of an option one by one. You do not need to declare optarg
in your program. It is provided by f90getopt's module automatically.
The maximum sizes of the short option character string is 80 characters as well as optarg
.
do
short = getopt("ab:h") ! Separate variable for ifort compatibility
select case(short)
case(char(0)) ! if no arguments are left
exit
case("a")
print*, "option -a"
case("b")
print*, "option -b=", trim(optarg) ! "trim" is quite useful to avoid trailing spaces
case("h")
print*, "help-screen"
end select
end do
Your done.
program short_options
! Full working sample program for short options
use f90getopt
implicit none
character(len=1) :: short ! getopt short variable
! If no options were committed
! ----------------------------
if (command_argument_count() .eq. 0) then
print*, "ERROR: Program has options: -a -b x -h"
end if
! START Processing options
! ------------------------
do
short = getopt("ab:h") ! Separate variable for ifort compatibility
select case(short)
case(char(0))
exit
case("a")
print*, "option alpha/a"
case("b")
print*, "option beta/b=", trim(optarg)
case("h")
print*, "help-screen"
end select
end do
end program
You can run it by e.g.:
./short_options -a -b 3.14
./short_options -ab 3.14
./short_options -b "Title"
./short_options -h
First, you cannot use long options GNU extension without the POSIX-compliant short ones in f90getopt. The GNU-style is just an extension of the POSIX standard.
But if you want to use long options (GNU-style), e.g. "--alpha" in your program additionally, you just have to add their declaration by the derived type array variable option_s
before you process the options one by one as done in the short option section. That means you program is constructed in the following order:
- Add
use f90getopt
statement - Handle no options
- Declare
option_s
derived type array variable for long options (see below) -
Process options one by one in a do-loop with character function
getopt()
. Important: You have to add an additional argument to `getopt()' in comparison to the short option handling (see below). But everything else stay the same.
For long options you need to declare option_s
derived-type array variable before processing the options in the do-loop. option_s
contains 3 values:
No. | Description | Type | Size | Example |
---|---|---|---|---|
1 | Long option name | character | 2-80 | "alpha" |
2 | Value required | logical | 1 | .true. |
3 | Short option name | character | 1 | "a" |
A complete definition of option_s
for the long option "--alpha", "--beta" and "--help" could look like:
type(option_s) :: opts(2)
opts(1) = option_s("alpha", .false., "a") ! has no argument
opts(2) = option_s("beta", .true., "b") ! has an argument
opts(3) = option_s("help", .false., "h") ! has no argument
For long option you have to add additionally to the short option character array a second argument to getopt()
: The name of the long option declaration option_s
, here opts
. Your getopts
-call looks for the examples above as:
getopts("ab:h", opts)
instead of `getopt("ab:h") for short options only.
IMPORTANT: The short option names declared in option_s
have to match the ones in the short option character array!
program f90getopt_sample
! Full working sample program for short and long options
use f90getopt
implicit none
! START for longopts only (optional)
! ----------------------------------
type(option_s) :: opts(3)
opts(1) = option_s("alpha", .false., "a")
opts(2) = option_s("beta", .true., "b")
opts(3) = option_s("help", .false., "h")
! If no options were committed
! ----------------------------
if (command_argument_count() .eq. 0) then
print*, "ERROR: Program has options: -a. --alpha -b x --beta=x --beta x -h --help"
end if
! START Processing options
do
select case(getopt("ab:h", opts))
case(char(0)) ! When all options are processed
exit
case("a")
print*, "option alpha/a"
case("b")
print*, "option beta/b=", trim(optarg)
case("h")
print*, "help-screen"
end select
end do
end program f90getopt_sample
If you commit a number by optarg
and you want to do some calculations with it, you need to convert it by read(optarg,*) x
. Where "x" is declared as the type you need, e.g.:
! Conversion of character variable "optarg" to double variable "x"
double precision :: x
read(optarg,*) x