RECL= is required for direct access I/O, but is permitted
as well for sequential I/O, where it is defined by the
standard to specify a maximum record (line) length.
The standard does not say what should happen when an
sequential formatted input record appears whose length is
unequal to RECL= when it is specified.
Precedents from other compilers are unclear: one raises an error,
some honor RECL= as an effective truncation, and a few ignore the
situation. On output, all other compilers tested raised an
error when an attempt is made to emit a record longer than RECL=.
This patch treats RECL= as effective truncation on input and
as a hard limit with error on output, and also ensures that
RECL= can be set *longer* than the actual input record lengths.
Differential Revision: https://reviews.llvm.org/D115102
INQUIRE(POSITION=)'s results need to reflect the POSITION=
specifier used for the OPEN statement until the unit has been
repositioned. Preserve the POSITION= from OPEN and used it
for INQUIRE(POSITION=) until is becomes obsolete.
INQUIRE(PAD=) is implemented here in the case of an unconnected unit
with Fortran 2018 semantics; i.e., "UNDEFINED", rather than Fortran 90's
"YES"/"NO" (see 4.3.6 para 2). Apparent failures with F'90-only tests
will persist with INQUIRE(PAD=); these discrepancies don't seem to warrant
an option or environment variable.
To make the implementation of INQUIRE more closely match the language
in the standard, rename IsOpen() to IsConnected(), and use it explicitly
for the various INQUIRE specifiers.
Differential Revision: https://reviews.llvm.org/D114755
The predefined units were not being initialized with FORM='FORMATTED',
so INQUIRE(PAD=) was failing if no I/O had already been done.
INQUIRE(POSITION=) was returning 'REWIND' on stdin/stdout (which
is somewhat defensible from the definition, and is what Intel Fortran
does), but most implementations return 'ASIS'. Change the runtime
to return 'REWIND' only for positionable external files, but 'ASIS'
for terminals, sockets, &c.
Differential Revision: https://reviews.llvm.org/D114028
The inquire by output list form of the INQUIRE statement calculates the
number of file storage units that would be required to store the data
of an output list in an unformatted file. Currently, the result is
incorrectly multiplied by the number of bytes for a data type. A query
for "INTEGER(KIND=4) A(10)" should be 40, not 160.
Update formatting.
1. To avoid overwriting the part of the record read in the non advancing read,
the furtherPositionInRecord field must be set to the max of the
furtherPositionInRecord and the positionInRecord at the beginning of the
IO write.
2. To allow any further read to succeed after the write, the unit
beganReadingRecord_ must be set to false when resetting the recordLength
during the write, otherwise, recordLength will not be computed in further
read and an assert is hit (at unit.cpp(398)).
The added unit test exercises both of these scenarios.
Differential Revision: https://reviews.llvm.org/D113740
Profiling a basic internal real input read benchmark shows some
hot spots in the code used to prepare input for decimal-to-binary
conversion, which is of course where the time should be spent.
The library that implements decimal to/from binary conversions has
been optimized, but not the code in the Fortran runtime that calls it,
and there are some obvious light changes worth making here.
Move some member functions from *.cpp files into the class definitions
of Descriptor and IoStatementState to enable inlining and specialization.
Make GetNextInputBytes() the new basic input API within the
runtime, replacing GetCurrentChar() -- which is rewritten in terms of
GetNextInputBytes -- so that input routines can have the
ability to acquire more than one input character at a time
and amortize overhead.
These changes speed up the time to read 1M random reals
using internal I/O from a character array from 1.29s to 0.54s
on my machine, which on par with Intel Fortran and much faster than
GNU Fortran.
Differential Revision: https://reviews.llvm.org/D113697
When processing the devious NAMELIST input
&group logarray = t t t
= 666 /
for LOGICAL::logarray(3) and INTEGER::t, the runtime library
needs to do some look-ahead on the input stream to make sure
that the last "t" on the first line is a truth value rather than
an item name -- which in this case it is. This look-ahead
was implemented in a previous patch but only worked for internal
input cases; this patch implements look-ahead capabilities for
input from an external file, too (and also adjusts repeated
list-directed input items to use this infrastructure, too).
Differential Revision: https://reviews.llvm.org/D113311
ExternalFileUnit::BeginReadingRecord() must be called at least once
during an external formatted READ statement before FinishReadingRecord().
In the case of a formatted external READ with no data items, the call
to finish processing of the format (which might have lingering control
items that need doing) was taking place before the call to BeginReadingRecord
from ExternalIoStatementState::EndIoStatement. Add a call to
BeginReadingRecord on this path.
Differential Revision: https://reviews.llvm.org/D112351
Count input characters corresponding to formatted edit descriptors
for READ(SIZE=); count output bytes for INQUIRE(IOLENGTH=).
The I/O APIs GetSize() and GetLength() were adjusted to return
std::size_t as function results.
Basic unit tests were added (and others fixed).
Differential Revision: https://reviews.llvm.org/D110291
When an end of record is met in non advancing IO:
- Set IOSTAT if present according to 12.11.4 (5).
- Position the file to the next record (12.11.4 (4)).
The previous code was only signaling EOR for fixed record length IO.
Reading at 12.11.4, I do not find the rational for this condition, so I
removed it.
It also does not seem the presence of padding should prevent
the EOR signaling.
The positionning to the next record was block when EOR is signaling
in FinishReadingRecord because ErrorHandler.isError() is true in this
case.
EOR in input is not an error, but I am not confident to modify
ErrorHandler.isError() to cover that. However, In FinishReadingRecord,
the code should not bail if the error is simply an end of record.
I did not check the SIZE requirements here because GetSize runtime is
not yet implemented.
Differential Revision: https://reviews.llvm.org/D109505
Move the closure of the subset of flang/runtime/*.h header files that
are referenced by source files outside flang/runtime (apart from unit tests)
into a new directory (flang/include/flang/Runtime) so that relative
include paths into ../runtime need not be used.
flang/runtime/pgmath.h.inc is moved to flang/include/flang/Evaluate;
it's not used by the runtime.
Differential Revision: https://reviews.llvm.org/D109107
The standard specifies that the form must be set to a default at the
end of an open statement (C.7.4 point 2) where it was not specified.
Only in the case of a pre-connected unit can the form be deferred
until the first data transfer statement.
Set back the default form setting in OpenStatementState::EndIoStatement
that had been removed when deferring the pre-connected unit from setting
in 199a623ebf.
Also return "UNDEFINED" instead of "UNKNOWN" to the FORM inquiry when the
form was not yet specified as defined in 12.10.2.12.
Related test: syntax 215a216.
Differential Revision: https://reviews.llvm.org/D108990
A recent runtime I/O change[1] was meant to improve the handling of
input from external files missing a terminal newline on their last
records; the change was "triggered" by the wrong circumstances and
causing reads that should have pulled more data into the buffer to be
treated as EOFs. So fix that, and also don't retain input data
in the buffer once an input record has been finished unless it's
known that list-directed or NAMELIST input of a repeated input item
may need to backspace a non-positionable external unit to return
to the beginning of the repeated item.
[1] 6578893a0453384346f149479f8574dfff977ace
Differential Revision: https://reviews.llvm.org/D108164
A repeated null value at the end of an input record with a count > 1
would incorrectly advance to the next record when resumed. Fix.
Improve some poor naming and code flow noticed while debugging, so
next time will be easier.
Extend a unit test to check this case.
Differential Revision: https://reviews.llvm.org/D107917
Non-advancing I/O was failing; ExternalFileUnit was losing
track of what writes had been committed to the file. Fixed.
Also, support the common extension of $ and \ in a FORMAT
as being equivalent to ADVANCE=NO.
Differential Revision: https://reviews.llvm.org/D105046
With derived type description tables now available to the
runtime library, it is possible to implement the concept
of "child" I/O statements in the runtime and use them to
convert instances of derived type I/O data transfers into
calls to user-defined subroutines when they have been specified
for a type. (See Fortran 2018, subclauses 12.6.4.8 & 13.7.6).
- Support formatted, list-directed, and NAMELIST
transfers to internal parent units; support these, and unformatted
transfers, for external parent units.
- Support nested child defined derived type I/O.
- Parse DT'foo'(v-list) FORMAT data edit descriptors and passes
their strings &/or v-list values as arguments to the defined
formatted I/O routines.
- Fix problems with this feature encountered in semantics and
FORMAT valiation during development and end-to-end testing.
- Convert typeInfo::SpecialBinding from a struct to a class
after adding a member function.
Differential Revision: https://reviews.llvm.org/D104930
Add InputNamelist and OutputNamelist as I/O data transfer APIs
to be used with internal & external list-directed I/O; delete the
needless original namelist-specific Begin... calls.
Implement NAMELIST output and input; add basic tests.
Differential Revision: https://reviews.llvm.org/D101931
What the Fortran standard calls "preconnected" external I/O units
might not be known to be connected to unformatted or formatted files
until the first I/O data transfer statement is executed.
Support this deferred determination by representing the flag as
a tri-state Boolean and adapting its points of use.
Differential Revision: https://reviews.llvm.org/D101929
Debug the input path for READ statements with END= labels;
don't emit errors when the program can handle them.
BeginReadingRecord() member functions have been made
"bool" for more convenient handling of error cases,
and some code in IoErrorHandler has been cleaned up.
Differential Revision: https://reviews.llvm.org/D100421
An OPEN statement that affects an already connected unit
without changing its external file is required to have
STATUS="OLD" or default STATUS=. The code was eliciting
spurious runtime errors in situations where an OPEN statement
pertained to an existing unit number but did not need to have
STATUS="OLD'.
Differential Revision: https://reviews.llvm.org/D100352
It turns out that unformatted fixed-size output records
do need to be padded out if short, in order to avoid a
spurious EOF crash on a short record at the end of the file.
While here in AdvanceRecord(), move the unformatted
variable-length record header/footer writing code to here
from EndIoStatement().
Differential revision: https://reviews.llvm.org/D88685
Don't give false positives from INQUIRE about possible
access mode changes on connected units. DIRECT and SEQUENTIAL
cannot be intermixed, apart from allowing DIRECT on a SEQUENTIAL
file with fixed-size records and positioning. Nor can
FORMATTED and UNFORMATTED be interchanged. On unconnected
files, the best that we can do is "UNKNOWN".
Differential revision: https://reviews.llvm.org/D88673
The '/' control edit descriptor causes a runtime crash for an
external formatted sequential READ because the AdvanceRecord()
member function for external units implemented only the tasks
to finish reading the current record. Split those out into
a new FinishReadingRecord() member function, call that instead
from EndIoStatement(), and change AdvanceRecord() to both
finish reading the current record and to begin reading the next
one.
Differential revision: https://reviews.llvm.org/D88607
External input was detecting "end of file" conditions in
BeginExternal...Input() and BeginUnformattedInput() routines
before EnableHandlers() could have been called. Defer the
"start next record" processing to the input data item
handlers (and EndIoStatement() for when there are no data
items).
Differential Revision: https://reviews.llvm.org/D85161
It turns out that COMPLEX formatted input needs its own runtime APIs
so that null values in list-directed input skip the entire COMPLEX
datum rather than just a real or imaginary part thereof.
Reviewed By: sscalpone
Differential Revision: https://reviews.llvm.org/D84370
Add SetConvert() to the OPEN statement's runtime API.
Add ByteswapOption() to the main program's runtime API.
Check a $FORT_CONVERT environment variable, too, for
a swapping specifier.
Reviewed By: sscalpone
Differential Revision: https://reviews.llvm.org/D84284
The runtime was requiring that STATUS='OLD' be explicitly specified
on an OPEN statement for a connected unit. There error should issue
only if a STATUS= other than 'OLD' is specified; an OPEN with no
STATUS= specifier is okay.
Reviewed By: sscalpone
Differential Revision: https://reviews.llvm.org/D84079
Anonymous Fortran unit files (e.g., "./fort.7") need to be created
O_RDWR so that they can be written, rewound, and read. Other
files opened with no ACTION= specifier need to set read/write
permissions based on the file, if it exists.
Reviewed By: sscalpone
Differential Revision: https://reviews.llvm.org/D84063
Allow repeated nulls in list-directed input (e.g., "4*,") and
ignore excess characters in list-directed LOGICAL input after the
T or F.
Fixes FCVS test fm923.f.
Reviewed By: sscalpone
Differential Revision: https://reviews.llvm.org/D83810
The per-I/O-statement state structures need to support missing
external I/O statements, and some bugs found in testing with
formatted input and record advancement are fixed. The effects
of these changes will not be visible until further patches to
the I/O API handlers are pushed.
Reviewed By: tskeith
Differential Revision: https://reviews.llvm.org/D83151
Scan FORMAT strings locally to avoid C++ binary runtime dependence when computing deepest parenthesis nesting
Remove a dependency on ostream from runtime
Remove remaining direct external references from runtime to C++ library binaries
Remove runtime dependences on lib/common
SetPos() and SetRec()
Instantiate templates for input
Begin input; rearrange locking, deal with CLOSE races
View()
Update error message in test to agree with compiler change
First cut at real input
More robust I/O runtime error handling
Debugging of REAL input
Add iostat.{h,cpp}
Rename runtime/numeric-* to runtime/edit-*
Move templates around, templatize integer output editing
Move LOGICAL and CHARACTER output from io-api.cpp to edit-output.cpp
Change pointer argument to reference
More list-directed input
Complex list-directed input
Use enum class Direction rather than bool for templates
Catch up with changes to master
Undo reformatting of Lower code
Use record number instead of subscripts for internal unit
Unformatted sequential backspace
Testing and debugging
Dodge bogus GCC warning
Add <cstddef> for std::size_t to fix CI build
Address review comments
Original-commit: flang-compiler/f18@50406b3496
Reviewed-on: https://github.com/flang-compiler/f18/pull/1053
Use internal units for internal I/O state
Replace use of virtual functions
reference_wrapper
Internal formatted output to array descriptor
Delete dead code
Begin list-directed internal output
Refactorings and renamings for clarity
List-directed external I/O (character)
COMPLEX list-directed output
Control list items
First cut at unformatted I/O
More OPEN statement work; rename class to ExternalFileUnit
Complete OPEN (exc. for POSITION=), add CLOSE()
OPEN(POSITION=)
Flush buffers on crash and for terminal output; clean up
Documentation
Fix backquote in documentation
Fix typo in comment
Begin implementation of input
Refactor binary floating-point properties to a new header, simplify numeric output editing
Dodge spurious GCC 7.2 build warning
Address review comments
Original-commit: flang-compiler/f18@9c4bba11cf
Reviewed-on: https://github.com/flang-compiler/f18/pull/982
Address review comments
Integer output data editing (I,B,O,Z)
Full integer output formatting
Stub out some work in progress
Progress on E output data editing
E, D, EN, and ES output editing done
Fw.d output editing
Real G output editing
G output editing for reals
Make environment a distinct module
CHARACTER and LOGICAL output editing
Minimal decimal representations for E0, F0, G0 editing
Move real output editing code into its own file
Fix/dodge some GCC build problems
Prep work for external I/O statement state
External HELLO, WORLD
Fix build problem with GCC
Add virtual destructors where needed
Add new test
Original-commit: flang-compiler/f18@c3f1774f8e
Reviewed-on: https://github.com/flang-compiler/f18/pull/950
Updated CMake files accordingly, using better regex
Updated license headers to match new extension and fit within 80 columns
Updated other comments within files that referred to the old extension
Original-commit: flang-compiler/f18@ae7721e611
Reviewed-on: https://github.com/flang-compiler/f18/pull/958