2020-07-05 05:24:32 +08:00
|
|
|
// Sanity test for all external I/O modes
|
|
|
|
|
|
|
|
#include "testing.h"
|
|
|
|
#include "../../runtime/io-api.h"
|
|
|
|
#include "../../runtime/main.h"
|
|
|
|
#include "../../runtime/stop.h"
|
|
|
|
#include "llvm/Support/raw_ostream.h"
|
|
|
|
#include <cstring>
|
|
|
|
|
|
|
|
using namespace Fortran::runtime::io;
|
|
|
|
|
|
|
|
void TestDirectUnformatted() {
|
|
|
|
llvm::errs() << "begin TestDirectUnformatted()\n";
|
|
|
|
// OPEN(NEWUNIT=unit,ACCESS='DIRECT',ACTION='READWRITE',&
|
|
|
|
// FORM='UNFORMATTED',RECL=8,STATUS='SCRATCH')
|
|
|
|
auto io{IONAME(BeginOpenNewUnit)(__FILE__, __LINE__)};
|
|
|
|
IONAME(SetAccess)(io, "DIRECT", 6) || (Fail() << "SetAccess(DIRECT)", 0);
|
|
|
|
IONAME(SetAction)
|
|
|
|
(io, "READWRITE", 9) || (Fail() << "SetAction(READWRITE)", 0);
|
|
|
|
IONAME(SetForm)
|
|
|
|
(io, "UNFORMATTED", 11) || (Fail() << "SetForm(UNFORMATTED)", 0);
|
|
|
|
std::int64_t buffer;
|
|
|
|
static constexpr std::size_t recl{sizeof buffer};
|
|
|
|
IONAME(SetRecl)(io, recl) || (Fail() << "SetRecl()", 0);
|
|
|
|
IONAME(SetStatus)(io, "SCRATCH", 7) || (Fail() << "SetStatus(SCRATCH)", 0);
|
|
|
|
int unit{-1};
|
|
|
|
IONAME(GetNewUnit)(io, unit) || (Fail() << "GetNewUnit()", 0);
|
|
|
|
llvm::errs() << "unit=" << unit << '\n';
|
|
|
|
IONAME(EndIoStatement)
|
|
|
|
(io) == IostatOk || (Fail() << "EndIoStatement() for OpenNewUnit", 0);
|
|
|
|
static constexpr int records{10};
|
|
|
|
for (int j{1}; j <= records; ++j) {
|
|
|
|
// WRITE(UNIT=unit,REC=j) j
|
|
|
|
io = IONAME(BeginUnformattedOutput)(unit, __FILE__, __LINE__);
|
|
|
|
IONAME(SetRec)(io, j) || (Fail() << "SetRec(" << j << ')', 0);
|
|
|
|
buffer = j;
|
|
|
|
IONAME(OutputUnformattedBlock)
|
2020-07-22 08:37:35 +08:00
|
|
|
(io, reinterpret_cast<const char *>(&buffer), recl, recl) ||
|
2020-07-05 05:24:32 +08:00
|
|
|
(Fail() << "OutputUnformattedBlock()", 0);
|
|
|
|
IONAME(EndIoStatement)
|
|
|
|
(io) == IostatOk ||
|
|
|
|
(Fail() << "EndIoStatement() for OutputUnformattedBlock", 0);
|
|
|
|
}
|
|
|
|
for (int j{records}; j >= 1; --j) {
|
|
|
|
// READ(UNIT=unit,REC=j) n
|
|
|
|
io = IONAME(BeginUnformattedInput)(unit, __FILE__, __LINE__);
|
|
|
|
IONAME(SetRec)
|
|
|
|
(io, j) || (Fail() << "SetRec(" << j << ')', 0);
|
|
|
|
IONAME(InputUnformattedBlock)
|
2020-07-22 08:37:35 +08:00
|
|
|
(io, reinterpret_cast<char *>(&buffer), recl, recl) ||
|
2020-07-05 05:24:32 +08:00
|
|
|
(Fail() << "InputUnformattedBlock()", 0);
|
|
|
|
IONAME(EndIoStatement)
|
|
|
|
(io) == IostatOk ||
|
|
|
|
(Fail() << "EndIoStatement() for InputUnformattedBlock", 0);
|
|
|
|
if (buffer != j) {
|
|
|
|
Fail() << "Read back " << buffer << " from direct unformatted record "
|
|
|
|
<< j << ", expected " << j << '\n';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// CLOSE(UNIT=unit,STATUS='DELETE')
|
|
|
|
io = IONAME(BeginClose)(unit, __FILE__, __LINE__);
|
|
|
|
IONAME(SetStatus)(io, "DELETE", 6) || (Fail() << "SetStatus(DELETE)", 0);
|
|
|
|
IONAME(EndIoStatement)
|
|
|
|
(io) == IostatOk || (Fail() << "EndIoStatement() for Close", 0);
|
|
|
|
llvm::errs() << "end TestDirectUnformatted()\n";
|
|
|
|
}
|
|
|
|
|
2020-07-22 08:37:35 +08:00
|
|
|
void TestDirectUnformattedSwapped() {
|
|
|
|
llvm::errs() << "begin TestDirectUnformattedSwapped()\n";
|
|
|
|
// OPEN(NEWUNIT=unit,ACCESS='DIRECT',ACTION='READWRITE',&
|
|
|
|
// FORM='UNFORMATTED',RECL=8,STATUS='SCRATCH',CONVERT='NATIVE')
|
|
|
|
auto io{IONAME(BeginOpenNewUnit)(__FILE__, __LINE__)};
|
|
|
|
IONAME(SetAccess)(io, "DIRECT", 6) || (Fail() << "SetAccess(DIRECT)", 0);
|
|
|
|
IONAME(SetAction)
|
|
|
|
(io, "READWRITE", 9) || (Fail() << "SetAction(READWRITE)", 0);
|
|
|
|
IONAME(SetForm)
|
|
|
|
(io, "UNFORMATTED", 11) || (Fail() << "SetForm(UNFORMATTED)", 0);
|
|
|
|
IONAME(SetConvert)
|
|
|
|
(io, "NATIVE", 6) || (Fail() << "SetConvert(NATIVE)", 0);
|
|
|
|
std::int64_t buffer;
|
|
|
|
static constexpr std::size_t recl{sizeof buffer};
|
|
|
|
IONAME(SetRecl)(io, recl) || (Fail() << "SetRecl()", 0);
|
|
|
|
IONAME(SetStatus)(io, "SCRATCH", 7) || (Fail() << "SetStatus(SCRATCH)", 0);
|
|
|
|
int unit{-1};
|
|
|
|
IONAME(GetNewUnit)(io, unit) || (Fail() << "GetNewUnit()", 0);
|
|
|
|
llvm::errs() << "unit=" << unit << '\n';
|
|
|
|
IONAME(EndIoStatement)
|
|
|
|
(io) == IostatOk || (Fail() << "EndIoStatement() for OpenNewUnit", 0);
|
|
|
|
static constexpr int records{10};
|
|
|
|
for (int j{1}; j <= records; ++j) {
|
|
|
|
// WRITE(UNIT=unit,REC=j) j
|
|
|
|
io = IONAME(BeginUnformattedOutput)(unit, __FILE__, __LINE__);
|
|
|
|
IONAME(SetRec)(io, j) || (Fail() << "SetRec(" << j << ')', 0);
|
|
|
|
buffer = j;
|
|
|
|
IONAME(OutputUnformattedBlock)
|
|
|
|
(io, reinterpret_cast<const char *>(&buffer), recl, recl) ||
|
|
|
|
(Fail() << "OutputUnformattedBlock()", 0);
|
|
|
|
IONAME(EndIoStatement)
|
|
|
|
(io) == IostatOk ||
|
|
|
|
(Fail() << "EndIoStatement() for OutputUnformattedBlock", 0);
|
|
|
|
}
|
|
|
|
// OPEN(UNIT=unit,STATUS='OLD',CONVERT='SWAP')
|
|
|
|
io = IONAME(BeginOpenUnit)(unit, __FILE__, __LINE__);
|
|
|
|
IONAME(SetStatus)(io, "OLD", 3) || (Fail() << "SetStatus(OLD)", 0);
|
|
|
|
IONAME(SetConvert)
|
|
|
|
(io, "SWAP", 4) || (Fail() << "SetConvert(SWAP)", 0);
|
|
|
|
IONAME(EndIoStatement)
|
|
|
|
(io) == IostatOk || (Fail() << "EndIoStatement() for OpenUnit", 0);
|
|
|
|
for (int j{records}; j >= 1; --j) {
|
|
|
|
// READ(UNIT=unit,REC=j) n
|
|
|
|
io = IONAME(BeginUnformattedInput)(unit, __FILE__, __LINE__);
|
|
|
|
IONAME(SetRec)
|
|
|
|
(io, j) || (Fail() << "SetRec(" << j << ')', 0);
|
|
|
|
IONAME(InputUnformattedBlock)
|
|
|
|
(io, reinterpret_cast<char *>(&buffer), recl, recl) ||
|
|
|
|
(Fail() << "InputUnformattedBlock()", 0);
|
|
|
|
IONAME(EndIoStatement)
|
|
|
|
(io) == IostatOk ||
|
|
|
|
(Fail() << "EndIoStatement() for InputUnformattedBlock", 0);
|
|
|
|
if (buffer >> 56 != j) {
|
|
|
|
Fail() << "Read back " << (buffer >> 56)
|
|
|
|
<< " from direct unformatted record " << j << ", expected " << j
|
|
|
|
<< '\n';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// CLOSE(UNIT=unit,STATUS='DELETE')
|
|
|
|
io = IONAME(BeginClose)(unit, __FILE__, __LINE__);
|
|
|
|
IONAME(SetStatus)(io, "DELETE", 6) || (Fail() << "SetStatus(DELETE)", 0);
|
|
|
|
IONAME(EndIoStatement)
|
|
|
|
(io) == IostatOk || (Fail() << "EndIoStatement() for Close", 0);
|
|
|
|
llvm::errs() << "end TestDirectUnformatted()\n";
|
|
|
|
}
|
|
|
|
|
2020-07-05 05:24:32 +08:00
|
|
|
void TestSequentialFixedUnformatted() {
|
|
|
|
llvm::errs() << "begin TestSequentialFixedUnformatted()\n";
|
|
|
|
// OPEN(NEWUNIT=unit,ACCESS='SEQUENTIAL',ACTION='READWRITE',&
|
|
|
|
// FORM='UNFORMATTED',RECL=8,STATUS='SCRATCH')
|
|
|
|
auto io{IONAME(BeginOpenNewUnit)(__FILE__, __LINE__)};
|
|
|
|
IONAME(SetAccess)
|
2020-08-07 07:56:14 +08:00
|
|
|
(io, "SEQUENTIAL", 10) || (Fail() << "SetAccess(SEQUENTIAL)", 0);
|
2020-07-05 05:24:32 +08:00
|
|
|
IONAME(SetAction)
|
|
|
|
(io, "READWRITE", 9) || (Fail() << "SetAction(READWRITE)", 0);
|
|
|
|
IONAME(SetForm)
|
|
|
|
(io, "UNFORMATTED", 11) || (Fail() << "SetForm(UNFORMATTED)", 0);
|
|
|
|
std::int64_t buffer;
|
|
|
|
static constexpr std::size_t recl{sizeof buffer};
|
|
|
|
IONAME(SetRecl)(io, recl) || (Fail() << "SetRecl()", 0);
|
|
|
|
IONAME(SetStatus)(io, "SCRATCH", 7) || (Fail() << "SetStatus(SCRATCH)", 0);
|
|
|
|
int unit{-1};
|
|
|
|
IONAME(GetNewUnit)(io, unit) || (Fail() << "GetNewUnit()", 0);
|
|
|
|
llvm::errs() << "unit=" << unit << '\n';
|
|
|
|
IONAME(EndIoStatement)
|
|
|
|
(io) == IostatOk || (Fail() << "EndIoStatement() for OpenNewUnit", 0);
|
|
|
|
static const int records{10};
|
|
|
|
for (int j{1}; j <= records; ++j) {
|
|
|
|
// DO J=1,RECORDS; WRITE(UNIT=unit) j; END DO
|
|
|
|
io = IONAME(BeginUnformattedOutput)(unit, __FILE__, __LINE__);
|
|
|
|
buffer = j;
|
|
|
|
IONAME(OutputUnformattedBlock)
|
2020-07-22 08:37:35 +08:00
|
|
|
(io, reinterpret_cast<const char *>(&buffer), recl, recl) ||
|
2020-07-05 05:24:32 +08:00
|
|
|
(Fail() << "OutputUnformattedBlock()", 0);
|
|
|
|
IONAME(EndIoStatement)
|
|
|
|
(io) == IostatOk ||
|
|
|
|
(Fail() << "EndIoStatement() for OutputUnformattedBlock", 0);
|
|
|
|
}
|
|
|
|
// REWIND(UNIT=unit)
|
|
|
|
io = IONAME(BeginRewind)(unit, __FILE__, __LINE__);
|
|
|
|
IONAME(EndIoStatement)
|
|
|
|
(io) == IostatOk || (Fail() << "EndIoStatement() for Rewind", 0);
|
|
|
|
for (int j{1}; j <= records; ++j) {
|
|
|
|
// DO J=1,RECORDS; READ(UNIT=unit) n; check n; END DO
|
|
|
|
io = IONAME(BeginUnformattedInput)(unit, __FILE__, __LINE__);
|
|
|
|
IONAME(InputUnformattedBlock)
|
2020-07-22 08:37:35 +08:00
|
|
|
(io, reinterpret_cast<char *>(&buffer), recl, recl) ||
|
2020-07-05 05:24:32 +08:00
|
|
|
(Fail() << "InputUnformattedBlock()", 0);
|
|
|
|
IONAME(EndIoStatement)
|
|
|
|
(io) == IostatOk ||
|
|
|
|
(Fail() << "EndIoStatement() for InputUnformattedBlock", 0);
|
|
|
|
if (buffer != j) {
|
|
|
|
Fail() << "Read back " << buffer
|
|
|
|
<< " from sequential fixed unformatted record " << j
|
|
|
|
<< ", expected " << j << '\n';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (int j{records}; j >= 1; --j) {
|
|
|
|
// BACKSPACE(UNIT=unit)
|
|
|
|
io = IONAME(BeginBackspace)(unit, __FILE__, __LINE__);
|
|
|
|
IONAME(EndIoStatement)
|
|
|
|
(io) == IostatOk ||
|
|
|
|
(Fail() << "EndIoStatement() for Backspace (before read)", 0);
|
|
|
|
// READ(UNIT=unit) n
|
|
|
|
io = IONAME(BeginUnformattedInput)(unit, __FILE__, __LINE__);
|
|
|
|
IONAME(InputUnformattedBlock)
|
2020-07-22 08:37:35 +08:00
|
|
|
(io, reinterpret_cast<char *>(&buffer), recl, recl) ||
|
2020-07-05 05:24:32 +08:00
|
|
|
(Fail() << "InputUnformattedBlock()", 0);
|
|
|
|
IONAME(EndIoStatement)
|
|
|
|
(io) == IostatOk ||
|
|
|
|
(Fail() << "EndIoStatement() for InputUnformattedBlock", 0);
|
|
|
|
if (buffer != j) {
|
|
|
|
Fail() << "Read back " << buffer
|
|
|
|
<< " from sequential fixed unformatted record " << j
|
|
|
|
<< " after backspacing, expected " << j << '\n';
|
|
|
|
}
|
|
|
|
// BACKSPACE(UNIT=unit)
|
|
|
|
io = IONAME(BeginBackspace)(unit, __FILE__, __LINE__);
|
|
|
|
IONAME(EndIoStatement)
|
|
|
|
(io) == IostatOk ||
|
|
|
|
(Fail() << "EndIoStatement() for Backspace (after read)", 0);
|
|
|
|
}
|
|
|
|
// CLOSE(UNIT=unit,STATUS='DELETE')
|
|
|
|
io = IONAME(BeginClose)(unit, __FILE__, __LINE__);
|
|
|
|
IONAME(SetStatus)(io, "DELETE", 6) || (Fail() << "SetStatus(DELETE)", 0);
|
|
|
|
IONAME(EndIoStatement)
|
|
|
|
(io) == IostatOk || (Fail() << "EndIoStatement() for Close", 0);
|
|
|
|
llvm::errs() << "end TestSequentialFixedUnformatted()\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
void TestSequentialVariableUnformatted() {
|
|
|
|
llvm::errs() << "begin TestSequentialVariableUnformatted()\n";
|
|
|
|
// OPEN(NEWUNIT=unit,ACCESS='SEQUENTIAL',ACTION='READWRITE',&
|
|
|
|
// FORM='UNFORMATTED',STATUS='SCRATCH')
|
|
|
|
auto io{IONAME(BeginOpenNewUnit)(__FILE__, __LINE__)};
|
|
|
|
IONAME(SetAccess)
|
|
|
|
(io, "SEQUENTIAL", 10) || (Fail() << "SetAccess(SEQUENTIAL)", 0);
|
|
|
|
IONAME(SetAction)
|
|
|
|
(io, "READWRITE", 9) || (Fail() << "SetAction(READWRITE)", 0);
|
|
|
|
IONAME(SetForm)
|
|
|
|
(io, "UNFORMATTED", 11) || (Fail() << "SetForm(UNFORMATTED)", 0);
|
|
|
|
IONAME(SetStatus)(io, "SCRATCH", 7) || (Fail() << "SetStatus(SCRATCH)", 0);
|
|
|
|
int unit{-1};
|
|
|
|
IONAME(GetNewUnit)(io, unit) || (Fail() << "GetNewUnit()", 0);
|
|
|
|
llvm::errs() << "unit=" << unit << '\n';
|
|
|
|
IONAME(EndIoStatement)
|
|
|
|
(io) == IostatOk || (Fail() << "EndIoStatement() for OpenNewUnit", 0);
|
|
|
|
static const int records{10};
|
|
|
|
std::int64_t buffer[records]; // INTEGER*8 :: BUFFER(0:9) = [(j,j=0,9)]
|
|
|
|
for (int j{0}; j < records; ++j) {
|
|
|
|
buffer[j] = j;
|
|
|
|
}
|
|
|
|
for (int j{1}; j <= records; ++j) {
|
|
|
|
// DO J=1,RECORDS; WRITE(UNIT=unit) BUFFER(0:j); END DO
|
|
|
|
io = IONAME(BeginUnformattedOutput)(unit, __FILE__, __LINE__);
|
|
|
|
IONAME(OutputUnformattedBlock)
|
2020-07-22 08:37:35 +08:00
|
|
|
(io, reinterpret_cast<const char *>(&buffer), j * sizeof *buffer,
|
|
|
|
sizeof *buffer) ||
|
2020-07-05 05:24:32 +08:00
|
|
|
(Fail() << "OutputUnformattedBlock()", 0);
|
|
|
|
IONAME(EndIoStatement)
|
|
|
|
(io) == IostatOk ||
|
|
|
|
(Fail() << "EndIoStatement() for OutputUnformattedBlock", 0);
|
|
|
|
}
|
|
|
|
// REWIND(UNIT=unit)
|
|
|
|
io = IONAME(BeginRewind)(unit, __FILE__, __LINE__);
|
|
|
|
IONAME(EndIoStatement)
|
|
|
|
(io) == IostatOk || (Fail() << "EndIoStatement() for Rewind", 0);
|
|
|
|
for (int j{1}; j <= records; ++j) {
|
|
|
|
// DO J=1,RECORDS; READ(UNIT=unit) n; check n; END DO
|
|
|
|
io = IONAME(BeginUnformattedInput)(unit, __FILE__, __LINE__);
|
|
|
|
IONAME(InputUnformattedBlock)
|
2020-07-22 08:37:35 +08:00
|
|
|
(io, reinterpret_cast<char *>(&buffer), j * sizeof *buffer,
|
|
|
|
sizeof *buffer) ||
|
2020-07-05 05:24:32 +08:00
|
|
|
(Fail() << "InputUnformattedBlock()", 0);
|
|
|
|
IONAME(EndIoStatement)
|
|
|
|
(io) == IostatOk ||
|
|
|
|
(Fail() << "EndIoStatement() for InputUnformattedBlock", 0);
|
|
|
|
for (int k{0}; k < j; ++k) {
|
|
|
|
if (buffer[k] != k) {
|
|
|
|
Fail() << "Read back [" << k << "]=" << buffer[k]
|
|
|
|
<< " from direct unformatted record " << j << ", expected " << k
|
|
|
|
<< '\n';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (int j{records}; j >= 1; --j) {
|
|
|
|
// BACKSPACE(unit)
|
|
|
|
io = IONAME(BeginBackspace)(unit, __FILE__, __LINE__);
|
|
|
|
IONAME(EndIoStatement)
|
|
|
|
(io) == IostatOk ||
|
|
|
|
(Fail() << "EndIoStatement() for Backspace (before read)", 0);
|
|
|
|
// READ(unit=unit) n; check
|
|
|
|
io = IONAME(BeginUnformattedInput)(unit, __FILE__, __LINE__);
|
|
|
|
IONAME(InputUnformattedBlock)
|
2020-07-22 08:37:35 +08:00
|
|
|
(io, reinterpret_cast<char *>(&buffer), j * sizeof *buffer,
|
|
|
|
sizeof *buffer) ||
|
2020-07-05 05:24:32 +08:00
|
|
|
(Fail() << "InputUnformattedBlock()", 0);
|
|
|
|
IONAME(EndIoStatement)
|
|
|
|
(io) == IostatOk ||
|
|
|
|
(Fail() << "EndIoStatement() for InputUnformattedBlock", 0);
|
|
|
|
for (int k{0}; k < j; ++k) {
|
|
|
|
if (buffer[k] != k) {
|
|
|
|
Fail() << "Read back [" << k << "]=" << buffer[k]
|
|
|
|
<< " from sequential variable unformatted record " << j
|
|
|
|
<< ", expected " << k << '\n';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// BACKSPACE(unit)
|
|
|
|
io = IONAME(BeginBackspace)(unit, __FILE__, __LINE__);
|
|
|
|
IONAME(EndIoStatement)
|
|
|
|
(io) == IostatOk ||
|
|
|
|
(Fail() << "EndIoStatement() for Backspace (after read)", 0);
|
|
|
|
}
|
|
|
|
// CLOSE(UNIT=unit,STATUS='DELETE')
|
|
|
|
io = IONAME(BeginClose)(unit, __FILE__, __LINE__);
|
|
|
|
IONAME(SetStatus)(io, "DELETE", 6) || (Fail() << "SetStatus(DELETE)", 0);
|
|
|
|
IONAME(EndIoStatement)
|
|
|
|
(io) == IostatOk || (Fail() << "EndIoStatement() for Close", 0);
|
|
|
|
llvm::errs() << "end TestSequentialVariableUnformatted()\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
void TestDirectFormatted() {
|
|
|
|
llvm::errs() << "begin TestDirectFormatted()\n";
|
|
|
|
// OPEN(NEWUNIT=unit,ACCESS='DIRECT',ACTION='READWRITE',&
|
|
|
|
// FORM='FORMATTED',RECL=8,STATUS='SCRATCH')
|
|
|
|
auto io{IONAME(BeginOpenNewUnit)(__FILE__, __LINE__)};
|
|
|
|
IONAME(SetAccess)(io, "DIRECT", 6) || (Fail() << "SetAccess(DIRECT)", 0);
|
|
|
|
IONAME(SetAction)
|
|
|
|
(io, "READWRITE", 9) || (Fail() << "SetAction(READWRITE)", 0);
|
|
|
|
IONAME(SetForm)
|
|
|
|
(io, "FORMATTED", 9) || (Fail() << "SetForm(FORMATTED)", 0);
|
|
|
|
static constexpr std::size_t recl{8};
|
|
|
|
IONAME(SetRecl)(io, recl) || (Fail() << "SetRecl()", 0);
|
|
|
|
IONAME(SetStatus)(io, "SCRATCH", 7) || (Fail() << "SetStatus(SCRATCH)", 0);
|
|
|
|
int unit{-1};
|
|
|
|
IONAME(GetNewUnit)(io, unit) || (Fail() << "GetNewUnit()", 0);
|
|
|
|
llvm::errs() << "unit=" << unit << '\n';
|
|
|
|
IONAME(EndIoStatement)
|
|
|
|
(io) == IostatOk || (Fail() << "EndIoStatement() for OpenNewUnit", 0);
|
|
|
|
static constexpr int records{10};
|
|
|
|
static const char fmt[]{"(I4)"};
|
|
|
|
for (int j{1}; j <= records; ++j) {
|
|
|
|
// WRITE(UNIT=unit,FMT=fmt,REC=j) j
|
|
|
|
io = IONAME(BeginExternalFormattedOutput)(
|
|
|
|
fmt, sizeof fmt - 1, unit, __FILE__, __LINE__);
|
|
|
|
IONAME(SetRec)(io, j) || (Fail() << "SetRec(" << j << ')', 0);
|
|
|
|
IONAME(OutputInteger64)(io, j) || (Fail() << "OutputInteger64()", 0);
|
|
|
|
IONAME(EndIoStatement)
|
|
|
|
(io) == IostatOk || (Fail() << "EndIoStatement() for OutputInteger64", 0);
|
|
|
|
}
|
|
|
|
for (int j{records}; j >= 1; --j) {
|
|
|
|
// READ(UNIT=unit,FMT=fmt,REC=j) n
|
|
|
|
io = IONAME(BeginExternalFormattedInput)(
|
|
|
|
fmt, sizeof fmt - 1, unit, __FILE__, __LINE__);
|
|
|
|
IONAME(SetRec)(io, j) || (Fail() << "SetRec(" << j << ')', 0);
|
|
|
|
std::int64_t buffer;
|
|
|
|
IONAME(InputInteger)(io, buffer) || (Fail() << "InputInteger()", 0);
|
|
|
|
IONAME(EndIoStatement)
|
|
|
|
(io) == IostatOk || (Fail() << "EndIoStatement() for InputInteger", 0);
|
|
|
|
if (buffer != j) {
|
|
|
|
Fail() << "Read back " << buffer << " from direct formatted record " << j
|
|
|
|
<< ", expected " << j << '\n';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// CLOSE(UNIT=unit,STATUS='DELETE')
|
|
|
|
io = IONAME(BeginClose)(unit, __FILE__, __LINE__);
|
|
|
|
IONAME(SetStatus)(io, "DELETE", 6) || (Fail() << "SetStatus(DELETE)", 0);
|
|
|
|
IONAME(EndIoStatement)
|
|
|
|
(io) == IostatOk || (Fail() << "EndIoStatement() for Close", 0);
|
|
|
|
llvm::errs() << "end TestDirectformatted()\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
void TestSequentialVariableFormatted() {
|
|
|
|
llvm::errs() << "begin TestSequentialVariableFormatted()\n";
|
|
|
|
// OPEN(NEWUNIT=unit,ACCESS='SEQUENTIAL',ACTION='READWRITE',&
|
|
|
|
// FORM='FORMATTED',STATUS='SCRATCH')
|
|
|
|
auto io{IONAME(BeginOpenNewUnit)(__FILE__, __LINE__)};
|
|
|
|
IONAME(SetAccess)
|
|
|
|
(io, "SEQUENTIAL", 10) || (Fail() << "SetAccess(SEQUENTIAL)", 0);
|
|
|
|
IONAME(SetAction)
|
|
|
|
(io, "READWRITE", 9) || (Fail() << "SetAction(READWRITE)", 0);
|
|
|
|
IONAME(SetForm)
|
|
|
|
(io, "FORMATTED", 9) || (Fail() << "SetForm(FORMATTED)", 0);
|
|
|
|
IONAME(SetStatus)(io, "SCRATCH", 7) || (Fail() << "SetStatus(SCRATCH)", 0);
|
|
|
|
int unit{-1};
|
|
|
|
IONAME(GetNewUnit)(io, unit) || (Fail() << "GetNewUnit()", 0);
|
|
|
|
llvm::errs() << "unit=" << unit << '\n';
|
|
|
|
IONAME(EndIoStatement)
|
|
|
|
(io) == IostatOk || (Fail() << "EndIoStatement() for OpenNewUnit", 0);
|
|
|
|
static const int records{10};
|
|
|
|
std::int64_t buffer[records]; // INTEGER*8 :: BUFFER(0:9) = [(j,j=0,9)]
|
|
|
|
for (int j{0}; j < records; ++j) {
|
|
|
|
buffer[j] = j;
|
|
|
|
}
|
|
|
|
char fmt[32];
|
|
|
|
for (int j{1}; j <= records; ++j) {
|
|
|
|
std::snprintf(fmt, sizeof fmt, "(%dI4)", j);
|
|
|
|
// DO J=1,RECORDS; WRITE(UNIT=unit,FMT=fmt) BUFFER(0:j); END DO
|
|
|
|
io = IONAME(BeginExternalFormattedOutput)(
|
|
|
|
fmt, std::strlen(fmt), unit, __FILE__, __LINE__);
|
|
|
|
for (int k{0}; k < j; ++k) {
|
|
|
|
IONAME(OutputInteger64)
|
|
|
|
(io, buffer[k]) || (Fail() << "OutputInteger64()", 0);
|
|
|
|
}
|
|
|
|
IONAME(EndIoStatement)
|
|
|
|
(io) == IostatOk || (Fail() << "EndIoStatement() for OutputInteger64", 0);
|
|
|
|
}
|
|
|
|
// REWIND(UNIT=unit)
|
|
|
|
io = IONAME(BeginRewind)(unit, __FILE__, __LINE__);
|
|
|
|
IONAME(EndIoStatement)
|
|
|
|
(io) == IostatOk || (Fail() << "EndIoStatement() for Rewind", 0);
|
|
|
|
for (int j{1}; j <= records; ++j) {
|
|
|
|
std::snprintf(fmt, sizeof fmt, "(%dI4)", j);
|
|
|
|
// DO J=1,RECORDS; READ(UNIT=unit,FMT=fmt) n; check n; END DO
|
|
|
|
io = IONAME(BeginExternalFormattedInput)(
|
|
|
|
fmt, std::strlen(fmt), unit, __FILE__, __LINE__);
|
|
|
|
std::int64_t check[records];
|
|
|
|
for (int k{0}; k < j; ++k) {
|
|
|
|
IONAME(InputInteger)(io, check[k]) || (Fail() << "InputInteger()", 0);
|
|
|
|
}
|
|
|
|
IONAME(EndIoStatement)
|
|
|
|
(io) == IostatOk || (Fail() << "EndIoStatement() for InputInteger", 0);
|
|
|
|
for (int k{0}; k < j; ++k) {
|
|
|
|
if (buffer[k] != check[k]) {
|
|
|
|
Fail() << "Read back [" << k << "]=" << check[k]
|
|
|
|
<< " from sequential variable formatted record " << j
|
|
|
|
<< ", expected " << buffer[k] << '\n';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (int j{records}; j >= 1; --j) {
|
|
|
|
// BACKSPACE(unit)
|
|
|
|
io = IONAME(BeginBackspace)(unit, __FILE__, __LINE__);
|
|
|
|
IONAME(EndIoStatement)
|
|
|
|
(io) == IostatOk ||
|
|
|
|
(Fail() << "EndIoStatement() for Backspace (before read)", 0);
|
|
|
|
std::snprintf(fmt, sizeof fmt, "(%dI4)", j);
|
|
|
|
// READ(UNIT=unit,FMT=fmt) n; check
|
|
|
|
io = IONAME(BeginExternalFormattedInput)(
|
|
|
|
fmt, std::strlen(fmt), unit, __FILE__, __LINE__);
|
|
|
|
std::int64_t check[records];
|
|
|
|
for (int k{0}; k < j; ++k) {
|
|
|
|
IONAME(InputInteger)(io, check[k]) || (Fail() << "InputInteger()", 0);
|
|
|
|
}
|
|
|
|
IONAME(EndIoStatement)
|
|
|
|
(io) == IostatOk || (Fail() << "EndIoStatement() for InputInteger", 0);
|
|
|
|
for (int k{0}; k < j; ++k) {
|
|
|
|
if (buffer[k] != check[k]) {
|
|
|
|
Fail() << "Read back [" << k << "]=" << buffer[k]
|
|
|
|
<< " from sequential variable formatted record " << j
|
|
|
|
<< ", expected " << buffer[k] << '\n';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// BACKSPACE(unit)
|
|
|
|
io = IONAME(BeginBackspace)(unit, __FILE__, __LINE__);
|
|
|
|
IONAME(EndIoStatement)
|
|
|
|
(io) == IostatOk ||
|
|
|
|
(Fail() << "EndIoStatement() for Backspace (after read)", 0);
|
|
|
|
}
|
|
|
|
// CLOSE(UNIT=unit,STATUS='DELETE')
|
|
|
|
io = IONAME(BeginClose)(unit, __FILE__, __LINE__);
|
|
|
|
IONAME(SetStatus)(io, "DELETE", 6) || (Fail() << "SetStatus(DELETE)", 0);
|
|
|
|
IONAME(EndIoStatement)
|
|
|
|
(io) == IostatOk || (Fail() << "EndIoStatement() for Close", 0);
|
|
|
|
llvm::errs() << "end TestSequentialVariableFormatted()\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
void TestStreamUnformatted() {
|
|
|
|
// TODO
|
|
|
|
}
|
|
|
|
|
|
|
|
int main() {
|
|
|
|
StartTests();
|
|
|
|
TestDirectUnformatted();
|
2020-07-22 08:37:35 +08:00
|
|
|
TestDirectUnformattedSwapped();
|
2020-07-05 05:24:32 +08:00
|
|
|
TestSequentialFixedUnformatted();
|
|
|
|
TestSequentialVariableUnformatted();
|
|
|
|
TestDirectFormatted();
|
|
|
|
TestSequentialVariableFormatted();
|
|
|
|
TestStreamUnformatted();
|
|
|
|
return EndTests();
|
|
|
|
}
|