Skip to content

Commit 0e98aa7

Browse files
committed
GETLOG runtime and extension implementation: get login username
Get login username, ussage: CHARACTER(32) :: login CALL getlog(login) WRITE(*,*) login
1 parent 1ad920f commit 0e98aa7

File tree

7 files changed

+77
-2
lines changed

7 files changed

+77
-2
lines changed

flang/docs/Intrinsics.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -751,7 +751,7 @@ This phase currently supports all the intrinsic procedures listed above but the
751751
| Object characteristic inquiry functions | ALLOCATED, ASSOCIATED, EXTENDS_TYPE_OF, IS_CONTIGUOUS, PRESENT, RANK, SAME_TYPE, STORAGE_SIZE |
752752
| Type inquiry intrinsic functions | BIT_SIZE, DIGITS, EPSILON, HUGE, KIND, MAXEXPONENT, MINEXPONENT, NEW_LINE, PRECISION, RADIX, RANGE, TINY|
753753
| Non-standard intrinsic functions | AND, OR, XOR, SHIFT, ZEXT, IZEXT, COSD, SIND, TAND, ACOSD, ASIND, ATAND, ATAN2D, COMPL, EQV, NEQV, INT8, JINT, JNINT, KNINT, QCMPLX, DREAL, DFLOAT, QEXT, QFLOAT, QREAL, DNUM, NUM, JNUM, KNUM, QNUM, RNUM, RAN, RANF, ILEN, SIZEOF, MCLOCK, SECNDS, COTAN, IBCHNG, ISHA, ISHC, ISHL, IXOR, IARG, IARGC, NARGS, NUMARG, BADDRESS, IADDR, CACHESIZE, EOF, FP_CLASS, INT_PTR_KIND, ISNAN, MALLOC |
754-
| Intrinsic subroutines |MVBITS (elemental), CPU_TIME, DATE_AND_TIME, EVENT_QUERY, EXECUTE_COMMAND_LINE, GET_COMMAND, GET_COMMAND_ARGUMENT, GET_ENVIRONMENT_VARIABLE, MOVE_ALLOC, RANDOM_INIT, RANDOM_NUMBER, RANDOM_SEED, SYSTEM_CLOCK |
754+
| Intrinsic subroutines |MVBITS (elemental), CPU_TIME, DATE_AND_TIME, EVENT_QUERY, EXECUTE_COMMAND_LINE, GET_COMMAND, GET_COMMAND_ARGUMENT, GET_ENVIRONMENT_VARIABLE, GETLOG, MOVE_ALLOC, RANDOM_INIT, RANDOM_NUMBER, RANDOM_SEED, SYSTEM_CLOCK |
755755
| Atomic intrinsic subroutines | ATOMIC_ADD |
756756
| Collective intrinsic subroutines | CO_REDUCE |
757757

flang/include/flang/Optimizer/Builder/Runtime/RTBuilder.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,14 @@ using FuncTypeBuilderFunc = mlir::FunctionType (*)(mlir::MLIRContext *);
6262
/// standard type `i32` when `sizeof(int)` is 4.
6363
template <typename T>
6464
static constexpr TypeBuilderFunc getModel();
65+
66+
template <>
67+
constexpr TypeBuilderFunc getModel<unsigned int>() {
68+
return [](mlir::MLIRContext *context) -> mlir::Type {
69+
return mlir::IntegerType::get(context, 8 * sizeof(unsigned int));
70+
};
71+
}
72+
6573
template <>
6674
constexpr TypeBuilderFunc getModel<short int>() {
6775
return [](mlir::MLIRContext *context) -> mlir::Type {

flang/include/flang/Runtime/command.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,12 @@ std::int32_t RTNAME(GetEnvVariable)(const Descriptor &name,
4747
bool trim_name = true, const Descriptor *errmsg = nullptr,
4848
const char *sourceFile = nullptr, int line = 0);
4949
}
50+
51+
// Try to get the name of current user
52+
// Returns a STATUS as described in the standard.
53+
std::int32_t RTNAME(GetLog)(
54+
const Descriptor *argument = nullptr, const Descriptor *errmsg = nullptr);
55+
5056
} // namespace Fortran::runtime
5157

5258
#endif // FORTRAN_RUNTIME_COMMAND_H_

flang/include/flang/Runtime/extensions.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,5 +28,7 @@ std::int32_t FORTRAN_PROCEDURE_NAME(iargc)();
2828
void FORTRAN_PROCEDURE_NAME(getarg)(
2929
std::int32_t &n, std::int8_t *arg, std::int64_t length);
3030

