1 //===-- runtime/environment.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 #include "environment.h" 10 #include "memory.h" 11 #include "tools.h" 12 #include <cstdio> 13 #include <cstdlib> 14 #include <cstring> 15 #include <limits> 16 17 namespace Fortran::runtime { 18 19 ExecutionEnvironment executionEnvironment; 20 21 std::optional<Convert> GetConvertFromString(const char *x, std::size_t n) { 22 static const char *keywords[]{ 23 "UNKNOWN", "NATIVE", "LITTLE_ENDIAN", "BIG_ENDIAN", "SWAP", nullptr}; 24 switch (IdentifyValue(x, n, keywords)) { 25 case 0: 26 return Convert::Unknown; 27 case 1: 28 return Convert::Native; 29 case 2: 30 return Convert::LittleEndian; 31 case 3: 32 return Convert::BigEndian; 33 case 4: 34 return Convert::Swap; 35 default: 36 return std::nullopt; 37 } 38 } 39 40 void ExecutionEnvironment::Configure( 41 int ac, const char *av[], const char *env[]) { 42 argc = ac; 43 argv = av; 44 envp = env; 45 listDirectedOutputLineLengthLimit = 79; // PGI default 46 defaultOutputRoundingMode = 47 decimal::FortranRounding::RoundNearest; // RP(==RN) 48 conversion = Convert::Unknown; 49 50 if (auto *x{std::getenv("FORT_FMT_RECL")}) { 51 char *end; 52 auto n{std::strtol(x, &end, 10)}; 53 if (n > 0 && n < std::numeric_limits<int>::max() && *end == '\0') { 54 listDirectedOutputLineLengthLimit = n; 55 } else { 56 std::fprintf( 57 stderr, "Fortran runtime: FORT_FMT_RECL=%s is invalid; ignored\n", x); 58 } 59 } 60 61 if (auto *x{std::getenv("FORT_CONVERT")}) { 62 if (auto convert{GetConvertFromString(x, std::strlen(x))}) { 63 conversion = *convert; 64 } else { 65 std::fprintf( 66 stderr, "Fortran runtime: FORT_CONVERT=%s is invalid; ignored\n", x); 67 } 68 } 69 70 // TODO: Set RP/ROUND='PROCESSOR_DEFINED' from environment 71 } 72 73 const char *ExecutionEnvironment::GetEnv( 74 const char *name, std::size_t name_length, const Terminator &terminator) { 75 RUNTIME_CHECK(terminator, name && name_length); 76 77 OwningPtr<char> cStyleName{ 78 SaveDefaultCharacter(name, name_length, terminator)}; 79 RUNTIME_CHECK(terminator, cStyleName); 80 81 return std::getenv(cStyleName.get()); 82 } 83 } // namespace Fortran::runtime 84