Line data Source code
1 : #include "ErrorHandler/MessageAnalyzer/ma_richmsg.h"
2 : #include "ErrorHandler/MessageAnalyzer/ma_rule.h"
3 :
4 : using namespace novadaq::errorhandler;
5 :
6 : namespace {
7 :
8 0 : bool parse_msg_ref(std::string const& s, ma_rule const* rule, std::vector<cond_arg_t>& symbols)
9 : {
10 0 : size_t pos = s.find('.');
11 :
12 0 : if (pos == std::string::npos) return false; // no .
13 :
14 0 : cond_idx_t cond_idx = rule->get_cond_idx(s.substr(0, pos));
15 :
16 0 : ++pos;
17 :
18 0 : if (pos == s.size() || s[pos] != '$') return false; // no $
19 :
20 0 : ++pos;
21 :
22 0 : if (pos == s.size() || std::string("stmg").find(s[pos]) == std::string::npos) return false;
23 :
24 0 : switch (s[pos])
25 : {
26 0 : case 's': // $s, source
27 0 : if (pos == s.size() - 1)
28 : {
29 0 : symbols.push_back(cond_arg_t(cond_idx, SOURCE));
30 0 : return true;
31 : }
32 0 : return false;
33 :
34 0 : case 't': // $t, target
35 0 : if (pos == s.size() - 1)
36 : {
37 0 : symbols.push_back(cond_arg_t(cond_idx, TARGET));
38 0 : return true;
39 : }
40 0 : return false;
41 :
42 0 : case 'm': // $m, message
43 0 : if (pos == s.size() - 1)
44 : {
45 0 : symbols.push_back(cond_arg_t(cond_idx, MESSAGE));
46 0 : return true;
47 : }
48 0 : return false;
49 :
50 0 : case 'g': // $gn, group-n
51 0 : if (pos == s.size() - 2 && s[pos + 1] >= '1' && s[pos + 1] <= '9')
52 : {
53 0 : symbols.push_back(cond_arg_t(cond_idx, (arg_t)(GROUP1 + s[pos + 1] - '1')));
54 0 : return true;
55 : }
56 0 : return false;
57 :
58 0 : default:
59 0 : return false;
60 : }
61 : }
62 :
63 0 : bool parse_msg(std::string const& s, ma_rule const* rule, std::string& stripped_msg, std::vector<size_t>& insert_pos, std::vector<cond_arg_t>& symbols)
64 : {
65 0 : size_t old = 0;
66 0 : size_t pos = s.find("${");
67 0 : size_t ins = 0;
68 :
69 0 : while (pos != std::string::npos)
70 : {
71 0 : ins += (pos - old);
72 0 : insert_pos.push_back(ins);
73 0 : stripped_msg.append(s, old, pos - old);
74 :
75 0 : size_t close = s.find('}', pos);
76 :
77 0 : if (close == std::string::npos)
78 0 : return false; // no close '}'
79 :
80 0 : if (!parse_msg_ref(s.substr(pos + 2, close - pos - 2), rule, symbols))
81 0 : return false;
82 :
83 0 : old = close + 1;
84 0 : pos = s.find("${", old);
85 : }
86 :
87 0 : if (old < s.size())
88 0 : stripped_msg.append(s.substr(old));
89 :
90 0 : return true;
91 : }
92 :
93 : } // end of anonymous namespace
94 :
95 0 : ma_richmsg::ma_richmsg()
96 0 : : rule(NULL)
97 0 : , plain_msg()
98 0 : , stripped_msg()
99 0 : , insert_pos()
100 0 : , symbols()
101 : {
102 0 : }
103 :
104 0 : ma_richmsg::ma_richmsg(std::string const& s, ma_rule const* parent)
105 0 : : rule(NULL)
106 0 : , plain_msg()
107 0 : , stripped_msg()
108 0 : , insert_pos()
109 0 : , symbols()
110 : {
111 0 : init(parent, s);
112 0 : }
113 :
114 0 : void ma_richmsg::init(ma_rule const* parent, std::string const& s)
115 : {
116 0 : rule = parent;
117 0 : plain_msg = s;
118 :
119 0 : if (!parse_msg(plain_msg, rule, stripped_msg, insert_pos, symbols))
120 0 : throw std::runtime_error("Error parsing rule messages!");
121 0 : }
122 :
123 0 : const std::string& ma_richmsg::plain_message() const
124 : {
125 0 : return plain_msg;
126 : }
127 :
128 0 : std::string ma_richmsg::message() const
129 : {
130 0 : std::string result = stripped_msg;
131 0 : ma_domain const& alarm = rule->get_alarm();
132 :
133 0 : for (int i = symbols.size() - 1; i >= 0; --i)
134 : {
135 0 : ma_condition* cond_ptr = symbols[i].first.first;
136 0 : size_t cond_idx = symbols[i].first.second;
137 0 : arg_t cond_arg = symbols[i].second;
138 :
139 0 : result.insert(insert_pos[i], cond_ptr->get_arg(alarm[cond_idx], cond_arg));
140 : }
141 :
142 0 : return result;
143 0 : }
|