[flang] Honor RECL= in list-directed/namelist output

Advancement to new output lines was taking fixed-sized direct-access
and internal character array element lengths into account, but not
RECL= settings from OPEN statements.

Differential Revision: https://reviews.llvm.org/D120837
This commit is contained in:
Peter Klausler 2022-02-17 15:32:06 -08:00
parent 6cb42cd666
commit 3a96446d51
3 changed files with 8 additions and 6 deletions

View file

@ -14,8 +14,8 @@
namespace Fortran::runtime::io {
std::size_t ConnectionState::RemainingSpaceInRecord() const {
auto recl{recordLength.value_or(
executionEnvironment.listDirectedOutputLineLengthLimit)};
auto recl{recordLength.value_or(openRecl.value_or(
executionEnvironment.listDirectedOutputLineLengthLimit))};
return positionInRecord >= recl ? 0 : recl - positionInRecord;
}

View file

@ -477,13 +477,13 @@ bool ListDirectedDefaultCharacterOutput(IoStatementState &io,
ok = ok && list.EmitLeadingSpaceOrAdvance(io);
// Value is delimited with ' or " marks, and interior
// instances of that character are doubled.
ok = ok && io.Emit(&modes.delim, 1);
auto EmitOne{[&](char ch) {
if (connection.NeedAdvance(1)) {
ok = ok && io.AdvanceRecord();
}
ok = ok && io.Emit(&ch, 1);
}};
EmitOne(modes.delim);
for (std::size_t j{0}; j < length; ++j) {
// Doubled delimiters must be put on the same record
// in order to be acceptable as list-directed or NAMELIST
@ -502,9 +502,7 @@ bool ListDirectedDefaultCharacterOutput(IoStatementState &io,
EmitOne(modes.delim);
} else {
// Undelimited list-directed output
ok = ok &&
list.EmitLeadingSpaceOrAdvance(
io, length > 0 && !list.lastWasUndelimitedCharacter());
ok = ok && list.EmitLeadingSpaceOrAdvance(io, length > 0 ? 1 : 0, true);
std::size_t put{0};
while (ok && put < length) {
auto chunk{std::min(length - put, connection.RemainingSpaceInRecord())};

View file

@ -54,9 +54,13 @@ bool IONAME(OutputNamelist)(Cookie cookie, const NamelistGroup &group) {
if (!(EmitWithAdvance('&') && EmitUpperCase(group.groupName))) {
return false;
}
auto *listOutput{io.get_if<ListDirectedStatementState<Direction::Output>>()};
for (std::size_t j{0}; j < group.items; ++j) {
// [,]ITEM=...
const NamelistGroup::Item &item{group.item[j]};
if (listOutput) {
listOutput->set_lastWasUndelimitedCharacter(false);
}
if (!(EmitWithAdvance(j == 0 ? ' ' : comma) && EmitUpperCase(item.name) &&
EmitWithAdvance('=') &&
descr::DescriptorIO<Direction::Output>(io, item.descriptor))) {