The Battle for Wesnoth  1.19.0-dev
config_filters.cpp
Go to the documentation of this file.
1 /*
2  Copyright (C) 2003 - 2024
3  Part of the Battle for Wesnoth Project https://www.wesnoth.org/
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; either version 2 of the License, or
8  (at your option) any later version.
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY.
11 
12  See the COPYING file for more details.
13 */
14 
15 #include <algorithm>
16 #include <vector>
17 
18 #include "utils/config_filters.hpp"
19 
20 #include "serialization/string_utils.hpp" // for utils::split
21 #include "utils/math.hpp" // for in_ranges
22 
23 bool utils::config_filters::bool_matches_if_present(const config& filter, const config& cfg, const std::string& attribute, bool def)
24 {
25  if(!filter.has_attribute(attribute)) {
26  return true;
27  }
28 
29  return filter[attribute].to_bool() == cfg[attribute].to_bool(def);
30 }
31 
33  const config& filter, const config& cfg, const std::string& attribute, const std::string& def)
34 {
35  if(!filter.has_attribute(attribute)) {
36  return true;
37  }
38 
39  const std::vector<std::string> filter_attribute = utils::split(filter[attribute]);
40  return (
41  std::find(filter_attribute.begin(), filter_attribute.end(), cfg[attribute].str(def)) != filter_attribute.end());
42 }
43 
44 bool utils::config_filters::unsigned_matches_if_present(const config& filter, const config& cfg, const std::string& attribute)
45 {
46  if(!filter.has_attribute(attribute)) {
47  return true;
48  }
49  if(!cfg.has_attribute(attribute)) {
50  return false;
51  }
52 
53  return in_ranges<int>(cfg[attribute].to_int(0), utils::parse_ranges_unsigned(filter[attribute].str()));
54 }
55 
56 bool utils::config_filters::int_matches_if_present(const config& filter, const config& cfg, const std::string& attribute, std::optional<int> def)
57 {
58  if(!filter.has_attribute(attribute)) {
59  return true;
60  }
61  if(!cfg.has_attribute(attribute) && !def) {
62  return false;
63  }
64 
65  int value_def = def ? (*def) : 0;
66  return in_ranges<int>(cfg[attribute].to_int(value_def), utils::parse_ranges_int(filter[attribute].str()));
67 }
68 
70  const config& filter, const config& cfg, const std::string& attribute, const std::string& opposite, std::optional<int> def)
71 {
72  if(int_matches_if_present(filter, cfg, attribute, def)) {
73  return true;
74  }
75 
76  // Check if cfg[opposite].empty() and have optional def.
77  // If def don't exist return false.
78  if(!cfg.has_attribute(attribute)) {
79  if(!cfg.has_attribute(opposite) && !def) {
80  return false;
81  }
82  int value_def = def ? (*def) : 0;
83  return in_ranges<int>(-cfg[opposite].to_int(value_def), utils::parse_ranges_int(filter[attribute].str()));
84  }
85 
86  return false;
87 }
88 
89 bool utils::config_filters::double_matches_if_present(const config& filter, const config& cfg, const std::string& attribute, std::optional<double> def)
90 {
91  if(!filter.has_attribute(attribute)) {
92  return true;
93  }
94  if(!cfg.has_attribute(attribute) && !def) {
95  return false;
96  }
97 
98  double value_def = def ? (*def) : 1;
99  return in_ranges<double>(cfg[attribute].to_double(value_def), utils::parse_ranges_real(filter[attribute].str()));
100 }
101 
102 bool utils::config_filters::bool_or_empty(const config& filter, const config& cfg, const std::string& attribute)
103 {
104  if(!filter.has_attribute(attribute)) {
105  return true;
106  }
107 
108  std::set<std::string> filter_attribute = utils::split_set(filter[attribute].str());
109  bool is_matches = false;
110  if(cfg.has_attribute(attribute)){
111  if(filter_attribute.count("yes") != 0 || filter_attribute.count("true") != 0){
112  is_matches = cfg[attribute].to_bool();
113  }
114  if(!is_matches && (filter_attribute.count("no") != 0 || filter_attribute.count("false") != 0)){
115  is_matches = !cfg[attribute].to_bool();
116  }
117  } else {
118  if(filter_attribute.count("none") != 0){
119  is_matches = true;
120  }
121  }
122  return is_matches;
123 }
A config object defines a single node in a WML file, with access to child nodes.
Definition: config.hpp:159
bool has_attribute(config_key_type key) const
Definition: config.cpp:155
General math utility functions.
bool unsigned_matches_if_present(const config &filter, const config &cfg, const std::string &attribute)
Restricts filters to only looking for values that are zero or more.
bool int_matches_if_present(const config &filter, const config &cfg, const std::string &attribute, std::optional< int > def=std::nullopt)
bool string_matches_if_present(const config &filter, const config &cfg, const std::string &attribute, const std::string &def)
bool double_matches_if_present(const config &filter, const config &cfg, const std::string &attribute, std::optional< double > def=std::nullopt)
Checks whether the filter matches the value of cfg[attribute].
bool bool_or_empty(const config &filter, const config &cfg, const std::string &attribute)
bool int_matches_if_present_or_negative(const config &filter, const config &cfg, const std::string &attribute, const std::string &opposite, std::optional< int > def=std::nullopt)
Supports filters using "add" and "sub" attributes, for example a filter add=1 matching a cfg containi...
bool bool_matches_if_present(const config &filter, const config &cfg, const std::string &attribute, bool def)
Checks whether the filter matches the value of cfg[attribute].
std::set< std::string > split_set(std::string_view s, char sep, const int flags)
std::vector< std::pair< int, int > > parse_ranges_int(const std::string &str)
Handles a comma-separated list of inputs to parse_range.
std::vector< std::pair< int, int > > parse_ranges_unsigned(const std::string &str)
Handles a comma-separated list of inputs to parse_range, in a context that does not expect negative v...
std::vector< std::pair< double, double > > parse_ranges_real(const std::string &str)
std::vector< std::string > split(const config_attribute_value &val)