reapack

Package manager for REAPER
Log | Files | Refs | Submodules | README | LICENSE

commit 7df2401ebc03693adaba29709e60516a02846612
parent bad9e8b36a2d9f8447652807b6f4d65941b5b2cd
Author: cfillion <cfillion@users.noreply.github.com>
Date:   Sat, 17 Jun 2017 21:22:36 -0400

filesystem: write custom file/directory exists logic

...to avoid OS-dependent return value inconsistencies in REAPER's implementation
of file_exists. See <http://forum.cockos.com/showthread.php?p=1856571>.

Diffstat:
Msrc/filesystem.cpp | 42++++++++++++++++++++++++++++--------------
Msrc/filesystem.hpp | 2+-
Msrc/main.cpp | 2--
Mtest/filesystem.cpp | 32++++++++++++++++++++++----------
4 files changed, 51 insertions(+), 27 deletions(-)

diff --git a/src/filesystem.cpp b/src/filesystem.cpp @@ -33,6 +33,25 @@ using namespace std; +#ifdef _WIN32 +#define stat _stat +#endif + +static bool stat(const Path &path, struct stat *out) +{ + const Path &fullPath = Path::prefixRoot(path); + +#ifdef _WIN32 + if(_wstat(make_autostring(fullPath.join()).c_str(), out)) + return false; +#else + if(::stat(fullPath.join().c_str(), out)) + return false; +#endif + + return true; +} + FILE *FS::open(const Path &path) { const Path &fullPath = Path::prefixRoot(path); @@ -145,34 +164,29 @@ bool FS::removeRecursive(const Path &file) bool FS::mtime(const Path &path, time_t *time) { - const Path &fullPath = Path::prefixRoot(path); - -#ifdef _WIN32 - struct _stat st; - - if(_wstat(make_autostring(fullPath.join()).c_str(), &st)) - return false; -#else struct stat st; - if(stat(fullPath.join().c_str(), &st)) + if(!stat(path, &st)) return false; -#endif *time = st.st_mtime; return true; } -bool FS::exists(const Path &path) +bool FS::exists(const Path &path, const bool dir) { - const Path &fullPath = Path::prefixRoot(path); - return file_exists(fullPath.join().c_str()); + struct stat st; + + if(stat(path, &st)) + return (bool)(st.st_mode & S_IFDIR) == dir; + else + return false; } bool FS::mkdir(const Path &path) { - if(exists(path)) + if(exists(path, true)) return true; Path fullPath = Path::root(); diff --git a/src/filesystem.hpp b/src/filesystem.hpp @@ -33,7 +33,7 @@ namespace FS { bool remove(const Path &); bool removeRecursive(const Path &); bool mtime(const Path &, time_t *); - bool exists(const Path &); + bool exists(const Path &, bool dir = false); bool mkdir(const Path &); std::string lastError(); diff --git a/src/main.cpp b/src/main.cpp @@ -37,13 +37,11 @@ static bool loadAPI(void *(*getFunc)(const char *)) const ApiFunc funcs[] = { REQUIRED_API(AddExtensionsMainMenu), - REQUIRED_API(file_exists), REQUIRED_API(GetAppVersion), REQUIRED_API(GetMainHwnd), REQUIRED_API(GetResourcePath), REQUIRED_API(NamedCommandLookup), // v3.1415 REQUIRED_API(plugin_register), - REQUIRED_API(RecursiveCreateDirectory), // v4.60 REQUIRED_API(ShowMessageBox), REQUIRED_API(Splash_GetWnd), // v4.7 diff --git a/test/filesystem.cpp b/test/filesystem.cpp @@ -7,18 +7,30 @@ static const char *M = "[filesystem]"; #define RIPATH "test/indexes" -TEST_CASE("unicode filename", M) { +TEST_CASE("open unicode file", M) { UseRootPath root(RIPATH); const Path &path = Index::pathFor("Новая папка"); - SECTION("FS::open") { - FILE *file = FS::open(path); - REQUIRE(file); - fclose(file); - } + FILE *file = FS::open(path); + REQUIRE(file); + fclose(file); +} + +TEST_CASE("file modification time", M) { + UseRootPath root(RIPATH); + const Path &path = Index::pathFor("Новая папка"); + + time_t time = 0; + REQUIRE(FS::mtime(path, &time)); + REQUIRE(time > 0); +} + +TEST_CASE("file exists", M) { + UseRootPath root(RIPATH); + + REQUIRE(FS::exists(Index::pathFor("Новая папка"))); + REQUIRE_FALSE(FS::exists(Index::pathFor("Новая папка"), true)); - SECTION("FS::mtime") { - time_t time; - REQUIRE(FS::mtime(path, &time)); - } + REQUIRE_FALSE(FS::exists(Path("ReaPack"))); + REQUIRE(FS::exists(Path("ReaPack"), true)); }