1 //===-- runtime/environment.cpp -------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "environment.h"
10 #include "environment-default-list.h"
19 extern char **_environ
;
21 extern char **environ
;
24 namespace Fortran::runtime
{
26 #ifndef FLANG_RUNTIME_NO_GLOBAL_VAR_DEFS
27 RT_OFFLOAD_VAR_GROUP_BEGIN
28 RT_VAR_ATTRS ExecutionEnvironment executionEnvironment
;
29 RT_OFFLOAD_VAR_GROUP_END
30 #endif // FLANG_RUNTIME_NO_GLOBAL_VAR_DEFS
32 static void SetEnvironmentDefaults(const EnvironmentDefaultList
*envDefaults
) {
37 for (int itemIndex
= 0; itemIndex
< envDefaults
->numItems
; ++itemIndex
) {
38 const char *name
= envDefaults
->item
[itemIndex
].name
;
39 const char *value
= envDefaults
->item
[itemIndex
].value
;
41 if (auto *x
{std::getenv(name
)}) {
44 if (_putenv_s(name
, value
) != 0) {
46 if (setenv(name
, value
, /*overwrite=*/0) == -1) {
48 Fortran::runtime::Terminator
{__FILE__
, __LINE__
}.Crash(
49 std::strerror(errno
));
54 RT_OFFLOAD_API_GROUP_BEGIN
55 Fortran::common::optional
<Convert
> GetConvertFromString(
56 const char *x
, std::size_t n
) {
57 static const char *keywords
[]{
58 "UNKNOWN", "NATIVE", "LITTLE_ENDIAN", "BIG_ENDIAN", "SWAP", nullptr};
59 switch (IdentifyValue(x
, n
, keywords
)) {
61 return Convert::Unknown
;
63 return Convert::Native
;
65 return Convert::LittleEndian
;
67 return Convert::BigEndian
;
71 return Fortran::common::nullopt
;
74 RT_OFFLOAD_API_GROUP_END
76 void ExecutionEnvironment::Configure(int ac
, const char *av
[],
77 const char *env
[], const EnvironmentDefaultList
*envDefaults
) {
80 SetEnvironmentDefaults(envDefaults
);
86 listDirectedOutputLineLengthLimit
= 79; // PGI default
87 defaultOutputRoundingMode
=
88 decimal::FortranRounding::RoundNearest
; // RP(==RN)
89 conversion
= Convert::Unknown
;
91 if (auto *x
{std::getenv("FORT_FMT_RECL")}) {
93 auto n
{std::strtol(x
, &end
, 10)};
94 if (n
> 0 && n
< std::numeric_limits
<int>::max() && *end
== '\0') {
95 listDirectedOutputLineLengthLimit
= n
;
98 stderr
, "Fortran runtime: FORT_FMT_RECL=%s is invalid; ignored\n", x
);
102 if (auto *x
{std::getenv("FORT_CONVERT")}) {
103 if (auto convert
{GetConvertFromString(x
, std::strlen(x
))}) {
104 conversion
= *convert
;
107 stderr
, "Fortran runtime: FORT_CONVERT=%s is invalid; ignored\n", x
);
111 if (auto *x
{std::getenv("NO_STOP_MESSAGE")}) {
113 auto n
{std::strtol(x
, &end
, 10)};
114 if (n
>= 0 && n
<= 1 && *end
== '\0') {
115 noStopMessage
= n
!= 0;
118 "Fortran runtime: NO_STOP_MESSAGE=%s is invalid; ignored\n", x
);
122 if (auto *x
{std::getenv("DEFAULT_UTF8")}) {
124 auto n
{std::strtol(x
, &end
, 10)};
125 if (n
>= 0 && n
<= 1 && *end
== '\0') {
126 defaultUTF8
= n
!= 0;
129 stderr
, "Fortran runtime: DEFAULT_UTF8=%s is invalid; ignored\n", x
);
133 if (auto *x
{std::getenv("FORT_CHECK_POINTER_DEALLOCATION")}) {
135 auto n
{std::strtol(x
, &end
, 10)};
136 if (n
>= 0 && n
<= 1 && *end
== '\0') {
137 checkPointerDeallocation
= n
!= 0;
140 "Fortran runtime: FORT_CHECK_POINTER_DEALLOCATION=%s is invalid; "
146 // TODO: Set RP/ROUND='PROCESSOR_DEFINED' from environment
149 const char *ExecutionEnvironment::GetEnv(
150 const char *name
, std::size_t name_length
, const Terminator
&terminator
) {
151 RUNTIME_CHECK(terminator
, name
&& name_length
);
153 OwningPtr
<char> cStyleName
{
154 SaveDefaultCharacter(name
, name_length
, terminator
)};
155 RUNTIME_CHECK(terminator
, cStyleName
);
157 return std::getenv(cStyleName
.get());
159 } // namespace Fortran::runtime