[flang-commits] [flang] [flang][runtime] Extension: NAMELIST input may omit terminal '/' (PR #76476)
Peter Klausler via flang-commits
flang-commits at lists.llvm.org
Fri Dec 29 11:51:00 PST 2023
https://github.com/klausler updated https://github.com/llvm/llvm-project/pull/76476
>From ca4d51a8215ec9ae06a380b982a32f93aae3a904 Mon Sep 17 00:00:00 2001
From: Peter Klausler <pklausler at nvidia.com>
Date: Wed, 27 Dec 2023 15:49:18 -0800
Subject: [PATCH] [flang][runtime] Extension: NAMELIST input may omit terminal
'/'
... when it is followed eventually by the '&' that begins the next
NAMELIST input group. This is a gfortran extension. While here,
also support '$' as a substitute for '&' before a NAMELIST input
group name.
Fixes llvm-test-suite/Fortran/gfortran/regression/namelist_21.f90
and .../namelist_37.f90.
---
flang/docs/Extensions.md | 3 +++
flang/runtime/namelist.cpp | 23 ++++++++++++++---------
2 files changed, 17 insertions(+), 9 deletions(-)
diff --git a/flang/docs/Extensions.md b/flang/docs/Extensions.md
index 6c6588025a392d..ab040b61703c8b 100644
--- a/flang/docs/Extensions.md
+++ b/flang/docs/Extensions.md
@@ -315,6 +315,9 @@ end
* When a file included via an `INCLUDE` line or `#include` directive
has a continuation marker at the end of its last line in free form,
Fortran line continuation works.
+* A `NAMELIST` input group may omit its trailing `/` character if
+ it is followed by another `NAMELIST` input group.
+* A `NAMELIST` input group may begin with either `&` or `$`.
### Extensions supported when enabled by options
diff --git a/flang/runtime/namelist.cpp b/flang/runtime/namelist.cpp
index 61815a7cc8a403..45285cf2b533ef 100644
--- a/flang/runtime/namelist.cpp
+++ b/flang/runtime/namelist.cpp
@@ -378,12 +378,13 @@ static bool HandleComponent(IoStatementState &io, Descriptor &desc,
return false;
}
-// Advance to the terminal '/' of a namelist group.
+// Advance to the terminal '/' of a namelist group or leading '&'/'$'
+// of the next.
static void SkipNamelistGroup(IoStatementState &io) {
std::size_t byteCount{0};
while (auto ch{io.GetNextNonBlank(byteCount)}) {
io.HandleRelativePosition(byteCount);
- if (*ch == '/') {
+ if (*ch == '/' || *ch == '&' || *ch == '$') {
break;
} else if (*ch == '\'' || *ch == '"') {
// Skip quoted character literal
@@ -418,7 +419,7 @@ bool IONAME(InputNamelist)(Cookie cookie, const NamelistGroup &group) {
std::size_t byteCount{0};
while (true) {
next = io.GetNextNonBlank(byteCount);
- while (next && *next != '&') {
+ while (next && *next != '&' && *next != '$') {
// Extension: comment lines without ! before namelist groups
if (!io.AdvanceRecord()) {
next.reset();
@@ -430,9 +431,10 @@ bool IONAME(InputNamelist)(Cookie cookie, const NamelistGroup &group) {
handler.SignalEnd();
return false;
}
- if (*next != '&') {
+ if (*next != '&' && *next != '$') {
handler.SignalError(
- "NAMELIST input group does not begin with '&' (at '%lc')", *next);
+ "NAMELIST input group does not begin with '&' or '$' (at '%lc')",
+ *next);
return false;
}
io.HandleRelativePosition(byteCount);
@@ -448,7 +450,7 @@ bool IONAME(InputNamelist)(Cookie cookie, const NamelistGroup &group) {
// Read the group's items
while (true) {
next = io.GetNextNonBlank(byteCount);
- if (!next || *next == '/') {
+ if (!next || *next == '/' || *next == '&' || *next == '$') {
break;
}
if (!GetLowerCaseName(io, name, sizeof name)) {
@@ -540,12 +542,15 @@ bool IONAME(InputNamelist)(Cookie cookie, const NamelistGroup &group) {
io.HandleRelativePosition(byteCount);
}
}
- if (!next || *next != '/') {
+ if (next && *next == '/') {
+ io.HandleRelativePosition(byteCount);
+ } else if (*next && (*next == '&' || *next == '$')) {
+ // stop at beginning of next group
+ } else {
handler.SignalError(
"No '/' found after NAMELIST group '%s'", group.groupName);
return false;
}
- io.HandleRelativePosition(byteCount);
return true;
}
@@ -565,7 +570,7 @@ bool IsNamelistNameOrSlash(IoStatementState &io) {
// TODO: how to deal with NaN(...) ambiguity?
return ch && (*ch == '=' || *ch == '(' || *ch == '%');
} else {
- return *ch == '/';
+ return *ch == '/' || *ch == '&' || *ch == '$';
}
}
}
More information about the flang-commits
mailing list