Skip to content

Commit 0446f12

Browse files
committed
[flang] GET_COMMAND_ARGUMENT(ERRMSG) runtime implementation
Implement the final part of GET_COMMAND_ARGUMENT, i.e. the handling of ERRMSG. This uses some of the infrastructure in stat.h and gets rid of the magic numbers that we were using for return codes. Differential Revision: https://reviews.llvm.org/D109814
1 parent df63023 commit 0446f12

File tree

5 files changed

+55
-9
lines changed

5 files changed

+55
-9
lines changed

flang/include/flang/Runtime/magic-numbers.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,12 @@ start at 100 so as to never conflict with those codes.
3939
#define FORTRAN_RUNTIME_STAT_STOPPED_IMAGE 104
4040
#define FORTRAN_RUNTIME_STAT_UNLOCKED 105
4141
#define FORTRAN_RUNTIME_STAT_UNLOCKED_FAILED_IMAGE 106
42+
43+
#if 0
44+
Status codes for GET_COMMAND_ARGUMENT. The status for 'value too short' needs
45+
to be -1, the others must be positive.
46+
#endif
47+
#define FORTRAN_RUNTIME_STAT_INVALID_ARG_NUMBER 107
48+
#define FORTRAN_RUNTIME_STAT_MISSING_ARG 108
49+
#define FORTRAN_RUNTIME_STAT_VALUE_TOO_SHORT -1
4250
#endif

flang/runtime/command.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99
#include "flang/Runtime/command.h"
1010
#include "environment.h"
11+
#include "stat.h"
1112
#include "flang/Runtime/descriptor.h"
1213
#include <limits>
1314

@@ -58,23 +59,24 @@ std::int32_t RTNAME(ArgumentValue)(
5859
}
5960

6061
if (n < 0 || n >= executionEnvironment.argc) {
61-
return 1;
62+
return ToErrmsg(errmsg, StatInvalidArgumentNumber);
6263
}
6364

6465
if (IsValidCharDescriptor(value)) {
6566
std::int64_t argLen{ArgumentLength(n)};
6667
if (argLen <= 0) {
67-
return 2;
68+
return ToErrmsg(errmsg, StatMissingArgument);
6869
}
6970

7071
std::int64_t toCopy{
7172
std::min(argLen, static_cast<std::int64_t>(value->ElementBytes()))};
7273
std::strncpy(value->OffsetElement(), executionEnvironment.argv[n], toCopy);
7374

7475
if (argLen > toCopy) {
75-
return -1;
76+
return ToErrmsg(errmsg, StatValueTooShort);
7677
}
7778
}
78-
return 0;
79+
80+
return StatOk;
7981
}
8082
} // namespace Fortran::runtime

flang/runtime/stat.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,13 @@ const char *StatErrorString(int stat) {
5050
case StatUnlockedFailedImage:
5151
return "Failed image unlocked";
5252

53+
case StatInvalidArgumentNumber:
54+
return "Invalid argument number";
55+
case StatMissingArgument:
56+
return "Missing argument";
57+
case StatValueTooShort:
58+
return "Value too short";
59+
5360
default:
5461
return nullptr;
5562
}

flang/runtime/stat.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ enum Stat {
4444
StatUnlockedFailedImage = FORTRAN_RUNTIME_STAT_UNLOCKED_FAILED_IMAGE,
4545

4646
// Additional "processor-defined" STAT= values
47+
StatInvalidArgumentNumber = FORTRAN_RUNTIME_STAT_INVALID_ARG_NUMBER,
48+
StatMissingArgument = FORTRAN_RUNTIME_STAT_MISSING_ARG,
49+
StatValueTooShort = FORTRAN_RUNTIME_STAT_VALUE_TOO_SHORT,
4750
};
4851

4952
const char *StatErrorString(int);

flang/unittests/Runtime/CommandTest.cpp

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
//===----------------------------------------------------------------------===//
88

