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 ExecutionEnvironment executionEnvironment
;
28 static void SetEnvironmentDefaults(const EnvironmentDefaultList
*envDefaults
) {
33 for (int itemIndex
= 0; itemIndex
< envDefaults
->numItems
; ++itemIndex
) {
34 const char *name
= envDefaults
->item
[itemIndex
].name
;
35 const char *value
= envDefaults
->item
[itemIndex
].value
;
37 if (auto *x
{std::getenv(name
)}) {
40 if (_putenv_s(name
, value
) != 0) {
42 if (setenv(name
, value
, /*overwrite=*/0) == -1) {
44 Fortran::runtime::Terminator
{__FILE__
, __LINE__
}.Crash(
45 std::strerror(errno
));
50 std::optional
<Convert
> GetConvertFromString(const char *x
, std::size_t n
) {
51 static const char *keywords
[]{
52 "UNKNOWN", "NATIVE", "LITTLE_ENDIAN", "BIG_ENDIAN", "SWAP", nullptr};
53 switch (IdentifyValue(x
, n
, keywords
)) {
55 return Convert::Unknown
;
57 return Convert::Native
;
59 return Convert::LittleEndian
;
61 return Convert::BigEndian
;
69 void ExecutionEnvironment::Configure(int ac
, const char *av
[],
70 const char *env
[], const EnvironmentDefaultList
*envDefaults
) {
73 SetEnvironmentDefaults(envDefaults
);
79 listDirectedOutputLineLengthLimit
= 79; // PGI default
80 defaultOutputRoundingMode
=
81 decimal::FortranRounding::RoundNearest
; // RP(==RN)
82 conversion
= Convert::Unknown
;
84 if (auto *x
{std::getenv("FORT_FMT_RECL")}) {
86 auto n
{std::strtol(x
, &end
, 10)};
87 if (n
> 0 && n
< std::numeric_limits
<int>::max() && *end
== '\0') {
88 listDirectedOutputLineLengthLimit
= n
;
91 stderr
, "Fortran runtime: FORT_FMT_RECL=%s is invalid; ignored\n", x
);
95 if (auto *x
{std::getenv("FORT_CONVERT")}) {
96 if (auto convert
{GetConvertFromString(x
, std::strlen(x
))}) {
97 conversion
= *convert
;
100 stderr
, "Fortran runtime: FORT_CONVERT=%s is invalid; ignored\n", x
);
104 if (auto *x
{std::getenv("NO_STOP_MESSAGE")}) {
106 auto n
{std::strtol(x
, &end
, 10)};
107 if (n
>= 0 && n
<= 1 && *end
== '\0') {
108 noStopMessage
= n
!= 0;
111 "Fortran runtime: NO_STOP_MESSAGE=%s is invalid; ignored\n", x
);
115 if (auto *x
{std::getenv("DEFAULT_UTF8")}) {
117 auto n
{std::strtol(x
, &end
, 10)};
118 if (n
>= 0 && n
<= 1 && *end
== '\0') {
119 defaultUTF8
= n
!= 0;
122 stderr
, "Fortran runtime: DEFAULT_UTF8=%s is invalid; ignored\n", x
);
126 // TODO: Set RP/ROUND='PROCESSOR_DEFINED' from environment
129 const char *ExecutionEnvironment::GetEnv(
130 const char *name
, std::size_t name_length
, const Terminator
&terminator
) {
131 RUNTIME_CHECK(terminator
, name
&& name_length
);
133 OwningPtr
<char> cStyleName
{
134 SaveDefaultCharacter(name
, name_length
, terminator
)};
135 RUNTIME_CHECK(terminator
, cStyleName
);
137 return std::getenv(cStyleName
.get());
139 } // namespace Fortran::runtime