Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
FoundationUtils.cxx
Go to the documentation of this file.
1 /// \file FoundationUtils.hxx
2 ///
3 /// \brief The file contains utilities which are foundational and could be used
4 /// across the core component of ROOT.
5 ///
6 ///
7 /// \author Vassil Vassilev <vvasilev@cern.ch>
8 ///
9 /// \date June, 2019
10 ///
11 /*************************************************************************
12  * Copyright (C) 1995-2019, Rene Brun and Fons Rademakers. *
13  * All rights reserved. *
14  * *
15  * For the licensing terms see $ROOTSYS/LICENSE. *
16  * For the list of contributors see $ROOTSYS/README/CREDITS. *
17  *************************************************************************/
18 
19 #include <ROOT/FoundationUtils.hxx>
20 
21 #include <RConfigure.h>
22 
23 #include <algorithm>
24 
25 #include <errno.h>
26 #include <string.h>
27 #ifdef _WIN32
28 #include <direct.h>
29 #include <Windows4Root.h>
30 #else
31 #include <unistd.h>
32 #endif // _WIN32
33 
34 namespace ROOT {
35 namespace FoundationUtils {
36 std::string GetCurrentDir()
37 {
38  char fixedLength[1024];
39  char *currWorkDir = fixedLength;
40  size_t len = 1024;
41  char *result = currWorkDir;
42 
43  do {
44  if (result == 0) {
45  len = 2 * len;
46  if (fixedLength != currWorkDir) {
47  delete[] currWorkDir;
48  }
49  currWorkDir = new char[len];
50  }
51 #ifdef WIN32
52  result = ::_getcwd(currWorkDir, len);
53 #else
54  result = getcwd(currWorkDir, len);
55 #endif
56  } while (result == 0 && errno == ERANGE);
57 
58  std::string output = currWorkDir;
59  output += '/';
60 #ifdef WIN32
61  // convert backslashes into forward slashes
62  std::replace(output.begin(), output.end(), '\\', '/');
63 #endif
64 
65  if (fixedLength != currWorkDir) {
66  delete[] currWorkDir;
67  }
68  return output;
69 }
70 
71 std::string MakePathRelative(const std::string &path, const std::string &base, bool isBuildingROOT /* = false*/)
72 {
73  std::string result(path);
74 
75  const char *currWorkDir = base.c_str();
76  size_t lenCurrWorkDir = strlen(currWorkDir);
77  if (result.substr(0, lenCurrWorkDir) == currWorkDir) {
78  // Convert to path relative to $PWD.
79  // If that's not what the caller wants, she should pass -I to rootcling and a
80  // different relative path to the header files.
81  result.erase(0, lenCurrWorkDir);
82  }
83  // FIXME: This is not a generic approach for an interface. We should rework
84  // this part.
85  if (isBuildingROOT) {
86  // For ROOT, convert module directories like core/base/inc/ to include/
87  int posInc = result.find("/inc/");
88  if (posInc != -1) {
89  result = /*std::string("include") +*/ result.substr(posInc + 5, -1);
90  }
91  }
92  return result;
93 }
94 
95 /// Transforms a file path by replacing its backslashes with slashes.
96 void ConvertToUnixPath(std::string& Path) {
97  std::replace(Path.begin(), Path.end(), '\\', '/');
98 }
99 
100 const std::string& GetFallbackRootSys() {
101  static std::string fallback;
102  if (!fallback.empty())
103  return fallback;
104 #ifdef WIN32
105  static char lpFilename[_MAX_PATH];
106  if (::GetModuleFileNameA(
107  NULL, // handle to module to find filename for
108  lpFilename, // pointer to buffer to receive module path
109  sizeof(lpFilename))) { // size of buffer, in characters
110  auto parent_path = [](std::string path) {
111  return path.substr(0, path.find_last_of("/\\"));
112  };
113  fallback = parent_path(parent_path(lpFilename));
114  }
115 #else
116  // FIXME: We should not hardcode this path. We can use a similar to the
117  // windows technique to get the path to the executable. The easiest way
118  // to do this is to depend on LLVMSupport and use getMainExecutable.
119  fallback = "/usr/local/root";
120 #endif
121  return fallback;
122 }
123 
124 #ifdef ROOTPREFIX
125 static bool IgnorePrefix() {
126  static bool ignorePrefix = ::getenv("ROOTIGNOREPREFIX");
127  return ignorePrefix;
128 }
129 #endif
130 
131 const std::string& GetRootSys() {
132 #ifdef ROOTPREFIX
133  if (!IgnorePrefix()) {
134  const static std::string rootsys = ROOTPREFIX;
135  return rootsys;
136  }
137 #endif
138  static std::string rootsys;
139  if (rootsys.empty()) {
140  if (const char* envValue = ::getenv("ROOTSYS")) {
141  rootsys = envValue;
142  // We cannot use gSystem->UnixPathName.
143  ConvertToUnixPath(rootsys);
144  }
145  }
146  // FIXME: Should this also call UnixPathName for consistency?
147  if (rootsys.empty())
148  rootsys = GetFallbackRootSys();
149  return rootsys;
150 }
151 
152 
153 const std::string& GetIncludeDir() {
154 #ifdef ROOTINCDIR
155  if (!IgnorePrefix()) {
156  const static std::string rootincdir = ROOTINCDIR;
157  return rootincdir;
158  }
159 #endif
160  static std::string rootincdir;
161  if (rootincdir.empty()) {
162  const std::string& sep = GetPathSeparator();
163  rootincdir = GetRootSys() + sep + "include" + sep;
164  }
165  return rootincdir;
166 }
167 
168 const std::string& GetEtcDir() {
169 #ifdef ROOTETCDIR
170  if (!IgnorePrefix()) {
171  const static std::string rootetcdir = ROOTETCDIR;
172  return rootetcdir;
173  }
174 #endif
175 
176  const static std::string rootetcdir =
177  GetRootSys() + GetPathSeparator() + "etc" + GetPathSeparator();;
178  return rootetcdir;
179 }
180 
181 } // namespace FoundationUtils
182 } // namespace ROOT