From f3d3143aa67d1d038f5eee1103c2b783d54955c4 Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Fri, 30 Nov 2018 13:28:04 +0300 Subject: Match build configuration names, targets and machine names as paths --- mod/build-config.cxx | 78 ++++++++++++++++++++++++++++++++++++++++++-------- mod/build-config.hxx | 11 +++++++ mod/mod-build-task.cxx | 17 ++++++++--- 3 files changed, 90 insertions(+), 16 deletions(-) (limited to 'mod') diff --git a/mod/build-config.cxx b/mod/build-config.cxx index 5d3f46b..9368d33 100644 --- a/mod/build-config.cxx +++ b/mod/build-config.cxx @@ -6,7 +6,7 @@ #include #include -#include // find() +#include // replace() #include #include // throw_generic_error(), alpha(), etc. @@ -245,24 +245,78 @@ namespace brep // Now check if the configuration is excluded/included via the patterns. // - const string& cn (cfg.name); - string tg (cfg.target.string ()); - - for (const build_constraint& c: constrs) + // To implement matching of absent name components with wildcard-only name + // components we are going to convert names into paths (see + // from_build_config_name() for details). + // + // And if any of the build-{include,exclude} values (which is legal) or + // the build configuration name/target (illegal) are invalid paths, + // then we assume no match. + // + try { - if (path_match (c.config, cn) && - (!c.target || path_match (*c.target, tg))) + path cn (from_build_config_name (cfg.name)); + path tg (from_build_config_name (cfg.target.string ())); + + for (const build_constraint& c: constrs) { - if (!c.exclusion) - return false; + if (path_match (from_build_config_name (c.config), + cn, + dir_path () /* start */, + path_match_flags::match_absent) && + (!c.target || + path_match (from_build_config_name (*c.target), + tg, + dir_path () /* start */, + path_match_flags::match_absent))) + { + if (!c.exclusion) + return false; - if (reason != nullptr) - *reason = sanitize (c.comment); + if (reason != nullptr) + *reason = sanitize (c.comment); - return true; + return true; + } } } + catch (const invalid_path&) {} return false; } + + path + from_build_config_name (const string& s) + { + string r; + for (size_t i (0); i != s.size (); ++i) + { + char c (s[i]); + + switch (c) + { + case '-': + { + r += '/'; + break; + } + case '*': + { + if (s[i + 1] == '*') // Can be '\0'. + { + r += "*/**/*"; + ++i; + break; + } + } + default: + { + r += c; + break; + } + } + } + + return path (move (r)); + } } diff --git a/mod/build-config.hxx b/mod/build-config.hxx index e7ee9eb..a6f9902 100644 --- a/mod/build-config.hxx +++ b/mod/build-config.hxx @@ -80,6 +80,17 @@ namespace brep { return exclude (p.builds, p.constraints, c, r); } + + // Convert the build configuration name, target, machine name or their + // pattern into path, replacing dashes with slashes and double stars with + // the `*/**/*` substring for a subsequent match using our path_match() + // functionality. Throw invalid_path if the resulting path is invalid. + // + // Note that it is assumed that the match_absent path match flag will be + // used for matching for the double star replacement to make sense. + // + path + from_build_config_name (const string&); } #endif // MOD_BUILD_CONFIG_HXX diff --git a/mod/mod-build-task.cxx b/mod/mod-build-task.cxx index 03c053a..d66e90c 100644 --- a/mod/mod-build-task.cxx +++ b/mod/mod-build-task.cxx @@ -154,10 +154,19 @@ handle (request& rq, response& rs) { for (auto& m: tqm.machines) { - if (path_match (c.machine_pattern, m.name) && - cfg_machines.insert ( - make_pair (c.name.c_str (), config_machine ({&c, &m}))).second) - cfg_names.push_back (c.name.c_str ()); + // The same story as in exclude() from build-config.cxx. + // + try + { + if (path_match (from_build_config_name (c.machine_pattern), + from_build_config_name (m.name), + dir_path () /* start */, + path_match_flags::match_absent) && + cfg_machines.insert ( + make_pair (c.name.c_str (), config_machine ({&c, &m}))).second) + cfg_names.push_back (c.name.c_str ()); + } + catch (const invalid_path&) {} } } -- cgit v1.1