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