Mercurial > code
changeset 547:ecf5fb9319da
Fs: switch to spaces, add FS_EXPORT
author | David Demelier <markand@malikania.fr> |
---|---|
date | Wed, 15 Jun 2016 11:59:17 +0200 |
parents | 40c27081958a |
children | f48bb09bccc7 |
files | CMakeLists.txt modules/fs/fs.cpp modules/fs/fs.hpp |
diffstat | 3 files changed, 243 insertions(+), 222 deletions(-) [+] |
line wrap: on
line diff
--- a/CMakeLists.txt Tue Jun 14 17:04:25 2016 +0200 +++ b/CMakeLists.txt Wed Jun 15 11:59:17 2016 +0200 @@ -19,6 +19,9 @@ cmake_minimum_required(VERSION 3.5) project(code) +set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD_REQUIRED On) + include(${code_SOURCE_DIR}/cmake/CodeDefineModule.cmake) add_subdirectory(extern)
--- a/modules/fs/fs.cpp Tue Jun 14 17:04:25 2016 +0200 +++ b/modules/fs/fs.cpp Wed Jun 15 11:59:17 2016 +0200 @@ -54,22 +54,22 @@ std::string error() { - LPSTR error = nullptr; - std::string errmsg = "Unknown error"; + LPSTR error = nullptr; + std::string errmsg = "Unknown error"; - FormatMessageA( - FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, - nullptr, - GetLastError(), - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPSTR)&error, 0, nullptr); + FormatMessageA( + FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, + nullptr, + GetLastError(), + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPSTR)&error, 0, nullptr); - if (error) { - errmsg = std::string(error); - LocalFree(error); - } + if (error) { + errmsg = std::string(error); + LocalFree(error); + } - return errmsg; + return errmsg; } #endif @@ -82,17 +82,17 @@ */ bool hasAccess(const std::string &path, const std::string &mode) { - assert(mode.length() == 1); - assert(mode[0] == 'r' || mode[0] == 'w'); + assert(mode.length() == 1); + assert(mode[0] == 'r' || mode[0] == 'w'); - auto fp = std::fopen(path.c_str(), mode.c_str()); + auto fp = std::fopen(path.c_str(), mode.c_str()); - if (fp == nullptr) - return false; + if (fp == nullptr) + return false; - std::fclose(fp); + std::fclose(fp); - return true; + return true; } /* @@ -110,12 +110,12 @@ template <typename Predicate> bool typeOf(const std::string &path, Predicate &&predicate) { - DWORD result = GetFileAttributesA(path.c_str()); + DWORD result = GetFileAttributesA(path.c_str()); - if (result == INVALID_FILE_ATTRIBUTES) - return false; + if (result == INVALID_FILE_ATTRIBUTES) + return false; - return predicate(result); + return predicate(result); } #elif defined(FS_HAVE_STAT) @@ -123,12 +123,12 @@ template <typename Predicate> bool typeOf(const std::string &path, Predicate &&predicate) noexcept { - struct stat st; + struct stat st; - if (::stat(path.c_str(), &st) < 0) - return false; + if (::stat(path.c_str(), &st) < 0) + return false; - return predicate(st); + return predicate(st); } #else @@ -136,7 +136,7 @@ template <typename Predicate> bool typeOf(const std::string &path, Predicate &&predicate) noexcept { - throw std::runtime_error(std::strerror(ENOSYS)); + throw std::runtime_error(std::strerror(ENOSYS)); } #endif @@ -149,28 +149,28 @@ */ std::string clean(std::string input) { - if (input.empty()) - return input; + if (input.empty()) + return input; - /* First, remove any duplicates */ - input.erase(std::unique(input.begin(), input.end(), [&] (char c1, char c2) { - return c1 == c2 && (c1 == '/' || c1 == '\\'); - }), input.end()); + // First, remove any duplicates. + input.erase(std::unique(input.begin(), input.end(), [&] (char c1, char c2) { + return c1 == c2 && (c1 == '/' || c1 == '\\'); + }), input.end()); - /* Add a trailing / or \\ */ - char c = input[input.length() - 1]; + // Add a trailing / or \\. + char c = input[input.length() - 1]; - if (c != '/' && c != '\\') - input += separator(); + if (c != '/' && c != '\\') + input += separator(); - /* Now converts all / to \\ for Windows and the opposite for Unix */ + // Now converts all / to \\ for Windows and the opposite for Unix. #if defined(_WIN32) - std::replace(input.begin(), input.end(), '/', '\\'); + std::replace(input.begin(), input.end(), '/', '\\'); #else - std::replace(input.begin(), input.end(), '\\', '/'); + std::replace(input.begin(), input.end(), '\\', '/'); #endif - return input; + return input; } /* @@ -179,12 +179,12 @@ */ std::string baseName(std::string path) { - auto pos = path.find_last_of("\\/"); + auto pos = path.find_last_of("\\/"); - if (pos != std::string::npos) - path = path.substr(pos + 1); + if (pos != std::string::npos) + path = path.substr(pos + 1); - return path; + return path; } /* @@ -193,14 +193,14 @@ */ std::string dirName(std::string path) { - auto pos = path.find_last_of("\\/"); + auto pos = path.find_last_of("\\/"); - if (pos == std::string::npos) - path = "."; - else - path = path.substr(0, pos); + if (pos == std::string::npos) + path = "."; + else + path = path.substr(0, pos); - return path; + return path; } /* @@ -210,9 +210,9 @@ bool isAbsolute(const std::string &path) noexcept { #if defined(_WIN32) - return !isRelative(path); + return !isRelative(path); #else - return path.size() > 0 && path[0] == '/'; + return path.size() > 0 && path[0] == '/'; #endif } @@ -223,9 +223,9 @@ bool isRelative(const std::string &path) noexcept { #if defined(_WIN32) - return PathIsRelativeA(path.c_str()) == 1; + return PathIsRelativeA(path.c_str()) == 1; #else - return !isAbsolute(path); + return !isAbsolute(path); #endif } @@ -235,7 +235,7 @@ */ bool isReadable(const std::string &path) noexcept { - return hasAccess(path, "r"); + return hasAccess(path, "r"); } /* @@ -244,7 +244,7 @@ */ bool isWritable(const std::string &path) noexcept { - return hasAccess(path, "w"); + return hasAccess(path, "w"); } /* @@ -253,13 +253,13 @@ */ bool isFile(const std::string &path) { - return typeOf(path, [] (const auto &object) { + return typeOf(path, [] (const auto &object) { #if defined(_WIN32) - return (object & FILE_ATTRIBUTE_ARCHIVE) == FILE_ATTRIBUTE_ARCHIVE; + return (object & FILE_ATTRIBUTE_ARCHIVE) == FILE_ATTRIBUTE_ARCHIVE; #elif defined(FS_HAVE_STAT) - return S_ISREG(object.st_mode); + return S_ISREG(object.st_mode); #endif - }); + }); } /* @@ -268,13 +268,13 @@ */ bool isDirectory(const std::string &path) { - return typeOf(path, [] (const auto &object) { + return typeOf(path, [] (const auto &object) { #if defined(_WIN32) - return (object & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY; + return (object & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY; #elif defined(FS_HAVE_STAT) - return S_ISDIR(object.st_mode); + return S_ISDIR(object.st_mode); #endif - }); + }); } /* @@ -283,13 +283,13 @@ */ bool isSymlink(const std::string &path) { - return typeOf(path, [] (const auto &object) { + return typeOf(path, [] (const auto &object) { #if defined(_WIN32) - return (object & FILE_ATTRIBUTE_REPARSE_POINT) == FILE_ATTRIBUTE_REPARSE_POINT; + return (object & FILE_ATTRIBUTE_REPARSE_POINT) == FILE_ATTRIBUTE_REPARSE_POINT; #elif defined(FS_HAVE_STAT) - return S_ISLNK(object.st_mode); + return S_ISLNK(object.st_mode); #endif - }); + }); } /* @@ -300,12 +300,12 @@ struct stat stat(const std::string &path) { - struct stat st; + struct stat st; - if (::stat(path.c_str(), &st) < 0) - throw std::runtime_error(std::strerror(errno)); + if (::stat(path.c_str(), &st) < 0) + throw std::runtime_error(std::strerror(errno)); - return st; + return st; } #endif @@ -317,11 +317,11 @@ bool exists(const std::string &path) noexcept { #if defined(FS_HAVE_STAT) - struct stat st; + struct stat st; - return ::stat(path.c_str(), &st) == 0; + return ::stat(path.c_str(), &st) == 0; #else - return hasAccess(path, "r"); + return hasAccess(path, "r"); #endif } @@ -331,84 +331,84 @@ */ std::vector<Entry> readdir(const std::string &path, int flags) { - std::vector<Entry> entries; + std::vector<Entry> entries; #if defined(_WIN32) - std::ostringstream oss; - HANDLE handle; - WIN32_FIND_DATA fdata; + std::ostringstream oss; + HANDLE handle; + WIN32_FIND_DATA fdata; - oss << path << "\\*"; - handle = FindFirstFile(oss.str().c_str(), &fdata); + oss << path << "\\*"; + handle = FindFirstFile(oss.str().c_str(), &fdata); - if (handle == nullptr) - throw std::runtime_error(error()); + if (handle == nullptr) + throw std::runtime_error(error()); - do { - Entry entry; + do { + Entry entry; - entry.name = fdata.cFileName; + entry.name = fdata.cFileName; - if (entry.name == "." && !(flags & Dot)) - continue; - if (entry.name == ".." && !(flags & DotDot)) - continue; + if (entry.name == "." && !(flags & Dot)) + continue; + if (entry.name == ".." && !(flags & DotDot)) + continue; - switch (fdata.dwFileAttributes) { - case FILE_ATTRIBUTE_DIRECTORY: - entry.type = Entry::Dir; - break; - case FILE_ATTRIBUTE_NORMAL: - entry.type = Entry::File; - break; - case FILE_ATTRIBUTE_REPARSE_POINT: - entry.type = Entry::Link; - break; - default: - break; - } + switch (fdata.dwFileAttributes) { + case FILE_ATTRIBUTE_DIRECTORY: + entry.type = Entry::Dir; + break; + case FILE_ATTRIBUTE_NORMAL: + entry.type = Entry::File; + break; + case FILE_ATTRIBUTE_REPARSE_POINT: + entry.type = Entry::Link; + break; + default: + break; + } - entries.push_back(std::move(entry)); - } while (FindNextFile(handle, &fdata) != 0); + entries.push_back(std::move(entry)); + } while (FindNextFile(handle, &fdata) != 0); - FindClose(handle); + FindClose(handle); #else - DIR *dp; - struct dirent *ent; + DIR *dp; + struct dirent *ent; - if ((dp = opendir(path.c_str())) == nullptr) - throw std::runtime_error(std::strerror(errno)); + if ((dp = opendir(path.c_str())) == nullptr) + throw std::runtime_error(std::strerror(errno)); - while ((ent = readdir(dp)) != nullptr) { - Entry entry; + while ((ent = readdir(dp)) != nullptr) { + Entry entry; - entry.name = ent->d_name; - if (entry.name == "." && !(flags & Dot)) - continue; - if (entry.name == ".." && !(flags & DotDot)) - continue; + entry.name = ent->d_name; + if (entry.name == "." && !(flags & Dot)) + continue; + if (entry.name == ".." && !(flags & DotDot)) + continue; - switch (ent->d_type) { - case DT_DIR: - entry.type = Entry::Dir; - break; - case DT_REG: - entry.type = Entry::File; - break; - case DT_LNK: - entry.type = Entry::Link; - break; - default: - break; - } + switch (ent->d_type) { + case DT_DIR: + entry.type = Entry::Dir; + break; + case DT_REG: + entry.type = Entry::File; + break; + case DT_LNK: + entry.type = Entry::Link; + break; + default: + break; + } - entries.push_back(std::move(entry)); - } + entries.push_back(std::move(entry)); + } - closedir(dp); + closedir(dp); #endif - return entries; + return entries; } /* @@ -417,28 +417,28 @@ */ void mkdir(const std::string &path, int mode) { - std::string::size_type next = 0; - std::string part; + std::string::size_type next = 0; + std::string part; - for (;;) { - next = path.find_first_of("\\/", next); - part = path.substr(0, next); + for (;;) { + next = path.find_first_of("\\/", next); + part = path.substr(0, next); - if (!part.empty()) { + if (!part.empty()) { #if defined(_WIN32) - (void)mode; + (void)mode; - if (::_mkdir(part.c_str()) < 0 && errno != EEXIST) - throw std::runtime_error(std::strerror(errno)); + if (::_mkdir(part.c_str()) < 0 && errno != EEXIST) + throw std::runtime_error(std::strerror(errno)); #else - if (::mkdir(part.c_str(), mode) < 0 && errno != EEXIST) - throw std::runtime_error(std::strerror(errno)); + if (::mkdir(part.c_str(), mode) < 0 && errno != EEXIST) + throw std::runtime_error(std::strerror(errno)); #endif - } + } - if (next++ == std::string::npos) - break; - } + if (next++ == std::string::npos) + break; + } } /* @@ -447,23 +447,23 @@ */ void rmdir(const std::string &base) noexcept { - try { - for (const auto &entry : readdir(base)) { - std::string path = base + separator() + entry.name; + try { + for (const auto &entry : readdir(base)) { + std::string path = base + separator() + entry.name; - if (entry.type == Entry::Dir) - rmdir(path); - else - remove(path.c_str()); - } - } catch (...) { - /* Silently discard to remove as much as possible */ - } + if (entry.type == Entry::Dir) + rmdir(path); + else + ::remove(path.c_str()); + } + } catch (...) { + // Silently discard to remove as much as possible. + } #if defined(_WIN32) - RemoveDirectoryA(base.c_str()); + ::RemoveDirectoryA(base.c_str()); #else - remove(base.c_str()); + ::remove(base.c_str()); #endif } @@ -474,19 +474,19 @@ std::string cwd() { #if defined(_WIN32) - char path[MAX_PATH]; + char path[MAX_PATH]; - if (!GetCurrentDirectoryA(sizeof (path), path)) - throw std::runtime_error("failed to get current working directory"); + if (!::GetCurrentDirectoryA(sizeof (path), path)) + throw std::runtime_error("failed to get current working directory"); - return path; + return path; #else - char path[PATH_MAX]; + char path[PATH_MAX]; - if (getcwd(path, sizeof (path)) == nullptr) - throw std::runtime_error{std::strerror(errno)}; + if (::getcwd(path, sizeof (path)) == nullptr) + throw std::runtime_error{std::strerror(errno)}; - return path; + return path; #endif }
--- a/modules/fs/fs.hpp Tue Jun 14 17:04:25 2016 +0200 +++ b/modules/fs/fs.hpp Wed Jun 15 11:59:17 2016 +0200 @@ -28,11 +28,20 @@ * \page filesystem Filesystem * \brief Filesystem support * + * ## Options + * * The following options can be set by the user: * * - **FS_HAVE_STAT**: (bool) Set to true if sys/stat.h and stat function are available, automatically detected. - * - **FS_BUILDING_DLL**: (bool) Set to true if building this code as DLL, see also FS_EXPORT, - * - **FS_EXPORT**: (unspecified) Attribute to export symbols, __declspec(dllexport) on Windows if FS_BUILDING_DLL is set. + * + * ## Export macros + * + * You must define `FS_DLL` globally and `FS_BUILDING_DLL` when compiling the library if you want a DLL, alternatively you can provide + * your own `FS_EXPORT` macro instead. + */ + +/** + * \cond FS_HIDDEN_SYMBOLS */ #if !defined(FS_HAVE_STAT) @@ -47,17 +56,26 @@ # endif #endif -/** - * \brief DLL export. - */ #if !defined(FS_EXPORT) -# if defined(FS_BUILDING_DLL) && defined(_WIN32) -# define FS_EXPORT __declspec(dllexport) +# if defined(FS_DLL) +# if defined(_WIN32) +# if defined(FS_BUILDING_DLL) +# define FS_EXPORT __declspec(dllexport) +# else +# define FS_EXPORT __declspec(dllimport) +# endif +# else +# define FS_EXPORT +# endif # else # define FS_EXPORT # endif #endif +/** + * \endcond + */ + #if defined(FS_HAVE_STAT) # include <sys/stat.h> #endif @@ -76,8 +94,8 @@ * \brief Flags for readdir. */ enum Flags { - Dot = (1 << 0), //!< if set, also lists "." - DotDot = (1 << 1) //!< if set, also lists ".." + Dot = (1 << 0), //!< if set, also lists "." + DotDot = (1 << 1) //!< if set, also lists ".." }; /** @@ -86,18 +104,18 @@ */ class Entry { public: - /** - * \brief Describe the type of an entry - */ - enum Type : char { - Unknown, //!< File type is unknown, - File, //!< File is regular type, - Dir, //!< File is directory, - Link //!< File is link - }; + /** + * \brief Describe the type of an entry + */ + enum Type : char { + Unknown, //!< File type is unknown, + File, //!< File is regular type, + Dir, //!< File is directory, + Link //!< File is link + }; - std::string name; //!< name of entry (base name) - Type type{Unknown}; //!< type of file + std::string name; //!< name of entry (base name) + Type type{Unknown}; //!< type of file }; /** @@ -109,7 +127,7 @@ */ inline bool operator==(const Entry &e1, const Entry &e2) noexcept { - return e1.name == e2.name && e1.type == e2.type; + return e1.name == e2.name && e1.type == e2.type; } /** @@ -121,7 +139,7 @@ */ inline bool operator!=(const Entry &e1, const Entry &e2) noexcept { - return !(e1 == e2); + return !(e1 == e2); } /** @@ -132,9 +150,9 @@ inline char separator() noexcept { #if defined(_WIN32) - return '\\'; + return '\\'; #else - return '/'; + return '/'; #endif } @@ -281,7 +299,7 @@ * Search an item recursively. * * The predicate must have the following signature: - * void f(const std::string &base, const Entry &entry) + * void f(const std::string &base, const Entry &entry) * * Where: * - base is the current parent directory in the tree @@ -295,34 +313,34 @@ template <typename Predicate> std::string findIf(const std::string &base, Predicate &&predicate) { - /* - * Do not go deeply to the tree before testing all files in the current directory for performances reasons, we iterate - * this directory to search for the entry name and iterate again over all sub directories if not found. - */ - std::string path; - std::vector<Entry> entries = readdir(base); + /* + * Do not go deeply to the tree before testing all files in the current directory for performances reasons, we iterate + * this directory to search for the entry name and iterate again over all sub directories if not found. + */ + std::string path; + std::vector<Entry> entries = readdir(base); - for (const auto &entry : entries) { - if (predicate(base, entry)) { - path = base + separator() + entry.name; - break; - } - } + for (const auto &entry : entries) { + if (predicate(base, entry)) { + path = base + separator() + entry.name; + break; + } + } - if (!path.empty()) - return path; + if (!path.empty()) + return path; - for (const auto &entry : entries) { - if (entry.type != Entry::Dir) - continue; + for (const auto &entry : entries) { + if (entry.type != Entry::Dir) + continue; - path = findIf(base + separator() + entry.name, std::forward<Predicate>(predicate)); + path = findIf(base + separator() + entry.name, std::forward<Predicate>(predicate)); - if (!path.empty()) - break; - } + if (!path.empty()) + break; + } - return path; + return path; } /** @@ -335,7 +353,7 @@ */ inline std::string find(const std::string &base, const std::string &name) { - return findIf(base, [&] (const auto &, const auto &entry) { return entry.name == name; }); + return findIf(base, [&] (const auto &, const auto &entry) { return entry.name == name; }); } /** @@ -348,7 +366,7 @@ */ inline std::string find(const std::string &base, const std::regex ®ex) { - return findIf(base, [&] (const auto &, const auto &entry) { return std::regex_match(entry.name, regex); }); + return findIf(base, [&] (const auto &, const auto &entry) { return std::regex_match(entry.name, regex); }); } /**