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