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