diff options
author | John Wiegley <johnw@newartisans.com> | 2010-03-17 02:40:42 -0400 |
---|---|---|
committer | John Wiegley <johnw@newartisans.com> | 2010-03-17 02:40:42 -0400 |
commit | 8dd362b57cf2b49c5268e72898ae873522d8756f (patch) | |
tree | 4c5741d682e89b1ea4e567c32a78d32ba17737db /src | |
parent | 36b616da5e0e2b31138e05d347b0ff3599467c00 (diff) | |
download | fork-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.cc | 34 | ||||
-rw-r--r-- | src/mask.h | 1 | ||||
-rw-r--r-- | src/textual.cc | 38 |
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 @@ -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) |