问题
I want to wrap the fortran write-statement in a custom subroutine or function which includes some additional debug-logic.
But I'm currently stuck with defining the prototype of the function/subroutine. Is this possible? If yes, how?
回答1:
The title of your question exhibits a misunderstanding, though the text suggests you know better. Nevertheless, for the record, write
is a Fortran statement, it is neither a subroutine nor a function.
I think you have a number of options. One, which I have used occasionally, would be to write a function which returns a string. Perhaps
function error_message(error)
character(len=*), intent(in) :: error
character(len=:), allocatable :: error_message
error_message = 'ERROR: '//trim(error)
end function error_message
which you can then use like this
write(*,*) error_message('Oh s**t')
You could certainly write a subroutine or a function with side effects which include writing to an ouput channel, but if you adopt this approach you have to be careful to observe the rules for recursive i/o.
EDIT
after OP's comment.
If you want to switch off debug messages another option you have is to direct them to a null device or file, eg /dev/null
on Linux or NUL
on Windows. Something like
integer, parameter :: debug_channel = 99
logical, parameter :: debugging = .false.
...
if (debugging) then
open(debug_channel, file='NUL')
else
open(debug_channel, file='debuglog'
end if
and then
write(debug_channel,*) 'message'
回答2:
a relatively simple way to accomplish most of what you want is to simply put the if
inline in front of every write that is subject to debug control:
if(debug)write(..,..)..
where debug is a global logical value, or even:
if(debugf(level))write(..,..)..
where the logical function debugf determines whether to write based on some argument.
回答3:
In addition to the other answers, you may be able to avoid using if (debug) write...
with derived type IO.
I say "may", as it is quite silly unless you already have a suitable structure, and compiler support is currently rare.
However, as an example, compiled with ifort 14.0.1:
module errormod
type error_t
character(len=:), allocatable :: message
contains
procedure write_error
generic :: write(formatted) => write_error
end type error_t
logical debug_verbose
contains
subroutine write_error(err, unit, iotype, v_list, iostat, iomsg)
class(error_t), intent(in) :: err
integer, intent(in) :: unit
character(len=*), intent(in) :: iotype
integer, intent(in), dimension(:) :: v_list
integer, intent(out) :: iostat
character(len=*), intent(inout) :: iomsg
if (debug_verbose) then
write(unit, '("Error: ", A)', iostat=iostat, iomsg=iomsg) err%message
else
write(unit, '()', advance='no')
end if
end subroutine write_error
end module errormod
program test
use errormod
implicit none
type(error_t) error
debug_verbose = .TRUE.
error%message = "This error will be reported."
write(*, '(dt)') error
debug_verbose = .FALSE.
error%message = "This error will not be reported."
write(*, '(dt)') error
debug_verbose = .TRUE.
error%message = "This final error will also be reported."
write(*, '(dt)') error
end program test
The first and third messages will appear, but not the second.
来源:https://stackoverflow.com/questions/19906446/how-to-wrap-the-fortran-write-statement