blob: 1c025d40b395247d6cf877d65be9f0b107d62803 [file] [log] [blame]
Peter Klausler627a8ac2021-12-07 22:38:171//===-- runtime/extensions.cpp --------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9// These C-coded entry points with Fortran-mangled names implement legacy
10// extensions that will eventually be implemented in Fortran.
11
12#include "flang/Runtime/extensions.h"
Yi Wu18af0322023-12-21 10:35:2813#include "tools.h"
Peixin-Qiao1d4238b2022-10-11 02:29:2314#include "flang/Runtime/command.h"
15#include "flang/Runtime/descriptor.h"
Peter Klausler627a8ac2021-12-07 22:38:1716#include "flang/Runtime/io-api.h"
17
Yi Wu18af0322023-12-21 10:35:2818#if _REENTRANT || _POSIX_C_SOURCE >= 199506L
19// System is posix-compliant and has getlogin_r
20#include <unistd.h>
21#endif
22
Peter Klausler627a8ac2021-12-07 22:38:1723extern "C" {
24
Peixin-Qiao1d4238b2022-10-11 02:29:2325namespace Fortran::runtime {
Yi Wu18af0322023-12-21 10:35:2826
27void GetUsernameEnvVar(
28 const char *envName, std::byte *arg, std::int64_t length) {
29 Descriptor name{*Descriptor::Create(
30 1, std::strlen(envName) + 1, const_cast<char *>(envName), 0)};
31 Descriptor value{*Descriptor::Create(1, length, arg, 0)};
32
33 RTNAME(GetEnvVariable)
34 (name, &value, nullptr, false, nullptr, __FILE__, __LINE__);
35}
Peixin-Qiao1d4238b2022-10-11 02:29:2336namespace io {
Peter Klausler627a8ac2021-12-07 22:38:1737// SUBROUTINE FLUSH(N)
38// FLUSH N
39// END
Peixin-Qiao1d4238b2022-10-11 02:29:2340void FORTRAN_PROCEDURE_NAME(flush)(const int &unit) {
Peter Klausler627a8ac2021-12-07 22:38:1741 Cookie cookie{IONAME(BeginFlush)(unit, __FILE__, __LINE__)};
42 IONAME(EndIoStatement)(cookie);
43}
Peixin-Qiao1d4238b2022-10-11 02:29:2344} // namespace io
45
46// RESULT = IARGC()
47std::int32_t FORTRAN_PROCEDURE_NAME(iargc)() { return RTNAME(ArgumentCount)(); }
48
49// CALL GETARG(N, ARG)
50void FORTRAN_PROCEDURE_NAME(getarg)(
51 std::int32_t &n, std::int8_t *arg, std::int64_t length) {
52 Descriptor value{*Descriptor::Create(1, length, arg, 0)};
53 (void)RTNAME(GetCommandArgument)(
54 n, &value, nullptr, nullptr, __FILE__, __LINE__);
55}
Yi Wu18af0322023-12-21 10:35:2856
57// CALL GETLOG(USRNAME)
58void FORTRAN_PROCEDURE_NAME(getlog)(std::byte *arg, std::int64_t length) {
59#if _REENTRANT || _POSIX_C_SOURCE >= 199506L
60 const int nameMaxLen{LOGIN_NAME_MAX + 1};
61 char str[nameMaxLen];
62
63 int error{getlogin_r(str, nameMaxLen)};
64 if (error == 0) {
65 // no error: find first \0 in string then pad from there
66 CopyAndPad(reinterpret_cast<char *>(arg), str, length, std::strlen(str));
67 } else {
68 // error occur: get username from environment variable
69 GetUsernameEnvVar("LOGNAME", arg, length);
70 }
71#elif _WIN32
72 // Get username from environment to avoid link to Advapi32.lib
73 GetUsernameEnvVar("USERNAME", arg, length);
74#else
75 GetUsernameEnvVar("LOGNAME", arg, length);
76#endif
77}
78
Peixin-Qiao1d4238b2022-10-11 02:29:2379} // namespace Fortran::runtime
Peter Klausler627a8ac2021-12-07 22:38:1780} // extern "C"