Skip to content

Commit a39e9cf

Browse files
committed
[flang] Basic tests of external I/O runtime (part 9/9)
Add new unit tests for external Fortran I/O that drive the Fortran I/O runtime API from C++ and exercise basic writing and read-back in the various combinations of access modes, record length variability, and formatting. Sequential modes are tested with positioning. More thorough tests written in Fortran will follow when they can be compiled and run. The Fortran runtime's error termination callback registration was extended with source file and line number positions for better failure messages in unit testing. Reviewed By: sscalpone Differential Revision: https://reviews.llvm.org/D83164
1 parent 39d2ae0 commit a39e9cf

File tree

7 files changed

+449
-8
lines changed

7 files changed

+449
-8
lines changed

flang/runtime/terminator.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,18 @@ namespace Fortran::runtime {
1818
CrashArgs(message, ap);
1919
}
2020

21-
static void (*crashHandler)(const char *, va_list &){nullptr};
21+
static void (*crashHandler)(const char *, int, const char *, va_list &){
22+
nullptr};
2223

2324
void Terminator::RegisterCrashHandler(
24-
void (*handler)(const char *, va_list &)) {
25+
void (*handler)(const char *, int, const char *, va_list &)) {
2526
crashHandler = handler;
2627
}
2728

2829
[[noreturn]] void Terminator::CrashArgs(
2930
const char *message, va_list &ap) const {
3031
if (crashHandler) {
31-
crashHandler(message, ap);
32+
crashHandler(sourceFileName_, sourceLine_, message, ap);
3233
}
3334
std::fputs("\nfatal Fortran runtime error", stderr);
3435
if (sourceFileName_) {

flang/runtime/terminator.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ class Terminator {
3434
const char *predicate, const char *file, int line) const;
3535

3636
// For test harnessing - overrides CrashArgs().
37-
static void RegisterCrashHandler(void (*)(const char *, va_list &));
37+
static void RegisterCrashHandler(void (*)(const char *sourceFile,
38+
int sourceLine, const char *message, va_list &ap));
3839

3940
private:
4041
const char *sourceFileName_{nullptr};

flang/unittests/Runtime/CMakeLists.txt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,18 @@ target_link_libraries(external-hello-world
4141
LLVMSupport
4242
)
4343

44+
add_executable(external-io
45+
external-io.cpp
46+
)
47+
48+
target_link_libraries(external-io
49+
RuntimeTesting
50+
FortranRuntime
51+
LLVMSupport
52+
)
53+
54+
add_test(NAME ExternalIO COMMAND external-io)
55+
4456
add_executable(list-input-test
4557
list-input.cpp
4658
)

flang/unittests/Runtime/external-hello.cpp

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,8 @@
55

66
using namespace Fortran::runtime::io;
77

8-
int main(int argc, const char *argv[], const char *envp[]) {
9-
RTNAME(ProgramStart)(argc, argv, envp);
10-
auto *io{IONAME(BeginExternalListOutput)()};
8+
void output1() {
9+
auto io{IONAME(BeginExternalListOutput)()};
1110
const char str[]{"Hello, world!"};
1211
IONAME(OutputAscii)(io, str, std::strlen(str));
1312
IONAME(OutputInteger64)(io, 678);
@@ -21,6 +20,31 @@ int main(int argc, const char *argv[], const char *envp[]) {
2120
IONAME(OutputLogical)(io, false);
2221
IONAME(OutputLogical)(io, true);
2322
IONAME(EndIoStatement)(io);
23+
}
24+
25+
void input1() {
26+
auto io{IONAME(BeginExternalListOutput)()};
27+
const char prompt[]{"Enter an integer value:"};
28+
IONAME(OutputAscii)(io, prompt, std::strlen(prompt));
29+
IONAME(EndIoStatement)(io);
30+
31+
io = IONAME(BeginExternalListInput)();
32+
std::int64_t n{-666};
33+
IONAME(InputInteger)(io, n);
34+
IONAME(EndIoStatement)(io);
35+
36+
io = IONAME(BeginExternalListOutput)();
37+
const char str[]{"Result:"};
38+
IONAME(OutputAscii)(io, str, std::strlen(str));
39+
IONAME(OutputInteger64)(io, n);
40+
IONAME(EndIoStatement)(io);
41+
}
42+
43+
int main(int argc, const char *argv[], const char *envp[]) {
44+
RTNAME(ProgramStart)(argc, argv, envp);
45+
output1();
46+
input1();
47+
RTNAME(PauseStatement)();
2448
RTNAME(ProgramEndStatement)();
2549
return 0;
2650
}

0 commit comments

Comments
 (0)