1 #include "rule_match.hpp"
2 #include "block/block.hpp"
3 #include "block/net.hpp"
4 #include "common/lut.hpp"
5 #include <glibmm.h>
6 #include "nlohmann/json.hpp"
7 #include "rule.hpp"
8 
9 namespace horizon {
10 static const LutEnumStr<RuleMatch::Mode> mode_lut = {
11         {"all", RuleMatch::Mode::ALL},
12         {"net", RuleMatch::Mode::NET},
13         {"net_class", RuleMatch::Mode::NET_CLASS},
14         {"net_name_regex", RuleMatch::Mode::NET_NAME_REGEX},
15         {"net_class_regex", RuleMatch::Mode::NET_CLASS_REGEX},
16 };
17 
RuleMatch()18 RuleMatch::RuleMatch()
19 {
20 }
21 
RuleMatch(const json & j)22 RuleMatch::RuleMatch(const json &j)
23     : mode(mode_lut.lookup(j.at("mode"))), net(j.at("net").get<std::string>()),
24       net_class(j.at("net_class").get<std::string>()), net_name_regex(j.at("net_name_regex").get<std::string>()),
25       net_class_regex(j.value("net_class_regex", ""))
26 {
27 }
28 
RuleMatch(const json & j,const RuleImportMap & import_map)29 RuleMatch::RuleMatch(const json &j, const RuleImportMap &import_map) : RuleMatch(j)
30 {
31     net_class = import_map.get_net_class(net_class);
32 }
33 
serialize() const34 json RuleMatch::serialize() const
35 {
36     json j;
37     j["mode"] = mode_lut.lookup_reverse(mode);
38     j["net"] = static_cast<std::string>(net);
39     j["net_class"] = static_cast<std::string>(net_class);
40     j["net_name_regex"] = net_name_regex;
41     if (net_class_regex.size())
42         j["net_class_regex"] = net_class_regex;
43 
44     return j;
45 }
46 
match(const Net * n) const47 bool RuleMatch::match(const Net *n) const
48 {
49     switch (mode) {
50     case Mode::ALL:
51         return true;
52 
53     case Mode::NET:
54         return n && n->uuid == net;
55 
56     case Mode::NET_CLASS:
57         return n && n->net_class->uuid == net_class;
58 
59     case Mode::NET_NAME_REGEX: {
60         const Glib::ustring u(net_name_regex);
61         const auto re = Glib::Regex::create(u);
62         return n && re->match(n->name);
63     }
64 
65     case Mode::NET_CLASS_REGEX: {
66         const Glib::ustring u(net_class_regex);
67         const auto re = Glib::Regex::create(u);
68         return n && n->net_class && re->match(n->net_class->name);
69     }
70     }
71     return false;
72 }
73 
cleanup(const Block * block)74 void RuleMatch::cleanup(const Block *block)
75 {
76     if (!block->nets.count(net))
77         net = UUID();
78     if (!block->net_classes.count(net_class))
79         net_class = block->net_class_default->uuid;
80 }
81 
get_brief(const Block * block) const82 std::string RuleMatch::get_brief(const Block *block) const
83 {
84     if (block) {
85         switch (mode) {
86         case Mode::ALL:
87             return "All";
88 
89         case Mode::NET:
90             return "Net " + (net ? block->nets.at(net).name : "?");
91 
92         case Mode::NET_CLASS:
93             return "Net class " + (net_class ? block->net_classes.at(net_class).name : "?");
94 
95         case Mode::NET_NAME_REGEX:
96             return "Net name regex";
97 
98         case Mode::NET_CLASS_REGEX:
99             return "Net class regex";
100         }
101     }
102     else {
103         switch (mode) {
104         case Mode::ALL:
105             return "All";
106 
107         case Mode::NET:
108             return "Net";
109 
110         case Mode::NET_CLASS:
111             return "Net class";
112 
113         case Mode::NET_NAME_REGEX:
114             return "Net name regex";
115 
116         case Mode::NET_CLASS_REGEX:
117             return "Net class regex";
118         }
119     }
120     return "";
121 }
122 
can_export() const123 bool RuleMatch::can_export() const
124 {
125     switch (mode) {
126     case Mode::ALL:
127     case Mode::NET_CLASS:
128     case Mode::NET_NAME_REGEX:
129     case Mode::NET_CLASS_REGEX:
130         return true;
131     default:
132         return false;
133     }
134 }
135 
136 } // namespace horizon
137