Line data Source code
1 :
2 : #include "ErrorHandler/MessageAnalyzer/ma_domain_cond.h"
3 : #include "ErrorHandler/MessageAnalyzer/ma_domain_expr.h"
4 : #include "ErrorHandler/MessageAnalyzer/ma_domain_ops.h"
5 : #include "ErrorHandler/MessageAnalyzer/ma_rule.h"
6 :
7 : using namespace novadaq::errorhandler;
8 :
9 0 : ma_domain_cond::ma_domain_cond()
10 0 : : cond_type(COND)
11 0 : , conds()
12 0 : , str_cond()
13 0 : , cond_size(0)
14 0 : , expr()
15 : {
16 0 : }
17 :
18 0 : void ma_domain_cond::insert_expr(ma_domain_expr const& d_expr)
19 : {
20 0 : expr.reset(new ma_domain_expr(d_expr));
21 0 : cond_type = EXPR;
22 0 : }
23 :
24 0 : void ma_domain_cond::evaluate(ma_domains& domains) const
25 : {
26 0 : ma_domains worksheet;
27 :
28 : // 1. '(' >> expr >> ')'
29 :
30 0 : if (cond_type == EXPR)
31 : {
32 0 : if (expr.get() == NULL)
33 0 : throw std::runtime_error("expr not exist");
34 :
35 0 : expr->evaluate(worksheet);
36 : }
37 :
38 : // 2. cond_1.$ = cond_2.$ = ... = 'string literal'
39 :
40 0 : else if (!str_cond.empty())
41 : {
42 : // # of conds must be not empty
43 0 : if (conds.empty())
44 0 : throw std::runtime_error("cond_arg_list cannot be empty");
45 :
46 : // init with (*,*) to all condition domains
47 0 : ma_domain domain = ma_domain_ctor_any(cond_size);
48 :
49 : // whether to keep the domain
50 0 : bool keep = true;
51 :
52 : // iterate
53 0 : cond_arg_list_t::const_iterator it = conds.begin();
54 0 : while (it != conds.end())
55 : {
56 0 : ma_condition* c_ptr = it->first.first;
57 0 : size_t c_idx = it->first.second;
58 0 : arg_t c_arg = it->second;
59 :
60 0 : int idx = c_ptr->find_arg(str_cond, c_arg);
61 :
62 0 : if (idx == D_NIL)
63 : {
64 0 : keep = false;
65 0 : break;
66 : }
67 : else
68 0 : domain[c_idx] = ma_cond_domain_ctor(idx, c_arg);
69 :
70 0 : ++it;
71 : }
72 :
73 : // push the domain if not flagged
74 0 : if (keep) worksheet.push_back(domain);
75 0 : }
76 :
77 : // 3. cond_1.$ = cond_2.$ = ...
78 :
79 : else
80 : {
81 : // # of conds must be 1 or greater
82 0 : if (conds.empty())
83 0 : throw std::runtime_error("no cond in cond list of ma_domain_cond");
84 :
85 : // first condition in the list
86 0 : ma_condition* c1_ptr = conds.front().first.first;
87 0 : int c1_idx = conds.front().first.second;
88 0 : arg_t c1_arg_type = conds.front().second;
89 :
90 : // get the src/target list
91 0 : idx_t const& c1_args = c1_ptr->get_args(c1_arg_type);
92 :
93 : // loop through the arg list
94 0 : idx_t::const_iterator it = c1_args.begin();
95 0 : for (; it != c1_args.end(); ++it)
96 : {
97 : // init everyone with (*,*)
98 0 : ma_domain domain = ma_domain_ctor_any(cond_size);
99 :
100 : // whether to keep this domain or not
101 0 : bool keep = true;
102 :
103 : // get the actual src/target string and index
104 0 : std::string const& c1_arg_str = it->first;
105 0 : size_t c1_arg_idx = it->second;
106 :
107 : // domain[c1_idx] = domain[c1_idx] n (c1_arg_idx, *)
108 0 : domain_intersect(domain[c1_idx], ma_cond_domain_ctor(c1_arg_idx, c1_arg_type));
109 :
110 : // iterate through the remaining conds
111 0 : cond_arg_list_t::const_iterator cond_it = conds.begin();
112 :
113 0 : while (++cond_it != conds.end())
114 : {
115 : // idx of current cond and its arg type (source/target)
116 0 : ma_condition* c_ptr = cond_it->first.first;
117 0 : size_t c_idx = cond_it->first.second;
118 0 : arg_t c_arg_type = cond_it->second;
119 :
120 : // find arg_str_c1 from current cond
121 0 : int c_arg_idx = c_ptr->find_arg(c1_arg_str, c_arg_type);
122 :
123 : // cannot find arg_str in the current cond. go for next arg_str
124 0 : if (c_arg_idx == D_NIL)
125 : {
126 0 : keep = false;
127 0 : break;
128 : }
129 :
130 : // domain[idx_c] = domain[idx_c] n (arg_idx_c, *)
131 0 : domain_intersect(domain[c_idx], ma_cond_domain_ctor(c_arg_idx, c_arg_type));
132 :
133 : // stop if domain[idx_c] is null, go for next arg_str
134 0 : if (domain_is_null(domain[c_idx]))
135 : {
136 0 : keep = false;
137 0 : break;
138 : }
139 : }
140 :
141 : // push the domain to the worksheet
142 0 : if (keep) worksheet.push_back(domain);
143 0 : }
144 : }
145 :
146 : // combine the domain list from the worksheet, and the list passed
147 : // in from above levels
148 :
149 0 : and_merge(domains, worksheet);
150 0 : }
151 :
152 : ma_domains&
153 0 : ma_domain_cond::and_merge(ma_domains& domains, ma_domains& worksheet) const
154 : {
155 0 : if (domains.empty())
156 : {
157 0 : domains.splice(domains.end(), worksheet);
158 0 : return domains;
159 : }
160 :
161 : // null worksheet will null everything in the domains
162 0 : if (worksheet.empty())
163 : {
164 0 : domains.clear();
165 0 : return domains;
166 : }
167 :
168 : // first expand the domains to the size of
169 : // N_domains * N_worksheet
170 0 : size_t nw = worksheet.size();
171 0 : ma_domains::iterator dit = domains.begin();
172 0 : for (; dit != domains.end(); ++dit)
173 0 : domains.insert(dit, nw - 1, *dit);
174 :
175 : // domain intersect operation
176 0 : dit = domains.begin();
177 0 : ma_domains::iterator wit = worksheet.begin();
178 0 : for (; dit != domains.end(); ++dit, ++wit)
179 : {
180 0 : if (wit == worksheet.end()) wit = worksheet.begin();
181 :
182 0 : domain_intersect(*dit, *wit);
183 : }
184 :
185 : // remove null domains
186 0 : domains.remove(ma_domain_ctor_null());
187 :
188 0 : return domains;
189 : }
|