Line data Source code
1 : #include "kiss/path.h"
2 :
3 : #ifdef WIN32
4 : # include "windows.h"
5 : # ifndef S_ISREG
6 : # define S_ISREG(x) (((x) & S_IFMT) == S_IFREG)
7 : # endif
8 : # ifndef S_ISDIR
9 : # define S_ISDIR(x) (((x) & S_IFMT) == S_IFDIR)
10 : # endif
11 : # include "sys/stat.h"
12 : #else
13 : #include <sys/types.h>
14 : #include <fcntl.h>
15 : #include <unistd.h>
16 : #include <dirent.h>
17 : #include "sys/stat.h"
18 : #endif
19 :
20 : #ifdef __APPLE__
21 : #include <mach-o/dyld.h>
22 : #endif
23 :
24 : #ifndef PATH_MAX
25 : #define PATH_MAX 4096
26 : #endif
27 :
28 : #include <stdexcept>
29 : #include <cstdio>
30 :
31 0 : bool create_directory(const std::string &path, size_t user_permission,
32 : size_t group_permission, size_t other_permission) {
33 : #ifdef WIN32
34 : BOOL result = ::CreateDirectoryA(path.c_str(), 0);
35 : return result == TRUE;
36 : #else
37 : mode_t m = 0;
38 0 : m |= (user_permission << 6);
39 0 : m |= (group_permission << 3);
40 0 : m |= (other_permission << 0);
41 0 : int result = mkdir(path.c_str(), m);
42 0 : return (result == 0);
43 : #endif
44 : }
45 :
46 187 : bool is_directory(const std::string &path) {
47 : #ifdef WIN32
48 : struct _stat buf;
49 : int result = _stat(path.c_str(), &buf);
50 : if (result == 0 && S_ISDIR(buf.st_mode))
51 : return true;
52 : else
53 : return false;
54 : #else
55 : struct stat buf;
56 187 : int result = stat(path.c_str(), &buf);
57 187 : if (result == 0 && S_ISDIR(buf.st_mode))
58 : return true;
59 : else
60 173 : return false;
61 : #endif
62 : }
63 :
64 0 : bool list_directory(const std::string &directory,
65 : std::vector<std::string> &elements) {
66 : #ifdef WIN32
67 : WIN32_FIND_DATA findData;
68 : HANDLE hFind = FindFirstFileA((directory + "\\*.*").c_str(), &findData);
69 : if (hFind == INVALID_HANDLE_VALUE)
70 : throw std::runtime_error("Failed to get directory list");
71 : for (;;) {
72 : if (findData.cFileName[0] != '.') {
73 : elements.push_back(findData.cFileName);
74 : }
75 : if (FindNextFileA(hFind, &findData) == 0)
76 : break;
77 : }
78 : FindClose(hFind);
79 : #else
80 0 : DIR* dir = opendir(directory.c_str());
81 0 : if (dir == NULL)
82 : return false;
83 : dirent* entry;
84 0 : while ((entry = readdir(dir)) != NULL) {
85 0 : if (entry->d_name[0] != '.') {
86 0 : elements.push_back(entry->d_name);
87 : }
88 : }
89 0 : closedir(dir);
90 : #endif
91 0 : return true;
92 : }
93 :
94 0 : bool create_directory_recursive(const std::string &dir, size_t user_permission,
95 : size_t group_permission, size_t other_permission) {
96 : // split path
97 0 : const char seperators[] = "\\/";
98 : std::vector<std::string> elements;
99 : std::string::size_type a, b;
100 : a = dir.find_first_not_of(seperators), b = dir.find_first_of(seperators, a);
101 0 : while (a != std::string::npos) {
102 0 : elements.push_back(dir.substr(a, b - a));
103 : a = dir.find_first_not_of(seperators, b), b = dir.find_first_of(
104 : seperators, a);
105 : }
106 :
107 : // create all non existing parts
108 : std::string path;
109 0 : for (size_t i = 0; i < elements.size(); i++) {
110 : path += elements[i];
111 : path += path_seperator;
112 0 : if (is_directory(path) == false)
113 0 : create_directory(path);
114 : }
115 :
116 0 : return is_directory(dir);
117 0 : }
118 :
119 597 : std::string concat_path(const std::string &a, const std::string &b) {
120 597 : char last = *a.rbegin();
121 597 : if (last == '\\' || last == '/')
122 : return a + b;
123 : else
124 1194 : return a + path_seperator + b;
125 :
126 : }
127 :
128 0 : std::string concat_path(const std::string &a, const std::string &b,
129 : const std::string &c) {
130 : std::string p = a;
131 0 : if (*p.rbegin() != '\\' && *p.rbegin() != '/')
132 : p += path_seperator;
133 : p += b;
134 0 : if (*p.rbegin() != '\\' && *p.rbegin() != '/')
135 : p += path_seperator;
136 : p += c;
137 0 : return p;
138 : }
139 :
140 0 : void append_file(const std::string &target, const std::string &source,
141 : bool binary) {
142 0 : FILE *t = fopen(target.c_str(), binary ? "wb+" : "w+");
143 0 : if (t == NULL)
144 0 : return;
145 :
146 0 : FILE *s = fopen(source.c_str(), binary ? "rb" : "r");
147 0 : if (s == NULL) {
148 0 : fclose(t);
149 0 : return;
150 : }
151 :
152 : size_t size = 0;
153 : char buffer[1 << 20];
154 0 : while ((size = fread(buffer, 1, sizeof(buffer), s)) > 0) {
155 0 : fwrite(buffer, 1, size, t);
156 : }
157 :
158 0 : fclose(t);
159 0 : fclose(s);
160 : }
161 :
162 : // see https://stackoverflow.com/a/60250581
163 14 : std::string executable_path() {
164 : #ifdef __APPLE__
165 : char rawPathName[PATH_MAX];
166 : char realPathName[PATH_MAX];
167 : uint32_t rawPathSize = (uint32_t)sizeof(rawPathName);
168 :
169 : if(!_NSGetExecutablePath(rawPathName, &rawPathSize)) {
170 : realpath(rawPathName, realPathName);
171 : }
172 : return std::string(realPathName) + "/";
173 : #else
174 : char buf[PATH_MAX];
175 :
176 : #ifdef __linux__
177 14 : size_t len = readlink("/proc/self/exe", buf, sizeof(buf)-1);
178 : #elif defined(_WIN32)
179 : size_t len = ::GetModuleFileName(NULL, buf, sizeof(buf)-1 );
180 : #endif // __linux__
181 :
182 202 : for (size_t i = 1; i < len; i++) {
183 198 : if (buf[len - 1] == path_seperator)
184 : break;
185 : else
186 : len --;
187 : }
188 14 : return std::string(buf, len);
189 :
190 : #endif // __APPLE__
191 : }
|