diff --git a/src/helpers/string_utils.cpp b/src/helpers/string_utils.cpp index 86f62301..1390127c 100644 --- a/src/helpers/string_utils.cpp +++ b/src/helpers/string_utils.cpp @@ -1,6 +1,36 @@ #include "string_utils.h" #include +namespace { + +void replace_substring(std::string &data, const std::string &from, const std::string &to) +{ + std::size_t pos = data.find(from); + while(pos != std::string::npos) { + data.replace(pos, from.size(), to); + pos = data.find(from, pos + to.size()); + } +} + +void escape_regex(std::string ®ex) +{ + replace_substring(regex, "\\", "\\\\"); + replace_substring(regex, "^", "\\^"); + replace_substring(regex, ".", "\\."); + replace_substring(regex, "$", "\\$"); + replace_substring(regex, "|", "\\|"); + replace_substring(regex, "(", "\\("); + replace_substring(regex, ")", "\\)"); + replace_substring(regex, "[", "\\["); + replace_substring(regex, "]", "\\]"); + replace_substring(regex, "*", "\\*"); + replace_substring(regex, "+", "\\+"); + replace_substring(regex, "?", "\\?"); + replace_substring(regex, "/", "\\/"); +} + +} // namespace + std::string helpers::random_alphanum_string(std::size_t length) { auto randchar = []() -> char { @@ -23,3 +53,15 @@ void helpers::filter_non_printable_chars(std::string &text) [](char c) { return !isprint(static_cast(c)) && !iscntrl(static_cast(c)); }), text.end()); } + +std::regex helpers::wildcards_regex(std::string wildcard_pattern) +{ + // Escape all regex special chars + escape_regex(wildcard_pattern); + + // Convert chars '*?' back to their regex equivalents + replace_substring(wildcard_pattern, "\\?", "."); + replace_substring(wildcard_pattern, "\\*", ".*"); + + return std::regex(wildcard_pattern); +} diff --git a/src/helpers/string_utils.h b/src/helpers/string_utils.h index f2fd682c..12a8c564 100644 --- a/src/helpers/string_utils.h +++ b/src/helpers/string_utils.h @@ -3,6 +3,7 @@ #include #include +#include namespace helpers { @@ -18,6 +19,13 @@ namespace helpers * @param text */ void filter_non_printable_chars(std::string &text); + + /** + * Constructs appropriate regular expression for given wildcard. + * @param string with wildcard pattern + * @return regex + */ + std::regex wildcards_regex(std::string wildcard_pattern); } // namespace helpers diff --git a/src/tasks/internal/cp_task.cpp b/src/tasks/internal/cp_task.cpp index 9d643d80..56c93b66 100644 --- a/src/tasks/internal/cp_task.cpp +++ b/src/tasks/internal/cp_task.cpp @@ -1,5 +1,5 @@ #include "cp_task.h" -#include +#include "helpers/string_utils.h" #include "helpers/filesystem.h" #define BOOST_FILESYSTEM_NO_DEPRECATED @@ -8,48 +8,6 @@ namespace fs = boost::filesystem; -namespace { - -void replace_substring(std::string &data, const std::string &from, const std::string &to) -{ - std::size_t pos = data.find(from); - while(pos != std::string::npos) { - data.replace(pos, from.size(), to); - pos = data.find(from, pos + to.size()); - } -} - -void escape_regex(std::string ®ex) -{ - replace_substring(regex, "\\", "\\\\"); - replace_substring(regex, "^", "\\^"); - replace_substring(regex, ".", "\\."); - replace_substring(regex, "$", "\\$"); - replace_substring(regex, "|", "\\|"); - replace_substring(regex, "(", "\\("); - replace_substring(regex, ")", "\\)"); - replace_substring(regex, "[", "\\["); - replace_substring(regex, "]", "\\]"); - replace_substring(regex, "*", "\\*"); - replace_substring(regex, "+", "\\+"); - replace_substring(regex, "?", "\\?"); - replace_substring(regex, "/", "\\/"); -} - -std::regex wildcards_regex(std::string wildcard_pattern) -{ - // Escape all regex special chars - escape_regex(wildcard_pattern); - - // Convert chars '*?' back to their regex equivalents - replace_substring(wildcard_pattern, "\\?", "."); - replace_substring(wildcard_pattern, "\\*", ".*"); - - return std::regex(wildcard_pattern); -} - -} // namespace - cp_task::cp_task(std::size_t id, std::shared_ptr task_meta) : task_base(id, task_meta) { @@ -79,7 +37,7 @@ std::shared_ptr cp_task::run() fs::path input(task_meta_->cmd_args[0]); auto filename_matcher = input.filename().string(); auto base_dir = input.remove_filename(); - auto pattern = wildcards_regex(filename_matcher); + auto pattern = helpers::wildcards_regex(filename_matcher); // parse output path and check if it is existing directory or not fs::path output(task_meta_->cmd_args[1]);