diff --git a/flang/runtime/io-stmt.h b/flang/runtime/io-stmt.h --- a/flang/runtime/io-stmt.h +++ b/flang/runtime/io-stmt.h @@ -322,7 +322,6 @@ using ExternalIoStatementState::ExternalIoStatementState; bool Receive(char *, std::size_t, std::size_t elementBytes = 0); bool Emit(const char *, std::size_t, std::size_t elementBytes = 0); - int EndIoStatement(); }; class OpenStatementState : public ExternalIoStatementBase { diff --git a/flang/runtime/io-stmt.cpp b/flang/runtime/io-stmt.cpp --- a/flang/runtime/io-stmt.cpp +++ b/flang/runtime/io-stmt.cpp @@ -698,32 +698,6 @@ return ExternalIoStatementState::Emit(data, bytes, elementBytes); } -template -int UnformattedIoStatementState::EndIoStatement() { - ExternalFileUnit &unit{this->unit()}; - if constexpr (DIR == Direction::Output) { - if (unit.access == Access::Sequential && !unit.isFixedRecordLength) { - // Append the length of a sequential unformatted variable-length record - // as its footer, then overwrite the reserved first four bytes of the - // record with its length as its header. These four bytes were skipped - // over in BeginUnformattedOutput(). - // TODO: Break very large records up into subrecords with negative - // headers &/or footers - union { - std::uint32_t u; - char c[sizeof u]; - } u; - u.u = unit.furthestPositionInRecord - sizeof u; - // TODO: Convert record length to little-endian on big-endian host? - if (!(this->Emit(u.c, sizeof u) && - (this->HandleAbsolutePosition(0), this->Emit(u.c, sizeof u)))) { - return false; - } - } - } - return ExternalIoStatementState::EndIoStatement(); -} - template class InternalIoStatementState; template class InternalIoStatementState; template class InternalFormattedIoStatementState; diff --git a/flang/runtime/unit.cpp b/flang/runtime/unit.cpp --- a/flang/runtime/unit.cpp +++ b/flang/runtime/unit.cpp @@ -406,15 +406,32 @@ FinishReadingRecord(handler); BeginReadingRecord(handler); } else { // Direction::Output - if (!isUnformatted) { - if (isFixedRecordLength && recordLength) { - if (furthestPositionInRecord < *recordLength) { - WriteFrame(frameOffsetInFile_, *recordLength, handler); - std::memset(Frame() + recordOffsetInFrame_ + furthestPositionInRecord, - ' ', *recordLength - furthestPositionInRecord); - } + if (isFixedRecordLength && recordLength) { + // Pad remainder of fixed length record + if (furthestPositionInRecord < *recordLength) { + WriteFrame( + frameOffsetInFile_, recordOffsetInFrame_ + *recordLength, handler); + std::memset(Frame() + recordOffsetInFrame_ + furthestPositionInRecord, + isUnformatted ? 0 : ' ', *recordLength - furthestPositionInRecord); + } + } else { + positionInRecord = furthestPositionInRecord; + if (isUnformatted) { + // Append the length of a sequential unformatted variable-length record + // as its footer, then overwrite the reserved first four bytes of the + // record with its length as its header. These four bytes were skipped + // over in BeginUnformattedIO(). + // TODO: Break very large records up into subrecords with negative + // headers &/or footers + std::uint32_t length; + length = furthestPositionInRecord - sizeof length; + ok &= Emit(reinterpret_cast(&length), sizeof length, + sizeof length, handler); + positionInRecord = 0; + ok &= Emit(reinterpret_cast(&length), sizeof length, + sizeof length, handler); } else { - positionInRecord = furthestPositionInRecord; + // Terminate formatted variable length record ok &= Emit("\n", 1, 1, handler); // TODO: Windows CR+LF } }