summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Wiegley <johnw@newartisans.com>2010-03-17 02:40:42 -0400
committerJohn Wiegley <johnw@newartisans.com>2010-03-17 02:40:42 -0400
commit8dd362b57cf2b49c5268e72898ae873522d8756f (patch)
tree4c5741d682e89b1ea4e567c32a78d32ba17737db /src
parent36b616da5e0e2b31138e05d347b0ff3599467c00 (diff)
downloadfork-ledger-8dd362b57cf2b49c5268e72898ae873522d8756f.tar.gz
fork-ledger-8dd362b57cf2b49c5268e72898ae873522d8756f.tar.bz2
fork-ledger-8dd362b57cf2b49c5268e72898ae873522d8756f.zip
The include directive now supports file globbing
This only happens at the base filename, not for any of the directory names for now.
Diffstat (limited to 'src')
-rw-r--r--src/mask.cc34
-rw-r--r--src/mask.h1
-rw-r--r--src/textual.cc38
3 files changed, 68 insertions, 5 deletions
diff --git a/src/mask.cc b/src/mask.cc
index 601d2a6a..cd516fe2 100644
--- a/src/mask.cc
+++ b/src/mask.cc
@@ -52,4 +52,38 @@ mask_t& mask_t::operator=(const string& pat)
return *this;
}
+mask_t& mask_t::assign_glob(const string& pat)
+{
+ string re_pat = "";
+ string::size_type len = pat.length();
+ for (string::size_type i = 0; i < len; i++) {
+ switch (pat[i]) {
+ case '?':
+ re_pat += '.';
+ break;
+ case '*':
+ re_pat += ".*";
+ break;
+ case '[':
+ while (i < len && pat[i] != ']')
+ re_pat += pat[i++];
+ if (i < len)
+ re_pat += pat[i];
+ break;
+
+ case '\\':
+ if (i + 1 < len) {
+ re_pat += pat[++i];
+ break;
+ } else {
+ // fallthrough...
+ }
+ default:
+ re_pat += pat[i];
+ break;
+ }
+ }
+ return (*this = re_pat);
+}
+
} // namespace ledger
diff --git a/src/mask.h b/src/mask.h
index 755a2229..ed9e8ac1 100644
--- a/src/mask.h
+++ b/src/mask.h
@@ -73,6 +73,7 @@ public:
}
mask_t& operator=(const string& other);
+ mask_t& assign_glob(const string& other);
bool operator<(const mask_t& other) const {
return expr < other.expr;
diff --git a/src/textual.cc b/src/textual.cc
index 0a2166f8..dfca7943 100644
--- a/src/textual.cc
+++ b/src/textual.cc
@@ -665,14 +665,42 @@ void instance_t::include_directive(char * line)
filename = resolve_path(filename);
DEBUG("textual.include", "resolved path: " << filename.string());
- if (! exists(filename))
+ mask_t glob;
+#if BOOST_VERSION >= 103700
+ path parent_path = filename.parent_path();
+ glob.assign_glob(filename.filename());
+#else // BOOST_VERSION >= 103700
+ path parent_path = filename.branch_path();
+ glob.assign_glob(filename.leaf());
+#endif // BOOST_VERSION >= 103700
+
+ bool files_found = false;
+ if (exists(parent_path)) {
+ filesystem::directory_iterator end;
+ for (filesystem::directory_iterator iter(parent_path);
+ iter != end;
+ ++iter) {
+ if (is_regular_file(*iter)) {
+#if BOOST_VERSION >= 103700
+ string base = (*iter).filename();
+#else // BOOST_VERSION >= 103700
+ string base = (*iter).leaf();
+#endif // BOOST_VERSION >= 103700
+ if (glob.match(base)) {
+ path inner_file(*iter);
+ ifstream stream(inner_file);
+ instance_t instance(context, stream, master, &inner_file, this);
+ instance.parse();
+ files_found = true;
+ }
+ }
+ }
+ }
+
+ if (! files_found)
throw_(std::runtime_error,
_("File to include was not found: '%1'") << filename);
- ifstream stream(filename);
-
- instance_t instance(context, stream, master, &filename, this);
- instance.parse();
}
void instance_t::master_account_directive(char * line)