COMMAND LINE CRACKING WITH GET_COMMAND() AND WHY THE PROCEDURE NEEDS CLARIFIED OR CHANGED:

John S. Urban Dec,2008

Well, the good news is starting with Fortran 2003 there is a standard way to get the command line with the GET_COMMAND() procedure. It is already very widely available in f90+ compilers (g95, gfortran, ifort, ...). Or, you can use the F2KCLI package to add it if your compiler does not have it; or you can make something very much like it using the often-available GETARGS() and IARG() procedures or their equivalent (I don't know of a Fortran /FORTRAN compiler that doesn't have one anymore).

The GET_COMMAND() routine is clarified in the most recent Fortran 2008 proposal; but there's still a flaw in making what GET_COMMAND() returns determinant; and different compilers seem to have solved the "problem" differently. G95 seems to do the most reasonable thing -- leave the command "verb" out of the "complete command string" and let you get the verb with GET_COMMAND_ARGUMENT(0) if you can. But the standard seems to imply the verb should be returned by GET_COMMAND() (and gfortran, ifort, and IBM include it). Yet the description of GET_COMMAND_ARGUMENT() clearly states that GET_COMMAND_ARGUMENT(0) may not exist or be accessable, while other arguments (ie. 1, 2, 3, ...) may be.

SIMPLE EXAMPLE OF WHERE THIS LEADS TO PROBLEMS:

Lets say the verb should be part of what GET_COMMAND() returns:

A related procedure (GET_COMMAND_ARGUMENT()) makes it clear the command verb may legally not be defined. And so if you use GET_COMMAND() you don't know if the returned value includes the pathname to the command or not; and some systems allow filenames with blank characters (or backslashes,etc.); and you are going to have to make sure the returned value is big enough for any pathname plus the actual arguments.

Lets say the verb is not part of what GET_COMMAND() returns:

You can still get it with GET_COMMAND_ARGUMENT(0,VERB,STATUS) as one string, so things like blanks in the filename are not confusing.

So I say that the G95 interpretation ends up with a better routine. In fact, GET_COMMAND() is better off replaced with a routine that concatenates the strings returned by GET_COMMAND_ARGUMENT() if interpretation (A) is used.

AGAIN WITH EXAMPLES AND DOCUMENTATION EXTRACTS:

! ------------------------------------------------------------------ ! TEST PROGRAM: ! ------------- ! ISSUE: ! ifort(1) and gfortran(1) return get_command_argument(0) at beginning of ! string returned by get_command(3f). g95(1) return string that begins ! with get_command_argument(1) ------------------------------------------------------------------- ! pros and cons: ! get_command_argument implies there may not be a meaningful ! get_command_argument(0); so you can't know if the "verb" is there or not. ! Could resolve that by letting you control if ! get_command_argument(0) is present in COMMAND or not; ! or less desirably STATUS could have values assigned that mean ! returned-OK-with-arg(0) and returned-OK-without-arg(0). ! That is, STATUS=0 means OK with; STATUS=1 means OK without. ! Using STATUS means the current command does not change, but this ! means you would have to conditionally parse arg(0) if present. ! But is get_command_argument(0) "exactly as typed" or the ! full path or ! the path leaf? ! What about spaces and non-alphameric characters like \ in the command? ! ! Something else that is not clear to me -- is the only delimiter for ! get_command_argument(3F) a space? What about tab, comma, colon, and so on? ! ! the other problem is that the length of the COMMAND variable would have ! to be able to hold all the parameters plus the longest possible arg(0) ! option; which is typically a system pathname. Program echo integer :: i integer :: ierr character :: command*256 call get_command_argument(0,command,i,ier) write (*,*) "get_command_argument(0) is "//command(:len_trim(command)) call get_command(command,i,ier) write (*,*) "get_command is " //command(:len_trim(command)) do i10=1,command_argument_count() call get_command_argument(i10,command) write (*,*) i10, "th argument="//command(:len_trim(command)) enddo end program echo
  -------------------------------------------------------------------
!GFORTRAN RUN:
  ------------
!
!gfortran-4 --version 
!   GNU Fortran (GCC) 4.3.2 20080827 (alpha-testing) 1
!   Copyright (C) 2008 Free Software Foundation, Inc.
!     :
!
!gfortran-4 bug1.f90
!./a
!   get_command_argument(0) is ./a
!   get_command is ./a                    <--- arg(0) is in COMMAND
!
  -------------------------------------------------------------------
!G95 RUN:
  -------
!
!g95 --version
!G95 (GCC 4.0.3 (g95 0.92!) Aug 21 2008)
!Copyright (C) 2002-2005 Free Software Foundation, Inc.
!     :
!
!g95 bug1.f90
!./a
! get_command_argument(0) is ./a
! get_command is                      <--- arg(0) is not in COMMAND
  -------------------------------------------------------------------

So, what should GET_COMMAND(3f) and GET_COMMAND_ARGUMENT(3f) return from a Unix platform (for example) if the command executed is:

/bin/"parsed command" -header  hello

Is there any system where the following should execute? what would they return if run with the program above?

program.exe,a=10,b=20,c,d
.\program.exe/a=10/b=20
RESULTS FROM GFORTRAN COMPILER:
Microsoft Windows [Version 6.0.6001]
Copyright (c) 2006 Microsoft Corporation.  All rights reserved.

# program called "gf"
gf;a;b;c
 get_command_argument(0) is gf
 get_command is gf ;a;b;c             <-- notice the space
           1 th argument=;a;b;c

# program called "g f.exe"
"g f"/a=10/b=20                         
 get_command_argument(0) is gf
 get_command is g f /a=10/b=20
           1 th argument=/a=10/b=20

# two ways on MSW to execute the same program. Results varied a lot 
# with each compiler. Some showed "g f.exe" in GET_COMMAND(), but "g f" in
# GET_COMMAND_ARGUMENT(), for example.
"g f" hello
"g f.exe" hello

#############################################################################