-
Notifications
You must be signed in to change notification settings - Fork 1
/
demo5.f90
executable file
·137 lines (131 loc) · 5.16 KB
/
demo5.f90
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
program demo5
!! FULL EXAMPLE ADDING HELP AND VERSION DISPLAY AND INTERACTIVE EXAMPLE
use M_CLI, only : commandline, check_commandline, unnamed
implicit none
integer :: i
character(len=:),allocatable :: status
character(len=255) :: message ! use for I/O error messages
character(len=:),allocatable :: readme ! stores updated namelist
character(len=:),allocatable :: help_text(:), version_text(:)
integer :: ios
real :: x, y, z ; namelist /args/ x, y, z
real :: point(3) ; namelist /args/ point
character(len=80) :: title ; namelist /args/ title
logical :: l, l_ ; namelist /args/ l, l_
character(len=*),parameter :: cmd=&
' -x 1 -y 2 -z 3 --point -1,-2,-3 --title "my title" -l F -L F '
call set() !! set text values for help
readme=commandline(cmd)
read(readme,nml=args,iostat=ios,iomsg=message)
call check_commandline(ios,message,help_text,version_text)
do
call readargs(status) ! interactively change NAMELIST group
if(status.eq.'stop')exit
call dosomething() ! use the NAMELIST values
enddo
!! ALL DONE CRACKING THE COMMAND LINE USE THE VALUES IN YOUR PROGRAM.
!! THE OPTIONAL UNNAMED VALUES ON THE COMMAND LINE ARE
!! ACCUMULATED IN THE CHARACTER ARRAY "UNNAMED"
if(size(unnamed).gt.0)then
write(*,'(a)')'files:'
write(*,'(i6.6,3a)')(i,'[',unnamed(i),']',i=1,size(unnamed))
endif
contains
subroutine set()
help_text=[character(len=80) :: &
'NAME ', &
' myprocedure(1) - make all things possible ', &
'SYNOPSIS ', &
' function myprocedure(stuff) ', &
' class(*) :: stuff ', &
'DESCRIPTION ', &
' myprocedure(1) makes all things possible given STUFF ', &
'OPTIONS ', &
' STUFF things to do things to ', &
'RETURNS ', &
' MYPROCEDURE the answers you want ', &
'EXAMPLE ', &
'' ]
version_text=[character(len=80) :: &
'@(#)PROGRAM: demo5 >', &
'@(#)DESCRIPTION: My demo program >', &
'@(#)VERSION: 1.0 20200115 >', &
'@(#)AUTHOR: me, myself, and I>', &
'@(#)LICENSE: Public Domain >', &
'' ]
end subroutine set
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)',iostat=ios)line
if(is_iostat_end(ios))stop 1
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,delim='quote')['A','H']
!!write(*,nml=*NML,delim='quote')args['A','H']
case('help')
write(*,'(a)')[character(len=80) :: &
' You are in interactive mode where you can display and change your values using', &
' NAMELIST syntax:', &
' KEYWORD=VALUE(S) -- change a variable value', &
' show -- show current values', &
' stop -- stop program', &
' . -- return to program and run', &
' write FILENAME -- write NAMELIST group to specified file',&
' read FILENAME -- read NAMELIST input file', &
' sh -- start shell process', &
'', &
'' ]
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 demo5