diff --git a/flang/runtime/connection.h b/flang/runtime/connection.h --- a/flang/runtime/connection.h +++ b/flang/runtime/connection.h @@ -66,9 +66,17 @@ std::optional recordLength; - // Positions in a record file (sequential or direct, not stream) std::int64_t currentRecordNumber{1}; // 1 is first - std::int64_t positionInRecord{0}; // offset in current record + + // positionInRecord is the 0-based offset in the current recurd to/from + // which the next data transfer will occur. It can be past + // furthestPositionInRecord if moved by an X or T or TR control edit + // descriptor. + std::int64_t positionInRecord{0}; + + // furthestPositionInRecord is the 0-based offset of the greatest + // position in the current record to/from which any data transfer has + // occurred, plus one. It can be viewed as a count of bytes processed. std::int64_t furthestPositionInRecord{0}; // max(position+bytes) // Set at end of non-advancing I/O data transfer diff --git a/flang/runtime/edit-input.cpp b/flang/runtime/edit-input.cpp --- a/flang/runtime/edit-input.cpp +++ b/flang/runtime/edit-input.cpp @@ -679,11 +679,10 @@ remaining = *edit.width; } // When the field is wider than the variable, we drop the leading - // characters. When the variable is wider than the field, there's + // characters. When the variable is wider than the field, there can be // trailing padding. const char *input{nullptr}; std::size_t ready{0}; - bool hitEnd{false}; // Skip leading bytes. // These bytes don't count towards INQUIRE(IOLENGTH=). std::size_t skip{remaining > length ? remaining - length : 0}; @@ -692,8 +691,10 @@ if (ready == 0) { ready = io.GetNextInputBytes(input); if (ready == 0) { - hitEnd = true; - break; + if (io.CheckForEndOfRecord()) { + std::fill_n(x, length, ' '); // PAD='YES' + } + return !io.GetIoErrorHandler().InError(); } } std::size_t chunk; @@ -731,9 +732,6 @@ } // Pad the remainder of the input variable, if any. std::fill_n(x, length, ' '); - if (hitEnd) { - io.CheckForEndOfRecord(); // signal any needed error - } return true; } diff --git a/flang/runtime/io-api.cpp b/flang/runtime/io-api.cpp --- a/flang/runtime/io-api.cpp +++ b/flang/runtime/io-api.cpp @@ -1176,7 +1176,7 @@ } bool IONAME(InputAscii)(Cookie cookie, char *x, std::size_t length) { - return IONAME(InputCharacter(cookie, x, length, 1)); + return IONAME(InputCharacter)(cookie, x, length, 1); } bool IONAME(OutputLogical)(Cookie cookie, bool truth) { diff --git a/flang/unittests/Runtime/ExternalIOTest.cpp b/flang/unittests/Runtime/ExternalIOTest.cpp --- a/flang/unittests/Runtime/ExternalIOTest.cpp +++ b/flang/unittests/Runtime/ExternalIOTest.cpp @@ -544,8 +544,9 @@ fmt.data(), fmt.length(), unit, __FILE__, __LINE__); IONAME(EnableHandlers)(io, true, false, false, false, false); ASSERT_TRUE(IONAME(SetAdvance)(io, "NO", 2)) << "SetAdvance(NO)" << j; - ASSERT_TRUE( - IONAME(InputAscii)(io, inputItem.item.data(), inputItem.item.length())) + bool result{ + IONAME(InputAscii)(io, inputItem.item.data(), inputItem.item.length())}; + ASSERT_EQ(result, inputItem.expectedIoStat == IostatOk) << "InputAscii() " << j; ASSERT_EQ(IONAME(EndIoStatement)(io), inputItem.expectedIoStat) << "EndIoStatement() for Read " << j;