1 ////////////////////////////////////////////////////////////////////////// 2 // // 3 // StMessage // 4 // // 5 // This is the class of messages used by StMessageManager in STAR. // 6 // Messages have a type and message specified at instantiation, // 7 // and also include a time-date stamp and options for printing. // 8 // // 9 ////////////////////////////////////////////////////////////////////////// 10 11 #ifdef __ROOT__ 12 #include "TROOT.h" 13 #endif 14 #include <assert.h> 15 #include <ctype.h> 16 #include <string.h> 17 #include "StMessage.h" 18 #include "StMessageCounter.h" 19 #include "Stsstream.h" 20 #include "StMessageStream.h" 21 using namespace std; 22 static StMessageCounter* messCounter = StMessageCounter::Instance(); 23 24 static ostrstream messBuffer; 25 static char space = ' '; 26 static char tab = '\t'; 27 28 int StMessage::repeats=1; 29 static ostrstream lastMessBuffer; 30 31 #ifdef __ROOT__ 32 ClassImp(StMessage) 33 #endif 34 35 //_____________________________________________________________________________ 36 StMessage::StMessage(const char *mess, const char *ty, const char* opt) { 37 time(&messTime); 38 *type = *ty; 39 type[1] = 0; 40 SetOptions(opt); 41 // location = "Unknown"; 42 // runNumber = 0; 43 int len = strlen(mess); 44 while (mess[--len] == space) {} // remove trailing spaces 45 message = new char[(++len + 1)]; 46 for (int i=0;i<len;i++) { 47 message[i]=mess[i]; 48 if (mess[i]=='\n') continue; 49 if (mess[i]=='\t') continue; 50 if (!iscntrl(mess[i])) continue; 51 assert(0); 52 } 53 message[len]=0; 54 Print(0); 55 } 56 //_____________________________________________________________________________ 57 StMessage::~StMessage() { 58 delete [] message; 59 } 60 //_____________________________________________________________________________ 61 int StMessage::Print(int nChars) { 62 //_nChars_:___mode__:_printing_ 63 // <0 : view : as intended, no limits, use options 64 // =0 : normal : as intended, use limits, use options 65 // >0 : summary : stdout upto nChars/first endofline, no limits, no options 66 static const char* leader = "St"; 67 static const char* insert0 = ""; 68 static const char* insert1 = ": "; 69 static const char* insert2 = " <"; 70 static const char* insert3 = ">"; 71 static const char* endofline = "\n"; 72 int printIt=1; 73 if (!nChars) { 74 printIt = messCounter->CheckLimit(message,type); 75 } 76 messBuffer.seekp(0); 77 if (printIt) { 78 const char* insert; 79 if (!(option & kMessOptP)) { 80 if (!(option & kMessOptS)) messBuffer << leader; // "No St" option 81 const char* temp(StMessTypeList::Instance()->Text(type)); 82 if (temp) messBuffer << temp; 83 insert = insert1; 84 } else insert = insert0; 85 if ((nChars != 0) && (strchr(message,tab))) { // If nChars, replace 86 char* message2 = new char[strlen(message)+1]; // tabs with spaces 87 char* m0 = message; 88 char* m1 = message2; 89 while (*m0) { // Go to end of string 90 if (*m0==tab) *m1 = space; // tab => space, 91 else *m1 = *m0; // otherwise copy 92 m0++; m1++; 93 } 94 *m1 = 0; 95 messBuffer << insert << message2; // ": ",message 96 delete [] message2; 97 } else { 98 messBuffer << insert << message; // ": ",message 99 } 100 if (nChars<=0) { 101 if (option & kMessOptT) { // "time" option 102 char* temp2 = (ctime(&messTime) + 4); // First 4 are day 103 *(temp2 + 20) = 0; // 24th is end-line 104 messBuffer << insert2 << temp2 << insert3 ; // " (",time,")" 105 } 106 messBuffer << endofline; // "\n" end-line 107 } 108 } 109 const char* addedMessage=0; 110 if (nChars == 0) { 111 addedMessage = messCounter->str(); // Any limit message 112 } else { 113 if (nChars>0) { 114 if (messBuffer.tellp() >= nChars) 115 messBuffer.seekp(nChars-1); // set end-of-string at nChars 116 int noReturns = strcspn(messBuffer.str(),endofline); 117 if (noReturns < messBuffer.tellp()) messBuffer.seekp(noReturns); 118 } else 119 nChars = 0; 120 } 121 messBuffer << ends; 122 if (!repeats) { 123 if (!strcmp(messBuffer.str(),lastMessBuffer.str())) { 124 return messBuffer.tellp(); 125 } else { 126 lastMessBuffer.seekp(0); 127 lastMessBuffer << messBuffer.str() << ends; 128 } 129 } 130 if ((option & kMessOptO) || (nChars != 0)) { 131 myout << messBuffer.str(); 132 if (addedMessage) myout << addedMessage; 133 myout.flush(); 134 } 135 if ((option & kMessOptE) && (nChars == 0)) { 136 myerr << messBuffer.str(); 137 if (addedMessage) myerr << addedMessage; 138 myerr.flush(); 139 } 140 return messBuffer.tellp(); 141 } 142 //_____________________________________________________________________________ 143 char* StMessage::GetOptions() const { 144 static char optStr[32]; // Use single, static instance to avoid memory leak 145 char* sPtr = optStr; 146 if (option & kMessOptO) sprintf(sPtr++,"%c",'O'); 147 if (option & kMessOptE) sprintf(sPtr++,"%c",'E'); 148 if (option & kMessOptS) sprintf(sPtr++,"%c",'S'); 149 if (option & kMessOptT) sprintf(sPtr++,"%c",'T'); 150 if (option & kMessOptP) sprintf(sPtr++,"%c",'P'); 151 if (option & kMessOptDash) sprintf(sPtr++,"%c",'-'); 152 (*sPtr) = 0; // Terminate string 153 return optStr; 154 } 155 //_____________________________________________________________________________ 156 void StMessage::SetOptions(const char* opt) { 157 option = kMessOptNone; 158 if (!opt) return; 159 int len = strlen(opt); 160 while (len--) { 161 switch (toupper(opt[len])) { 162 case ('O') : { option |= kMessOptO; break; } 163 case ('E') : { option |= kMessOptE; break; } 164 case ('S') : { option |= kMessOptS; break; } 165 case ('T') : { option |= kMessOptT; break; } 166 case ('P') : { option |= kMessOptP; break; } 167 case ('-') : { option |= kMessOptDash; break; } 168 default : {} 169 } 170 } 171 } 172 //_____________________________________________________________________________ 173 size_t StMessage::GetMemoryUsage() { 174 size_t msize = strlen(message) + 1; 175 msize += sizeof(*this); // Determine overhead 176 return msize; 177 } 178 //_____________________________________________________________________________ 179 void StMessage::PrintInfo() { 180 printf("**************************************************************\n"); 181 printf("* $Id: StMessage.cxx,v 1.29 2016/06/14 06:24:54 genevb Exp $\n"); 182 // printf("* %s *\n",m_VersionCVS); 183 printf("**************************************************************\n"); 184 } 185 //_____________________________________________________________________________ 186 int StMessage::InitBuffer() { 187 // Initialize buffer with 1088 bytes. 188 messBuffer << ch64 << ch64 << ch64 << ch64 << ch64 << ch64 << ch64 << ch64 189 << ch64 << ch64 << ch64 << ch64 << ch64 << ch64 << ch64 << ch64 << ch64; 190 return messBuffer.tellp(); 191 } 192 193 int tmpp = StMessage::InitBuffer(); 194 195 //_____________________________________________________________________________ 196 // $Id: StMessage.cxx,v 1.29 2016/06/14 06:24:54 genevb Exp $ 197 // $Log: StMessage.cxx,v $ 198 // Revision 1.29 2016/06/14 06:24:54 genevb 199 // Very old cut-and-paste typo (Coverity) 200 // 201 // Revision 1.28 2012/06/11 15:05:34 fisyak 202 // std namespace 203 // 204 // Revision 1.27 2004/04/02 22:17:14 genevb 205 // Added protected Ignore/AllowRepeats() for friend StBFChain class 206 // 207 // Revision 1.26 2004/03/01 17:52:13 fisyak 208 // Add include for assert (osf required) 209 // 210 // Revision 1.25 2004/01/28 00:09:14 genevb 211 // Messages (except Debug) default to no time-date stamp 212 // 213 // Revision 1.24 2003/10/01 20:06:50 genevb 214 // Initialize and test ostrstream buffer sizes (support for gcc before 3.2) 215 // 216 // Revision 1.23 2003/09/25 21:18:14 genevb 217 // Changed option storage 218 // 219 // Revision 1.22 2003/09/22 01:30:41 perev 220 // some cleanup 221 // 222 // Revision 1.21 2003/09/02 17:59:20 perev 223 // gcc 3.2 updates + WarnOff 224 // 225 // Revision 1.20 2001/05/14 20:53:20 genevb 226 // Add features to examine memory use, switch from TDatime to time_t 227 // 228 // Revision 1.19 2000/01/05 19:53:46 genevb 229 // Fixed CC5 warnings, and several other small improvements under the hood 230 // 231 // Revision 1.18 1999/12/28 21:29:55 porter 232 // added 'using std::vector' and a (char*) cast to allow compilation 233 // using solaris CC5. Many warnings of const char* vs char* still 234 // exist but will await Gene's return to fix these 235 // 236 // Revision 1.17 1999/09/16 15:50:25 genevb 237 // Fixed a bug in over-writing memory when calling from FORTRAN, use char=0 instead of strcpy 238 // 239 // Revision 1.16 1999/09/14 15:42:03 genevb 240 // Some bug fixes, workaround for nulls in strings 241 // 242 // Revision 1.15 1999/09/11 23:12:23 fisyak 243 // Add cast for HP 244 // 245 // Revision 1.14 1999/09/10 21:05:55 genevb 246 // Some workarounds for RedHat6.0 247 // 248 // Revision 1.13 1999/08/10 22:07:35 genevb 249 // Added QAInfo message types 250 // 251 // Revision 1.12 1999/07/22 00:17:47 genevb 252 // make messBuffer static 253 // 254 // Revision 1.11 1999/07/15 05:15:06 genevb 255 // Fixed an odd bug with seekp(0) on an empty stream buffer 256 // 257 // Revision 1.10 1999/07/08 22:58:18 genevb 258 // Created an abstract interface with StMessMgr.h hiding template implementation from others, a few other small fixes 259 // 260 // Revision 1.9 1999/07/01 01:24:46 genevb 261 // Fixed FORTRAN character string bug on linux, removed a memory leak from Summary() 262 // 263 // Revision 1.7 1999/06/30 04:18:45 genevb 264 // Fixes: summary wrap-around, unsigned ints, last character of message, <> for time; no KNOWN remaining bugs 265 // 266 // Revision 1.6 1999/06/29 23:32:41 genevb 267 // Handle multi-line calls to fortran routines better 268 // 269 // Revision 1.5 1999/06/29 19:17:14 genevb 270 // Lots of fixes.. 271 // 272 // Revision 1.3 1999/06/26 00:24:52 genevb 273 // Fixed const type mismatches 274 // 275 // Revision 1.2 1999/06/24 16:30:41 genevb 276 // Fixed some memory leaks 277 // 278 // Revision 1.1 1999/06/23 15:17:46 genevb 279 // Introduction of StMessageManager 280 // 281 // Revision 1.0 1999/01/27 10:28:29 genevb 282 // 283