Command Line Subcommands in Fortran
Here’s the translation of the Go code to Fortran, with explanations in Markdown format suitable for Hugo:
Our program demonstrates the use of command-line subcommands, each with its own set of flags. This is similar to how tools like git
have different subcommands (e.g., git commit
, git push
) with their own specific options.
program main
use, intrinsic :: iso_fortran_env, only: error_unit
implicit none
integer :: num_args
character(len=32) :: arg
! Variables for 'foo' subcommand
logical :: foo_enable = .false.
character(len=32) :: foo_name = ""
! Variables for 'bar' subcommand
integer :: bar_level = 0
num_args = command_argument_count()
if (num_args < 1) then
write(error_unit, *) "expected 'foo' or 'bar' subcommands"
stop 1
end if
call get_command_argument(1, arg)
select case (arg)
case ("foo")
call parse_foo_args()
print *, "subcommand 'foo'"
print *, " enable:", foo_enable
print *, " name:", trim(foo_name)
call print_remaining_args(3)
case ("bar")
call parse_bar_args()
print *, "subcommand 'bar'"
print *, " level:", bar_level
call print_remaining_args(3)
case default
write(error_unit, *) "expected 'foo' or 'bar' subcommands"
stop 1
end select
contains
subroutine parse_foo_args()
integer :: i
character(len=32) :: arg_value
do i = 2, num_args
call get_command_argument(i, arg)
if (arg == "--enable") then
foo_enable = .true.
else if (arg(1:7) == "--name=") then
foo_name = arg(8:)
end if
end do
end subroutine parse_foo_args
subroutine parse_bar_args()
integer :: i
character(len=32) :: arg_value
do i = 2, num_args
call get_command_argument(i, arg)
if (arg(1:8) == "--level=") then
read(arg(9:), *) bar_level
end if
end do
end subroutine parse_bar_args
subroutine print_remaining_args(start_index)
integer, intent(in) :: start_index
integer :: i
print *, " tail:"
do i = start_index, num_args
call get_command_argument(i, arg)
print *, " ", trim(arg)
end do
end subroutine print_remaining_args
end program main
To compile and run the program:
$ gfortran -o command_line_subcommands command_line_subcommands.f90
First, invoke the foo subcommand:
$ ./command_line_subcommands foo --enable --name=joe a1 a2
subcommand 'foo'
enable: T
name: joe
tail:
a1
a2
Now try bar:
$ ./command_line_subcommands bar --level=8 a1
subcommand 'bar'
level: 8
tail:
a1
But bar won’t accept foo’s flags:
$ ./command_line_subcommands bar --enable a1
subcommand 'bar'
level: 0
tail:
--enable
a1
Note that Fortran doesn’t have built-in flag parsing like Go’s flag
package. This example implements a simple custom parsing logic. For more complex command-line argument parsing in Fortran, you might want to use external libraries or implement a more robust parsing system.
Next, we’ll look at environment variables, another common way to parameterize programs.