From 3e043291f06aaa791ce723a9fe02319d8d605dca Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Mon, 25 May 2015 10:11:41 -0400 Subject: [PATCH] Cleanup: Combined File, Path and Directory into FS - The three objects are related and always travel together, so they are now combined. --- src/CLI.h | 3 +- src/CMakeLists.txt | 4 +- src/Config.cpp | 3 +- src/Config.h | 2 +- src/Context.cpp | 3 +- src/Context.h | 4 +- src/Directory.cpp | 241 --------------- src/Directory.h | 60 ---- src/{File.cpp => FS.cpp} | 477 ++++++++++++++++++++++++++++- src/{File.h => FS.h} | 69 ++++- src/Path.cpp | 301 ------------------ src/Path.h | 70 ----- src/TDB2.h | 2 +- src/commands/CmdShow.cpp | 2 +- test/.gitignore | 4 +- test/CMakeLists.txt | 19 +- test/file.t.cpp | 101 ------ test/{directory.t.cpp => fs.t.cpp} | 134 +++++++- test/json_test.cpp | 2 +- test/path.t.cpp | 123 -------- 20 files changed, 689 insertions(+), 935 deletions(-) delete mode 100644 src/Directory.cpp delete mode 100644 src/Directory.h rename src/{File.cpp => FS.cpp} (51%) rename src/{File.h => FS.h} (67%) delete mode 100644 src/Path.cpp delete mode 100644 src/Path.h delete mode 100644 test/file.t.cpp rename test/{directory.t.cpp => fs.t.cpp} (56%) delete mode 100644 test/path.t.cpp diff --git a/src/CLI.h b/src/CLI.h index 5abf2da29..11454f595 100644 --- a/src/CLI.h +++ b/src/CLI.h @@ -30,8 +30,7 @@ #include #include #include -#include -#include +#include // Represents a single argument. class A diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ec1d5deed..3f7a99842 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -12,18 +12,16 @@ set (task_SRCS CLI.cpp CLI.h DOM.cpp DOM.h Date.cpp Date.h Dates.cpp Dates.h - Directory.cpp Directory.h Duration.cpp Duration.h Eval.cpp Eval.h - File.cpp File.h Filter.cpp Filter.h + FS.cpp FS.h Hooks.cpp Hooks.h ISO8601.cpp ISO8601.h JSON.cpp JSON.h Lexer.cpp Lexer.h Msg.cpp Msg.h Nibbler.cpp Nibbler.h - Path.cpp Path.h RX.cpp RX.h TDB2.cpp TDB2.h Task.cpp Task.h diff --git a/src/Config.cpp b/src/Config.cpp index fc60e9d72..ae7ea6728 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -33,9 +33,8 @@ #include #include #include -#include #include -#include +#include #include #include #include diff --git a/src/Config.h b/src/Config.h index f043a51b1..c024c802b 100644 --- a/src/Config.h +++ b/src/Config.h @@ -30,7 +30,7 @@ #include #include #include -#include +#include class Config : public std::map { diff --git a/src/Context.cpp b/src/Context.cpp index 8c69eb637..8bd251f92 100644 --- a/src/Context.cpp +++ b/src/Context.cpp @@ -34,8 +34,7 @@ #include #include #include -#include -#include +#include #include #include #include diff --git a/src/Context.h b/src/Context.h index 40d1ed3db..64ea6f044 100644 --- a/src/Context.h +++ b/src/Context.h @@ -34,9 +34,7 @@ #include #include #include -#include -#include -#include +#include #include #include diff --git a/src/Directory.cpp b/src/Directory.cpp deleted file mode 100644 index 6390cc45d..000000000 --- a/src/Directory.cpp +++ /dev/null @@ -1,241 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// -// Copyright 2006 - 2015, Paul Beckingham, Federico Hernandez. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -// http://www.opensource.org/licenses/mit-license.php -// -//////////////////////////////////////////////////////////////////////////////// - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined SOLARIS || defined NETBSD || defined FREEBSD -#include -#endif - -//////////////////////////////////////////////////////////////////////////////// -Directory::Directory () -{ -} - -//////////////////////////////////////////////////////////////////////////////// -Directory::Directory (const Directory& other) -: File::File (other) -{ -} - -//////////////////////////////////////////////////////////////////////////////// -Directory::Directory (const File& other) -: File::File (other) -{ -} - -//////////////////////////////////////////////////////////////////////////////// -Directory::Directory (const Path& other) -: File::File (other) -{ -} - -//////////////////////////////////////////////////////////////////////////////// -Directory::Directory (const std::string& in) -: File::File (in) -{ -} - -//////////////////////////////////////////////////////////////////////////////// -Directory::~Directory () -{ -} - -//////////////////////////////////////////////////////////////////////////////// -Directory& Directory::operator= (const Directory& other) -{ - if (this != &other) - { - File::operator= (other); - } - - return *this; -} - -//////////////////////////////////////////////////////////////////////////////// -bool Directory::create (int mode /* = 0755 */) -{ - return mkdir (_data.c_str (), mode) == 0 ? true : false; -} - -//////////////////////////////////////////////////////////////////////////////// -bool Directory::remove () const -{ - return remove_directory (_data); -} - -//////////////////////////////////////////////////////////////////////////////// -bool Directory::remove_directory (const std::string& dir) const -{ - DIR* dp = opendir (dir.c_str ()); - if (dp != NULL) - { - struct dirent* de; - while ((de = readdir (dp)) != NULL) - { - if (!strcmp (de->d_name, ".") || - !strcmp (de->d_name, "..")) - continue; - -#if defined (SOLARIS) || defined (HAIKU) - struct stat s; - lstat ((dir + "/" + de->d_name).c_str (), &s); - if (S_ISDIR (s.st_mode)) - remove_directory (dir + "/" + de->d_name); - else - unlink ((dir + "/" + de->d_name).c_str ()); -#else - if (de->d_type == DT_UNKNOWN) - { - struct stat s; - lstat ((dir + "/" + de->d_name).c_str (), &s); - if (S_ISDIR (s.st_mode)) - de->d_type = DT_DIR; - } - if (de->d_type == DT_DIR) - remove_directory (dir + "/" + de->d_name); - else - unlink ((dir + "/" + de->d_name).c_str ()); -#endif - } - - closedir (dp); - } - - return rmdir (dir.c_str ()) ? false : true; -} - -//////////////////////////////////////////////////////////////////////////////// -std::vector Directory::list () -{ - std::vector files; - list (_data, files, false); - return files; -} - -//////////////////////////////////////////////////////////////////////////////// -std::vector Directory::listRecursive () -{ - std::vector files; - list (_data, files, true); - return files; -} - -//////////////////////////////////////////////////////////////////////////////// -std::string Directory::cwd () -{ -#ifdef HAVE_GET_CURRENT_DIR_NAME - char *buf = get_current_dir_name (); - if (buf == NULL) - throw std::bad_alloc (); - std::string result (buf); - free (buf); - return result; -#else - char buf[PATH_MAX]; - getcwd (buf, PATH_MAX - 1); - return std::string (buf); -#endif -} - -//////////////////////////////////////////////////////////////////////////////// -bool Directory::up () -{ - if (_data == "/") - return false; - - auto slash = _data.rfind ('/'); - if (slash == 0) - { - _data = "/"; // Root dir should retain the slash. - return true; - } - else if (slash != std::string::npos) - { - _data = _data.substr (0, slash); - return true; - } - - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -bool Directory::cd () const -{ - return chdir (_data.c_str ()) == 0 ? true : false; -} - -//////////////////////////////////////////////////////////////////////////////// -void Directory::list ( - const std::string& base, - std::vector & results, - bool recursive) -{ - DIR* dp = opendir (base.c_str ()); - if (dp != NULL) - { - struct dirent* de; - while ((de = readdir (dp)) != NULL) - { - if (!strcmp (de->d_name, ".") || - !strcmp (de->d_name, "..")) - continue; - -#if defined (SOLARIS) || defined (HAIKU) - struct stat s; - stat ((base + "/" + de->d_name).c_str (), &s); - if (recursive && S_ISDIR (s.st_mode)) - list (base + "/" + de->d_name, results, recursive); - else - results.push_back (base + "/" + de->d_name); -#else - if (recursive && de->d_type == DT_UNKNOWN) - { - struct stat s; - lstat ((base + "/" + de->d_name).c_str (), &s); - if (S_ISDIR (s.st_mode)) - de->d_type = DT_DIR; - } - if (recursive && de->d_type == DT_DIR) - list (base + "/" + de->d_name, results, recursive); - else - results.push_back (base + "/" + de->d_name); -#endif - } - - closedir (dp); - } -} - -//////////////////////////////////////////////////////////////////////////////// diff --git a/src/Directory.h b/src/Directory.h deleted file mode 100644 index aef7d5ee7..000000000 --- a/src/Directory.h +++ /dev/null @@ -1,60 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// -// Copyright 2006 - 2015, Paul Beckingham, Federico Hernandez. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -// http://www.opensource.org/licenses/mit-license.php -// -//////////////////////////////////////////////////////////////////////////////// - -#ifndef INCLUDED_DIRECTORY -#define INCLUDED_DIRECTORY - -#include - -class Directory : public File -{ -public: - Directory (); - Directory (const Directory&); - Directory (const File&); - Directory (const Path&); - Directory (const std::string&); - virtual ~Directory (); - - Directory& operator= (const Directory&); - - virtual bool create (int mode = 0755); - virtual bool remove () const; - - std::vector list (); - std::vector listRecursive (); - - static std::string cwd (); - bool up (); - bool cd () const; - -private: - void list (const std::string&, std::vector &, bool); - bool remove_directory (const std::string&) const; -}; - -#endif -//////////////////////////////////////////////////////////////////////////////// diff --git a/src/File.cpp b/src/FS.cpp similarity index 51% rename from src/File.cpp rename to src/FS.cpp index 021dc2160..220283162 100644 --- a/src/File.cpp +++ b/src/FS.cpp @@ -26,16 +26,286 @@ #include #include +#include #include #include -#include -#include -#include +#include #include -#include +#include +#include +#include +#include +#include +#include #include #include #include +#include + +#if defined SOLARIS || defined NETBSD || defined FREEBSD +#include +#endif + +// Fixes build with musl libc. +#ifndef GLOB_TILDE +#define GLOB_TILDE 0 +#endif + +#ifndef GLOB_BRACE +#define GLOB_BRACE 0 +#endif + +//////////////////////////////////////////////////////////////////////////////// +std::ostream& operator<< (std::ostream& out, const Path& path) +{ + out << path._data; + return out; +} + +//////////////////////////////////////////////////////////////////////////////// +Path::Path () +{ +} + +//////////////////////////////////////////////////////////////////////////////// +Path::Path (const Path& other) +{ + if (this != &other) + { + _original = other._original; + _data = other._data; + } +} + +//////////////////////////////////////////////////////////////////////////////// +Path::Path (const std::string& in) +{ + _original = in; + _data = expand (in); +} + +//////////////////////////////////////////////////////////////////////////////// +Path::~Path () +{ +} + +//////////////////////////////////////////////////////////////////////////////// +Path& Path::operator= (const Path& other) +{ + if (this != &other) + { + this->_original = other._original; + this->_data = other._data; + } + + return *this; +} + +//////////////////////////////////////////////////////////////////////////////// +bool Path::operator== (const Path& other) +{ + return _data == other._data; +} + +//////////////////////////////////////////////////////////////////////////////// +Path& Path::operator+= (const std::string& dir) +{ + _data += "/" + dir; + return *this; +} + +//////////////////////////////////////////////////////////////////////////////// +Path::operator std::string () const +{ + return _data; +} + +//////////////////////////////////////////////////////////////////////////////// +std::string Path::name () const +{ + if (_data.length ()) + { + auto slash = _data.rfind ('/'); + if (slash != std::string::npos) + return _data.substr (slash + 1, std::string::npos); + } + + return _data; +} + +//////////////////////////////////////////////////////////////////////////////// +std::string Path::parent () const +{ + if (_data.length ()) + { + auto slash = _data.rfind ('/'); + if (slash != std::string::npos) + return _data.substr (0, slash); + } + + return ""; +} + +//////////////////////////////////////////////////////////////////////////////// +std::string Path::extension () const +{ + if (_data.length ()) + { + auto dot = _data.rfind ('.'); + if (dot != std::string::npos) + return _data.substr (dot + 1, std::string::npos); + } + + return ""; +} + +//////////////////////////////////////////////////////////////////////////////// +bool Path::exists () const +{ + return access (_data.c_str (), F_OK) ? false : true; +} + +//////////////////////////////////////////////////////////////////////////////// +bool Path::is_directory () const +{ + struct stat s = {0}; + if (! stat (_data.c_str (), &s) && + S_ISDIR (s.st_mode)) + return true; + + return false; +} + +//////////////////////////////////////////////////////////////////////////////// +bool Path::is_absolute () const +{ + if (_data.length () && _data[0] == '/') + return true; + + return false; +} + +//////////////////////////////////////////////////////////////////////////////// +bool Path::is_link () const +{ + struct stat s = {0}; + if (! lstat (_data.c_str (), &s) && + S_ISLNK (s.st_mode)) + return true; + + return false; +} + +//////////////////////////////////////////////////////////////////////////////// +bool Path::readable () const +{ + return access (_data.c_str (), R_OK) ? false : true; +} + +//////////////////////////////////////////////////////////////////////////////// +bool Path::writable () const +{ + return access (_data.c_str (), W_OK) ? false : true; +} + +//////////////////////////////////////////////////////////////////////////////// +bool Path::executable () const +{ + return access (_data.c_str (), X_OK) ? false : true; +} + +//////////////////////////////////////////////////////////////////////////////// +bool Path::rename (const std::string& new_name) +{ + std::string expanded = expand (new_name); + if (_data != expanded) + { + if (::rename (_data.c_str (), expanded.c_str ()) == 0) + { + _data = expanded; + return true; + } + } + + return false; +} + +//////////////////////////////////////////////////////////////////////////////// +// ~ --> /home/user +// ~foo/x --> /home/foo/s +// ~/x --> /home/foo/x +// ./x --> $PWD/x +// x --> $PWD/x +std::string Path::expand (const std::string& in) +{ + std::string copy = in; + + auto tilde = copy.find ("~"); + std::string::size_type slash; + + if (tilde != std::string::npos) + { + const char *home = getenv("HOME"); + if (home == NULL) + { + struct passwd* pw = getpwuid (getuid ()); + home = pw->pw_dir; + } + + // Convert: ~ --> /home/user + if (copy.length () == 1) + copy = home; + + // Convert: ~/x --> /home/user/x + else if (copy.length () > tilde + 1 && + copy[tilde + 1] == '/') + { + copy.replace (tilde, 1, home); + } + + // Convert: ~foo/x --> /home/foo/x + else if ((slash = copy.find ("/", tilde)) != std::string::npos) + { + std::string name = copy.substr (tilde + 1, slash - tilde - 1); + struct passwd* pw = getpwnam (name.c_str ()); + if (pw) + copy.replace (tilde, slash - tilde, pw->pw_dir); + } + } + + // Relative paths + else if (in.length () > 2 && + in.substr (0, 2) == "./") + { + copy = Directory::cwd () + "/" + in.substr (2); + } + else if (in.length () > 1 && + in[0] != '.' && + in[0] != '/') + { + copy = Directory::cwd () + "/" + in; + } + + return copy; +} + +//////////////////////////////////////////////////////////////////////////////// +std::vector Path::glob (const std::string& pattern) +{ + std::vector results; + + glob_t g; +#ifdef SOLARIS + if (!::glob (pattern.c_str (), GLOB_ERR, NULL, &g)) +#else + if (!::glob (pattern.c_str (), GLOB_ERR | GLOB_BRACE | GLOB_TILDE, NULL, &g)) +#endif + for (int i = 0; i < (int) g.gl_pathc; ++i) + results.push_back (g.gl_pathv[i]); + + globfree (&g); + return results; +} //////////////////////////////////////////////////////////////////////////////// File::File () @@ -518,4 +788,203 @@ bool File::remove (const std::string& name) } //////////////////////////////////////////////////////////////////////////////// +Directory::Directory () +{ +} +//////////////////////////////////////////////////////////////////////////////// +Directory::Directory (const Directory& other) +: File::File (other) +{ +} + +//////////////////////////////////////////////////////////////////////////////// +Directory::Directory (const File& other) +: File::File (other) +{ +} + +//////////////////////////////////////////////////////////////////////////////// +Directory::Directory (const Path& other) +: File::File (other) +{ +} + +//////////////////////////////////////////////////////////////////////////////// +Directory::Directory (const std::string& in) +: File::File (in) +{ +} + +//////////////////////////////////////////////////////////////////////////////// +Directory::~Directory () +{ +} + +//////////////////////////////////////////////////////////////////////////////// +Directory& Directory::operator= (const Directory& other) +{ + if (this != &other) + { + File::operator= (other); + } + + return *this; +} + +//////////////////////////////////////////////////////////////////////////////// +bool Directory::create (int mode /* = 0755 */) +{ + return mkdir (_data.c_str (), mode) == 0 ? true : false; +} + +//////////////////////////////////////////////////////////////////////////////// +bool Directory::remove () const +{ + return remove_directory (_data); +} + +//////////////////////////////////////////////////////////////////////////////// +bool Directory::remove_directory (const std::string& dir) const +{ + DIR* dp = opendir (dir.c_str ()); + if (dp != NULL) + { + struct dirent* de; + while ((de = readdir (dp)) != NULL) + { + if (!strcmp (de->d_name, ".") || + !strcmp (de->d_name, "..")) + continue; + +#if defined (SOLARIS) || defined (HAIKU) + struct stat s; + lstat ((dir + "/" + de->d_name).c_str (), &s); + if (S_ISDIR (s.st_mode)) + remove_directory (dir + "/" + de->d_name); + else + unlink ((dir + "/" + de->d_name).c_str ()); +#else + if (de->d_type == DT_UNKNOWN) + { + struct stat s; + lstat ((dir + "/" + de->d_name).c_str (), &s); + if (S_ISDIR (s.st_mode)) + de->d_type = DT_DIR; + } + if (de->d_type == DT_DIR) + remove_directory (dir + "/" + de->d_name); + else + unlink ((dir + "/" + de->d_name).c_str ()); +#endif + } + + closedir (dp); + } + + return rmdir (dir.c_str ()) ? false : true; +} + +//////////////////////////////////////////////////////////////////////////////// +std::vector Directory::list () +{ + std::vector files; + list (_data, files, false); + return files; +} + +//////////////////////////////////////////////////////////////////////////////// +std::vector Directory::listRecursive () +{ + std::vector files; + list (_data, files, true); + return files; +} + +//////////////////////////////////////////////////////////////////////////////// +std::string Directory::cwd () +{ +#ifdef HAVE_GET_CURRENT_DIR_NAME + char *buf = get_current_dir_name (); + if (buf == NULL) + throw std::bad_alloc (); + std::string result (buf); + free (buf); + return result; +#else + char buf[PATH_MAX]; + getcwd (buf, PATH_MAX - 1); + return std::string (buf); +#endif +} + +//////////////////////////////////////////////////////////////////////////////// +bool Directory::up () +{ + if (_data == "/") + return false; + + auto slash = _data.rfind ('/'); + if (slash == 0) + { + _data = "/"; // Root dir should retain the slash. + return true; + } + else if (slash != std::string::npos) + { + _data = _data.substr (0, slash); + return true; + } + + return false; +} + +//////////////////////////////////////////////////////////////////////////////// +bool Directory::cd () const +{ + return chdir (_data.c_str ()) == 0 ? true : false; +} + +//////////////////////////////////////////////////////////////////////////////// +void Directory::list ( + const std::string& base, + std::vector & results, + bool recursive) +{ + DIR* dp = opendir (base.c_str ()); + if (dp != NULL) + { + struct dirent* de; + while ((de = readdir (dp)) != NULL) + { + if (!strcmp (de->d_name, ".") || + !strcmp (de->d_name, "..")) + continue; + +#if defined (SOLARIS) || defined (HAIKU) + struct stat s; + stat ((base + "/" + de->d_name).c_str (), &s); + if (recursive && S_ISDIR (s.st_mode)) + list (base + "/" + de->d_name, results, recursive); + else + results.push_back (base + "/" + de->d_name); +#else + if (recursive && de->d_type == DT_UNKNOWN) + { + struct stat s; + lstat ((base + "/" + de->d_name).c_str (), &s); + if (S_ISDIR (s.st_mode)) + de->d_type = DT_DIR; + } + if (recursive && de->d_type == DT_DIR) + list (base + "/" + de->d_name, results, recursive); + else + results.push_back (base + "/" + de->d_name); +#endif + } + + closedir (dp); + } +} + +//////////////////////////////////////////////////////////////////////////////// diff --git a/src/File.h b/src/FS.h similarity index 67% rename from src/File.h rename to src/FS.h index 007ca35a0..d44df7e2d 100644 --- a/src/File.h +++ b/src/FS.h @@ -24,14 +24,47 @@ // //////////////////////////////////////////////////////////////////////////////// -#ifndef INCLUDED_FILE -#define INCLUDED_FILE +#ifndef INCLUDED_FS +#define INCLUDED_FS #include #include #include #include -#include + +class Path +{ +public: + Path (); + Path (const Path&); + Path (const std::string&); + virtual ~Path (); + + Path& operator= (const Path&); + bool operator== (const Path&); + Path& operator+= (const std::string&); + operator std::string () const; + + std::string name () const; + std::string parent () const; + std::string extension () const; + bool exists () const; + bool is_directory () const; + bool is_absolute () const; + bool is_link () const; + bool readable () const; + bool writable () const; + bool executable () const; + bool rename (const std::string&); + + // Statics + static std::string expand (const std::string&); + static std::vector glob (const std::string&); + +public: + std::string _original; + std::string _data; +}; class File : public Path { @@ -87,5 +120,35 @@ private: bool _locked; }; +class Directory : public File +{ +public: + Directory (); + Directory (const Directory&); + Directory (const File&); + Directory (const Path&); + Directory (const std::string&); + virtual ~Directory (); + + Directory& operator= (const Directory&); + + virtual bool create (int mode = 0755); + virtual bool remove () const; + + std::vector list (); + std::vector listRecursive (); + + static std::string cwd (); + bool up (); + bool cd () const; + +private: + void list (const std::string&, std::vector &, bool); + bool remove_directory (const std::string&) const; +}; + +std::ostream& operator<< (std::ostream&, const Path&); + #endif //////////////////////////////////////////////////////////////////////////////// + diff --git a/src/Path.cpp b/src/Path.cpp deleted file mode 100644 index 908e5d08a..000000000 --- a/src/Path.cpp +++ /dev/null @@ -1,301 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// -// Copyright 2006 - 2015, Paul Beckingham, Federico Hernandez. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -// http://www.opensource.org/licenses/mit-license.php -// -//////////////////////////////////////////////////////////////////////////////// - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// Fixes build with musl libc. -#ifndef GLOB_TILDE -#define GLOB_TILDE 0 -#endif - -#ifndef GLOB_BRACE -#define GLOB_BRACE 0 -#endif - -//////////////////////////////////////////////////////////////////////////////// -std::ostream& operator<< (std::ostream& out, const Path& path) -{ - out << path._data; - return out; -} - -//////////////////////////////////////////////////////////////////////////////// -Path::Path () -{ -} - -//////////////////////////////////////////////////////////////////////////////// -Path::Path (const Path& other) -{ - if (this != &other) - { - _original = other._original; - _data = other._data; - } -} - -//////////////////////////////////////////////////////////////////////////////// -Path::Path (const std::string& in) -{ - _original = in; - _data = expand (in); -} - -//////////////////////////////////////////////////////////////////////////////// -Path::~Path () -{ -} - -//////////////////////////////////////////////////////////////////////////////// -Path& Path::operator= (const Path& other) -{ - if (this != &other) - { - this->_original = other._original; - this->_data = other._data; - } - - return *this; -} - -//////////////////////////////////////////////////////////////////////////////// -bool Path::operator== (const Path& other) -{ - return _data == other._data; -} - -//////////////////////////////////////////////////////////////////////////////// -Path& Path::operator+= (const std::string& dir) -{ - _data += "/" + dir; - return *this; -} - -//////////////////////////////////////////////////////////////////////////////// -Path::operator std::string () const -{ - return _data; -} - -//////////////////////////////////////////////////////////////////////////////// -std::string Path::name () const -{ - if (_data.length ()) - { - auto slash = _data.rfind ('/'); - if (slash != std::string::npos) - return _data.substr (slash + 1, std::string::npos); - } - - return _data; -} - -//////////////////////////////////////////////////////////////////////////////// -std::string Path::parent () const -{ - if (_data.length ()) - { - auto slash = _data.rfind ('/'); - if (slash != std::string::npos) - return _data.substr (0, slash); - } - - return ""; -} - -//////////////////////////////////////////////////////////////////////////////// -std::string Path::extension () const -{ - if (_data.length ()) - { - auto dot = _data.rfind ('.'); - if (dot != std::string::npos) - return _data.substr (dot + 1, std::string::npos); - } - - return ""; -} - -//////////////////////////////////////////////////////////////////////////////// -bool Path::exists () const -{ - return access (_data.c_str (), F_OK) ? false : true; -} - -//////////////////////////////////////////////////////////////////////////////// -bool Path::is_directory () const -{ - struct stat s = {0}; - if (! stat (_data.c_str (), &s) && - S_ISDIR (s.st_mode)) - return true; - - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -bool Path::is_absolute () const -{ - if (_data.length () && _data[0] == '/') - return true; - - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -bool Path::is_link () const -{ - struct stat s = {0}; - if (! lstat (_data.c_str (), &s) && - S_ISLNK (s.st_mode)) - return true; - - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -bool Path::readable () const -{ - return access (_data.c_str (), R_OK) ? false : true; -} - -//////////////////////////////////////////////////////////////////////////////// -bool Path::writable () const -{ - return access (_data.c_str (), W_OK) ? false : true; -} - -//////////////////////////////////////////////////////////////////////////////// -bool Path::executable () const -{ - return access (_data.c_str (), X_OK) ? false : true; -} - -//////////////////////////////////////////////////////////////////////////////// -bool Path::rename (const std::string& new_name) -{ - std::string expanded = expand (new_name); - if (_data != expanded) - { - if (::rename (_data.c_str (), expanded.c_str ()) == 0) - { - _data = expanded; - return true; - } - } - - return false; -} - -//////////////////////////////////////////////////////////////////////////////// -// ~ --> /home/user -// ~foo/x --> /home/foo/s -// ~/x --> /home/foo/x -// ./x --> $PWD/x -// x --> $PWD/x -std::string Path::expand (const std::string& in) -{ - std::string copy = in; - - auto tilde = copy.find ("~"); - std::string::size_type slash; - - if (tilde != std::string::npos) - { - const char *home = getenv("HOME"); - if (home == NULL) - { - struct passwd* pw = getpwuid (getuid ()); - home = pw->pw_dir; - } - - // Convert: ~ --> /home/user - if (copy.length () == 1) - copy = home; - - // Convert: ~/x --> /home/user/x - else if (copy.length () > tilde + 1 && - copy[tilde + 1] == '/') - { - copy.replace (tilde, 1, home); - } - - // Convert: ~foo/x --> /home/foo/x - else if ((slash = copy.find ("/", tilde)) != std::string::npos) - { - std::string name = copy.substr (tilde + 1, slash - tilde - 1); - struct passwd* pw = getpwnam (name.c_str ()); - if (pw) - copy.replace (tilde, slash - tilde, pw->pw_dir); - } - } - - // Relative paths - else if (in.length () > 2 && - in.substr (0, 2) == "./") - { - copy = Directory::cwd () + "/" + in.substr (2); - } - else if (in.length () > 1 && - in[0] != '.' && - in[0] != '/') - { - copy = Directory::cwd () + "/" + in; - } - - return copy; -} - -//////////////////////////////////////////////////////////////////////////////// -std::vector Path::glob (const std::string& pattern) -{ - std::vector results; - - glob_t g; -#ifdef SOLARIS - if (!::glob (pattern.c_str (), GLOB_ERR, NULL, &g)) -#else - if (!::glob (pattern.c_str (), GLOB_ERR | GLOB_BRACE | GLOB_TILDE, NULL, &g)) -#endif - for (int i = 0; i < (int) g.gl_pathc; ++i) - results.push_back (g.gl_pathv[i]); - - globfree (&g); - return results; -} - -//////////////////////////////////////////////////////////////////////////////// diff --git a/src/Path.h b/src/Path.h deleted file mode 100644 index be7a02edc..000000000 --- a/src/Path.h +++ /dev/null @@ -1,70 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// -// Copyright 2006 - 2015, Paul Beckingham, Federico Hernandez. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -// http://www.opensource.org/licenses/mit-license.php -// -//////////////////////////////////////////////////////////////////////////////// - -#ifndef INCLUDED_PATH -#define INCLUDED_PATH - -#include -#include - -class Path -{ -public: - Path (); - Path (const Path&); - Path (const std::string&); - virtual ~Path (); - - Path& operator= (const Path&); - bool operator== (const Path&); - Path& operator+= (const std::string&); - operator std::string () const; - - std::string name () const; - std::string parent () const; - std::string extension () const; - bool exists () const; - bool is_directory () const; - bool is_absolute () const; - bool is_link () const; - bool readable () const; - bool writable () const; - bool executable () const; - bool rename (const std::string&); - - // Statics - static std::string expand (const std::string&); - static std::vector glob (const std::string&); - -public: - std::string _original; - std::string _data; -}; - -std::ostream& operator<< (std::ostream&, const Path&); - -#endif -//////////////////////////////////////////////////////////////////////////////// diff --git a/src/TDB2.h b/src/TDB2.h index d019fc487..8f1912365 100644 --- a/src/TDB2.h +++ b/src/TDB2.h @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include // TF2 Class represents a single file in the task database. diff --git a/src/commands/CmdShow.cpp b/src/commands/CmdShow.cpp index 6237eb3e4..fcb3b0a94 100644 --- a/src/commands/CmdShow.cpp +++ b/src/commands/CmdShow.cpp @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include #include diff --git a/test/.gitignore b/test/.gitignore index 805d51ec3..3ae360e5b 100644 --- a/test/.gitignore +++ b/test/.gitignore @@ -11,11 +11,10 @@ color.t config.t date.t dates.t -directory.t dom.t duration.t eval.t -file.t +fs.t i18n.t iso8601d.t iso8601p.t @@ -24,7 +23,6 @@ lexer.t list.t msg.t nibbler.t -path.t rx.t t.t t2.t diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 48ac35060..68127fb5c 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -6,16 +6,15 @@ include_directories (${CMAKE_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/test ${TASK_INCLUDE_DIRS}) -set (test_SRCS autocomplete.t color.t config.t date.t directory.t dom.t - file.t i18n.t json.t list.t msg.t nibbler.t path.t rx.t t.t t2.t - t3.t tdb2.t text.t utf8.t util.t view.t json_test lexer.t - iso8601d.t iso8601p.t duration.t variant_add.t - variant_and.t variant_cast.t variant_divide.t variant_equal.t - variant_exp.t variant_gt.t variant_gte.t variant_inequal.t - variant_lt.t variant_lte.t variant_match.t variant_math.t - variant_modulo.t variant_multiply.t variant_nomatch.t - variant_not.t variant_or.t variant_partial.t variant_subtract.t - variant_xor.t eval.t dates.t) +set (test_SRCS autocomplete.t color.t config.t date.t dom.t fs.t i18n.t json.t + list.t msg.t nibbler.t rx.t t.t t2.t t3.t tdb2.t text.t utf8.t + util.t view.t json_test lexer.t iso8601d.t iso8601p.t duration.t + variant_add.t variant_and.t variant_cast.t variant_divide.t + variant_equal.t variant_exp.t variant_gt.t variant_gte.t + variant_inequal.t variant_lt.t variant_lte.t variant_match.t + variant_math.t variant_modulo.t variant_multiply.t + variant_nomatch.t variant_not.t variant_or.t variant_partial.t + variant_subtract.t variant_xor.t eval.t dates.t) message ("-- Configuring run_all") if (${CMAKE_SOURCE_DIR} STREQUAL ${CMAKE_BINARY_DIR}) diff --git a/test/file.t.cpp b/test/file.t.cpp deleted file mode 100644 index 108704ee8..000000000 --- a/test/file.t.cpp +++ /dev/null @@ -1,101 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// -// Copyright 2006 - 2015, Paul Beckingham, Federico Hernandez. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -// http://www.opensource.org/licenses/mit-license.php -// -//////////////////////////////////////////////////////////////////////////////// - -#include -#include -#include -#include -#include -#include - -Context context; - -int main (int argc, char** argv) -{ - UnitTest t (27); - - // Ensure environment has no influence. - unsetenv ("TASKDATA"); - unsetenv ("TASKRC"); - - Directory tmp ("tmp"); - tmp.create (); - t.ok (tmp.exists (), "tmp dir created."); - - File::write ("tmp/file.t.txt", "This is a test\n"); - File f6 ("tmp/file.t.txt"); - t.ok (f6.size () == 15, "File::size tmp/file.t.txt good"); - t.ok (f6.mode () & S_IRUSR, "File::mode tmp/file.t.txt good"); - t.ok (File::remove ("tmp/file.t.txt"), "File::remove tmp/file.t.txt good"); - - // operator (std::string) const; - t.is ((std::string) f6, Directory::cwd () + "/tmp/file.t.txt", "File::operator (std::string) const"); - - t.ok (File::create ("tmp/file.t.create"), "File::create tmp/file.t.create good"); - t.ok (File::remove ("tmp/file.t.create"), "File::remove tmp/file.t.create good"); - - // basename (std::string) const; - t.is (f6.name (), "file.t.txt", "File::basename tmp/file.t.txt --> file.t.txt"); - - // dirname (std::string) const; - t.is (f6.parent (), Directory::cwd () + "/tmp", "File::dirname tmp/file.t.txt --> tmp"); - - // bool rename (const std::string&); - File f7 ("tmp/file.t.2.txt"); - f7.append ("something\n"); - f7.close (); - - t.ok (f7.rename ("tmp/file.t.3.txt"), "File::rename did not fail"); - t.is (f7._data, Directory::cwd () + "/tmp/file.t.3.txt", "File::rename stored new name"); - t.ok (f7.exists (), "File::rename new file exists"); - t.ok (f7.remove (), "File::remove tmp/file.t.3.txt good"); - t.notok (f7.exists (), "File::remove new file no longer exists"); - - // Test permissions. - File f8 ("tmp/file.t.perm.txt"); - f8.create (0744); - t.ok (f8.exists (), "File::create perm file exists"); - mode_t m = f8.mode (); - t.ok (m & S_IFREG, "File::mode tmp/file.t.perm.txt S_IFREG good"); - t.ok (m & S_IRUSR, "File::mode tmp/file.t.perm.txt r-------- good"); - t.ok (m & S_IWUSR, "File::mode tmp/file.t.perm.txt -w------- good"); - t.ok (m & S_IXUSR, "File::mode tmp/file.t.perm.txt --x------ good"); - t.ok (m & S_IRGRP, "File::mode tmp/file.t.perm.txt ---r----- good"); - t.notok (m & S_IWGRP, "File::mode tmp/file.t.perm.txt ----w---- good"); - t.notok (m & S_IXGRP, "File::mode tmp/file.t.perm.txt -----x--- good"); - t.ok (m & S_IROTH, "File::mode tmp/file.t.perm.txt ------r-- good"); - t.notok (m & S_IWOTH, "File::mode tmp/file.t.perm.txt -------w- good"); - t.notok (m & S_IXOTH, "File::mode tmp/file.t.perm.txt --------x good"); - f8.remove (); - t.notok (f8.exists (), "File::remove perm file no longer exists"); - - tmp.remove (); - t.notok (tmp.exists (), "tmp dir removed."); - - return 0; -} - -//////////////////////////////////////////////////////////////////////////////// diff --git a/test/directory.t.cpp b/test/fs.t.cpp similarity index 56% rename from test/directory.t.cpp rename to test/fs.t.cpp index 8c7773521..2ae4e5bf3 100644 --- a/test/directory.t.cpp +++ b/test/fs.t.cpp @@ -28,23 +28,151 @@ #include #include #include -#include +#include #include Context context; int main (int argc, char** argv) { - UnitTest t (49); + UnitTest t (108); // Ensure environment has no influence. unsetenv ("TASKDATA"); unsetenv ("TASKRC"); + // Path (); + Path p0; + t.is (p0._data, "", "Path::Path"); + + // Path (const Path&); + Path p1 = Path ("foo"); + t.is (p1._data, Directory::cwd () + "/foo", "Path::operator="); + + // Path (const std::string&); + Path p2 ("~"); + t.ok (p2._data != "~", "~ expanded to " + p2._data); + + Path p3 ("/tmp"); + t.ok (p3._data == "/tmp", "/tmp -> /tmp"); + + // Path& operator= (const Path&); + Path p3_copy (p3); + t.is (p3._data, p3_copy._data, "Path::Path (Path&)"); + + // operator (std::string) const; + t.is ((std::string) p3, "/tmp", "Path::operator (std::string) const"); + + // std::string name () const; + Path p4 ("/a/b/c/file.ext"); + t.is (p4.name (), "file.ext", "/a/b/c/file.ext name is file.ext"); + + // std::string parent () const; + t.is (p4.parent (), "/a/b/c", "/a/b/c/file.ext parent is /a/b/c"); + + // std::string extension () const; + t.is (p4.extension (), "ext", "/a/b/c/file.ext extension is ext"); + + // bool exists () const; + t.ok (p2.exists (), "~ exists"); + t.ok (p3.exists (), "/tmp exists"); + + // bool is_directory () const; + t.ok (p2.is_directory (), "~ is_directory"); + t.ok (p3.is_directory (), "/tmp is_directory"); + + // bool readable () const; + t.ok (p2.readable (), "~ readable"); + t.ok (p3.readable (), "/tmp readable"); + + // bool writable () const; + t.ok (p2.writable (), "~ writable"); + t.ok (p3.writable (), "/tmp writable"); + + // bool executable () const; + t.ok (p2.executable (), "~ executable"); + t.ok (p3.executable (), "/tmp executable"); + + // static std::string expand (const std::string&); + t.ok (Path::expand ("~") != "~", "Path::expand ~ != ~"); + t.ok (Path::expand ("~/") != "~/", "Path::expand ~/ != ~/"); + + // static std::vector glob (const std::string&); + std::vector out = Path::glob ("/tmp"); + t.ok (out.size () == 1, "/tmp -> 1 result"); + t.is (out[0], "/tmp", "/tmp -> /tmp"); + + out = Path::glob ("/t?p"); + t.ok (out.size () == 1, "/t?p -> 1 result"); + t.is (out[0], "/tmp", "/t?p -> /tmp"); + + out = Path::glob ("/[s-u]mp"); + t.ok (out.size () == 1, "/[s-u]mp -> 1 result"); + t.is (out[0], "/tmp", "/[s-u]mp -> /tmp"); + + // bool is_absolute () const; + t.notok (p0.is_absolute (), "'' !is_absolute"); + t.ok (p1.is_absolute (), "foo is_absolute"); + t.ok (p2.is_absolute (), "~ is_absolute (after expansion)"); + t.ok (p3.is_absolute (), "/tmp is_absolute"); + t.ok (p4.is_absolute (), "/a/b/c/file.ext is_absolute"); + Directory tmp ("tmp"); tmp.create (); t.ok (tmp.exists (), "tmp dir created."); + File::write ("tmp/file.t.txt", "This is a test\n"); + File f6 ("tmp/file.t.txt"); + t.ok (f6.size () == 15, "File::size tmp/file.t.txt good"); + t.ok (f6.mode () & S_IRUSR, "File::mode tmp/file.t.txt good"); + t.ok (File::remove ("tmp/file.t.txt"), "File::remove tmp/file.t.txt good"); + + // operator (std::string) const; + t.is ((std::string) f6, Directory::cwd () + "/tmp/file.t.txt", "File::operator (std::string) const"); + + t.ok (File::create ("tmp/file.t.create"), "File::create tmp/file.t.create good"); + t.ok (File::remove ("tmp/file.t.create"), "File::remove tmp/file.t.create good"); + + // basename (std::string) const; + t.is (f6.name (), "file.t.txt", "File::basename tmp/file.t.txt --> file.t.txt"); + + // dirname (std::string) const; + t.is (f6.parent (), Directory::cwd () + "/tmp", "File::dirname tmp/file.t.txt --> tmp"); + + // bool rename (const std::string&); + File f7 ("tmp/file.t.2.txt"); + f7.append ("something\n"); + f7.close (); + + t.ok (f7.rename ("tmp/file.t.3.txt"), "File::rename did not fail"); + t.is (f7._data, Directory::cwd () + "/tmp/file.t.3.txt", "File::rename stored new name"); + t.ok (f7.exists (), "File::rename new file exists"); + t.ok (f7.remove (), "File::remove tmp/file.t.3.txt good"); + t.notok (f7.exists (), "File::remove new file no longer exists"); + + // Test permissions. + File f8 ("tmp/file.t.perm.txt"); + f8.create (0744); + t.ok (f8.exists (), "File::create perm file exists"); + mode_t m = f8.mode (); + t.ok (m & S_IFREG, "File::mode tmp/file.t.perm.txt S_IFREG good"); + t.ok (m & S_IRUSR, "File::mode tmp/file.t.perm.txt r-------- good"); + t.ok (m & S_IWUSR, "File::mode tmp/file.t.perm.txt -w------- good"); + t.ok (m & S_IXUSR, "File::mode tmp/file.t.perm.txt --x------ good"); + t.ok (m & S_IRGRP, "File::mode tmp/file.t.perm.txt ---r----- good"); + t.notok (m & S_IWGRP, "File::mode tmp/file.t.perm.txt ----w---- good"); + t.notok (m & S_IXGRP, "File::mode tmp/file.t.perm.txt -----x--- good"); + t.ok (m & S_IROTH, "File::mode tmp/file.t.perm.txt ------r-- good"); + t.notok (m & S_IWOTH, "File::mode tmp/file.t.perm.txt -------w- good"); + t.notok (m & S_IXOTH, "File::mode tmp/file.t.perm.txt --------x good"); + f8.remove (); + t.notok (f8.exists (), "File::remove perm file no longer exists"); + + tmp.remove (); + t.notok (tmp.exists (), "tmp dir removed."); + tmp.create (); + t.ok (tmp.exists (), "tmp dir created."); + // Directory (const File&); // Directory (const Path&); Directory d0 (Path ("tmp")); @@ -133,7 +261,7 @@ int main (int argc, char** argv) Directory d10 ("tmp/dir.perm"); d10.create (0750); t.ok (d10.exists (), "Directory::create perm file exists"); - mode_t m = d10.mode (); + m = d10.mode (); t.ok (m & S_IFDIR, "Directory::mode tmp/dir.perm S_IFDIR good"); t.ok (m & S_IRUSR, "Directory::mode tmp/dir.perm r-------- good"); t.ok (m & S_IWUSR, "Directory::mode tmp/dir.perm -w------- good"); diff --git a/test/json_test.cpp b/test/json_test.cpp index 4739990aa..d9b53959d 100644 --- a/test/json_test.cpp +++ b/test/json_test.cpp @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include #include diff --git a/test/path.t.cpp b/test/path.t.cpp deleted file mode 100644 index 133a9d74a..000000000 --- a/test/path.t.cpp +++ /dev/null @@ -1,123 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// -// Copyright 2006 - 2015, Paul Beckingham, Federico Hernandez. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included -// in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS -// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -// http://www.opensource.org/licenses/mit-license.php -// -//////////////////////////////////////////////////////////////////////////////// - -#include -#include -#include -#include -#include -#include - -Context context; - -int main (int argc, char** argv) -{ - UnitTest t (32); - - // Ensure environment has no influence. - unsetenv ("TASKDATA"); - unsetenv ("TASKRC"); - - // Path (); - Path p0; - t.is (p0._data, "", "Path::Path"); - - // Path (const Path&); - Path p1 = Path ("foo"); - t.is (p1._data, Directory::cwd () + "/foo", "Path::operator="); - - // Path (const std::string&); - Path p2 ("~"); - t.ok (p2._data != "~", "~ expanded to " + p2._data); - - Path p3 ("/tmp"); - t.ok (p3._data == "/tmp", "/tmp -> /tmp"); - - // Path& operator= (const Path&); - Path p3_copy (p3); - t.is (p3._data, p3_copy._data, "Path::Path (Path&)"); - - // operator (std::string) const; - t.is ((std::string) p3, "/tmp", "Path::operator (std::string) const"); - - // std::string name () const; - Path p4 ("/a/b/c/file.ext"); - t.is (p4.name (), "file.ext", "/a/b/c/file.ext name is file.ext"); - - // std::string parent () const; - t.is (p4.parent (), "/a/b/c", "/a/b/c/file.ext parent is /a/b/c"); - - // std::string extension () const; - t.is (p4.extension (), "ext", "/a/b/c/file.ext extension is ext"); - - // bool exists () const; - t.ok (p2.exists (), "~ exists"); - t.ok (p3.exists (), "/tmp exists"); - - // bool is_directory () const; - t.ok (p2.is_directory (), "~ is_directory"); - t.ok (p3.is_directory (), "/tmp is_directory"); - - // bool readable () const; - t.ok (p2.readable (), "~ readable"); - t.ok (p3.readable (), "/tmp readable"); - - // bool writable () const; - t.ok (p2.writable (), "~ writable"); - t.ok (p3.writable (), "/tmp writable"); - - // bool executable () const; - t.ok (p2.executable (), "~ executable"); - t.ok (p3.executable (), "/tmp executable"); - - // static std::string expand (const std::string&); - t.ok (Path::expand ("~") != "~", "Path::expand ~ != ~"); - t.ok (Path::expand ("~/") != "~/", "Path::expand ~/ != ~/"); - - // static std::vector glob (const std::string&); - std::vector out = Path::glob ("/tmp"); - t.ok (out.size () == 1, "/tmp -> 1 result"); - t.is (out[0], "/tmp", "/tmp -> /tmp"); - - out = Path::glob ("/t?p"); - t.ok (out.size () == 1, "/t?p -> 1 result"); - t.is (out[0], "/tmp", "/t?p -> /tmp"); - - out = Path::glob ("/[s-u]mp"); - t.ok (out.size () == 1, "/[s-u]mp -> 1 result"); - t.is (out[0], "/tmp", "/[s-u]mp -> /tmp"); - - // bool is_absolute () const; - t.notok (p0.is_absolute (), "'' !is_absolute"); - t.ok (p1.is_absolute (), "foo is_absolute"); - t.ok (p2.is_absolute (), "~ is_absolute (after expansion)"); - t.ok (p3.is_absolute (), "/tmp is_absolute"); - t.ok (p4.is_absolute (), "/a/b/c/file.ext is_absolute"); - - return 0; -} - -////////////////////////////////////////////////////////////////////////////////