StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
StMessageCounter.cxx
1 // //
3 // StMessageCounter //
4 // //
5 // This class manages message limiting in STAR. It is a singleton. //
6 // Limits can be placed on message types (i.e. "I" for info messages) //
7 // or on strings in messages (i.e. "dst_track empty") //
8 // //
10 
11 #include "StMessageCounter.h"
12 #include "StMessageStream.h"
13 #include <cstring>
14 using namespace std;
15 StMessageCounter* StMessageCounter::mInstance = 0;
16 
17 //_____________________________________________________________________________
18 StMessageCounter::StMessageCounter() : std::ostringstream(),
19 limitMessage(" - COUNT LIMIT REACHED!\n") {
20  messTypeList = StMessTypeList::Instance();
21  yesLimits = 0;
22  noLimits = 0;
23 }
24 //_____________________________________________________________________________
25 StMessageCounter::~StMessageCounter() {
26 }
27 //_____________________________________________________________________________
28 StMessageCounter* StMessageCounter::Instance() {
29  if (!mInstance) {
30  mInstance = new StMessageCounter;
31  }
32  return mInstance;
33 }
34 //_____________________________________________________________________________
35 void StMessageCounter::SetLimit(const char* str, int n) {
36  if (noLimits) return;
37  if (!yesLimits && (n >= 0)) yesLimits = 1;
38  const size_t len = strlen(str);
39  char* temp;
40  if (len==1) { // Limits by type
41  int typeN = messTypeList->FindTypeNum(str);
42  if (typeN) {
43  if (limitTList[typeN] != -5) // -5 means fixed with no limit
44  limitTList[typeN] = n;
45  } else { // Waiting list for type limits
46  if (limitWList.size()) {
47  size_t index = 0;
48  for (curString=limitWList.begin(); curString!=limitWList.end();
49  curString++) {
50  if (*str == *(*curString)) { // Already in the waiting list
51  if (limitWNList[index] != -5) // -5 means fixed with no limit
52  limitWNList[index] = n;
53  return;
54  }
55  index++;
56  }
57  }
58  temp = new char[len+1];
59  temp[len] = 0;
60  limitWList.push_back(strncpy(temp,str,len));
61  limitWNList.push_back(n);
62  }
63  } else { // Limits by string
64  size_t index=0;
65  for (curString=limitList.begin(); curString!=limitList.end();
66  curString++) {
67  if (!strcmp(str,(*curString))) {
68  if (limitNList[index] == -5) return; // -5 means fixed with no limit
69  if ((n < 0) && (n != -5)) {
70  limitList.erase(curString);
71  limitNList.erase(limitNList.begin()+index);
72  limitNCountList.erase(limitNCountList.begin()+index);
73  } else {
74  limitNList[index] = n;
75  }
76  return;
77  }
78  index++;
79  }
80  if ((n < 0) && (n != -5)) return;
81  temp = new char[len+1];
82  temp[len] = 0;
83  limitList.push_back(strncpy(temp,str,len));
84  limitNList.push_back(n);
85  limitNCountList.push_back(0);
86  }
87  return;
88 }
89 //_____________________________________________________________________________
90 int StMessageCounter::GetLimit(const char* str) {
91  const size_t len = strlen(str);
92  if (len==1) { // Limits by type
93  int typeN = messTypeList->FindTypeNum(str);
94  if (typeN) {
95  return limitTList[typeN];
96  } else { // Waiting list for type limits
97  if (limitWList.size()) {
98  size_t index = 0;
99  for (curString=limitWList.begin(); curString!=limitWList.end();
100  curString++) {
101  if (*str == *(*curString)) return limitWNList[index];
102  index++;
103  }
104  }
105  }
106  } else { // Limits by string
107  size_t index=0;
108  for (curString=limitList.begin(); curString!=limitList.end();
109  curString++) {
110  if (!strcmp(str,(*curString))) return limitNList[index];
111  index++;
112  }
113  }
114  return -1; // Not found, no limit
115 }
116 //_____________________________________________________________________________
117 void StMessageCounter::ListLimits() {
118  if (yesLimits) {
119  myout << "StMessage Limits: negative limit means no limit, ";
120  myout << "-5 means fixed with no limit\n";
121  myout << " Limits : counts : on message types" << endl;
122  size_t index=0;
123  for (index = 1; index < limitTList.size(); index++) {
124  myout.width(8);
125  myout << limitTList[index] << " : ";
126  myout.width(8);
127  myout << limitTCountList[index] << " : ";
128  myout << messTypeList->FindNumType(index) << " - ";
129  myout << messTypeList->FindNumText(index) << endl;
130  }
131  for (index = 0; index < limitWList.size(); index++) {
132  myout.width(8);
133  myout << limitWNList[index] << " : ";
134  myout.width(8);
135  myout << 0 << " : ";
136  myout << limitWList[index] << " - ";
137  myout << "???" << endl;
138  }
139  myout << " Limits : counts : on message strings" << endl;
140  index=0;
141  for (curString=limitList.begin(); curString!=limitList.end();
142  curString++) {
143  myout.width(8);
144  myout << limitNList[index] << " : ";
145  myout.width(8);
146  myout << limitNCountList[index++] << " : ";
147  myout << (*curString) << endl;
148  }
149  } else {
150  myout << "No limits have been set on messages." << endl;
151  }
152  return;
153 }
154 //_____________________________________________________________________________
155 int StMessageCounter::CheckLimit(char* mess, const char* type) {
156  static const char* leader="St";
157  static const char* colon =": ";
158  static const char* stmess="StMessage: ";
159  int printIt = 1;
160  int typeN = messTypeList->FindTypeNum(type);
161  int typeNewSize = limitTCountList[typeN] + 1;
162  limitTCountList[typeN] = typeNewSize;
163 
164  if (yesLimits && (! noLimits)) {
165  seekp(0);
166  int limit = limitTList[typeN];
167  if (typeNewSize == limit) {
168  *this << leader;
169  *this << (messTypeList->FindType(type)->Text());
170  *this << colon << limitMessage;
171  } else if ((limit >= 0) && (typeNewSize > limit)) {
172  printIt = 0;
173  }
174 
175  size_t index=0;
176  for (curString=limitList.begin(); curString!=limitList.end();
177  curString++) {
178  if (strstr(mess,(*curString))) {
179  int counts = limitNCountList[index] + 1;
180  limitNCountList[index] = counts;
181  limit = limitNList[index];
182  if (counts==limit) {
183  *this << stmess << (*curString) << limitMessage;
184  } else if ((limit >= 0) && (counts > limit)) {
185  printIt = 0;
186  }
187  }
188  index++;
189  }
190  }
191  return printIt;
192 }
193 //_____________________________________________________________________________
194 void StMessageCounter::AddType(const char* type) {
195  limitTList.push_back(-1);
196  limitTCountList.push_back(0);
197  if (limitWList.size()) {
198  size_t index=0; // Now check the waiting list
199  for (curString=limitWList.begin(); curString!=limitWList.end();
200  curString++) {
201  if (*type == *(*curString)) {
202  SetLimit((*curString),limitWNList[index]);
203  limitWList.erase(curString);
204  limitWNList.erase(limitWNList.begin()+index);
205  return;
206  }
207  index++;
208  }
209  }
210 }
211 
212 //_____________________________________________________________________________
213 // $Id: StMessageCounter.cxx,v 1.22 2016/06/14 06:26:34 genevb Exp $
214 // $Log: StMessageCounter.cxx,v $
215 // Revision 1.22 2016/06/14 06:26:34 genevb
216 // better initializations (Coverity)
217 //
218 // Revision 1.21 2012/06/11 15:05:34 fisyak
219 // std namespace
220 //
221 // Revision 1.20 2009/08/26 19:39:04 fine
222 // fix the compilation issues under SL5_64_bits gcc 4.3.2
223 //
224 // Revision 1.19 2003/10/01 20:06:50 genevb
225 // Initialize and test ostrstream buffer sizes (support for gcc before 3.2)
226 //
227 // Revision 1.18 2003/09/25 21:19:22 genevb
228 // Some new cout-like functions and friend functions, some doxygen-ization
229 //
230 // Revision 1.17 2003/09/02 17:59:20 perev
231 // gcc 3.2 updates + WarnOff
232 //
233 // Revision 1.16 2000/06/07 00:05:36 genevb
234 // Added FixOn(), enforcing no limits on a specific message type/string
235 //
236 // Revision 1.15 2000/03/30 16:12:55 genevb
237 // Add NoLimits() capability to turn off message limiting.
238 //
239 // Revision 1.14 2000/03/24 14:48:39 genevb
240 // Insurance on end-of-strings
241 //
242 // Revision 1.13 2000/01/05 19:53:46 genevb
243 // Fixed CC5 warnings, and several other small improvements under the hood
244 //
245 // Revision 1.12 1999/07/17 00:38:03 genevb
246 // Small typo
247 //
248 // Revision 1.11 1999/07/17 00:23:23 genevb
249 // Fixed bug when option fields are empty in FORTRAN, and let type limits be set before types are even added
250 //
251 // Revision 1.10 1999/07/15 05:15:06 genevb
252 // Fixed an odd bug with seekp(0) on an empty stream buffer
253 //
254 // Revision 1.9 1999/07/01 01:24:46 genevb
255 // Fixed FORTRAN character string bug on linux, removed a memory leak from Summary()
256 //
257 // Revision 1.7 1999/06/30 04:18:45 genevb
258 // Fixes: summary wrap-around, unsigned ints, last character of message, <> for time; no KNOWN remaining bugs
259 //
260 // Revision 1.6 1999/06/29 17:37:31 genevb
261 // Lots of fixes...
262 //
263 // Revision 1.5 1999/06/28 02:40:55 genevb
264 // Additional backward compatibilit with MSG (msg_enable, msg_enabled, msg_disable
265 //
266 // Revision 1.4 1999/06/26 00:24:52 genevb
267 // Fixed const type mismatches
268 //
269 // Revision 1.3 1999/06/25 22:57:56 genevb
270 // Fixed a small bug in MSG compatibiliti
271 //
272 // Revision 1.2 1999/06/24 16:30:42 genevb
273 // Fixed some memory leaks
274 //
275 // Revision 1.1 1999/06/23 15:17:49 genevb
276 // Introduction of StMessageManager
277 //