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