Lately I’m writing and reading from a file many arrays.
The easier way to check that the reading or the writing have been correct is to use the old go to label err inside each input or output statement like in:
open(newunit=lun, file='filename', ..., err=1)
...
write(lun, ..., err=1) a, b, c
write(lun, ..., err=1) aa, bb, cc
write(lun, ..., err=1) ...
...
close(lun)
return
1 continue
close(lun, status='delete') ! perhaps I don't want an half file
print *, 'Error'
Now, one can, instead of using a label, check an iostat variable every statement like in:
open(newunit=lun, file='filename', ...)
writing: block
...
write(lun, ..., iostat=ios) a, b, c
if (ios/=0) exit writing
write(lun, ..., iostat=ios) aa, bb, cc
if (ios/=0) exit writing
write(lun, ..., iostat=ios) ...
if (ios/=0) exit writing
...
close(lun)
return
end block writing
close(lun, status='delete') ! perhaps I don't want an half file
print *, 'Error'
But that definitely double the number of required statements.
What would be nice will be to retain the small number of output lines while not using a label for error detection.
The proposal is this one:
There is an almost opaque type in iso_fortran_env
called: io_error_type
(or whatever name could be used).
the open
statement accept an optional intent(out) io_error
variable of type io_error_type
.
The io_error
variable can be in two state: error
, or ok
. This state can checked with an appropriate function. The io_error_type
contains also the information that are stored into iostat
variable and the iomsg
variable that can be read with appropriate functions (so you don’t need to pass also this two other variables).
The presence of the io_error
variable will make the open behave like when err
variable or iostat
variable is present. Basically the variable is set with the appropriate error condition or with the no error condition.
But that is almost syntactic sugar, what it will be different is what happen when the variable is passed to the write
or read
statement.
The read
and write
statements will accept an optional
, intent(inout)
io_error
variable. If the variable is in the ok condition it can be set to an error condition if an error happen during the io
activity, while if contains an error condition there is no io activity and the variable is left unchanged, basically passing along the chain the error. Basically the previous program will be:
use iso_fortran_env, only: io_error_type
type(io_error_type) :: ioe
open(newunit=lun, file='filename', io_error=ioe)
...
write(lun, ..., io_error=ioe) a, b, c
write(lun, ..., io_error=ioe) aa, bb, cc
write(lun, ..., io_error=ioe) ...
...
if (.not. is_in_error(ioe)) then
close(lun)
else
close(lun, status='delete') ! perhaps I don't want an half file
print *, 'Error'
endif
One may also add an option to close
like:
close(lun, io_error=ioe, staus='delete_if_error')
Which may be useful when writing a file (not when reading of course). So the last part may be:
write(lun, ..., io_error=ioe)
...
close(lun, io_error=ioe, status='delete_if_error')
if (is_in_error(ioe)) print *,'Error', get_error_message(ioe)
Now if one add the possibility to set this io_error
variable in some way it may be used also in other part of a program (but is will be easy with an ad hoc user defined type, while the use in the write
and read
statement should be supported by the compiler) .
I hope you like it, tell me.
Cheers