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