99
#include "flang/Runtime/command.h"
10+
#include "gmock/gmock.h"
1011
#include "gtest/gtest.h"
1112
#include "flang/Runtime/descriptor.h"
1213
#include "flang/Runtime/main.h"
@@ -53,14 +54,21 @@ class CommandFixture : public ::testing::Test {
5354
CheckDescriptorEqStr(value.get(), expected);
5455
}
5556

56-
void CheckMissingArgumentValue(int n) const {
57+
void CheckMissingArgumentValue(int n, const char *errStr = nullptr) const {
5758
OwningPtr<Descriptor> value{CreateEmptyCharDescriptor()};
5859
ASSERT_NE(value, nullptr);
5960

60-
EXPECT_GT(RTNAME(ArgumentValue)(n, value.get(), nullptr), 0);
61+
OwningPtr<Descriptor> err{errStr ? CreateEmptyCharDescriptor() : nullptr};
62+
63+
EXPECT_GT(RTNAME(ArgumentValue)(n, value.get(), err.get()), 0);
6164

6265
std::string spaces(value->ElementBytes(), ' ');
6366
CheckDescriptorEqStr(value.get(), spaces);
67+
68+
if (errStr) {
69+
std::string paddedErrStr(GetPaddedStr(errStr, err->ElementBytes()));
70+
CheckDescriptorEqStr(err.get(), paddedErrStr);
71+
}
6472
}
6573
};
6674

@@ -128,7 +136,6 @@ TEST_F(SeveralArguments, ArgumentLength) {
128136
TEST_F(SeveralArguments, ArgumentValue) {
129137
CheckArgumentValue(0, severalArgsArgv[0]);
130138
CheckArgumentValue(1, severalArgsArgv[1]);
131-
CheckMissingArgumentValue(2);
132139
CheckArgumentValue(3, severalArgsArgv[3]);
133140
CheckArgumentValue(4, severalArgsArgv[4]);
134141
}
@@ -140,12 +147,31 @@ TEST_F(SeveralArguments, NoArgumentValue) {
140147
EXPECT_GT(RTNAME(ArgumentValue)(-1, nullptr, nullptr), 0);
141148
}
142149

143-
TEST_F(SeveralArguments, ArgumentValueErrors) {
144-
CheckMissingArgumentValue(-1);
150+
TEST_F(SeveralArguments, MissingArguments) {
151+
CheckMissingArgumentValue(-1, "Invalid argument number");
152+
CheckMissingArgumentValue(2, "Missing argument");
153+
CheckMissingArgumentValue(5, "Invalid argument number");
145154
CheckMissingArgumentValue(5);
155+
}
146156

157+
TEST_F(SeveralArguments, ValueTooShort) {
147158
OwningPtr<Descriptor> tooShort{CreateEmptyCharDescriptor<15>()};
148159
ASSERT_NE(tooShort, nullptr);
149160
EXPECT_EQ(RTNAME(ArgumentValue)(1, tooShort.get(), nullptr), -1);
150161
CheckDescriptorEqStr(tooShort.get(), severalArgsArgv[1]);
162+
163+
OwningPtr<Descriptor> errMsg{CreateEmptyCharDescriptor()};
164+
ASSERT_NE(errMsg, nullptr);
165+
166+
EXPECT_EQ(RTNAME(ArgumentValue)(1, tooShort.get(), errMsg.get()), -1);
167+
168+
std::string expectedErrMsg{
169+
GetPaddedStr("Value too short", errMsg->ElementBytes())};
170+
CheckDescriptorEqStr(errMsg.get(), expectedErrMsg);
171+
}
172+
173+
TEST_F(SeveralArguments, ErrMsgTooShort) {
174+
OwningPtr<Descriptor> errMsg{CreateEmptyCharDescriptor<3>()};
175+
EXPECT_GT(RTNAME(ArgumentValue)(-1, nullptr, errMsg.get()), 0);
176+
CheckDescriptorEqStr(errMsg.get(), "Inv");
151177
}

0 commit comments

Comments
 (0)