treelite
filesystem.h
Go to the documentation of this file.
1 
7 #ifndef TREELITE_COMMON_FILESYSTEM_H_
8 #define TREELITE_COMMON_FILESYSTEM_H_
9 
10 #include <dmlc/logging.h>
11 
12 #ifdef _WIN32
13 #define NOMINMAX
14 #include <windows.h>
15 #include <cstdlib>
16 #else
17 #include <errno.h>
18 #include <fcntl.h>
19 #include <sys/stat.h>
20 #include <sys/types.h>
21 #include <libgen.h>
22 #include <cstring>
23 #endif
24 
25 namespace treelite {
26 namespace common {
27 namespace filesystem {
28 
37 inline std::string GetBasename(const std::string& path) {
38 #ifdef _WIN32
39  /* remove any trailing backward or forward slashes
40  (UNIX does this automatically) */
41  std::string path_;
42  std::string::size_type tmp = path.find_last_of("/\\");
43  if (tmp == path.length() - 1) {
44  size_t i = tmp;
45  while ((path[i] == '/' || path[i] == '\\') && i >= 0) {
46  --i;
47  }
48  path_ = path.substr(0, i + 1);
49  } else {
50  path_ = path;
51  }
52  std::vector<char> fname(path_.length() + 1);
53  std::vector<char> ext(path_.length() + 1);
54  _splitpath_s(path_.c_str(), NULL, 0, NULL, 0,
55  &fname[0], path_.length() + 1, &ext[0], path_.length() + 1);
56  return std::string(&fname[0]) + std::string(&ext[0]);
57 #else
58  char* path_ = strdup(path.c_str());
59  char* base = basename(path_);
60  std::string ret(base);
61  free(path_);
62  return ret;
63 #endif
64 }
65 
66 inline void HandleSystemError(const std::string& msg) {
67 #ifdef _WIN32
68  LPVOID msg_buf;
69  DWORD dw = GetLastError();
70  FormatMessage(
71  FORMAT_MESSAGE_ALLOCATE_BUFFER |
72  FORMAT_MESSAGE_FROM_SYSTEM |
73  FORMAT_MESSAGE_IGNORE_INSERTS,
74  NULL,
75  dw,
76  MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
77  (LPTSTR)&msg_buf,
78  0, NULL);
79  const std::string msg_err(static_cast<const char*>(msg_buf));
80  LocalFree(msg_buf);
81 #else
82  const std::string msg_err(strerror(errno));
83 #endif
84  LOG(FATAL) << msg << "\nReason: " << msg_err;
85 }
86 
87 inline void CreateDirectoryIfNotExist(const char* dirpath) {
88 #ifdef _WIN32
89  DWORD ftyp = GetFileAttributesA(dirpath);
90  if (ftyp == INVALID_FILE_ATTRIBUTES) {
91  // directory doesn't seem to exist; attempt to create one
92  if (CreateDirectoryA(dirpath, NULL) == 0) {
93  // failed to create a new directory
94  HandleSystemError(std::string("CreateDirectoryIfNotExist: "
95  "failed to create new directory ") + dirpath);
96  }
97  } else {
98  if (!(ftyp & FILE_ATTRIBUTE_DIRECTORY)) {
99  LOG(FATAL) << "CreateDirectoryIfNotExist: "
100  << dirpath << " is a file, not a directory";
101  }
102  }
103 #else
104  struct stat sb;
105  if (stat(dirpath, &sb) != 0) {
106  // directory doesn't seem to exist; attempt to create one
107  if (mkdir(dirpath, S_IRUSR | S_IWUSR | S_IXUSR) != 0) {
108  // failed to create a new directory
109  HandleSystemError(std::string("CreateDirectoryIfNotExist: "
110  "failed to create new directory ") + dirpath);
111  }
112  } else {
113  if (!S_ISDIR(sb.st_mode)) {
114  LOG(FATAL) << "CreateDirectoryIfNotExist: "
115  << dirpath << " is a file, not a directory";
116  }
117  }
118 #endif
119 }
120 
121 } // namespace filesystem
122 } // namespace common
123 } // namespace treelite
124 
125 #endif // TREELITE_COMMON_FILESYSTEM_H_
std::string GetBasename(const std::string &path)
extract the base name from a full path. The base name is defined as the component that follows the la...
Definition: filesystem.h:37