Stride Reference Manual  - generated for commit 9643b11
FileSys.cpp
Go to the documentation of this file.
1 /*
2  * This is free software: you can redistribute it and/or modify it
3  * under the terms of the GNU General Public License as published by
4  * the Free Software Foundation, either version 3 of the License, or
5  * any later version.
6  * The software is distributed in the hope that it will be useful,
7  * but WITHOUT ANY WARRANTY; without even the implied warranty of
8  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9  * GNU General Public License for more details.
10  * You should have received a copy of the GNU General Public License
11  * along with the software. If not, see <http://www.gnu.org/licenses/>.
12  *
13  * Copyright 2017, Kuylen E, Willem L, Broeckhove J
14  */
15 
21 #include "FileSys.h"
22 
23 #include "util/StringUtils.h"
24 
25 #include <boost/property_tree/ptree.hpp>
26 #include <boost/property_tree/xml_parser.hpp>
27 #include <iostream>
28 #include <regex>
29 #include <string>
30 
31 #if defined(WIN32)
32 #include <stdlib.h>
33 #include <windows.h>
34 #elif defined(__linux__)
35 #include <limits.h>
36 #include <unistd.h>
37 #elif defined(__APPLE__)
38 #include <mach-o/dyld.h>
39 #endif
40 
41 namespace {
42 const auto empty_path = filesys::path();
43 }
44 
45 namespace stride {
46 namespace util {
47 
48 using namespace std;
49 using namespace boost::property_tree;
50 using namespace boost::property_tree::xml_parser;
51 
52 filesys::path FileSys::BuildPath(const std::string& output_prefix, const std::string& filename)
53 {
54  filesys::path p = output_prefix;
55  if (FileSys::IsDirectoryString(output_prefix)) {
56  // file <filename> in dircetory <output_prefix>
57  p /= filename;
58  } else {
59  // full name is <output_prefix><filename>
60  p += "_" + filename;
61  }
62  return p;
63 }
64 
65 bool FileSys::CheckInstallEnv(function<void(const string&)> logger)
66 {
67  bool status = true;
68 
69  // Current working dir has to be install root dir.
70  if (GetCurrentDir().compare(GetRootDir()) != 0) {
71  if (logger)
72  logger("Current working dir not install root!");
73  status = false;
74  }
76  if (GetConfigDir().empty()) {
77  if (logger)
78  logger("Config dir not present in install root!");
79  status = false;
80  }
82  if (GetDataDir().empty()) {
83  if (logger)
84  logger("Data dir not present in install root!");
85  status = false;
86  }
88  if (GetTestsDir().empty()) {
89  if (logger)
90  logger("Tests dir not present in install root!");
91  status = false;
92  }
93  return status;
94 }
95 
97 {
98  static Dirs dirs = Initialize();
99  return dirs;
100 }
101 
103 {
104  Dirs dirs;
105  //------- Retrieving path of executable
106  {
107 #if defined(WIN32)
108  char exePath[MAX_PATH];
109  HMODULE hModule = GetModuleHandle(NULL);
110  if (GetModuleFileName(NULL, exePath, sizeof(exePath)) != 0)
111  ;
112  {
113  dirs.m_exec_path = canonical(filesys::absolute(exePath));
114  }
115 #elif defined(__linux__)
116  char exePath[PATH_MAX];
117  auto size = static_cast<std::size_t>(::readlink("/proc/self/exe", exePath, sizeof(exePath)));
118  if (size > 0 && size < sizeof(exePath)) {
119  exePath[size] = '\0';
120  dirs.m_exec_path = canonical(filesys::absolute(exePath));
121  }
122 #elif defined(__APPLE__)
123  char exePath[PATH_MAX];
124  uint32_t size = sizeof(exePath);
125  if (_NSGetExecutablePath(exePath, &size) == 0) {
126  dirs.m_exec_path = canonical(filesys::absolute(exePath));
127  }
128 #endif
129  }
130 
131  //------- Retrieving root and bin directory (the subdirectory of the install root)
132  {
133  filesys::path exec_dir = dirs.m_exec_path.parent_path();
134  if (!dirs.m_exec_path.empty()) {
135 #if (__APPLE__)
136  if (exec_dir.filename().string() == "MacOS") {
137  // app
138  // -Contents <-Root Path
139  // -MacOS
140  // -executables
141  dirs.m_bin_dir = exec_dir;
142  dirs.m_root_dir = exec_dir.parent_path();
143  } else
144 #endif
145  if (ToLower(exec_dir.filename().string()) == "debug" ||
146  ToLower(exec_dir.filename().string()) == "release") {
147  // x/exec <-Root Path
148  // -bin
149  // -release/debug
150  // -executables
151  dirs.m_bin_dir = exec_dir.parent_path();
152  dirs.m_root_dir = exec_dir.parent_path().parent_path();
153  } else
154 #if (WIN32)
155  if (exec_dir.filename().string() != "bin") {
156  // Executables in root folder
157  dirs.m_bin_dir = exec_dir;
158  dirs.m_root_dir = exec_dir;
159  } else
160 #endif
161  {
162  // x/exec <-Root Path
163  // -bin
164  // -executables
165  dirs.m_bin_dir = exec_dir;
166  dirs.m_root_dir = exec_dir.parent_path();
167  }
168  }
169  }
170  //------- Current Dir
171  {
172  dirs.m_current_dir = filesys::absolute(filesys::current_path());
173  }
174  //------- Config Dir
175  {
176  dirs.m_config_dir = dirs.m_root_dir / "config";
177  dirs.m_config_dir = is_directory(dirs.m_config_dir) ? dirs.m_config_dir : empty_path;
178  }
179  //------- Data Dir
180  {
181  dirs.m_data_dir = dirs.m_root_dir / "data";
182  dirs.m_data_dir = is_directory(dirs.m_data_dir) ? dirs.m_data_dir : empty_path;
183  }
184  //------- Tests Dir
185  {
186  dirs.m_tests_dir = dirs.m_root_dir / "tests";
187  dirs.m_tests_dir = is_directory(dirs.m_tests_dir) ? dirs.m_tests_dir : empty_path;
188  }
189 
190  return dirs;
191 }
192 
193 bool FileSys::IsDirectoryString(const string& s)
194 {
195  const auto n = s.find('/');
196  return n != string::npos;
197 }
198 
199 bool FileSys::CreateDirectory(std::string s)
200 {
201  if (std::regex_match(s, std::regex(".*/$"))) {
202  // Strip the trailing / to make it work with std::filesystem
203  s = std::regex_replace(s, std::regex("\\/$"), "");
204  }
205  return filesys::create_directories(filesys::current_path() / s);
206 }
207 
208 ptree FileSys::ReadPtreeFile(const filesys::path& f_p)
209 {
210  ptree ret;
211  if (!exists(f_p) || !is_regular_file(f_p)) {
212  const string s = "FileSys::ReadPtreeFile> Abort! File " + f_p.string() + " not present.";
213  cerr << s << endl;
214  throw runtime_error(s);
215  } else {
216  try {
217  read_xml(canonical(f_p).string(), ret, xml_parser::trim_whitespace);
218  } catch (xml_parser_error& e) {
219  const string s = "FileSys::ReadPtreeFile> Abort! Error reading " + f_p.string();
220  cerr << s << endl;
221  throw runtime_error(s);
222  }
223  }
224  return ret;
225 }
226 
227 ptree FileSys::ReadPtreeFile(const string& f_n) { return ReadPtreeFile(filesys::absolute(f_n)); }
228 
229 void FileSys::WritePtreeFile(const filesys::path& f_p, const boost::property_tree::ptree& pt)
230 {
231  try {
232  write_xml(f_p.string(), pt, std::locale(), xml_writer_make_settings<ptree::key_type>(' ', 8));
233  } catch (xml_parser_error& e) {
234  const string s = "FileSys::ReadPtreeFile> Abort! Error reading " + f_p.string();
235  cerr << s << endl;
236  throw runtime_error(s);
237  }
238 }
239 
240 void FileSys::WritePtreeFile(const string& f_n, const boost::property_tree::ptree& pt)
241 {
242  WritePtreeFile(filesys::absolute(f_n), pt);
243 }
244 
245 } // namespace util
246 } // namespace stride
static Dirs Initialize()
Initialize all paths.
Definition: FileSys.cpp:102
filesys::path m_config_dir
Definition: FileSys.h:109
filesys::path m_bin_dir
Definition: FileSys.h:108
filesys::path m_data_dir
Definition: FileSys.h:110
static bool CreateDirectory(std::string s)
Create a directory relative to the current directory with the given path, returns if it was succesful...
Definition: FileSys.cpp:199
filesys::path m_root_dir
Definition: FileSys.h:111
static boost::property_tree::ptree ReadPtreeFile(const filesys::path &f_p)
Read ptree from file at path.
Definition: FileSys.cpp:208
STL namespace.
static Dirs & Get()
Return paths.
Definition: FileSys.cpp:96
filesys::path m_exec_path
Definition: FileSys.h:105
static bool CheckInstallEnv(std::function< void(const std::string &)> logger=std::function< void(const std::string &)>())
Verify that current dir is root dir and all install dirs are present.
Definition: FileSys.cpp:65
static filesys::path BuildPath(const std::string &output_prefix, const std::string &filename)
Interpret prefix (directory or filename prefix) and return appropriate path.
Definition: FileSys.cpp:52
filesys::path m_tests_dir
Definition: FileSys.h:112
static void WritePtreeFile(const filesys::path &f_p, const boost::property_tree::ptree &pt)
Write ptree to file at path.
Definition: FileSys.cpp:229
static bool IsDirectoryString(const std::string &s)
String represents a directory path (relative or absolute) iff it contains at least one / (may be a tr...
Definition: FileSys.cpp:193
Miscellaneous string utilities.
Interface for install directory queries.
Namespace for the simulator and related classes.
Definition: Calendar.cpp:28
filesys::path m_current_dir
Definition: FileSys.h:102
Using this to avoid global variables & their initialization.
Definition: FileSys.h:98
std::string ToLower(const std::string &source)
Builds a string with lower case characters only.
Definition: StringUtils.h:135