Skip to content

Commit

Permalink
Add glob patterns for --include option
Browse files Browse the repository at this point in the history
  • Loading branch information
dmitrivereshchagin committed Aug 15, 2016
1 parent 6e6d955 commit 02f467a
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 20 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ find_package(Boost REQUIRED COMPONENTS
date_time
system
program_options
regex
)
check_link_library(Boost Boost_LIBRARIES)
list(APPEND LIBRARIES ${Boost_LIBRARIES})
Expand Down
2 changes: 1 addition & 1 deletion doc/innoextract.1
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ Show a list of the supported options.
\fB\-I\fP, \fB\-\-include\fP \fIEXPR\fP
If this option is specified, innoextract will only process files whose path matches \fIEXPR\fP. The expression can be either a single path component (a file or directory name) or a series of successive path components joined by the OS path separator (\\ on Windows, / elsewhere).

The expression is always matched against one or more full path components. Filtering by parts of filenames is currently not supported. Matching is done case-insensitively.
The expression is always matched against one or more full path components. Matching is done case-insensitively. Each path component may contain wildcard characters. A '\fB*\fP' matches any part of path component, but it stops at path separator. A '\fB?\fP' matches any character except a path separator.

\fIEXPR\fP may contain one leading path separator, in which case the rest of the expression is matched against the start of the path. Otherwise, the expression is matched against any part of the path.

Expand Down
63 changes: 44 additions & 19 deletions src/cli/extract.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include <boost/filesystem/operations.hpp>
#include <boost/ptr_container/ptr_vector.hpp>
#include <boost/range/size.hpp>
#include <boost/regex.hpp>

#include <boost/version.hpp>
#if BOOST_VERSION >= 104800
Expand Down Expand Up @@ -168,19 +169,13 @@ typedef processed_item<setup::directory_entry> processed_directory;

class path_filter {

typedef std::pair<bool, std::string> Filter;
std::vector<Filter> includes;
std::vector<boost::regex> includes;

public:

explicit path_filter(const extract_options & o) {
BOOST_FOREACH(const std::string & include, o.include) {
if(!include.empty() && include[0] == setup::path_sep) {
includes.push_back(Filter(true, boost::to_lower_copy(include) + setup::path_sep));
} else {
includes.push_back(Filter(false, setup::path_sep + boost::to_lower_copy(include)
+ setup::path_sep));
}
includes.push_back(translate_glob(include));
}
}

Expand All @@ -190,22 +185,52 @@ class path_filter {
return true;
}

BOOST_FOREACH(const Filter & i, includes) {
if(i.first) {
if(!i.second.compare(1, i.second.size() - 1,
path + setup::path_sep, 0, i.second.size() - 1)) {
return true;
}
} else {
if((setup::path_sep + path + setup::path_sep).find(i.second) != std::string::npos) {
return true;
}
BOOST_FOREACH(const boost::regex & e, includes) {
if(boost::regex_search(setup::path_sep + path + setup::path_sep, e)) {
return true;
}
}

return false;
}


private:

static boost::regex translate_glob(const std::string & glob) {

std::string e = !glob.empty() && glob[0] == setup::path_sep
? "^" : setup::regex_path_sep;

char prev = '\0';
BOOST_FOREACH(char c, glob) {
e += translate_wildcards(c, prev);
prev = c;
}

e += setup::regex_path_sep;

return boost::regex(e, boost::regex::basic | boost::regex::icase);
}

static std::string translate_wildcards(char c, char prev) {

if(prev != '\\') {
if(c == '*') {
return setup::regex_not_path_sep + "*";
}

if(c == '?') {
return setup::regex_not_path_sep;
}

if(std::string("^.[$\\").find(c) != std::string::npos) {
return std::string("\\") + c;
}
}

return std::string() + c;
}

};

static void print_filter_info(const setup::item & item, bool temp) {
Expand Down
4 changes: 4 additions & 0 deletions src/setup/filename.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,12 @@ namespace setup {
//! Separator to use for output paths.
#if defined(_WIN32)
static const char path_sep = '\\';
static const std::string regex_path_sep = "\\\\";
static const std::string regex_not_path_sep = "[^\\]";
#else
static const char path_sep = '/';
static const std::string regex_path_sep = "/";
static const std::string regex_not_path_sep = "[^/]";
#endif

/*!
Expand Down

0 comments on commit 02f467a

Please sign in to comment.