//===-- runtime/io-stmt.cpp -----------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "io-stmt.h"
#include "connection.h"
#include "emit-encoded.h"
#include "format.h"
#include "tools.h"
#include "unit.h"
#include "utf.h"
#include "flang/Runtime/memory.h"
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <limits>
#include <type_traits>

namespace Fortran::runtime::io {
RT_OFFLOAD_API_GROUP_BEGIN

bool IoStatementBase::Emit(const char *, std::size_t, std::size_t) {
  return false;
}

std::size_t IoStatementBase::GetNextInputBytes(const char *&p) {
  p = nullptr;
  return 0;
}

bool IoStatementBase::AdvanceRecord(int) { return false; }

void IoStatementBase::BackspaceRecord() {}

bool IoStatementBase::Receive(char *, std::size_t, std::size_t) {
  return false;
}

Fortran::common::optional<DataEdit> IoStatementBase::GetNextDataEdit(
    IoStatementState &, int) {
  return Fortran::common::nullopt;
}

bool IoStatementBase::BeginReadingRecord() { return true; }

void IoStatementBase::FinishReadingRecord() {}

void IoStatementBase::HandleAbsolutePosition(std::int64_t) {}

void IoStatementBase::HandleRelativePosition(std::int64_t) {}

std::int64_t IoStatementBase::InquirePos() { return 0; }

ExternalFileUnit *IoStatementBase::GetExternalFileUnit() const {
  return nullptr;
}

bool IoStatementBase::Inquire(InquiryKeywordHash, char *, std::size_t) {
  return false;
}

bool IoStatementBase::Inquire(InquiryKeywordHash, bool &) { return false; }

bool IoStatementBase::Inquire(InquiryKeywordHash, std::int64_t, bool &) {
  return false;
}

bool IoStatementBase::Inquire(InquiryKeywordHash, std::int64_t &) {
  return false;
}

void IoStatementBase::BadInquiryKeywordHashCrash(InquiryKeywordHash inquiry) {
  char buffer[16];
  const char *decode{InquiryKeywordHashDecode(buffer, sizeof buffer, inquiry)};
  Crash("Bad InquiryKeywordHash 0x%x (%s)", inquiry,
      decode ? decode : "(cannot decode)");
}

template <Direction DIR>
InternalIoStatementState<DIR>::InternalIoStatementState(
    Buffer scalar, std::size_t length, const char *sourceFile, int sourceLine)
    : IoStatementBase{sourceFile, sourceLine}, unit_{scalar, length, 1} {}

template <Direction DIR>
InternalIoStatementState<DIR>::InternalIoStatementState(
    const Descriptor &d, const char *sourceFile, int sourceLine)
    : IoStatementBase{sourceFile, sourceLine}, unit_{d, *this} {}

template <Direction DIR>
bool InternalIoStatementState<DIR>::Emit(
    const char *data, std::size_t bytes, std::size_t /*elementBytes*/) {
  if constexpr (DIR == Direction::Input) {
    Crash("InternalIoStatementState<Direction::Input>::Emit() called");
    return false;
  }
  return unit_.Emit(data, bytes, *this);
}

template <Direction DIR>
std::size_t InternalIoStatementState<DIR>::GetNextInputBytes(const char *&p) {
  return unit_.GetNextInputBytes(p, *this);
}

template <Direction DIR>
bool InternalIoStatementState<DIR>::AdvanceRecord(int n) {
  while (n-- > 0) {
    if (!unit_.AdvanceRecord(*this)) {
      return false;
    }
  }
  return true;
}

template <Direction DIR> void InternalIoStatementState<DIR>::BackspaceRecord() {
  unit_.BackspaceRecord(*this);
}

template <Direction DIR> int InternalIoStatementState<DIR>::EndIoStatement() {
  auto result{IoStatementBase::EndIoStatement()};
  if (free_) {
    FreeMemory(this);
  }
  return result;
}

template <Direction DIR>
void InternalIoStatementState<DIR>::HandleAbsolutePosition(std::int64_t n) {
  return unit_.HandleAbsolutePosition(n);
}

template <Direction DIR>
void InternalIoStatementState<DIR>::HandleRelativePosition(std::int64_t n) {
  return unit_.HandleRelativePosition(n);
}

template <Direction DIR>
std::int64_t InternalIoStatementState<DIR>::InquirePos() {
  return unit_.InquirePos();
}

template <Direction DIR, typename CHAR>
RT_API_ATTRS
InternalFormattedIoStatementState<DIR, CHAR>::InternalFormattedIoStatementState(
    Buffer buffer, std::size_t length, const CharType *format,
    std::size_t formatLength, const Descriptor *formatDescriptor,
    const char *sourceFile, int sourceLine)
    : InternalIoStatementState<DIR>{buffer, length, sourceFile, sourceLine},
      ioStatementState_{*this},
      format_{*this, format, formatLength, formatDescriptor} {}

template <Direction DIR, typename CHAR>
RT_API_ATTRS
InternalFormattedIoStatementState<DIR, CHAR>::InternalFormattedIoStatementState(
    const Descriptor &d, const CharType *format, std::size_t formatLength,
    const Descriptor *formatDescriptor, const char *sourceFile, int sourceLine)
    : InternalIoStatementState<DIR>{d, sourceFile, sourceLine},
      ioStatementState_{*this},
      format_{*this, format, formatLength, formatDescriptor} {}

template <Direction DIR, typename CHAR>
void InternalFormattedIoStatementState<DIR, CHAR>::CompleteOperation() {
  if (!this->completedOperation()) {
    if constexpr (DIR == Direction::Output) {
      format_.Finish(*this);
      unit_.AdvanceRecord(*this);
    }
    IoStatementBase::CompleteOperation();
  }
}

template <Direction DIR, typename CHAR>
int InternalFormattedIoStatementState<DIR, CHAR>::EndIoStatement() {
  CompleteOperation();
  return InternalIoStatementState<DIR>::EndIoStatement();
}

template <Direction DIR>
InternalListIoStatementState<DIR>::InternalListIoStatementState(
    Buffer buffer, std::size_t length, const char *sourceFile, int sourceLine)
    : InternalIoStatementState<DIR>{buffer, length, sourceFile, sourceLine},
      ioStatementState_{*this} {}

template <Direction DIR>
InternalListIoStatementState<DIR>::InternalListIoStatementState(
    const Descriptor &d, const char *sourceFile, int sourceLine)
    : InternalIoStatementState<DIR>{d, sourceFile, sourceLine},
      ioStatementState_{*this} {}

template <Direction DIR>
void InternalListIoStatementState<DIR>::CompleteOperation() {
  if (!this->completedOperation()) {
    if constexpr (DIR == Direction::Output) {
      if (unit_.furthestPositionInRecord > 0) {
        unit_.AdvanceRecord(*this);
      }
    }
    IoStatementBase::CompleteOperation();
  }
}

template <Direction DIR>
int InternalListIoStatementState<DIR>::EndIoStatement() {
  CompleteOperation();
  if constexpr (DIR == Direction::Input) {
    if (int status{ListDirectedStatementState<DIR>::EndIoStatement()};
        status != IostatOk) {
      return status;
    }
  }
  return InternalIoStatementState<DIR>::EndIoStatement();
}

ExternalIoStatementBase::ExternalIoStatementBase(
    ExternalFileUnit &unit, const char *sourceFile, int sourceLine)
    : IoStatementBase{sourceFile, sourceLine}, unit_{unit} {}

MutableModes &ExternalIoStatementBase::mutableModes() {
  if (const ChildIo * child{unit_.GetChildIo()}) {
#if !defined(RT_DEVICE_AVOID_RECURSION)
    return child->parent().mutableModes();
#else
    ReportUnsupportedChildIo();
#endif
  }
  return unit_.modes;
}

ConnectionState &ExternalIoStatementBase::GetConnectionState() { return unit_; }

int ExternalIoStatementBase::EndIoStatement() {
  CompleteOperation();
  auto result{IoStatementBase::EndIoStatement()};
#if !defined(RT_USE_PSEUDO_FILE_UNIT)
  unit_.EndIoStatement(); // annihilates *this in unit_.u_
#else
  // Fetch the unit pointer before *this disappears.
  ExternalFileUnit *unitPtr{&unit_};
  // The pseudo file units are dynamically allocated
  // and are not tracked in the unit map.
  // They have to be destructed and deallocated here.
  unitPtr->~ExternalFileUnit();
  FreeMemory(unitPtr);
#endif
  return result;
}

void ExternalIoStatementBase::SetAsynchronous() {
  asynchronousID_ = unit().GetAsynchronousId(*this);
}

std::int64_t ExternalIoStatementBase::InquirePos() {
  return unit_.InquirePos();
}

void OpenStatementState::set_path(const char *path, std::size_t length) {
  pathLength_ = TrimTrailingSpaces(path, length);
  path_ = SaveDefaultCharacter(path, pathLength_, *this);
}

void OpenStatementState::CompleteOperation() {
  if (completedOperation()) {
    return;
  }
  if (position_) {
    if (access_ && *access_ == Access::Direct) {
      SignalError("POSITION= may not be set with ACCESS='DIRECT'");
      position_.reset();
    }
  }
  if (status_) { // 12.5.6.10
    if ((*status_ == OpenStatus::New || *status_ == OpenStatus::Replace) &&
        !path_.get()) {
      SignalError("FILE= required on OPEN with STATUS='NEW' or 'REPLACE'");
    } else if (*status_ == OpenStatus::Scratch && path_.get()) {
      SignalError("FILE= may not appear on OPEN with STATUS='SCRATCH'");
    }
  }
  // F'2023 12.5.6.13 - NEWUNIT= requires either FILE= or STATUS='SCRATCH'
  if (isNewUnit_ && !path_.get() &&
      status_.value_or(OpenStatus::Unknown) != OpenStatus::Scratch) {
    SignalError(IostatBadNewUnit);
    status_ = OpenStatus::Scratch; // error recovery
  }
  if (path_.get() || wasExtant_ ||
      (status_ && *status_ == OpenStatus::Scratch)) {
    if (unit().OpenUnit(status_, action_, position_.value_or(Position::AsIs),
            std::move(path_), pathLength_, convert_, *this)) {
      wasExtant_ = false; // existing unit was closed
    }
  } else {
    unit().OpenAnonymousUnit(
        status_, action_, position_.value_or(Position::AsIs), convert_, *this);
  }
  if (access_) {
    if (*access_ != unit().access) {
      if (wasExtant_) {
        SignalError("ACCESS= may not be changed on an open unit");
        access_.reset();
      }
    }
    if (access_) {
      unit().access = *access_;
    }
  }
  if (!unit().isUnformatted) {
    unit().isUnformatted = isUnformatted_;
  }
  if (isUnformatted_ && *isUnformatted_ != *unit().isUnformatted) {
    if (wasExtant_) {
      SignalError("FORM= may not be changed on an open unit");
    }
    unit().isUnformatted = *isUnformatted_;
  }
  if (!unit().isUnformatted) {
    // Set default format (C.7.4 point 2).
    unit().isUnformatted = unit().access != Access::Sequential;
  }
  if (!wasExtant_ && InError()) {
    // Release the new unit on failure
    unit().CloseUnit(CloseStatus::Delete, *this);
    unit().DestroyClosed();
  }
  IoStatementBase::CompleteOperation();
}

int OpenStatementState::EndIoStatement() {
  CompleteOperation();
  return ExternalIoStatementBase::EndIoStatement();
}

int CloseStatementState::EndIoStatement() {
  CompleteOperation();
  int result{ExternalIoStatementBase::EndIoStatement()};
  unit().CloseUnit(status_, *this);
  unit().DestroyClosed();
  return result;
}

void NoUnitIoStatementState::CompleteOperation() {
  SignalPendingError();
  IoStatementBase::CompleteOperation();
}

int NoUnitIoStatementState::EndIoStatement() {
  CompleteOperation();
  auto result{IoStatementBase::EndIoStatement()};
  FreeMemory(this);
  return result;
}

template <Direction DIR>
ExternalIoStatementState<DIR>::ExternalIoStatementState(
    ExternalFileUnit &unit, const char *sourceFile, int sourceLine)
    : ExternalIoStatementBase{unit, sourceFile, sourceLine}, mutableModes_{
                                                                 unit.modes} {
  if constexpr (DIR == Direction::Output) {
    // If the last statement was a non-advancing IO input statement, the unit
    // furthestPositionInRecord was not advanced, but the positionInRecord may
    // have been advanced. Advance furthestPositionInRecord here to avoid
    // overwriting the part of the record that has been read with blanks.
    unit.furthestPositionInRecord =
        std::max(unit.furthestPositionInRecord, unit.positionInRecord);
  }
}

template <Direction DIR>
void ExternalIoStatementState<DIR>::CompleteOperation() {
  if (completedOperation()) {
    return;
  }
  if constexpr (DIR == Direction::Input) {
    BeginReadingRecord(); // in case there were no I/O items
    if (mutableModes().nonAdvancing && !InError()) {
      unit().leftTabLimit = unit().furthestPositionInRecord;
    } else {
      FinishReadingRecord();
    }
  } else { // output
    if (mutableModes().nonAdvancing) {
      // Make effects of positioning past the last Emit() visible with blanks.
      if (unit().positionInRecord > unit().furthestPositionInRecord) {
        unit().Emit("", 0, 1, *this); // Emit() will pad
      }
      unit().leftTabLimit = unit().positionInRecord;
    } else {
      unit().AdvanceRecord(*this);
    }
    unit().FlushIfTerminal(*this);
  }
  return IoStatementBase::CompleteOperation();
}

template <Direction DIR> int ExternalIoStatementState<DIR>::EndIoStatement() {
  CompleteOperation();
  return ExternalIoStatementBase::EndIoStatement();
}

template <Direction DIR>
bool ExternalIoStatementState<DIR>::Emit(
    const char *data, std::size_t bytes, std::size_t elementBytes) {
  if constexpr (DIR == Direction::Input) {
    Crash("ExternalIoStatementState::Emit(char) called for input statement");
  }
  return unit().Emit(data, bytes, elementBytes, *this);
}

template <Direction DIR>
std::size_t ExternalIoStatementState<DIR>::GetNextInputBytes(const char *&p) {
  return unit().GetNextInputBytes(p, *this);
}

template <Direction DIR>
bool ExternalIoStatementState<DIR>::AdvanceRecord(int n) {
  while (n-- > 0) {
    if (!unit().AdvanceRecord(*this)) {
      return false;
    }
  }
  return true;
}

template <Direction DIR> void ExternalIoStatementState<DIR>::BackspaceRecord() {
  unit().BackspaceRecord(*this);
}

template <Direction DIR>
void ExternalIoStatementState<DIR>::HandleAbsolutePosition(std::int64_t n) {
  return unit().HandleAbsolutePosition(n);
}

template <Direction DIR>
void ExternalIoStatementState<DIR>::HandleRelativePosition(std::int64_t n) {
  return unit().HandleRelativePosition(n);
}

template <Direction DIR>
bool ExternalIoStatementState<DIR>::BeginReadingRecord() {
  if constexpr (DIR == Direction::Input) {
    return unit().BeginReadingRecord(*this);
  } else {
    Crash("ExternalIoStatementState<Direction::Output>::BeginReadingRecord() "
          "called");
    return false;
  }
}

template <Direction DIR>
void ExternalIoStatementState<DIR>::FinishReadingRecord() {
  if constexpr (DIR == Direction::Input) {
    unit().FinishReadingRecord(*this);
  } else {
    Crash("ExternalIoStatementState<Direction::Output>::FinishReadingRecord() "
          "called");
  }
}

template <Direction DIR, typename CHAR>
ExternalFormattedIoStatementState<DIR, CHAR>::ExternalFormattedIoStatementState(
    ExternalFileUnit &unit, const CHAR *format, std::size_t formatLength,
    const Descriptor *formatDescriptor, const char *sourceFile, int sourceLine)
    : ExternalIoStatementState<DIR>{unit, sourceFile, sourceLine},
      format_{*this, format, formatLength, formatDescriptor} {}

template <Direction DIR, typename CHAR>
void ExternalFormattedIoStatementState<DIR, CHAR>::CompleteOperation() {
  if (this->completedOperation()) {
    return;
  }
  if constexpr (DIR == Direction::Input) {
    this->BeginReadingRecord(); // in case there were no I/O items
  }
  format_.Finish(*this);
  return ExternalIoStatementState<DIR>::CompleteOperation();
}

template <Direction DIR, typename CHAR>
int ExternalFormattedIoStatementState<DIR, CHAR>::EndIoStatement() {
  CompleteOperation();
  return ExternalIoStatementState<DIR>::EndIoStatement();
}

Fortran::common::optional<DataEdit> IoStatementState::GetNextDataEdit(int n) {
  return common::visit(
      [&](auto &x) { return x.get().GetNextDataEdit(*this, n); }, u_);
}

bool IoStatementState::Emit(
    const char *data, std::size_t bytes, std::size_t elementBytes) {
  return common::visit(
      [=](auto &x) { return x.get().Emit(data, bytes, elementBytes); }, u_);
}

bool IoStatementState::Receive(
    char *data, std::size_t n, std::size_t elementBytes) {
  return common::visit(
      [=](auto &x) { return x.get().Receive(data, n, elementBytes); }, u_);
}

std::size_t IoStatementState::GetNextInputBytes(const char *&p) {
  return common::visit(
      [&](auto &x) { return x.get().GetNextInputBytes(p); }, u_);
}

bool IoStatementState::AdvanceRecord(int n) {
  return common::visit([=](auto &x) { return x.get().AdvanceRecord(n); }, u_);
}

void IoStatementState::BackspaceRecord() {
  common::visit([](auto &x) { x.get().BackspaceRecord(); }, u_);
}

void IoStatementState::HandleRelativePosition(std::int64_t n) {
  common::visit([=](auto &x) { x.get().HandleRelativePosition(n); }, u_);
}

void IoStatementState::HandleAbsolutePosition(std::int64_t n) {
  common::visit([=](auto &x) { x.get().HandleAbsolutePosition(n); }, u_);
}

void IoStatementState::CompleteOperation() {
  common::visit([](auto &x) { x.get().CompleteOperation(); }, u_);
}

int IoStatementState::EndIoStatement() {
  return common::visit([](auto &x) { return x.get().EndIoStatement(); }, u_);
}

ConnectionState &IoStatementState::GetConnectionState() {
  return common::visit(
      [](auto &x) -> ConnectionState & { return x.get().GetConnectionState(); },
      u_);
}

MutableModes &IoStatementState::mutableModes() {
  return common::visit(
      [](auto &x) -> MutableModes & { return x.get().mutableModes(); }, u_);
}

bool IoStatementState::BeginReadingRecord() {
  return common::visit(
      [](auto &x) { return x.get().BeginReadingRecord(); }, u_);
}

IoErrorHandler &IoStatementState::GetIoErrorHandler() const {
  return common::visit(
      [](auto &x) -> IoErrorHandler & {
        return static_cast<IoErrorHandler &>(x.get());
      },
      u_);
}

ExternalFileUnit *IoStatementState::GetExternalFileUnit() const {
  return common::visit(
      [](auto &x) { return x.get().GetExternalFileUnit(); }, u_);
}

Fortran::common::optional<char32_t> IoStatementState::GetCurrentChar(
    std::size_t &byteCount) {
  const char *p{nullptr};
  std::size_t bytes{GetNextInputBytes(p)};
  if (bytes == 0) {
    byteCount = 0;
    return Fortran::common::nullopt;
  } else {
    const ConnectionState &connection{GetConnectionState()};
    if (connection.isUTF8) {
      std::size_t length{MeasureUTF8Bytes(*p)};
      if (length <= bytes) {
        if (auto result{DecodeUTF8(p)}) {
          byteCount = length;
          return result;
        }
      }
      GetIoErrorHandler().SignalError(IostatUTF8Decoding);
      // Error recovery: return the next byte
    } else if (connection.internalIoCharKind > 1) {
      byteCount = connection.internalIoCharKind;
      if (byteCount == 2) {
        return *reinterpret_cast<const char16_t *>(p);
      } else {
        return *reinterpret_cast<const char32_t *>(p);
      }
    }
    byteCount = 1;
    return *p;
  }
}

Fortran::common::optional<char32_t> IoStatementState::NextInField(
    Fortran::common::optional<int> &remaining, const DataEdit &edit) {
  std::size_t byteCount{0};
  if (!remaining) { // Stream, list-directed, or NAMELIST
    if (auto next{GetCurrentChar(byteCount)}) {
      if (edit.IsListDirected()) {
        // list-directed or NAMELIST: check for separators
        switch (*next) {
        case ' ':
        case '\t':
        case '/':
        case '(':
        case ')':
        case '\'':
        case '"':
        case '*':
        case '\n': // for stream access
          return Fortran::common::nullopt;
        case '&':
        case '$':
          if (edit.IsNamelist()) {
            return Fortran::common::nullopt;
          }
          break;
        case ',':
          if (!(edit.modes.editingFlags & decimalComma)) {
            return Fortran::common::nullopt;
          }
          break;
        case ';':
          if (edit.modes.editingFlags & decimalComma) {
            return Fortran::common::nullopt;
          }
          break;
        default:
          break;
        }
      }
      HandleRelativePosition(byteCount);
      GotChar(byteCount);
      return next;
    }
  } else if (*remaining > 0) {
    if (auto next{GetCurrentChar(byteCount)}) {
      if (byteCount > static_cast<std::size_t>(*remaining)) {
        return Fortran::common::nullopt;
      }
      *remaining -= byteCount;
      HandleRelativePosition(byteCount);
      GotChar(byteCount);
      return next;
    }
    if (CheckForEndOfRecord(0)) { // do padding
      --*remaining;
      return Fortran::common::optional<char32_t>{' '};
    }
  }
  return Fortran::common::nullopt;
}

bool IoStatementState::CheckForEndOfRecord(std::size_t afterReading) {
  const ConnectionState &connection{GetConnectionState()};
  if (!connection.IsAtEOF()) {
    if (auto length{connection.EffectiveRecordLength()}) {
      if (connection.positionInRecord +
              static_cast<std::int64_t>(afterReading) >=
          *length) {
        IoErrorHandler &handler{GetIoErrorHandler()};
        const auto &modes{mutableModes()};
        if (modes.nonAdvancing) {
          if (connection.access == Access::Stream &&
              connection.unterminatedRecord) {
            // Reading final unterminated record left by a
            // non-advancing WRITE on a stream file prior to
            // positioning or ENDFILE.
            handler.SignalEnd();
          } else {
            handler.SignalEor();
          }
        } else if (!modes.pad) {
          handler.SignalError(IostatRecordReadOverrun);
        }
        return modes.pad; // PAD='YES'
      }
    }
  }
  return false;
}

bool IoStatementState::Inquire(
    InquiryKeywordHash inquiry, char *out, std::size_t chars) {
  return common::visit(
      [&](auto &x) { return x.get().Inquire(inquiry, out, chars); }, u_);
}

bool IoStatementState::Inquire(InquiryKeywordHash inquiry, bool &out) {
  return common::visit(
      [&](auto &x) { return x.get().Inquire(inquiry, out); }, u_);
}

bool IoStatementState::Inquire(
    InquiryKeywordHash inquiry, std::int64_t id, bool &out) {
  return common::visit(
      [&](auto &x) { return x.get().Inquire(inquiry, id, out); }, u_);
}

bool IoStatementState::Inquire(InquiryKeywordHash inquiry, std::int64_t &n) {
  return common::visit(
      [&](auto &x) { return x.get().Inquire(inquiry, n); }, u_);
}

std::int64_t IoStatementState::InquirePos() {
  return common::visit([&](auto &x) { return x.get().InquirePos(); }, u_);
}

void IoStatementState::GotChar(int n) {
  if (auto *formattedIn{
          get_if<FormattedIoStatementState<Direction::Input>>()}) {
    formattedIn->GotChar(n);
  } else {
    GetIoErrorHandler().Crash("IoStatementState::GotChar() called for "
                              "statement that is not formatted input");
  }
}

std::size_t
FormattedIoStatementState<Direction::Input>::GetEditDescriptorChars() const {
  return chars_;
}

void FormattedIoStatementState<Direction::Input>::GotChar(int n) {
  chars_ += n;
}

bool ListDirectedStatementState<Direction::Output>::EmitLeadingSpaceOrAdvance(
    IoStatementState &io, std::size_t length, bool isCharacter) {
  const ConnectionState &connection{io.GetConnectionState()};
  int space{connection.positionInRecord == 0 ||
      !(isCharacter && lastWasUndelimitedCharacter())};
  set_lastWasUndelimitedCharacter(false);
  if (connection.NeedAdvance(space + length)) {
    return io.AdvanceRecord();
  }
  if (space) {
    return EmitAscii(io, " ", 1);
  }
  return true;
}

Fortran::common::optional<DataEdit>
ListDirectedStatementState<Direction::Output>::GetNextDataEdit(
    IoStatementState &io, int maxRepeat) {
  DataEdit edit;
  edit.descriptor = DataEdit::ListDirected;
  edit.repeat = maxRepeat;
  edit.modes = io.mutableModes();
  return edit;
}

int ListDirectedStatementState<Direction::Input>::EndIoStatement() {
  if (repeatPosition_) {
    repeatPosition_->Cancel();
  }
  return IostatOk;
}

Fortran::common::optional<DataEdit>
ListDirectedStatementState<Direction::Input>::GetNextDataEdit(
    IoStatementState &io, int maxRepeat) {
  // N.B. list-directed transfers cannot be nonadvancing (C1221)
  ConnectionState &connection{io.GetConnectionState()};
  DataEdit edit;
  edit.descriptor = DataEdit::ListDirected;
  edit.repeat = 1; // may be overridden below
  edit.modes = io.mutableModes();
  if (hitSlash_) { // everything after '/' is nullified
    edit.descriptor = DataEdit::ListDirectedNullValue;
    return edit;
  }
  char32_t comma{','};
  if (edit.modes.editingFlags & decimalComma) {
    comma = ';';
  }
  std::size_t byteCount{0};
  if (remaining_ > 0 && !realPart_) { // "r*c" repetition in progress
    RUNTIME_CHECK(io.GetIoErrorHandler(), repeatPosition_.has_value());
    repeatPosition_.reset(); // restores the saved position
    if (!imaginaryPart_) {
      edit.repeat = std::min<int>(remaining_, maxRepeat);
      auto ch{io.GetCurrentChar(byteCount)};
      if (!ch || *ch == ' ' || *ch == '\t' || *ch == comma) {
        // "r*" repeated null
        edit.descriptor = DataEdit::ListDirectedNullValue;
      }
    }
    remaining_ -= edit.repeat;
    if (remaining_ > 0) {
      repeatPosition_.emplace(io);
    }
    if (!imaginaryPart_) {
      return edit;
    }
  }
  // Skip separators, handle a "r*c" repeat count; see 13.10.2 in Fortran 2018
  if (imaginaryPart_) {
    imaginaryPart_ = false;
  } else if (realPart_) {
    realPart_ = false;
    imaginaryPart_ = true;
    edit.descriptor = DataEdit::ListDirectedImaginaryPart;
  }
  auto ch{io.GetNextNonBlank(byteCount)};
  if (ch && *ch == comma && eatComma_) {
    // Consume comma & whitespace after previous item.
    // This includes the comma between real and imaginary components
    // in list-directed/NAMELIST complex input.
    // (When DECIMAL='COMMA', the comma is actually a semicolon.)
    io.HandleRelativePosition(byteCount);
    ch = io.GetNextNonBlank(byteCount);
  }
  eatComma_ = true;
  if (!ch) {
    return Fortran::common::nullopt;
  }
  if (*ch == '/') {
    hitSlash_ = true;
    edit.descriptor = DataEdit::ListDirectedNullValue;
    return edit;
  }
  if (*ch == comma) { // separator: null value
    edit.descriptor = DataEdit::ListDirectedNullValue;
    return edit;
  }
  if (imaginaryPart_) { // can't repeat components
    return edit;
  }
  if (*ch >= '0' && *ch <= '9') { // look for "r*" repetition count
    auto start{connection.positionInRecord};
    int r{0};
    do {
      static auto constexpr clamp{(std::numeric_limits<int>::max() - '9') / 10};
      if (r >= clamp) {
        r = 0;
        break;
      }
      r = 10 * r + (*ch - '0');
      io.HandleRelativePosition(byteCount);
      ch = io.GetCurrentChar(byteCount);
    } while (ch && *ch >= '0' && *ch <= '9');
    if (r > 0 && ch && *ch == '*') { // subtle: r must be nonzero
      io.HandleRelativePosition(byteCount);
      ch = io.GetCurrentChar(byteCount);
      if (ch && *ch == '/') { // r*/
        hitSlash_ = true;
        edit.descriptor = DataEdit::ListDirectedNullValue;
        return edit;
      }
      if (!ch || *ch == ' ' || *ch == '\t' || *ch == comma) { // "r*" null
        edit.descriptor = DataEdit::ListDirectedNullValue;
      }
      edit.repeat = std::min<int>(r, maxRepeat);
      remaining_ = r - edit.repeat;
      if (remaining_ > 0) {
        repeatPosition_.emplace(io);
      }
    } else { // not a repetition count, just an integer value; rewind
      connection.positionInRecord = start;
    }
  }
  if (!imaginaryPart_ && ch && *ch == '(') {
    realPart_ = true;
    io.HandleRelativePosition(byteCount);
    edit.descriptor = DataEdit::ListDirectedRealPart;
  }
  return edit;
}

template <Direction DIR>
int ExternalListIoStatementState<DIR>::EndIoStatement() {
  if constexpr (DIR == Direction::Input) {
    if (auto status{ListDirectedStatementState<DIR>::EndIoStatement()};
        status != IostatOk) {
      return status;
    }
  }
  return ExternalIoStatementState<DIR>::EndIoStatement();
}

template <Direction DIR>
bool ExternalUnformattedIoStatementState<DIR>::Receive(
    char *data, std::size_t bytes, std::size_t elementBytes) {
  if constexpr (DIR == Direction::Output) {
    this->Crash("ExternalUnformattedIoStatementState::Receive() called for "
                "output statement");
  }
  return this->unit().Receive(data, bytes, elementBytes, *this);
}

template <Direction DIR>
ChildIoStatementState<DIR>::ChildIoStatementState(
    ChildIo &child, const char *sourceFile, int sourceLine)
    : IoStatementBase{sourceFile, sourceLine}, child_{child} {}

template <Direction DIR>
MutableModes &ChildIoStatementState<DIR>::mutableModes() {
#if !defined(RT_DEVICE_AVOID_RECURSION)
  return child_.parent().mutableModes();
#else
  ReportUnsupportedChildIo();
#endif
}

template <Direction DIR>
ConnectionState &ChildIoStatementState<DIR>::GetConnectionState() {
#if !defined(RT_DEVICE_AVOID_RECURSION)
  return child_.parent().GetConnectionState();
#else
  ReportUnsupportedChildIo();
#endif
}

template <Direction DIR>
ExternalFileUnit *ChildIoStatementState<DIR>::GetExternalFileUnit() const {
#if !defined(RT_DEVICE_AVOID_RECURSION)
  return child_.parent().GetExternalFileUnit();
#else
  ReportUnsupportedChildIo();
#endif
}

template <Direction DIR> int ChildIoStatementState<DIR>::EndIoStatement() {
  CompleteOperation();
  auto result{IoStatementBase::EndIoStatement()};
  child_.EndIoStatement(); // annihilates *this in child_.u_
  return result;
}

template <Direction DIR>
bool ChildIoStatementState<DIR>::Emit(
    const char *data, std::size_t bytes, std::size_t elementBytes) {
#if !defined(RT_DEVICE_AVOID_RECURSION)
  return child_.parent().Emit(data, bytes, elementBytes);
#else
  ReportUnsupportedChildIo();
#endif
}

template <Direction DIR>
std::size_t ChildIoStatementState<DIR>::GetNextInputBytes(const char *&p) {
#if !defined(RT_DEVICE_AVOID_RECURSION)
  return child_.parent().GetNextInputBytes(p);
#else
  ReportUnsupportedChildIo();
#endif
}

template <Direction DIR>
void ChildIoStatementState<DIR>::HandleAbsolutePosition(std::int64_t n) {
#if !defined(RT_DEVICE_AVOID_RECURSION)
  return child_.parent().HandleAbsolutePosition(n);
#else
  ReportUnsupportedChildIo();
#endif
}

template <Direction DIR>
void ChildIoStatementState<DIR>::HandleRelativePosition(std::int64_t n) {
#if !defined(RT_DEVICE_AVOID_RECURSION)
  return child_.parent().HandleRelativePosition(n);
#else
  ReportUnsupportedChildIo();
#endif
}

template <Direction DIR, typename CHAR>
ChildFormattedIoStatementState<DIR, CHAR>::ChildFormattedIoStatementState(
    ChildIo &child, const CHAR *format, std::size_t formatLength,
    const Descriptor *formatDescriptor, const char *sourceFile, int sourceLine)
    : ChildIoStatementState<DIR>{child, sourceFile, sourceLine},
      mutableModes_{child.parent().mutableModes()}, format_{*this, format,
                                                        formatLength,
                                                        formatDescriptor} {}

template <Direction DIR, typename CHAR>
void ChildFormattedIoStatementState<DIR, CHAR>::CompleteOperation() {
  if (!this->completedOperation()) {
    format_.Finish(*this);
    ChildIoStatementState<DIR>::CompleteOperation();
  }
}

template <Direction DIR, typename CHAR>
int ChildFormattedIoStatementState<DIR, CHAR>::EndIoStatement() {
  CompleteOperation();
  return ChildIoStatementState<DIR>::EndIoStatement();
}

template <Direction DIR, typename CHAR>
bool ChildFormattedIoStatementState<DIR, CHAR>::AdvanceRecord(int n) {
#if !defined(RT_DEVICE_AVOID_RECURSION)
  return this->child().parent().AdvanceRecord(n);
#else
  this->ReportUnsupportedChildIo();
#endif
}

template <Direction DIR>
bool ChildUnformattedIoStatementState<DIR>::Receive(
    char *data, std::size_t bytes, std::size_t elementBytes) {
#if !defined(RT_DEVICE_AVOID_RECURSION)
  return this->child().parent().Receive(data, bytes, elementBytes);
#else
  this->ReportUnsupportedChildIo();
#endif
}

template <Direction DIR> int ChildListIoStatementState<DIR>::EndIoStatement() {
  if constexpr (DIR == Direction::Input) {
    if (int status{ListDirectedStatementState<DIR>::EndIoStatement()};
        status != IostatOk) {
      return status;
    }
  }
  return ChildIoStatementState<DIR>::EndIoStatement();
}

template class InternalIoStatementState<Direction::Output>;
template class InternalIoStatementState<Direction::Input>;
template class InternalFormattedIoStatementState<Direction::Output>;
template class InternalFormattedIoStatementState<Direction::Input>;
template class InternalListIoStatementState<Direction::Output>;
template class InternalListIoStatementState<Direction::Input>;
template class ExternalIoStatementState<Direction::Output>;
template class ExternalIoStatementState<Direction::Input>;
template class ExternalFormattedIoStatementState<Direction::Output>;
template class ExternalFormattedIoStatementState<Direction::Input>;
template class ExternalListIoStatementState<Direction::Output>;
template class ExternalListIoStatementState<Direction::Input>;
template class ExternalUnformattedIoStatementState<Direction::Output>;
template class ExternalUnformattedIoStatementState<Direction::Input>;
template class ChildIoStatementState<Direction::Output>;
template class ChildIoStatementState<Direction::Input>;
template class ChildFormattedIoStatementState<Direction::Output>;
template class ChildFormattedIoStatementState<Direction::Input>;
template class ChildListIoStatementState<Direction::Output>;
template class ChildListIoStatementState<Direction::Input>;
template class ChildUnformattedIoStatementState<Direction::Output>;
template class ChildUnformattedIoStatementState<Direction::Input>;

void ExternalMiscIoStatementState::CompleteOperation() {
  if (completedOperation()) {
    return;
  }
  ExternalFileUnit &ext{unit()};
  switch (which_) {
  case Flush:
    ext.FlushOutput(*this);
#if !defined(RT_DEVICE_COMPILATION)
    std::fflush(nullptr); // flushes C stdio output streams (12.9(2))
#endif
    break;
  case Backspace:
    ext.BackspaceRecord(*this);
    break;
  case Endfile:
    ext.Endfile(*this);
    break;
  case Rewind:
    ext.Rewind(*this);
    break;
  case Wait:
    break; // handled in io-api.cpp BeginWait
  }
  return IoStatementBase::CompleteOperation();
}

int ExternalMiscIoStatementState::EndIoStatement() {
  CompleteOperation();
  return ExternalIoStatementBase::EndIoStatement();
}

InquireUnitState::InquireUnitState(
    ExternalFileUnit &unit, const char *sourceFile, int sourceLine)
    : ExternalIoStatementBase{unit, sourceFile, sourceLine} {}

bool InquireUnitState::Inquire(
    InquiryKeywordHash inquiry, char *result, std::size_t length) {
  if (unit().createdForInternalChildIo()) {
    SignalError(IostatInquireInternalUnit,
        "INQUIRE of unit created for defined derived type I/O of an internal "
        "unit");
    return false;
  }
  const char *str{nullptr};
  switch (inquiry) {
  case HashInquiryKeyword("ACCESS"):
    if (!unit().IsConnected()) {
      str = "UNDEFINED";
    } else {
      switch (unit().access) {
      case Access::Sequential:
        str = "SEQUENTIAL";
        break;
      case Access::Direct:
        str = "DIRECT";
        break;
      case Access::Stream:
        str = "STREAM";
        break;
      }
    }
    break;
  case HashInquiryKeyword("ACTION"):
    str = !unit().IsConnected() ? "UNDEFINED"
        : unit().mayWrite()     ? unit().mayRead() ? "READWRITE" : "WRITE"
                                : "READ";
    break;
  case HashInquiryKeyword("ASYNCHRONOUS"):
    str = !unit().IsConnected()    ? "UNDEFINED"
        : unit().mayAsynchronous() ? "YES"
                                   : "NO";
    break;
  case HashInquiryKeyword("BLANK"):
    str = !unit().IsConnected() || unit().isUnformatted.value_or(true)
        ? "UNDEFINED"
        : mutableModes().editingFlags & blankZero ? "ZERO"
                                                  : "NULL";
    break;
  case HashInquiryKeyword("CARRIAGECONTROL"):
    str = "LIST";
    break;
  case HashInquiryKeyword("CONVERT"):
    str = unit().swapEndianness() ? "SWAP" : "NATIVE";
    break;
  case HashInquiryKeyword("DECIMAL"):
    str = !unit().IsConnected() || unit().isUnformatted.value_or(true)
        ? "UNDEFINED"
        : mutableModes().editingFlags & decimalComma ? "COMMA"
                                                     : "POINT";
    break;
  case HashInquiryKeyword("DELIM"):
    if (!unit().IsConnected() || unit().isUnformatted.value_or(true)) {
      str = "UNDEFINED";
    } else {
      switch (mutableModes().delim) {
      case '\'':
        str = "APOSTROPHE";
        break;
      case '"':
        str = "QUOTE";
        break;
      default:
        str = "NONE";
        break;
      }
    }
    break;
  case HashInquiryKeyword("DIRECT"):
    str = !unit().IsConnected() ? "UNKNOWN"
        : unit().access == Access::Direct ||
            (unit().mayPosition() && unit().openRecl)
        ? "YES"
        : "NO";
    break;
  case HashInquiryKeyword("ENCODING"):
    str = !unit().IsConnected()               ? "UNKNOWN"
        : unit().isUnformatted.value_or(true) ? "UNDEFINED"
        : unit().isUTF8                       ? "UTF-8"
                                              : "ASCII";
    break;
  case HashInquiryKeyword("FORM"):
    str = !unit().IsConnected() || !unit().isUnformatted ? "UNDEFINED"
        : *unit().isUnformatted                          ? "UNFORMATTED"
                                                         : "FORMATTED";
    break;
  case HashInquiryKeyword("FORMATTED"):
    str = !unit().IsConnected() ? "UNDEFINED"
        : !unit().isUnformatted ? "UNKNOWN"
        : *unit().isUnformatted ? "NO"
                                : "YES";
    break;
  case HashInquiryKeyword("NAME"):
    str = unit().path();
    if (!str) {
      return true; // result is undefined
    }
    break;
  case HashInquiryKeyword("PAD"):
    str = !unit().IsConnected() || unit().isUnformatted.value_or(true)
        ? "UNDEFINED"
        : mutableModes().pad ? "YES"
                             : "NO";
    break;
  case HashInquiryKeyword("POSITION"):
    if (!unit().IsConnected() || unit().access == Access::Direct) {
      str = "UNDEFINED";
    } else {
      switch (unit().InquirePosition()) {
      case Position::Rewind:
        str = "REWIND";
        break;
      case Position::Append:
        str = "APPEND";
        break;
      case Position::AsIs:
        str = "ASIS";
        break;
      }
    }
    break;
  case HashInquiryKeyword("READ"):
    str = !unit().IsConnected() ? "UNDEFINED" : unit().mayRead() ? "YES" : "NO";
    break;
  case HashInquiryKeyword("READWRITE"):
    str = !unit().IsConnected()                 ? "UNDEFINED"
        : unit().mayRead() && unit().mayWrite() ? "YES"
                                                : "NO";
    break;
  case HashInquiryKeyword("ROUND"):
    if (!unit().IsConnected() || unit().isUnformatted.value_or(true)) {
      str = "UNDEFINED";
    } else {
      switch (mutableModes().round) {
      case decimal::FortranRounding::RoundNearest:
        str = "NEAREST";
        break;
      case decimal::FortranRounding::RoundUp:
        str = "UP";
        break;
      case decimal::FortranRounding::RoundDown:
        str = "DOWN";
        break;
      case decimal::FortranRounding::RoundToZero:
        str = "ZERO";
        break;
      case decimal::FortranRounding::RoundCompatible:
        str = "COMPATIBLE";
        break;
      }
    }
    break;
  case HashInquiryKeyword("SEQUENTIAL"):
    // "NO" for Direct, since Sequential would not work if
    // the unit were reopened without RECL=.
    str = !unit().IsConnected()               ? "UNKNOWN"
        : unit().access == Access::Sequential ? "YES"
                                              : "NO";
    break;
  case HashInquiryKeyword("SIGN"):
    str = !unit().IsConnected() || unit().isUnformatted.value_or(true)
        ? "UNDEFINED"
        : mutableModes().editingFlags & signPlus ? "PLUS"
                                                 : "SUPPRESS";
    break;
  case HashInquiryKeyword("STREAM"):
    str = !unit().IsConnected()           ? "UNKNOWN"
        : unit().access == Access::Stream ? "YES"
                                          : "NO";
    break;
  case HashInquiryKeyword("UNFORMATTED"):
    str = !unit().IsConnected() || !unit().isUnformatted ? "UNKNOWN"
        : *unit().isUnformatted                          ? "YES"
                                                         : "NO";
    break;
  case HashInquiryKeyword("WRITE"):
    str = !unit().IsConnected() ? "UNKNOWN" : unit().mayWrite() ? "YES" : "NO";
    break;
  }
  if (str) {
    ToFortranDefaultCharacter(result, length, str);
    return true;
  } else {
    BadInquiryKeywordHashCrash(inquiry);
    return false;
  }
}

bool InquireUnitState::Inquire(InquiryKeywordHash inquiry, bool &result) {
  switch (inquiry) {
  case HashInquiryKeyword("EXIST"):
    result = true;
    return true;
  case HashInquiryKeyword("NAMED"):
    result = unit().path() != nullptr;
    return true;
  case HashInquiryKeyword("OPENED"):
    result = unit().IsConnected();
    return true;
  case HashInquiryKeyword("PENDING"):
    result = false; // asynchronous I/O is not implemented
    return true;
  default:
    BadInquiryKeywordHashCrash(inquiry);
    return false;
  }
}

bool InquireUnitState::Inquire(
    InquiryKeywordHash inquiry, std::int64_t, bool &result) {
  switch (inquiry) {
  case HashInquiryKeyword("PENDING"):
    result = false; // asynchronous I/O is not implemented
    return true;
  default:
    BadInquiryKeywordHashCrash(inquiry);
    return false;
  }
}

bool InquireUnitState::Inquire(
    InquiryKeywordHash inquiry, std::int64_t &result) {
  switch (inquiry) {
  case HashInquiryKeyword("NEXTREC"):
    if (unit().access == Access::Direct) {
      result = unit().currentRecordNumber;
    }
    return true;
  case HashInquiryKeyword("NUMBER"):
    result = unit().unitNumber();
    return true;
  case HashInquiryKeyword("POS"):
    result = unit().InquirePos();
    return true;
  case HashInquiryKeyword("RECL"):
    if (!unit().IsConnected()) {
      result = -1;
    } else if (unit().access == Access::Stream) {
      result = -2;
    } else if (unit().openRecl) {
      result = *unit().openRecl;
    } else {
      result = std::numeric_limits<std::int32_t>::max();
    }
    return true;
  case HashInquiryKeyword("SIZE"):
    result = -1;
    if (unit().IsConnected()) {
      unit().FlushOutput(*this);
      if (auto size{unit().knownSize()}) {
        result = *size;
      }
    }
    return true;
  default:
    BadInquiryKeywordHashCrash(inquiry);
    return false;
  }
}

InquireNoUnitState::InquireNoUnitState(
    const char *sourceFile, int sourceLine, int badUnitNumber)
    : NoUnitIoStatementState{*this, sourceFile, sourceLine, badUnitNumber} {}

bool InquireNoUnitState::Inquire(
    InquiryKeywordHash inquiry, char *result, std::size_t length) {
  switch (inquiry) {
  case HashInquiryKeyword("ACCESS"):
  case HashInquiryKeyword("ACTION"):
  case HashInquiryKeyword("ASYNCHRONOUS"):
  case HashInquiryKeyword("BLANK"):
  case HashInquiryKeyword("CARRIAGECONTROL"):
  case HashInquiryKeyword("CONVERT"):
  case HashInquiryKeyword("DECIMAL"):
  case HashInquiryKeyword("DELIM"):
  case HashInquiryKeyword("FORM"):
  case HashInquiryKeyword("NAME"):
  case HashInquiryKeyword("PAD"):
  case HashInquiryKeyword("POSITION"):
  case HashInquiryKeyword("ROUND"):
  case HashInquiryKeyword("SIGN"):
    ToFortranDefaultCharacter(result, length, "UNDEFINED");
    return true;
  case HashInquiryKeyword("DIRECT"):
  case HashInquiryKeyword("ENCODING"):
  case HashInquiryKeyword("FORMATTED"):
  case HashInquiryKeyword("READ"):
  case HashInquiryKeyword("READWRITE"):
  case HashInquiryKeyword("SEQUENTIAL"):
  case HashInquiryKeyword("STREAM"):
  case HashInquiryKeyword("WRITE"):
  case HashInquiryKeyword("UNFORMATTED"):
    ToFortranDefaultCharacter(result, length, "UNKNOWN");
    return true;
  default:
    BadInquiryKeywordHashCrash(inquiry);
    return false;
  }
}

bool InquireNoUnitState::Inquire(InquiryKeywordHash inquiry, bool &result) {
  switch (inquiry) {
  case HashInquiryKeyword("EXIST"):
    result = badUnitNumber() >= 0;
    return true;
  case HashInquiryKeyword("NAMED"):
  case HashInquiryKeyword("OPENED"):
  case HashInquiryKeyword("PENDING"):
    result = false;
    return true;
  default:
    BadInquiryKeywordHashCrash(inquiry);
    return false;
  }
}

bool InquireNoUnitState::Inquire(
    InquiryKeywordHash inquiry, std::int64_t, bool &result) {
  switch (inquiry) {
  case HashInquiryKeyword("PENDING"):
    result = false;
    return true;
  default:
    BadInquiryKeywordHashCrash(inquiry);
    return false;
  }
}

bool InquireNoUnitState::Inquire(
    InquiryKeywordHash inquiry, std::int64_t &result) {
  switch (inquiry) {
  case HashInquiryKeyword("NUMBER"):
    result = badUnitNumber();
    return true;
  case HashInquiryKeyword("NEXTREC"):
  case HashInquiryKeyword("POS"):
  case HashInquiryKeyword("RECL"):
  case HashInquiryKeyword("SIZE"):
    result = -1;
    return true;
  default:
    BadInquiryKeywordHashCrash(inquiry);
    return false;
  }
}

InquireUnconnectedFileState::InquireUnconnectedFileState(
    OwningPtr<char> &&path, const char *sourceFile, int sourceLine)
    : NoUnitIoStatementState{*this, sourceFile, sourceLine}, path_{std::move(
                                                                 path)} {}

bool InquireUnconnectedFileState::Inquire(
    InquiryKeywordHash inquiry, char *result, std::size_t length) {
  const char *str{nullptr};
  switch (inquiry) {
  case HashInquiryKeyword("ACCESS"):
  case HashInquiryKeyword("ACTION"):
  case HashInquiryKeyword("ASYNCHRONOUS"):
  case HashInquiryKeyword("BLANK"):
  case HashInquiryKeyword("CARRIAGECONTROL"):
  case HashInquiryKeyword("CONVERT"):
  case HashInquiryKeyword("DECIMAL"):
  case HashInquiryKeyword("DELIM"):
  case HashInquiryKeyword("FORM"):
  case HashInquiryKeyword("PAD"):
  case HashInquiryKeyword("POSITION"):
  case HashInquiryKeyword("ROUND"):
  case HashInquiryKeyword("SIGN"):
    str = "UNDEFINED";
    break;
  case HashInquiryKeyword("DIRECT"):
  case HashInquiryKeyword("ENCODING"):
  case HashInquiryKeyword("FORMATTED"):
  case HashInquiryKeyword("SEQUENTIAL"):
  case HashInquiryKeyword("STREAM"):
  case HashInquiryKeyword("UNFORMATTED"):
    str = "UNKNOWN";
    break;
  case HashInquiryKeyword("READ"):
    str =
        IsExtant(path_.get()) ? MayRead(path_.get()) ? "YES" : "NO" : "UNKNOWN";
    break;
  case HashInquiryKeyword("READWRITE"):
    str = IsExtant(path_.get()) ? MayReadAndWrite(path_.get()) ? "YES" : "NO"
                                : "UNKNOWN";
    break;
  case HashInquiryKeyword("WRITE"):
    str = IsExtant(path_.get()) ? MayWrite(path_.get()) ? "YES" : "NO"
                                : "UNKNOWN";
    break;
  case HashInquiryKeyword("NAME"):
    str = path_.get();
    if (!str) {
      return true; // result is undefined
    }
    break;
  }
  if (str) {
    ToFortranDefaultCharacter(result, length, str);
    return true;
  } else {
    BadInquiryKeywordHashCrash(inquiry);
    return false;
  }
}

bool InquireUnconnectedFileState::Inquire(
    InquiryKeywordHash inquiry, bool &result) {
  switch (inquiry) {
  case HashInquiryKeyword("EXIST"):
    result = IsExtant(path_.get());
    return true;
  case HashInquiryKeyword("NAMED"):
    result = true;
    return true;
  case HashInquiryKeyword("OPENED"):
    result = false;
    return true;
  case HashInquiryKeyword("PENDING"):
    result = false;
    return true;
  default:
    BadInquiryKeywordHashCrash(inquiry);
    return false;
  }
}

bool InquireUnconnectedFileState::Inquire(
    InquiryKeywordHash inquiry, std::int64_t, bool &result) {
  switch (inquiry) {
  case HashInquiryKeyword("PENDING"):
    result = false;
    return true;
  default:
    BadInquiryKeywordHashCrash(inquiry);
    return false;
  }
}

bool InquireUnconnectedFileState::Inquire(
    InquiryKeywordHash inquiry, std::int64_t &result) {
  switch (inquiry) {
  case HashInquiryKeyword("NEXTREC"):
  case HashInquiryKeyword("NUMBER"):
  case HashInquiryKeyword("POS"):
  case HashInquiryKeyword("RECL"):
    result = -1;
    return true;
  case HashInquiryKeyword("SIZE"):
    result = SizeInBytes(path_.get());
    return true;
  default:
    BadInquiryKeywordHashCrash(inquiry);
    return false;
  }
}

InquireIOLengthState::InquireIOLengthState(
    const char *sourceFile, int sourceLine)
    : NoUnitIoStatementState{*this, sourceFile, sourceLine} {}

bool InquireIOLengthState::Emit(const char *, std::size_t bytes, std::size_t) {
  bytes_ += bytes;
  return true;
}

int ErroneousIoStatementState::EndIoStatement() {
  SignalPendingError();
  if (unit_) {
    unit_->EndIoStatement();
  }
  return IoStatementBase::EndIoStatement();
}

RT_OFFLOAD_API_GROUP_END
} // namespace Fortran::runtime::io
