The include directive now supports file globbing

This only happens at the base filename, not for any of the directory
names for now.
This commit is contained in:
John Wiegley 2010-03-17 02:40:42 -04:00
parent 36b616da5e
commit 8dd362b57c
3 changed files with 68 additions and 5 deletions

View file

@ -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

View file

@ -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;

View file

@ -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)