31+
void FORTRAN_PROCEDURE_NAME(getlog)(std::int8_t *name, std::int64_t length);
32+
3133
} // extern "C"
3234
#endif // FORTRAN_RUNTIME_EXTENSIONS_H_

flang/runtime/command.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,30 @@
1515
#include <cstdlib>
1616
#include <limits>
1717

18+
#ifdef _WIN32
19+
#define WIN32_LEAN_AND_MEAN
20+
#define NOMINMAX
21+
#include <windows.h>
22+
23+
#include <Lmcons.h> // UNLEN=256
24+
25+
inline char *getlogin() {
26+
char *username = NULL;
27+
DWORD size = UNLEN + 1; // Constant for the maximum username length
28+
username = (char *)malloc(size);
29+
30+
if (GetUserName(username, &size)) {
31+
// Username retrieved successfully
32+
return username;
33+
} else {
34+
free(username);
35+
return NULL;
36+
}
37+
}
38+
#else
39+
#include <unistd.h>
40+
#endif
41+
1842
namespace Fortran::runtime {
1943
std::int32_t RTNAME(ArgumentCount)() {
2044
int argc{executionEnvironment.argc};
@@ -222,6 +246,22 @@ std::int32_t RTNAME(GetCommand)(const Descriptor *value,
222246
return stat;
223247
}
224248

249+
std::int32_t RTNAME(GetLog)(const Descriptor *value, const Descriptor *errmsg) {
250+
FillWithSpaces(*value);
251+
252+
const char *arg = getlogin();
253+
std::int64_t argLen{StringLength(arg)};
254+
if (argLen <= 0) {
255+
return ToErrmsg(errmsg, StatMissingArgument);
256+
}
257+
258+
if (value) {
259+
return CopyToDescriptor(*value, arg, argLen, errmsg);
260+
}
261+
262+
return StatOk;
263+
}
264+
225265
static std::size_t LengthWithoutTrailingSpaces(const Descriptor &d) {
226266
std::size_t s{d.ElementBytes() - 1};
227267
while (*d.OffsetElement(s) == ' ') {

flang/runtime/extensions.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,5 +37,11 @@ void FORTRAN_PROCEDURE_NAME(getarg)(
3737
(void)RTNAME(GetCommandArgument)(
3838
n, &value, nullptr, nullptr, __FILE__, __LINE__);
3939
}
40+
41+
void FORTRAN_PROCEDURE_NAME(getlog)(std::int8_t *arg, std::int64_t length) {
42+
Descriptor value{*Descriptor::Create(1, length, arg, 0)};
43+
(void)RTNAME(GetLog)(&value, nullptr);
44+
}
45+
4046
} // namespace Fortran::runtime
4147
} // extern "C"

flang/unittests/Runtime/CommandTest.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,12 @@ TEST_F(ZeroArguments, GetCommandArgument) {
225225
CheckMissingArgumentValue(1);
226226
}
227227

228+
TEST_F(ZeroArguments, GetLog) {
229+
CheckMissingArgumentValue(-1);
230+
CheckArgumentValue(commandOnlyArgv[0], 0);
231+
CheckMissingArgumentValue(1);
232+
}
233+
228234
TEST_F(ZeroArguments, GetCommand) { CheckCommandValue(commandOnlyArgv, 1); }
229235

230236
static const char *oneArgArgv[]{"aProgram", "anArgumentOfLength20"};
@@ -242,6 +248,13 @@ TEST_F(OneArgument, GetCommandArgument) {
242248
CheckMissingArgumentValue(2);
243249
}
244250

251+
TEST_F(OneArgument, GetLog) {
252+
CheckMissingArgumentValue(-1);
253+
CheckArgumentValue(oneArgArgv[0], 0);
254+
CheckArgumentValue(oneArgArgv[1], 1);
255+
CheckMissingArgumentValue(2);
256+
}
257+
245258
TEST_F(OneArgument, GetCommand) { CheckCommandValue(oneArgArgv, 2); }
246259

247260
static const char *severalArgsArgv[]{
@@ -284,7 +297,7 @@ TEST_F(SeveralArguments, ArgValueTooShort) {
284297
ASSERT_NE(tooShort, nullptr);
285298
EXPECT_EQ(RTNAME(GetCommandArgument)(1, tooShort.get()), -1);
286299
CheckDescriptorEqStr(tooShort.get(), severalArgsArgv[1]);
287-
300+
288301
OwningPtr<Descriptor> length{EmptyIntDescriptor()};
289302
ASSERT_NE(length, nullptr);
290303
OwningPtr<Descriptor> errMsg{CreateEmptyCharDescriptor()};

0 commit comments

Comments
 (0)