program cmdline !=============================================================================== ! reading the command line arguments combined ! with a configuration file and optional file ! and prompting all using NAMELIST ! ! John S. Urban -- Aug 29, 2009 !=============================================================================== CHARACTER(LEN=1000):: string(3) ! storage for command line arguments character(LEN=255) :: message ! storage for I/O messages ! ----------------------------------------------------- ! make a namelist group with various data types TYPE person INTEGER p_age CHARACTER(20) p_name REAL p_height END TYPE person INTEGER :: i=1,j=2,k=3 ! simple integers REAL :: s=1,t=2,r=3 ! simple reals INTEGER :: arr(3)=[10,20,30] ! numeric array COMPLEX :: x=(33.33,44.44) ! complex LOGICAL :: prompt=.false. ! logical, prompt for values CHARACTER(len=256) :: config='config.txt' ! character variable, config file CHARACTER(len=256) :: file='' ! character variable, auxiliary file TYPE(person) smith ! user-defined type namelist /cmd/ i,j,k,arr,smith,s,t,r,x,config,file,prompt ! ----------------------------------------------------- smith=person(20,'john smith',5.90) string(1)=" &cmd " string(3)=" /" ! ----------------------------------------------------- ! cannot seem to do this to * or use delim= on write() or read() open(6,delim='apostrophe') ! ----------------------------------------------------- ! crack command line options CALL GET_COMMAND_ARGUMENTS(string(2),icmd_len,ier) read(string,nml=cmd,iostat=ios,iomsg=message) if(ios.eq.0)then write(*,*)' read command line:'//string(2)(:len_trim(string(2))) else write(*,*)' error reading command line:'//string(2)(:len_trim(string(2))) write(*,*)'iostat=',ios write(*,*)'message=',message endif ! ----------------------------------------------------- ! try to open and read config file, possibly changed by command line if(config.ne.'')then open(unit=10,file=config(:len_trim(config)),iostat=ios) if(ios.eq.0)then read(10,nml=cmd,iostat=ios,iomsg=message) if(ios.eq.0)then write(*,*)' read config file '//config(:len_trim(config)) else write(*,*)' error reading config file '//config(:len_trim(config)) write(*,*)' iostat: ',ios write(*,*)' message:'//message endif else write(*,*)' could not open config file '//config(:len_trim(config)) endif endif close(unit=10,iostat=ios) ! ----------------------------------------------------- ! reapply command line options, except if config file is changed it will not be used read(string,nml=cmd,iostat=ios,iomsg=message) if(ios.eq.0)then write(*,*)' re-read command line:'//string(2)(:len_trim(string(2))) else write(*,*)' error re-reading command line:'//string(2)(:len_trim(string(2))) endif ! ----------------------------------------------------- ! try to open any auxiliary file given if(file.ne.'')then open(unit=10,file=file(:len_trim(file)),iostat=ios) if(ios.eq.0)then read(10,nml=cmd) if(ios.eq.0)then write(*,*)' read file '//file(:len_trim(file)) else write(*,*)' error reading auxiliary file '//file(:len_trim(file)) endif else write(*,*)' could not open auxiliary file '//file(:len_trim(file)) endif else write(*,*)' no auxiliary file '//file(:len_trim(file)) endif close(unit=10,iostat=ios) ! ----------------------------------------------------- ! if prompt=t was specified, read values from stdin one line if(prompt)then write(*,*)'? to display ; / to end' do write(*,*)'Enter values:(name=value or "/" to end or "?" to show namelist)' read(*,'(a)',iostat=ios)string(2) if(string(2).eq.'?')then WRITE(*,'(80(''=''))') WRITE(6,nml=cmd) WRITE(*,'(80(''=''))') elseif(string(2).eq.'/')then exit else READ(string,NML=cmd,IOSTAT=ios,iomsg=message) if(ios.ne.0)then write(*,*)'e-r-r-o-r:',ios write(*,*)' :',message write(*,*)'? to display ; / to end' endif endif enddo else write(*,*)' no prompting' endif ! ----------------------------------------------------- WRITE(6,'(80(''=''))') WRITE(6,*)'resulting namelist group values' !WRITE(*,nml=cmd,delim='apostrophe') WRITE(6,nml=cmd) WRITE(6,'(80(''=''))') ! ----------------------------------------------------- END PROGRAM cmdline !=============================================================================== subroutine get_command_arguments(string,istring_len,istatus) ! @(#)get_command_arguments: return all command arguments as a string character(len=*),intent(out) :: string ! string of all arguments integer,intent(out) :: istring_len ! last character position set integer,intent(out) :: istatus ! status (non-zero means error) integer :: ilength ! length of individual arguments integer :: i ! loop count integer :: icount ! count of number of arguments available character(len=255) :: value ! store individual arguments one at a time string="" ! initialize returned output string istring_len=0 ! initialize returned output string length istatus=0 ! initialize returned error code icount=command_argument_count() ! intrinsic gets number of arguments if(icount>0)then ! if there are arguments load them into string ! start with first argument call get_command_argument(1,string,istring_len,istatus) if(istatus == 0)then do i=2,icount ! append any additional arguments to first call get_command_argument(i,value,ilength,istatus) if(istatus /= 0)then exit ! stop on error endif string=string(:istring_len)//" "//value(:ilength) istring_len=istring_len+ilength+1 enddo endif ! keep track of length and so do not need to use len_trim istring_len=len_trim(string) endif return end subroutine get_command_arguments !===============================================================================