diff options
author | randomdan <randomdan@localhost> | 2011-12-20 14:40:20 +0000 |
---|---|---|
committer | randomdan <randomdan@localhost> | 2011-12-20 14:40:20 +0000 |
commit | 7c55397356b1a294df97eea86df563475ed89edb (patch) | |
tree | a65722f297ab9d9df9db03325946056a8e51fddb | |
parent | Split check and test functionality... if and check now take tests as children... (diff) | |
download | project2-7c55397356b1a294df97eea86df563475ed89edb.tar.bz2 project2-7c55397356b1a294df97eea86df563475ed89edb.tar.xz project2-7c55397356b1a294df97eea86df563475ed89edb.zip |
Pluggable file system row filters
fsrows now uses the proper variable instantiation methods
files module now includes a precompiled header
Supporting script changes
-rw-r--r-- | project2/files/Jamfile.jam | 4 | ||||
-rw-r--r-- | project2/files/fileRows.cpp | 1 | ||||
-rw-r--r-- | project2/files/fsFilterMaxDepth.cpp | 22 | ||||
-rw-r--r-- | project2/files/fsFilterName.cpp | 57 | ||||
-rw-r--r-- | project2/files/fsFilterType.cpp | 43 | ||||
-rw-r--r-- | project2/files/fsRows.cpp | 133 | ||||
-rw-r--r-- | project2/files/fsRows.h | 23 | ||||
-rw-r--r-- | project2/files/optionsSource.cpp | 1 | ||||
-rw-r--r-- | project2/files/pch.hpp | 33 | ||||
-rw-r--r-- | project2/files/streamRows.cpp | 1 |
10 files changed, 212 insertions, 106 deletions
diff --git a/project2/files/Jamfile.jam b/project2/files/Jamfile.jam index dd818b3..54df687 100644 --- a/project2/files/Jamfile.jam +++ b/project2/files/Jamfile.jam @@ -5,7 +5,11 @@ alias glibmm : : : : lib boost_system : : <name>boost_system ; lib boost_filesystem : : <name>boost_filesystem ; +cpp-pch pch : pch.hpp : + <library>../common//p2common + ; lib p2files : + pch [ glob *.cpp ] : <include>../libmisc diff --git a/project2/files/fileRows.cpp b/project2/files/fileRows.cpp index 3a8800b..bb0c059 100644 --- a/project2/files/fileRows.cpp +++ b/project2/files/fileRows.cpp @@ -1,3 +1,4 @@ +#include <pch.hpp> #include "fileRows.h" #include "logger.h" #include "scopeObject.h" diff --git a/project2/files/fsFilterMaxDepth.cpp b/project2/files/fsFilterMaxDepth.cpp new file mode 100644 index 0000000..f0d685e --- /dev/null +++ b/project2/files/fsFilterMaxDepth.cpp @@ -0,0 +1,22 @@ +#include <pch.hpp> +#include "fsRows.h" +#include "scripts.h" +#include <boost/lexical_cast.hpp> + +class FsRowSpecMaxDepth : public FsRows::SpecBase { + public: + FsRowSpecMaxDepth(ScriptNodePtr s) : + maxDepth(s, "depth") + { + } + FsRowSpecMaxDepth(const Glib::ustring & v) : + maxDepth(boost::lexical_cast<unsigned int>(v)) + { + } + bool recurse(const FsRows::SearchState * fs) const { + return (std::less<int64_t>()(depth(fs), maxDepth())); + } + Variable maxDepth; +}; + +DECLARE_COMPONENT_LOADER("maxdepth", FsRowSpecMaxDepth, FsRows::SpecBaseLoader); diff --git a/project2/files/fsFilterName.cpp b/project2/files/fsFilterName.cpp new file mode 100644 index 0000000..ad65c7e --- /dev/null +++ b/project2/files/fsFilterName.cpp @@ -0,0 +1,57 @@ +#include <pch.hpp> +#include "fsRows.h" +#include "scripts.h" + +class FsRowSpecName : public FsRows::SpecBase { + public: + FsRowSpecName(ScriptNodePtr s) : + pattern(s, "pattern") + { + } + FsRowSpecName(const Glib::ustring & v) : + pattern(v) + { + } + bool matches(const FsRows::SearchState * fs) const { + // Based on code written by Jack Handy - jakkhandy@hotmail.com + // from http://www.codeproject.com/KB/string/wildcmp.aspx + Glib::ustring patt = pattern(); + Glib::ustring::const_iterator wild = patt.begin(); + Glib::ustring leaf(curPath(fs).leaf().string()); + Glib::ustring::const_iterator string = leaf.begin(); + + while ((string != leaf.end()) && (*wild != '*')) { + if ((*wild != *string) && (*wild != '?')) { + return false; + } + wild++; + string++; + } + + Glib::ustring::const_iterator cp, mp; + while (string != leaf.end()) { + if (*wild == '*') { + if (!*++wild) { + return true; + } + mp = wild; + cp = string; + cp++; + } else if ((*wild == *string) || (*wild == '?')) { + wild++; + string++; + } else { + wild = mp; + string = cp++; + } + } + + while (*wild == '*') { + wild++; + } + return wild == patt.end(); + } + const Variable pattern; +}; + +DECLARE_COMPONENT_LOADER("name", FsRowSpecName, FsRows::SpecBaseLoader); diff --git a/project2/files/fsFilterType.cpp b/project2/files/fsFilterType.cpp new file mode 100644 index 0000000..0d0b27b --- /dev/null +++ b/project2/files/fsFilterType.cpp @@ -0,0 +1,43 @@ +#include <pch.hpp> +#include "fsRows.h" +#include "scripts.h" + +class FsRowSpecType : public FsRows::SpecBase { + public: + FsRowSpecType(ScriptNodePtr s) : + typelist(s, "types") + { + } + FsRowSpecType(const Glib::ustring & v) : + typelist(v) + { + } + bool matches(const FsRows::SearchState * fs) const { + const Glib::ustring types = typelist(); + if (S_ISREG(curStat(fs).st_mode)) { + return types.find('f') != Glib::ustring::npos; + } + if (S_ISDIR(curStat(fs).st_mode)) { + return types.find('d') != Glib::ustring::npos; + } + if (S_ISCHR(curStat(fs).st_mode)) { + return types.find('c') != Glib::ustring::npos; + } + if (S_ISBLK(curStat(fs).st_mode)) { + return types.find('b') != Glib::ustring::npos; + } + if (S_ISFIFO(curStat(fs).st_mode)) { + return types.find('p') != Glib::ustring::npos; + } + if (S_ISLNK(curStat(fs).st_mode)) { + return types.find('l') != Glib::ustring::npos; + } + if (S_ISSOCK(curStat(fs).st_mode)) { + return types.find('s') != Glib::ustring::npos; + } + return false; + } + const Variable typelist; +}; + +DECLARE_COMPONENT_LOADER("type", FsRowSpecType, FsRows::SpecBaseLoader); diff --git a/project2/files/fsRows.cpp b/project2/files/fsRows.cpp index 1c72473..6c8dd7c 100644 --- a/project2/files/fsRows.cpp +++ b/project2/files/fsRows.cpp @@ -1,3 +1,4 @@ +#include <pch.hpp> #include "fsRows.h" #include "logger.h" #include "scriptLoader.h" @@ -13,7 +14,6 @@ #include <grp.h> #include <stdio.h> #include <boost/date_time/posix_time/posix_time.hpp> -#include <boost/version.hpp> typedef boost::filesystem::directory_iterator DirEnt; @@ -42,94 +42,14 @@ const boost::filesystem::path & FsRows::SpecBase::curPath(const SearchState * fs unsigned int FsRows::SpecBase::depth(const SearchState * fs) const { return fs->depth; } const struct stat & FsRows::SpecBase::curStat(const SearchState * fs) const { return fs->curStat; } -class FsRowSpecName : public FsRows::SpecBase { - public: - FsRowSpecName(const Glib::ustring & v) : pattern(v) { } - bool matches(const FsRows::SearchState * fs) const { - // Based on code written by Jack Handy - jakkhandy@hotmail.com - // from http://www.codeproject.com/KB/string/wildcmp.aspx - Glib::ustring::const_iterator wild = pattern.begin(); -#if BOOST_VERSION >= 104500 - Glib::ustring leaf(curPath(fs).leaf().string()); -#else - Glib::ustring leaf(curPath(fs).leaf()); -#endif - Glib::ustring::const_iterator string = leaf.begin(); - - while ((string != leaf.end()) && (*wild != '*')) { - if ((*wild != *string) && (*wild != '?')) { - return false; - } - wild++; - string++; - } - - Glib::ustring::const_iterator cp, mp; - while (string != leaf.end()) { - if (*wild == '*') { - if (!*++wild) { - return true; - } - mp = wild; - cp = string; - cp++; - } else if ((*wild == *string) || (*wild == '?')) { - wild++; - string++; - } else { - wild = mp; - string = cp++; - } - } - - while (*wild == '*') { - wild++; - } - return wild == pattern.end(); - } - const Glib::ustring pattern; -}; -class FsRowSpecType : public FsRows::SpecBase { - public: - FsRowSpecType(const Glib::ustring & v) : types(v) { } - bool matches(const FsRows::SearchState * fs) const { - if (S_ISREG(curStat(fs).st_mode)) { - return types.find('f') != Glib::ustring::npos; - } - if (S_ISDIR(curStat(fs).st_mode)) { - return types.find('d') != Glib::ustring::npos; - } - if (S_ISCHR(curStat(fs).st_mode)) { - return types.find('c') != Glib::ustring::npos; - } - if (S_ISBLK(curStat(fs).st_mode)) { - return types.find('b') != Glib::ustring::npos; - } - if (S_ISFIFO(curStat(fs).st_mode)) { - return types.find('p') != Glib::ustring::npos; - } - if (S_ISLNK(curStat(fs).st_mode)) { - return types.find('l') != Glib::ustring::npos; - } - if (S_ISSOCK(curStat(fs).st_mode)) { - return types.find('s') != Glib::ustring::npos; - } - return false; - } - const Glib::ustring types; -}; -class FsRowSpecMaxDepth : public FsRows::SpecBase { - public: - FsRowSpecMaxDepth(const Glib::ustring & v) : maxDepth(boost::lexical_cast<unsigned int>(v)) { } - bool recurse(const FsRows::SearchState * fs) const { - return (depth(fs) < maxDepth); - } - const unsigned int maxDepth; -}; FsRows::FsRows(ScriptNodePtr p) : - RowSet(p) + RowSet(p), + root(p, "root"), + spec(p, "spec", ""), + ignoreErrors(p, "ignoreerrors", true) { + p->script->loader.addLoadTarget(p, Storer::into<SpecBaseLoader>(&specs)); } FsRows::~FsRows() @@ -140,7 +60,7 @@ FsRows::Path normalisePath(const std::string & p) { // Ensure there is a trailing / - if (*p.rend() != '/') { + if (*p.rbegin() != '/') { return p + "/"; } return p; @@ -149,24 +69,22 @@ normalisePath(const std::string & p) void FsRows::execute(const Glib::ustring &, const RowProcessor * rp) const { - SearchState ss(normalisePath(rp->getParameter("root"))); - SpecSpec s; - typedef SpecSpec & (*splitter)(SpecSpec &, const Glib::ustring &, bool (*)(gunichar), boost::algorithm::token_compress_mode_type); - splitter split = &boost::algorithm::split; - split(s, rp->getParameter("spec"), Glib::Unicode::isspace, boost::algorithm::token_compress_on); - for (SpecSpec::const_iterator sf = s.begin(); sf != s.end(); ) { - const Glib::ustring & name = (*sf++); - if (name == "-name") { - ss.specs.insert(new FsRowSpecName(*sf++)); - } - else if (name == "-type") { - ss.specs.insert(new FsRowSpecType(*sf++)); - } - else if (name == "-maxdepth") { - ss.specs.insert(new FsRowSpecMaxDepth(*sf++)); - } - else { - throw NotSupported(name); + SearchState ss(normalisePath(root())); + ss.specs = this->specs; + Glib::ustring sss = spec(); + if (!sss.empty()) { + SpecSpec s; + typedef SpecSpec & (*splitter)(SpecSpec &, const Glib::ustring &, bool (*)(gunichar), boost::algorithm::token_compress_mode_type); + splitter split = &boost::algorithm::split; + split(s, sss, Glib::Unicode::isspace, boost::algorithm::token_compress_on); + for (SpecSpec::const_iterator sf = s.begin(); sf != s.end(); ) { + const Glib::ustring & name = (*sf++); + if (name[0] == '-') { + ss.specs.insert(LoaderBase::getLoader<SpecBaseLoader, NotSupported>(name.substr(1))->create(*sf++)); + } + else { + throw NotSupported(name); + } } } execute(ss, ss.fsRoot, rp); @@ -180,6 +98,7 @@ FsRows::execute(SearchState & ss, const Path & dir, const RowProcessor * rp) con DirEnt end; for (DirEnt itr(dir); itr != end; ++itr) { ss.curPathStr = itr->path().string(); + ss.fields[0] = ss.curPathStr; ss.curPath = itr->path(); stat(ss.curPathStr.c_str(), &ss.curStat); @@ -193,6 +112,9 @@ FsRows::execute(SearchState & ss, const Path & dir, const RowProcessor * rp) con } } catch (const boost::filesystem::filesystem_error & e) { + if (!ignoreErrors()) { + throw; + } Logger()->messagef(LOG_WARNING, "%s when processing '%s'", e.what(), dir.string().c_str()); } ss.depth -= 1; @@ -201,6 +123,7 @@ FsRows::execute(SearchState & ss, const Path & dir, const RowProcessor * rp) con FsRows::SearchState::SearchState(const Path & dir) : fsRoot(dir) { + fields.resize(1); } const Columns & diff --git a/project2/files/fsRows.h b/project2/files/fsRows.h index a6b9c8c..acbce0d 100644 --- a/project2/files/fsRows.h +++ b/project2/files/fsRows.h @@ -6,6 +6,7 @@ #include <sys/stat.h> #include "variables.h" #include "rowSet.h" +#include "scriptStorage.h" class CommonObjects; @@ -23,13 +24,32 @@ class FsRows : public RowSet { const struct stat & curStat(const SearchState * fs) const; }; typedef boost::intrusive_ptr<SpecBase> SpecBasePtr; - typedef std::set<SpecBasePtr> SpecBases; + class SpecBaseLoader : public ComponentLoader { + public: + virtual SpecBasePtr createFrom(ScriptNodePtr) const = 0; + virtual SpecBasePtr create(const Glib::ustring &) const = 0; + }; + template <class T> + class SpecBaseLoaderImpl : public SpecBaseLoader { + public: + SpecBasePtr createFrom(ScriptNodePtr s) const { + return new T(s); + } + SpecBasePtr create(const Glib::ustring & v) const { + return new T(v); + } + }; + typedef ANONSTORAGEOF(SpecBase) SpecBases; typedef std::list<Glib::ustring> SpecSpec; typedef boost::filesystem::path Path; FsRows(ScriptNodePtr p); ~FsRows(); + const Variable root; + const Variable spec; + const Variable ignoreErrors; + void execute(const Glib::ustring &, const RowProcessor *) const; class SearchState : public RowState { public: @@ -59,6 +79,7 @@ class FsRows : public RowSet { protected: void execute(SearchState &, const Path & dir, const RowProcessor *) const; friend class SpecBase; + SpecBases specs; }; #endif diff --git a/project2/files/optionsSource.cpp b/project2/files/optionsSource.cpp index 95c2a57..84c06dc 100644 --- a/project2/files/optionsSource.cpp +++ b/project2/files/optionsSource.cpp @@ -1,3 +1,4 @@ +#include <pch.hpp> #include "optionsSource.h" #include <glibmm/iochannel.h> #include <glibmm/fileutils.h> diff --git a/project2/files/pch.hpp b/project2/files/pch.hpp new file mode 100644 index 0000000..0721191 --- /dev/null +++ b/project2/files/pch.hpp @@ -0,0 +1,33 @@ +#ifdef BOOST_BUILD_PCH_ENABLED +#ifndef FILES_PCH +#define FILES_PCH + +#include <boost/algorithm/string/predicate.hpp> +#include <boost/algorithm/string/split.hpp> +#include <boost/algorithm/string/trim.hpp> +#include <boost/bind.hpp> +#include <boost/date_time/posix_time/posix_time.hpp> +#include <boost/filesystem/operations.hpp> +#include <boost/filesystem/path.hpp> +#include <boost/intrusive_ptr.hpp> +#include <boost/lexical_cast.hpp> +#include "definedColumns.h" +#include "exceptions.h" +#include "fileRows.h" +#include "fsRows.h" +#include <glibmm/fileutils.h> +#include <glibmm/iochannel.h> +#include "logger.h" +#include "optionsSource.h" +#include "rowProcessor.h" +#include "rowSet.h" +#include "scopeObject.h" +#include "scriptLoader.h" +#include "scripts.h" +#include "scriptStorage.h" +#include "streamRows.h" +#include "variables.h" + +#endif +#endif + diff --git a/project2/files/streamRows.cpp b/project2/files/streamRows.cpp index fc2572d..26fb55b 100644 --- a/project2/files/streamRows.cpp +++ b/project2/files/streamRows.cpp @@ -1,3 +1,4 @@ +#include <pch.hpp> #include "streamRows.h" #include "rowProcessor.h" |