@@ -20,6 +20,7 @@ Date: January 2012
20
20
#include < dirent.h>
21
21
#include < cstdlib>
22
22
#include < cstdio>
23
+ #include < sys/stat.h>
23
24
#endif
24
25
25
26
#ifdef _WIN32
@@ -33,6 +34,7 @@ Date: January 2012
33
34
34
35
#include " file_util.h"
35
36
37
+
36
38
/* ******************************************************************\
37
39
38
40
Function: get_current_working_directory
@@ -144,3 +146,191 @@ std::string concat_dir_file(
144
146
file_name : directory+" /" +file_name;
145
147
#endif
146
148
}
149
+
150
+
151
+
152
+
153
+
154
+ #include < fstream>
155
+ #include < cstdlib>
156
+ #include < algorithm>
157
+ #include < sstream>
158
+ #include < vector>
159
+
160
+ #if defined(WIN32)
161
+ # include < windows.h>
162
+ #elif defined(__linux__) || defined(__APPLE__)
163
+ # include < sys/stat.h>
164
+ #endif
165
+
166
+ namespace fileutl { namespace {
167
+
168
+
169
+ std::string::size_type parse_last_dir_pos (std::string const & file_pathname)
170
+ {
171
+ std::string::size_type const last_slash_pos = file_pathname.find_last_of (' /' );
172
+ std::string::size_type const last_backslash_pos = file_pathname.find_last_of (' \\ ' );
173
+ std::string::size_type const last_dir_pos =
174
+ last_slash_pos == std::string::npos ?
175
+ (last_backslash_pos == std::string::npos ? 0ULL :
176
+ last_backslash_pos + 1ULL ) :
177
+ (last_backslash_pos == std::string::npos ? last_slash_pos + 1ULL :
178
+ (last_slash_pos < last_backslash_pos ? last_backslash_pos :
179
+ last_slash_pos))
180
+ ;
181
+ return last_dir_pos;
182
+ }
183
+
184
+
185
+ }}
186
+
187
+ namespace fileutl {
188
+
189
+
190
+ bool file_exists (std::string const & pathname)
191
+ {
192
+ std::ifstream f{pathname,std::ios::binary};
193
+ return f.good ();
194
+ }
195
+
196
+ bool is_directory (std::string const & pathname)
197
+ {
198
+ if (!file_exists (pathname))
199
+ return false ;
200
+ # if defined(WIN32)
201
+ return PathIsDirectory (pathname.c_str ());
202
+ # elif defined(__linux__) || defined(__APPLE__)
203
+ struct stat buf;
204
+ stat (pathname.c_str (), &buf);
205
+ return S_ISDIR (buf.st_mode );
206
+ // return S_ISREG(buf.st_mode); // is file ?
207
+ # else
208
+ # error "Unsuported platform."
209
+ # endif
210
+ }
211
+
212
+ uint64_t file_size (std::string const & file_pathname)
213
+ {
214
+ std::ifstream f{file_pathname,std::ios::binary};
215
+ std::streampos const begin = f.tellg ();
216
+ f.seekg (0ULL ,std::ios::end);
217
+ std::streampos const end = f.tellg ();
218
+ return end - begin;
219
+ }
220
+
221
+ std::string parse_name_in_pathname (std::string const & file_pathname)
222
+ {
223
+ return file_pathname.substr (parse_last_dir_pos (file_pathname));
224
+ }
225
+
226
+ std::string parse_path_in_pathname (std::string const & file_pathname)
227
+ {
228
+ return file_pathname.substr (0U ,parse_last_dir_pos (file_pathname));
229
+ }
230
+
231
+ std::string remove_extension (std::string const & filename)
232
+ {
233
+ return filename.substr (0U ,filename.find_last_of (' .' ));
234
+ }
235
+
236
+ void create_directory (std::string const & pathname)
237
+ {
238
+ # if defined(WIN32)
239
+ std::system ((std::string (" mkdir \" " ) + pathname + " \" " ).c_str ());
240
+ # elif defined(__linux__) || defined(__APPLE__)
241
+ auto ignore = std::system ((std::string (" mkdir -p \" " ) + pathname + " \" " ).c_str ());
242
+ (void )ignore;
243
+ # else
244
+ # error "Unsuported platform."
245
+ # endif
246
+ }
247
+
248
+ std::string concatenate_file_paths (std::string const & left_path, std::string const & right_path)
249
+ {
250
+ if (left_path.empty ())
251
+ return right_path;
252
+ if (right_path.empty ())
253
+ return left_path;
254
+ return left_path + " /" + right_path;
255
+ }
256
+
257
+ std::string absolute_path (std::string const & path)
258
+ {
259
+ // TODO: portability - this implementation won't probably work on Windows...
260
+ std::vector<char > buffer (10000 ,0 );
261
+ return realpath (path.c_str (),&buffer.at (0 ));
262
+ }
263
+
264
+ std::string normalise_path (std::string const & path)
265
+ {
266
+ std::string result = path;
267
+ std::replace (result.begin (),result.end (),' \\ ' ,' /' );
268
+ std::string::size_type pos = 0 ;
269
+ while ((pos = result.find (" /./" ,0 )) != std::string::npos)
270
+ result.replace (pos,3 ," /" );
271
+ // TODO: more fixes should be applied (e.g. /../, //, etc.)
272
+ return result;
273
+ }
274
+
275
+ void split_pathname (std::string const & pathname, std::vector<std::string>& output)
276
+ {
277
+ std::istringstream istr (normalise_path (pathname));
278
+ std::string token;
279
+ while (std::getline (istr,token,' /' ))
280
+ output.push_back (token);
281
+ }
282
+
283
+ std::string join_path_parts (std::vector<std::string> const & parts)
284
+ {
285
+ if (parts.empty ())
286
+ return " " ;
287
+ std::string result = parts.at (0 );
288
+ for (uint64_t i = 1ULL ; i < parts.size (); ++i)
289
+ {
290
+ result.push_back (' /' );
291
+ result.append (parts.at (i));
292
+ }
293
+ return result;
294
+ }
295
+
296
+ std::string get_common_preffix (std::string const & pathname1, std::string const & pathname2)
297
+ {
298
+ std::vector<std::string> split1;
299
+ split_pathname (pathname1,split1);
300
+
301
+ std::vector<std::string> split2;
302
+ split_pathname (pathname2,split2);
303
+
304
+ std::vector<std::string> common_split;
305
+ for (uint64_t i = 0ULL , size = std::min (split1.size (),split2.size ());
306
+ i < size && split1.at (i) == split2.at (i);
307
+ ++i)
308
+ common_split.push_back (split1.at (i));
309
+
310
+ std::string const result = join_path_parts (common_split);
311
+ return result;
312
+ }
313
+
314
+ std::string get_relative_path (std::string const & pathname, std::string const & directory)
315
+ {
316
+ std::vector<std::string> split1;
317
+ split_pathname (pathname,split1);
318
+ std::reverse (split1.begin (),split1.end ());
319
+
320
+ std::vector<std::string> split2;
321
+ split_pathname (directory,split2);
322
+ std::reverse (split2.begin (),split2.end ());
323
+
324
+ while (!split1.empty () && !split2.empty () && split1.back () == split2.back ())
325
+ {
326
+ split1.pop_back ();
327
+ split2.pop_back ();
328
+ }
329
+
330
+ std::reverse (split1.begin (),split1.end ());
331
+ std::string const result = join_path_parts (split1);
332
+ return result;
333
+ }
334
+
335
+
336
+ }
0 commit comments