From e24b4ec1a0fb3ba58a8ea67cd8d8affe3c5a0a71 Mon Sep 17 00:00:00 2001 From: Daniel Karbach Date: Fri, 7 Aug 2015 15:04:47 +0200 Subject: [PATCH] (hopefully) cross-platform directory functions --- src/app/io.cpp | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/app/io.hpp | 22 +++++++++++++++ 2 files changed, 97 insertions(+) create mode 100644 src/app/io.cpp create mode 100644 src/app/io.hpp diff --git a/src/app/io.cpp b/src/app/io.cpp new file mode 100644 index 0000000..7996be6 --- /dev/null +++ b/src/app/io.cpp @@ -0,0 +1,75 @@ +#include "io.hpp" + +#include +#ifdef _WIN32 +# include +#endif +#include + + +namespace blank { + +bool is_dir(const char *path) { +#ifdef _WIN32 + struct _stat info; + if (_stat(path, &info) != 0) { + return false; + } + return (info.st_mode & _S_IFDIR) != 0; +#else + struct stat info; + if (stat(path, &info) != 0) { + return false; + } + return (info.st_mode & S_IFDIR) != 0; +#endif +} + + +bool make_dir(const char *path) { +#ifdef _WIN32 + int ret = _mkdir(path); +#else + int ret = mkdir(path, 0777); +#endif + return ret == 0; +} + + +bool make_dirs(const std::string &path) { + if (make_dir(path.c_str())) { + return true; + } + + switch (errno) { + + case ENOENT: + // missing component + { +#ifdef _WIN32 + auto pos = path.find_last_of("\\/"); +#else + auto pos = path.find_last_of('/'); +#endif + if (pos == std::string::npos) { + return false; + } + if (!make_dirs(path.substr(0, pos))) { + return false; + } + } + // try again + return make_dir(path.c_str()); + + case EEXIST: + // something's there, check if it's a dir and we're good + return is_dir(path.c_str()); + + default: + // whatever else went wrong, it can't be good + return false; + + } +} + +} diff --git a/src/app/io.hpp b/src/app/io.hpp new file mode 100644 index 0000000..4869238 --- /dev/null +++ b/src/app/io.hpp @@ -0,0 +1,22 @@ +#ifndef BLANK_APP_IO_HPP_ +#define BLANK_APP_IO_HPP_ + +#include + + +namespace blank { + +/// check if give path points to an existing directory +bool is_dir(const char *); + +/// create given directory +/// @return true if the directory was created +/// the directory might already exist, see errno +bool make_dir(const char *); +/// create given directory and all parents +/// @return true if the directory was created or already exists +bool make_dirs(const std::string &); + +} + +#endif -- 2.39.2