From b43e083bb6b145905cac576b728f238a692a0048 Mon Sep 17 00:00:00 2001 From: peter klausler Date: Tue, 20 Jul 2021 11:39:21 -0700 Subject: [PATCH] [flang] Don't require newline at EOF in unformatted sequential runtime input F18 was sigalling an end-of-file error condition when reading an unformatted sequential input file without an ultimate newline (or CR-LF). Other Fortran implementations can handle it, so change the runtime to support it. Differential Revision: https://reviews.llvm.org/D106321 --- flang/runtime/file.cpp | 1 - flang/runtime/unit.cpp | 21 +++++++++++++-------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/flang/runtime/file.cpp b/flang/runtime/file.cpp index 73b7a24..35d305d 100644 --- a/flang/runtime/file.cpp +++ b/flang/runtime/file.cpp @@ -199,7 +199,6 @@ std::size_t OpenFile::Read(FileOffset at, char *buffer, std::size_t minBytes, while (got < minBytes) { auto chunk{::read(fd_, buffer + got, maxBytes - got)}; if (chunk == 0) { - handler.SignalEnd(); break; } else if (chunk < 0) { auto err{errno}; diff --git a/flang/runtime/unit.cpp b/flang/runtime/unit.cpp index e1ff6e7..8e870c0 100644 --- a/flang/runtime/unit.cpp +++ b/flang/runtime/unit.cpp @@ -341,19 +341,22 @@ const char *ExternalFileUnit::FrameNextInput( bool ExternalFileUnit::SetSequentialVariableFormattedRecordLength() { if (recordLength || access != Access::Sequential) { return true; - } - if (FrameLength() > recordOffsetInFrame_) { + } else if (FrameLength() > recordOffsetInFrame_) { const char *record{Frame() + recordOffsetInFrame_}; - if (const char *nl{reinterpret_cast( - std::memchr(record, '\n', FrameLength() - recordOffsetInFrame_))}) { + std::size_t bytes{FrameLength() - recordOffsetInFrame_}; + if (const char *nl{ + reinterpret_cast(std::memchr(record, '\n', bytes))}) { recordLength = nl - record; if (*recordLength > 0 && record[*recordLength - 1] == '\r') { --*recordLength; } - return true; + } else { + recordLength = bytes; // final record w/o \n } + return true; + } else { + return false; } - return false; } void ExternalFileUnit::SetLeftTabLimit() { @@ -413,8 +416,10 @@ void ExternalFileUnit::FinishReadingRecord(IoErrorHandler &handler) { if (Frame()[recordOffsetInFrame_ + *recordLength] == '\r') { ++recordOffsetInFrame_; } - recordOffsetInFrame_ += *recordLength + 1; - RUNTIME_CHECK(handler, Frame()[recordOffsetInFrame_ - 1] == '\n'); + if (Frame()[recordOffsetInFrame_ + *recordLength] == '\n') { + ++recordOffsetInFrame_; + } + recordOffsetInFrame_ += *recordLength; recordLength.reset(); } } -- 2.7.4