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:
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));
}