From 37ba76a271eb75b38eeade43a383eb5f020de977 Mon Sep 17 00:00:00 2001 From: Emanuele Danovaro Date: Mon, 29 Jul 2024 14:20:08 +0200 Subject: [PATCH] simplified default param expansion --- VERSION | 2 +- src/metkit/mars/MarsLanguage.cc | 9 ++-- src/metkit/mars/TypeParam.cc | 81 ++++++++++++++++----------------- 3 files changed, 46 insertions(+), 46 deletions(-) diff --git a/VERSION b/VERSION index a88326ef..bcc565f2 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.11.17 +1.11.18 diff --git a/src/metkit/mars/MarsLanguage.cc b/src/metkit/mars/MarsLanguage.cc index 64351d6b..ab478731 100644 --- a/src/metkit/mars/MarsLanguage.cc +++ b/src/metkit/mars/MarsLanguage.cc @@ -221,9 +221,9 @@ std::string MarsLanguage::bestMatch(const MarsExpandContext& ctx, const std::str } } + static std::string empty; if (best.empty()) { - if (!fail) { - static std::string empty; + if (!fail) { return empty; } @@ -250,7 +250,10 @@ std::string MarsLanguage::bestMatch(const MarsExpandContext& ctx, const std::str return best[0]; } - + if (!fail) { + return empty; + } + std::ostringstream oss; oss << "Ambiguous value '" << name << "' could be"; diff --git a/src/metkit/mars/TypeParam.cc b/src/metkit/mars/TypeParam.cc index 18970a3a..1253b039 100644 --- a/src/metkit/mars/TypeParam.cc +++ b/src/metkit/mars/TypeParam.cc @@ -84,9 +84,12 @@ bool Matcher::match(const metkit::mars::MarsRequest& request, bool partial) cons class Rule : public metkit::mars::MarsExpandContext { std::vector matchers_; + std::vector values_; + mutable std::map mapping_; - mutable std::map mapping_; + static std::vector defaultValues_; + static std::map defaultMapping_; public: @@ -95,7 +98,7 @@ class Rule : public metkit::mars::MarsExpandContext { long toParamid(const std::string& param) const; Rule(const eckit::Value& matchers, const eckit::Value& setters, const eckit::Value& ids); - Rule(const Rule& other, const eckit::Value& matchers, const eckit::Value& values, const eckit::Value& ids); + static void setDefault(const eckit::Value& setters, const eckit::Value& ids); void print(std::ostream& out) const { out << "{"; @@ -119,59 +122,44 @@ class Rule : public metkit::mars::MarsExpandContext { }; -Rule::Rule(const Rule& other, const eckit::Value& matchers, const eckit::Value& values, const eckit::Value& ids) { +std::vector Rule::defaultValues_; +std::map Rule::defaultMapping_; - std::map precedence; +void Rule::setDefault(const eckit::Value& values, const eckit::Value& ids) { - const eckit::Value& keys = matchers.keys(); - for (size_t i = 0; i < keys.size(); ++i) { - std::string name = keys[i]; - matchers_.push_back(Matcher(name, matchers[name])); - } - - // cloning other Rule - values_.reserve(other.values_.size()); - for (const std::string& v : other.values_) { - values_.push_back(v); - } - auto it = mapping_.begin(); - for (auto m : other.mapping_) { - mapping_.emplace_hint(it, m.first, m.second); - it = mapping_.end(); - } + std::map precedence; - // adding new values for (size_t i = 0; i < values.size(); ++i) { const eckit::Value& id = values[i]; std::string first = id; - values_.push_back(first); + defaultValues_.push_back(first); const eckit::Value& aliases = ids[id]; if (aliases.isNil()) { - LOG_DEBUG_LIB(LibMetkit) << "No aliases for " << id << " " << *this << std::endl; + LOG_DEBUG_LIB(LibMetkit) << "No aliases for " << id << std::endl; continue; } + + for (size_t j = 0; j < aliases.size(); ++j) { std::string v = aliases[j]; - if (mapping_.find(v) != mapping_.end()) { - auto it = precedence.find(v); + if (defaultMapping_.find(v) != defaultMapping_.end()) { - if (it != precedence.end() and (*it).second <= j) { + if (precedence[v] <= j) { LOG_DEBUG_LIB(LibMetkit) << "Redefinition ignored: param " << v << "='" << first << "', keeping previous value of '" - << mapping_[v] + << defaultMapping_[v] << "' " - << *this << std::endl; continue; } @@ -182,9 +170,8 @@ Rule::Rule(const Rule& other, const eckit::Value& matchers, const eckit::Value& << "='" << first << "', overriding previous value of '" - << mapping_[v] + << defaultMapping_[v] << "' " - << *this << std::endl; precedence[v] = j; @@ -193,13 +180,12 @@ Rule::Rule(const Rule& other, const eckit::Value& matchers, const eckit::Value& precedence[v] = j; } - mapping_[v] = first; - values_.push_back(v); + defaultMapping_[v] = first; + defaultValues_.push_back(v); } } } - Rule::Rule(const eckit::Value& matchers, const eckit::Value& values, const eckit::Value& ids) { std::map precedence; @@ -304,7 +290,6 @@ std::string Rule::lookup(const MarsExpandContext& ctx, const std::string & s, bo size_t *n = ¶m; bool ok = true; - for (std::string::const_iterator k = s.begin(); k != s.end(); ++k) { switch (*k) { case '0': @@ -352,6 +337,12 @@ std::string Rule::lookup(const MarsExpandContext& ctx, const std::string & s, bo } } + for (std::vector::const_iterator j = defaultValues_.begin(); j != defaultValues_.end(); ++j) { + if ((*j) == p) { + return p; + } + } + throw eckit::UserError("Cannot match parameter " + p); return p; } @@ -365,7 +356,13 @@ std::string Rule::lookup(const MarsExpandContext& ctx, const std::string & s, bo ChainedContext c(ctx, *this); - return metkit::mars::MarsLanguage::bestMatch(c, s, values_, fail, false, mapping_); + std::cout << "############# bestMatch 1111111111111111111\n"; + std::string paramid = metkit::mars::MarsLanguage::bestMatch(c, s, values_, false, false, mapping_); + if (!paramid.empty()) { + return paramid; + } + std::cout << "############# bestMatch 222222222222222222\n"; + return metkit::mars::MarsLanguage::bestMatch(c, s, defaultValues_, fail, false, defaultMapping_); } static std::vector* rules = nullptr; @@ -430,14 +427,17 @@ static void init() { return; } + Rule::setDefault(ids.keys(), ids); + if (metkitRawParam) { - (*rules).push_back(Rule(eckit::Value::makeMap(), ids.keys(), ids)); + // empty rule, to enable default + (*rules).push_back(Rule(eckit::Value::makeMap(), eckit::Value::makeList(), eckit::Value::makeMap())); return; } std::set shortnames; std::set associatedIDs; - eckit::ValueList unambiguousIDs; + // eckit::ValueList unambiguousIDs; const eckit::Value pc = eckit::YAMLParser::decodeFile(LibMetkit::shortnameContextYamlFile()); ASSERT(pc.isList()); @@ -455,11 +455,8 @@ static void init() { if (shortnames.find(val) != shortnames.end()) { associatedIDs.emplace(keys[i]); - } else { - unambiguousIDs.push_back(keys[i]); } } - Rule baseRule(eckit::Value::makeMap(), unambiguousIDs, ids); for (auto it = merge.begin(); it != merge.end(); it++) { auto listIDs = eckit::Value::makeList(); @@ -470,11 +467,11 @@ static void init() { } } if (listIDs.size() > 0) { - (*rules).push_back(Rule{baseRule, it->first, listIDs, ids}); + (*rules).push_back(Rule{it->first, listIDs, ids}); } } - (*rules).push_back(Rule{eckit::Value::makeMap(), ids.keys(), ids}); + (*rules).push_back(Rule{eckit::Value::makeMap(), eckit::Value::makeList(), eckit::Value::makeMap()}); } namespace metkit {