-
Notifications
You must be signed in to change notification settings - Fork 1
TO DO list
urbanjost edited this page Jan 18, 2020
·
1 revision
If enough interest:
-
DESCRIBE_COMMANDLINE('name','string') would be trivial to add so that --usage has optional descriptions
-
other command-line syntax (like DOS uses, perhaps?)
-
as long as the prototype has () in the values, allow them to be implied on input for complex values
-
allow subscript on keywords, like "--point(2:3) 100,200". Using NAMELIST, which already supports that type of syntax
-
interactive prompting mode, maybe screen-based using ncurses. Simplest one user could add would be something like
!# Using a NAMELIST group to create an interactive prompt for variables by name
!
!NAMELIST input has some underutilized uses. Unlike similar file formats
!it is built into the standard, allows multiple sets in a single file
!which it searches sequentially for by name, and ignores lines in the
!file not in a NAMELIST group format. One perhaps unexpected use is
!to let you simulate exposing variables in the program for the user to
!change interactively.
!
!Taking advantage of NAMELIST reads not requiring all values to be specified,
!it takes very little code to make an interactive prompt for values of the form
!
! NAME=VALUE(S)
!
!For example, the following relatively short program shows placing a number of
!variables into a NAMELIST and then letting you interactively change them with
!a session looking something like:
!
! args>>show
! args>>f='courier' t='new title'
! args>>view=1,2,3
! args>>a=456.789
! args>>! run with new values
! args>> .
! args>>h=t
! args>>! run again
! args>> .
! args>>stop
!
!~~~~~~~~~~ {: lang=fortran}
program namelist_prompter
implicit none
! create a NAMELIST group with lots of options
! this is just a sample
real :: a=0.0
real :: view(3)=[0.0,0.0,0.0]
character(len=80) :: t='title'
character(len=80) :: f='roman'
logical :: h=.false.
namelist /args/ a,view,t,h,f
character(len=:),allocatable :: status
do
call readargs(status) ! interactively change NAMELIST group
if(status.eq.'stop')exit
call dosomething() ! use the NAMELIST values
enddo
contains
subroutine readargs(status)
character(len=:),intent(out),allocatable :: status
character(len=256) :: line
character(len=256) :: answer
integer :: lun
integer :: ios
status=''
write(*,'(a)')'args>> "." to run, "stop" to end, "show" to show keywords, "read","write","sh"'
do
write(*,'(a)',advance='no')'args>>'
read(*,'(a)')line
if(line(1:1).eq.'!')cycle
select case(line)
case('.')
exit
case('show')
write(*,*)'SO FAR'
write(*,nml=args)
!! something where you could restrict nml output to just listed names would be nice
!!write(*,nml=args)['A','H']
!!write(*,nml=*NML)args['A','H']
case('stop')
status='stop'
exit
case('sh')
call execute_command_line('bash')
case('read')
write(*,'(a)',advance='no')'filename:'
read(*,'(a)',iostat=ios)answer
if(ios.ne.0)exit
open(file=answer,iostat=ios,newunit=lun)
if(ios.ne.0)exit
read(lun,args,iostat=ios)
close(unit=lun,iostat=ios)
case('write')
write(*,'(a)',advance='no')'filename:'
read(*,'(a)',iostat=ios)answer
if(ios.ne.0)exit
open(file=answer,iostat=ios,newunit=lun)
if(ios.ne.0)exit
write(lun,args,iostat=ios)
close(unit=lun,iostat=ios)
case default
UPDATE: block
character(len=:),allocatable :: intmp
character(len=256) :: message
integer :: ios
intmp='&ARGS '//trim(line)//'/'
read(intmp,nml=args,iostat=ios,iomsg=message)
if(ios.ne.0)then
write(*,*)'ERROR:',trim(message)
endif
endblock UPDATE
end select
enddo
end subroutine readargs
subroutine dosomething()
! placeholder
write(*,*)'USE ALL THOSE VALUES'
end subroutine dosomething
end program namelist_prompter