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