brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.4 KiB · ad6e79d Raw
98 lines · c
1//===-- lib/runtime/io-api-common.h -----------------------------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef FLANG_RT_RUNTIME_IO_API_COMMON_H_10#define FLANG_RT_RUNTIME_IO_API_COMMON_H_11 12#include "unit.h"13#include "flang-rt/runtime/io-stmt.h"14#include "flang-rt/runtime/terminator.h"15#include "flang/Common/api-attrs.h"16#include "flang/Common/optional.h"17#include "flang/Runtime/io-api.h"18 19namespace Fortran::runtime::io {20 21static inline RT_API_ATTRS Cookie NoopUnit(const Terminator &terminator,22    int unitNumber, enum Iostat iostat = IostatOk) {23  Cookie cookie{&New<NoopStatementState>{terminator}(24      terminator.sourceFileName(), terminator.sourceLine(), unitNumber)25                     .release()26                     ->ioStatementState()};27  if (iostat != IostatOk) {28    cookie->GetIoErrorHandler().SetPendingError(iostat);29  }30  return cookie;31}32 33static inline RT_API_ATTRS ExternalFileUnit *GetOrCreateUnit(int unitNumber,34    Direction direction, common::optional<bool> isUnformatted,35    const Terminator &terminator, Cookie &errorCookie) {36  IoErrorHandler handler{terminator};37  handler.HasIoStat();38  if (ExternalFileUnit *39      unit{ExternalFileUnit::LookUpOrCreateAnonymous(40          unitNumber, direction, isUnformatted, handler)}) {41    errorCookie = nullptr;42    return unit;43  } else {44    auto iostat{static_cast<enum Iostat>(handler.GetIoStat())};45    errorCookie = NoopUnit(terminator, unitNumber,46        iostat != IostatOk ? iostat : IostatBadUnitNumber);47    return nullptr;48  }49}50 51template <Direction DIR, template <Direction> class STATE, typename... A>52RT_API_ATTRS Cookie BeginExternalListIO(53    int unitNumber, const char *sourceFile, int sourceLine, A &&...xs) {54  Terminator terminator{sourceFile, sourceLine};55  Cookie errorCookie{nullptr};56  ExternalFileUnit *unit{GetOrCreateUnit(57      unitNumber, DIR, false /*!unformatted*/, terminator, errorCookie)};58  if (!unit) {59    return errorCookie;60  }61  if (!unit->isUnformatted.has_value()) {62    unit->isUnformatted = false;63  }64  Iostat iostat{IostatOk};65  if (*unit->isUnformatted) {66    iostat = IostatFormattedIoOnUnformattedUnit;67  }68  if (ChildIo * child{unit->GetChildIo()}) {69    if (iostat == IostatOk) {70      iostat = child->CheckFormattingAndDirection(false, DIR);71    }72    if (iostat == IostatOk) {73      return &child->BeginIoStatement<ChildListIoStatementState<DIR>>(74          *child, sourceFile, sourceLine);75    } else {76      return &child->BeginIoStatement<ErroneousIoStatementState>(77          iostat, nullptr /* no unit */, sourceFile, sourceLine);78    }79  } else {80    if (iostat == IostatOk && unit->access == Access::Direct) {81      iostat = IostatListIoOnDirectAccessUnit;82    }83    if (iostat == IostatOk) {84      iostat = unit->SetDirection(DIR);85    }86    if (iostat == IostatOk) {87      return &unit->BeginIoStatement<STATE<DIR>>(88          terminator, std::forward<A>(xs)..., *unit, sourceFile, sourceLine);89    } else {90      return &unit->BeginIoStatement<ErroneousIoStatementState>(91          terminator, iostat, unit, sourceFile, sourceLine);92    }93  }94}95 96} // namespace Fortran::runtime::io97#endif // FLANG_RT_RUNTIME_IO_API_COMMON_H_98