diff --git a/CMakeLists.txt b/CMakeLists.txt index a61f333..abc4746 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.10) project(GodotPckTool) set(GODOT_PCK_TOOL_VERSION_MAJOR 1) -set(GODOT_PCK_TOOL_VERSION_MINOR 5) +set(GODOT_PCK_TOOL_VERSION_MINOR 6) set(GODOT_PCK_TOOL_VERSION_STR "${GODOT_PCK_TOOL_VERSION_MAJOR}.${GODOT_PCK_TOOL_VERSION_MINOR}") diff --git a/README.md b/README.md index 57267a2..edbf0bd 100644 --- a/README.md +++ b/README.md @@ -131,6 +131,17 @@ For example to find files containing "po" but no "zh": godotpcktool -i '\.po' -e 'zh' ``` +#### Overriding filters + +If you need more complex filtering you can specify regular expressions with +`--include-override-filter` which makes any file matching any of those +regular expression be included in the operation, even if another filter +would cause the file to be excluded. For example you can use this to set +file size limits and then override those for specific type: +```sh +godotpcktool --min-size-filter 1000 --include-override-filter '\.txt' +``` + ### General info In the long form multiple files may be included like this: diff --git a/src/FileFilter.cpp b/src/FileFilter.cpp index dac73d6..7285eb3 100644 --- a/src/FileFilter.cpp +++ b/src/FileFilter.cpp @@ -5,17 +5,19 @@ using namespace pcktool; // ------------------------------------ // bool FileFilter::Include(const PckFile::ContainedFile& file) const { - if(file.Size < MinSizeLimit) - return false; - - if(file.Size > MaxSizeLimit) - return false; + if(!OverridePatterns.empty()) { + for(const auto& pattern : OverridePatterns) { + if(std::regex_search(file.Path, pattern)) { + return true; + } + } + } - if(!IncludePatterns.empty()){ + if(!IncludePatterns.empty()) { bool matched = false; - for(const auto& pattern : IncludePatterns){ - if(std::regex_search(file.Path, pattern)){ + for(const auto& pattern : IncludePatterns) { + if(std::regex_search(file.Path, pattern)) { matched = true; break; } @@ -25,8 +27,14 @@ bool FileFilter::Include(const PckFile::ContainedFile& file) const return false; } - if(!ExcludePatterns.empty()){ - for(const auto& pattern : ExcludePatterns){ + if(file.Size < MinSizeLimit) + return false; + + if(file.Size > MaxSizeLimit) + return false; + + if(!ExcludePatterns.empty()) { + for(const auto& pattern : ExcludePatterns) { if(std::regex_search(file.Path, pattern)) return false; } diff --git a/src/FileFilter.h b/src/FileFilter.h index 745e945..f56a07e 100644 --- a/src/FileFilter.h +++ b/src/FileFilter.h @@ -36,6 +36,11 @@ class FileFilter { ExcludePatterns = filters; } + void SetIncludeOverrideRegexes(const std::vector& filters) + { + OverridePatterns = filters; + } + private: //! File is excluded if it is under this size uint64_t MinSizeLimit = 0; @@ -51,6 +56,10 @@ class FileFilter { //! any file being checked) must not regex_search find a match in any regexes in this //! vector, if they do, they are excluded std::vector ExcludePatterns; + + //! If non-empty then any files that pass this filter are included anyway, even if they + //! would fail another inclusion check + std::vector OverridePatterns; }; } // namespace pcktool diff --git a/src/main.cpp b/src/main.cpp index 7e55526..465085d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -77,6 +77,10 @@ int main(int argc, char* argv[]) "if both include and exclude are specified includes are handled first and " "excludes exclude files that include filters passed through", cxxopts::value>()) + ("include-override-filter", "Set regexes for files to include in operation even if " + "another filter might exclude it, doesn't affect inclusion of files not " + "matching this", + cxxopts::value>()) ("q,quieter", "Don't output all processed files to keep output more compact") ("v,version", "Print version and quit") ("h,help", "Print help and quit") @@ -157,6 +161,11 @@ int main(int argc, char* argv[]) ParseRegexList(result["exclude-regex-filter"].as>())); } + if(result.count("include-override-filter")) { + filter.SetIncludeOverrideRegexes( + ParseRegexList(result["include-override-filter"].as>())); + } + if(result.count("quieter")) { reducedVerbosity = true; }