Expand Up
@@ -33,10 +33,12 @@ class UnitMap;
class ChildIo ;
class ExternalFileUnit ;
RT_OFFLOAD_VAR_GROUP_BEGIN
// Predefined file units.
extern ExternalFileUnit *defaultInput; // unit 5
extern ExternalFileUnit *defaultOutput; // unit 6
extern ExternalFileUnit *errorOutput; // unit 0 extension
extern RT_VAR_ATTRS ExternalFileUnit *defaultInput; // unit 5
extern RT_VAR_ATTRS ExternalFileUnit *defaultOutput; // unit 6
extern RT_VAR_ATTRS ExternalFileUnit *errorOutput; // unit 0 extension
RT_OFFLOAD_VAR_GROUP_END
#if defined(RT_USE_PSEUDO_FILE_UNIT)
// A flavor of OpenFile class that pretends to be a terminal,
Expand All
@@ -49,34 +51,36 @@ class PseudoOpenFile {
public:
using FileOffset = std::int64_t ;
const char *path () const { return nullptr ; }
std::size_t pathLength () const { return 0 ; }
void set_path (OwningPtr<char > &&, std::size_t bytes) {}
bool mayRead () const { return false ; }
bool mayWrite () const { return true ; }
bool mayPosition () const { return false ; }
bool mayAsynchronous () const { return false ; }
void set_mayAsynchronous (bool yes);
RT_API_ATTRS const char *path () const { return nullptr ; }
RT_API_ATTRS std::size_t pathLength () const { return 0 ; }
RT_API_ATTRS void set_path (OwningPtr<char > &&, std::size_t bytes) {}
RT_API_ATTRS bool mayRead () const { return false ; }
RT_API_ATTRS bool mayWrite () const { return true ; }
RT_API_ATTRS bool mayPosition () const { return false ; }
RT_API_ATTRS bool mayAsynchronous () const { return false ; }
RT_API_ATTRS void set_mayAsynchronous (bool yes);
// Pretend to be a terminal to force the output
// at the end of IO statement.
bool isTerminal () const { return true ; }
bool isWindowsTextFile () const { return false ; }
Fortran::common::optional<FileOffset> knownSize () const ;
bool IsConnected () const { return false ; }
void Open (OpenStatus, Fortran::common::optional<Action>, Position ,
IoErrorHandler &);
void Predefine (int fd) {}
void Close (CloseStatus, IoErrorHandler &);
std::size_t Read (FileOffset, char *, std::size_t minBytes,
RT_API_ATTRS bool isTerminal () const { return true ; }
RT_API_ATTRS bool isWindowsTextFile () const { return false ; }
RT_API_ATTRS Fortran::common::optional<FileOffset> knownSize () const ;
RT_API_ATTRS bool IsConnected () const { return false ; }
RT_API_ATTRS void Open (OpenStatus, Fortran::common::optional<Action>,
Position, IoErrorHandler &);
RT_API_ATTRS void Predefine (int fd) {}
RT_API_ATTRS void Close (CloseStatus, IoErrorHandler &);
RT_API_ATTRS std::size_t Read (FileOffset, char *, std::size_t minBytes,
std::size_t maxBytes, IoErrorHandler &);
std::size_t Write (FileOffset, const char *, std::size_t , IoErrorHandler &);
void Truncate (FileOffset, IoErrorHandler &);
int ReadAsynchronously (FileOffset, char *, std::size_t , IoErrorHandler &);
int WriteAsynchronously (
RT_API_ATTRS std::size_t Write (
FileOffset, const char *, std::size_t , IoErrorHandler &);
RT_API_ATTRS void Truncate (FileOffset, IoErrorHandler &);
RT_API_ATTRS int ReadAsynchronously (
FileOffset, char *, std::size_t , IoErrorHandler &);
RT_API_ATTRS int WriteAsynchronously (
FileOffset, const char *, std::size_t , IoErrorHandler &);
void Wait (int id, IoErrorHandler &);
void WaitAll (IoErrorHandler &);
Position InquirePosition () const ;
RT_API_ATTRS void Wait (int id, IoErrorHandler &);
RT_API_ATTRS void WaitAll (IoErrorHandler &);
RT_API_ATTRS Position InquirePosition () const ;
};
#endif // defined(RT_USE_PSEUDO_FILE_UNIT)
Expand All
@@ -95,44 +99,51 @@ class ExternalFileUnit : public ConnectionState,
public:
static constexpr int maxAsyncIds{64 * 16 };
explicit ExternalFileUnit (int unitNumber) : unitNumber_{unitNumber} {
explicit RT_API_ATTRS ExternalFileUnit (int unitNumber)
: unitNumber_{unitNumber} {
isUTF8 = executionEnvironment.defaultUTF8 ;
for (int j{0 }; 64 * j < maxAsyncIds; ++j) {
asyncIdAvailable_[j].set ();
}
asyncIdAvailable_[0 ].reset (0 );
}
~ExternalFileUnit () {}
RT_API_ATTRS ~ExternalFileUnit () {}
int unitNumber () const { return unitNumber_; }
bool swapEndianness () const { return swapEndianness_; }
bool createdForInternalChildIo () const { return createdForInternalChildIo_; }
RT_API_ATTRS int unitNumber () const { return unitNumber_; }
RT_API_ATTRS bool swapEndianness () const { return swapEndianness_; }
RT_API_ATTRS bool createdForInternalChildIo () const {
return createdForInternalChildIo_;
}
static ExternalFileUnit *LookUp (int unit);
static ExternalFileUnit *LookUpOrCreate (
static RT_API_ATTRS ExternalFileUnit *LookUp (int unit);
static RT_API_ATTRS ExternalFileUnit *LookUpOrCreate (
int unit, const Terminator &, bool &wasExtant);
static ExternalFileUnit *LookUpOrCreateAnonymous (int unit, Direction,
Fortran::common::optional<bool > isUnformatted, const Terminator &);
static ExternalFileUnit *LookUp (const char *path, std::size_t pathLen);
static ExternalFileUnit &CreateNew (int unit, const Terminator &);
static ExternalFileUnit *LookUpForClose (int unit);
static ExternalFileUnit &NewUnit (const Terminator &, bool forChildIo);
static void CloseAll (IoErrorHandler &);
static void FlushAll (IoErrorHandler &);
static RT_API_ATTRS ExternalFileUnit *LookUpOrCreateAnonymous (int unit,
Direction, Fortran::common::optional<bool > isUnformatted,
const Terminator &);
static RT_API_ATTRS ExternalFileUnit *LookUp (
const char *path, std::size_t pathLen);
static RT_API_ATTRS ExternalFileUnit &CreateNew (int unit, const Terminator &);
static RT_API_ATTRS ExternalFileUnit *LookUpForClose (int unit);
static RT_API_ATTRS ExternalFileUnit &NewUnit (
const Terminator &, bool forChildIo);
static RT_API_ATTRS void CloseAll (IoErrorHandler &);
static RT_API_ATTRS void FlushAll (IoErrorHandler &);
// Returns true if an existing unit was closed
bool OpenUnit (Fortran::common::optional<OpenStatus>,
RT_API_ATTRS bool OpenUnit (Fortran::common::optional<OpenStatus>,
Fortran::common::optional<Action>, Position, OwningPtr<char > &&path,
std::size_t pathLength, Convert, IoErrorHandler &);
void OpenAnonymousUnit (Fortran::common::optional<OpenStatus>,
RT_API_ATTRS void OpenAnonymousUnit (Fortran::common::optional<OpenStatus>,
Fortran::common::optional<Action>, Position, Convert, IoErrorHandler &);
void CloseUnit (CloseStatus, IoErrorHandler &);
void DestroyClosed ();
RT_API_ATTRS void CloseUnit (CloseStatus, IoErrorHandler &);
RT_API_ATTRS void DestroyClosed ();
Iostat SetDirection (Direction);
RT_API_ATTRS Iostat SetDirection (Direction);
template <typename A, typename ... X>
IoStatementState &BeginIoStatement (const Terminator &terminator, X &&...xs) {
RT_API_ATTRS IoStatementState &BeginIoStatement (
const Terminator &terminator, X &&...xs) {
// Take lock_ and hold it until EndIoStatement().
#if USE_PTHREADS
if (!lock_.TakeIfNoDeadlock ()) {
Expand All
@@ -141,7 +152,10 @@ class ExternalFileUnit : public ConnectionState,
#else
lock_.Take ();
#endif
RT_DIAG_PUSH
RT_DIAG_DISABLE_CALL_HOST_FROM_DEVICE_WARN
A &state{u_.emplace <A>(std::forward<X>(xs)...)};
RT_DIAG_POP
if constexpr (!std::is_same_v<A, OpenStatementState>) {
state.mutableModes () = ConnectionState::modes;
}
Expand All
@@ -150,50 +164,54 @@ class ExternalFileUnit : public ConnectionState,
return *io_;
}
bool Emit (
RT_API_ATTRS bool Emit (
const char *, std::size_t , std::size_t elementBytes, IoErrorHandler &);
bool Receive (char *, std::size_t , std::size_t elementBytes, IoErrorHandler &);
std::size_t GetNextInputBytes (const char *&, IoErrorHandler &);
bool BeginReadingRecord (IoErrorHandler &);
void FinishReadingRecord (IoErrorHandler &);
bool AdvanceRecord (IoErrorHandler &);
void BackspaceRecord (IoErrorHandler &);
void FlushOutput (IoErrorHandler &);
void FlushIfTerminal (IoErrorHandler &);
void Endfile (IoErrorHandler &);
void Rewind (IoErrorHandler &);
void EndIoStatement ();
bool SetStreamPos (std::int64_t , IoErrorHandler &); // one-based, for POS=
bool SetDirectRec (std::int64_t , IoErrorHandler &); // one-based, for REC=
std::int64_t InquirePos () const {
RT_API_ATTRS bool Receive (
char *, std::size_t , std::size_t elementBytes, IoErrorHandler &);
RT_API_ATTRS std::size_t GetNextInputBytes (const char *&, IoErrorHandler &);
RT_API_ATTRS bool BeginReadingRecord (IoErrorHandler &);
RT_API_ATTRS void FinishReadingRecord (IoErrorHandler &);
RT_API_ATTRS bool AdvanceRecord (IoErrorHandler &);
RT_API_ATTRS void BackspaceRecord (IoErrorHandler &);
RT_API_ATTRS void FlushOutput (IoErrorHandler &);
RT_API_ATTRS void FlushIfTerminal (IoErrorHandler &);
RT_API_ATTRS void Endfile (IoErrorHandler &);
RT_API_ATTRS void Rewind (IoErrorHandler &);
RT_API_ATTRS void EndIoStatement ();
RT_API_ATTRS bool SetStreamPos (
std::int64_t , IoErrorHandler &); // one-based, for POS=
RT_API_ATTRS bool SetDirectRec (
std::int64_t , IoErrorHandler &); // one-based, for REC=
RT_API_ATTRS std::int64_t InquirePos () const {
// 12.6.2.11 defines POS=1 as the beginning of file
return frameOffsetInFile_ + recordOffsetInFrame_ + positionInRecord + 1 ;
}
ChildIo *GetChildIo () { return child_.get (); }
ChildIo &PushChildIo (IoStatementState &);
void PopChildIo (ChildIo &);
RT_API_ATTRS ChildIo *GetChildIo () { return child_.get (); }
RT_API_ATTRS ChildIo &PushChildIo (IoStatementState &);
RT_API_ATTRS void PopChildIo (ChildIo &);
int GetAsynchronousId (IoErrorHandler &);
bool Wait (int );
RT_API_ATTRS int GetAsynchronousId (IoErrorHandler &);
RT_API_ATTRS bool Wait (int );
private:
static UnitMap &CreateUnitMap ();
static UnitMap &GetUnitMap ();
const char *FrameNextInput (IoErrorHandler &, std::size_t );
void SetPosition (std::int64_t , IoErrorHandler &); // zero-based
void BeginSequentialVariableUnformattedInputRecord (IoErrorHandler &);
void BeginVariableFormattedInputRecord (IoErrorHandler &);
void BackspaceFixedRecord (IoErrorHandler &);
void BackspaceVariableUnformattedRecord (IoErrorHandler &);
void BackspaceVariableFormattedRecord (IoErrorHandler &);
bool SetVariableFormattedRecordLength ();
void DoImpliedEndfile (IoErrorHandler &);
void DoEndfile (IoErrorHandler &);
void CommitWrites ();
bool CheckDirectAccess (IoErrorHandler &);
void HitEndOnRead (IoErrorHandler &);
std::int32_t ReadHeaderOrFooter (std::int64_t frameOffset);
static RT_API_ATTRS UnitMap &CreateUnitMap ();
static RT_API_ATTRS UnitMap &GetUnitMap ();
RT_API_ATTRS const char *FrameNextInput (IoErrorHandler &, std::size_t );
RT_API_ATTRS void SetPosition (std::int64_t , IoErrorHandler &); // zero-based
RT_API_ATTRS void BeginSequentialVariableUnformattedInputRecord (
IoErrorHandler &);
RT_API_ATTRS void BeginVariableFormattedInputRecord (IoErrorHandler &);
RT_API_ATTRS void BackspaceFixedRecord (IoErrorHandler &);
RT_API_ATTRS void BackspaceVariableUnformattedRecord (IoErrorHandler &);
RT_API_ATTRS void BackspaceVariableFormattedRecord (IoErrorHandler &);
RT_API_ATTRS bool SetVariableFormattedRecordLength ();
RT_API_ATTRS void DoImpliedEndfile (IoErrorHandler &);
RT_API_ATTRS void DoEndfile (IoErrorHandler &);
RT_API_ATTRS void CommitWrites ();
RT_API_ATTRS bool CheckDirectAccess (IoErrorHandler &);
RT_API_ATTRS void HitEndOnRead (IoErrorHandler &);
RT_API_ATTRS std::int32_t ReadHeaderOrFooter (std::int64_t frameOffset);
Lock lock_;
Expand Down
Expand Up
@@ -238,23 +256,28 @@ class ExternalFileUnit : public ConnectionState,
// be a child I/O statement.
class ChildIo {
public:
ChildIo (IoStatementState &parent, OwningPtr<ChildIo> &&previous)
RT_API_ATTRS ChildIo (IoStatementState &parent, OwningPtr<ChildIo> &&previous)
: parent_{parent}, previous_{std::move (previous)} {}
IoStatementState &parent () const { return parent_; }
RT_API_ATTRS IoStatementState &parent () const { return parent_; }
void EndIoStatement ();
RT_API_ATTRS void EndIoStatement ();
template <typename A, typename ... X>
IoStatementState &BeginIoStatement (X &&...xs) {
RT_API_ATTRS IoStatementState &BeginIoStatement (X &&...xs) {
RT_DIAG_PUSH
RT_DIAG_DISABLE_CALL_HOST_FROM_DEVICE_WARN
A &state{u_.emplace <A>(std::forward<X>(xs)...)};
RT_DIAG_POP
io_.emplace (state);
return *io_;
}
OwningPtr<ChildIo> AcquirePrevious () { return std::move (previous_); }
RT_API_ATTRS OwningPtr<ChildIo> AcquirePrevious () {
return std::move (previous_);
}
Iostat CheckFormattingAndDirection (bool unformatted, Direction);
RT_API_ATTRS Iostat CheckFormattingAndDirection (bool unformatted, Direction);
private:
IoStatementState &parent_;
Expand Down