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