summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrandomdan <randomdan@localhost>2011-12-20 14:40:20 +0000
committerrandomdan <randomdan@localhost>2011-12-20 14:40:20 +0000
commit7c55397356b1a294df97eea86df563475ed89edb (patch)
treea65722f297ab9d9df9db03325946056a8e51fddb
parentSplit check and test functionality... if and check now take tests as children... (diff)
downloadproject2-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.jam4
-rw-r--r--project2/files/fileRows.cpp1
-rw-r--r--project2/files/fsFilterMaxDepth.cpp22
-rw-r--r--project2/files/fsFilterName.cpp57
-rw-r--r--project2/files/fsFilterType.cpp43
-rw-r--r--project2/files/fsRows.cpp133
-rw-r--r--project2/files/fsRows.h23
-rw-r--r--project2/files/optionsSource.cpp1
-rw-r--r--project2/files/pch.hpp33
-rw-r--r--project2/files/streamRows.cpp1
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"