00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00015
00016 #ifdef __ROOT__
00017 #include "TROOT.h"
00018 #endif
00019
00020 #include "StMessageManager.h"
00021 #include "StMessageStream.h"
00022 #include <string.h>
00023 #ifdef __linux__
00024 #include <math.h>
00025 #endif
00026
00027
00028
00029
00030 std::ostream& StMessageManager::OperatorShift(std::ostream& os, StMessage* stm)
00031 {
00032 if (((&os) == (ostream*) gMessMgr) && (stm == endm)) {
00033 gMessMgr->Print();
00034 } else {
00035 if (stm) os << stm->GetMessage();
00036 }
00037 return os;
00038 }
00039
00040 static const char defaultMessType = 'I';
00041 static char emptyString[] = "";
00042 static char oOpt [] = "O";
00043
00044 static char eOpt [] = "E";
00045
00046 #ifdef __linux__
00047 static int sMessLength;
00048 static const int maxLOMP = 65536;
00049 static const int maxLOMP1 = (maxLOMP-1);
00050 static int lastLOMP = 0;
00051 static char* listOfMessPtrs[maxLOMP];
00052 static size_t listOfMessLens[maxLOMP];
00053 #endif
00054
00055 StMessMgr* StMessageManager::mInstance = 0;
00056
00057
00058
00059
00060 StMessageManager::StMessageManager() : StMessMgr()
00061 {
00062
00063
00064
00065
00066
00067 messTypeList=0;
00068 messCounter =0;
00069 curType = new char[ 2]; curType[0] = 0; curType[1] = 0;
00070 curOpt = new char[32]; curOpt [0] = 0;
00071 building =0;
00072 remember =0;
00073 gMessMgr = (StMessMgr*) this;
00074 messTypeList = StMessTypeList::Instance();
00075 messCounter = StMessageCounter::Instance();
00076 messCounter->AddType(emptyString);
00077
00078 messCollection.push_back(&messList);
00079 AddType("I","Info");
00080 AddType("W","Warning");
00081 AddType("E","Error");
00082 AddType("D","Debug");
00083 AddType("Q","QAInfo");
00084 AddType("U","UCMInfo");
00085 SwitchOff("D");
00086 #ifdef __linux__
00087 memset(listOfMessPtrs,0,(maxLOMP * sizeof(char*)));
00088 #endif
00089
00090 *this << ch64 << ch64 << ch64 << ch64 << ch64 << ch64 << ch64 << ch64
00091 << ch64 << ch64 << ch64 << ch64 << ch64 << ch64 << ch64 << ch64;
00092 }
00093
00094 StMessageManager::~StMessageManager() {
00095
00096
00097
00098 messVecIter current;
00099 for (current=messList.begin(); current!=messList.end(); current++)
00100 delete (*current);
00101 for (size_t i=1; i<messCollection.size(); i++)
00102 delete (messCollection[i]);
00103 myout << "WARNING!!! DELETING StMessageManager!" << endl;
00104 gMessMgr = 0;
00105 }
00106
00107 StMessMgr* StMessageManager::Instance() {
00108
00109
00110
00111
00112 if (gMessMgr) return gMessMgr;
00113 if (!mInstance) {
00114 mInstance = (StMessMgr*) new StMessageManager;
00115 }
00116 return mInstance;
00117 }
00118
00119 ostrstream& StMessageManager::Message(const char* mess, const char* type,
00120 const char* opt,const char *,int) {
00121
00122
00123
00124
00125 if (!opt) opt = "";
00126 size_t messSize = strlen(mess);
00127 if (messSize) {
00128 #ifdef __linux__
00129 if (sMessLength == 1) {
00130 for (int i=lastLOMP; i>=0; i--) {
00131 if (mess == listOfMessPtrs[i]) {
00132 (listOfMessPtrs[i])[(listOfMessLens[i]-1)]=0;
00133 lastLOMP = i;
00134 break;
00135 }
00136 if (i==0) {
00137 if (lastLOMP==maxLOMP1) {
00138 BuildMessage("StMessageManager - maximum depth reached on ptr list",
00139 "W","E");
00140 } else {
00141 lastLOMP++;
00142 listOfMessPtrs[lastLOMP] = const_cast<char*> (mess);
00143 listOfMessLens[lastLOMP] = messSize;
00144 }
00145 }
00146 }
00147 }
00148 #endif
00149 BuildMessage(mess, type, opt);
00150 } else {
00151 building = 1;
00152 *curType = *type;
00153 strcpy(curOpt,opt);
00154 seekp(0);
00155 }
00156 return *((StMessMgr*) this);
00157 }
00158
00159 void StMessageManager::BuildMessage(const char* mess, const char* type,
00160 const char* opt) {
00161
00162
00163
00164 if (!opt) opt = "";
00165 if (!(*type)) {
00166 static char dash = '-';
00167 const char* cptr = strchr(mess,dash);
00168 if (cptr)
00169 *curType = *(++cptr);
00170 else
00171 *curType = defaultMessType;
00172 } else {
00173 if (!building) *curType = *type;
00174 }
00175 if (!(opt[0])) {
00176 if ((*type == 'E') || (*type == 'W'))
00177 strcpy(curOpt,eOpt);
00178 else
00179 strcpy(curOpt,oOpt);
00180 } else
00181 if (!building) strcpy(curOpt,opt);
00182 int typeN = messTypeList->FindTypeNum(curType);
00183 if (!typeN) {
00184 *curType = defaultMessType;
00185 typeN = 1;
00186 }
00187 if ((!remember) || strchr(curOpt,'-')) {
00188 StMessage tmp(mess, curType, curOpt);
00189 gMessage = endm;
00190 } else {
00191 gMessage = new StMessage(mess, curType, curOpt);
00192 #ifndef i386_redhat60
00193 messList.push_back(gMessage);
00194 messCollection[typeN]->push_back(gMessage);
00195 #endif
00196 endm = gMessage;
00197 }
00198 }
00199
00200 void StMessageManager::Print() {
00201
00202
00203
00204
00205 if (building) {
00206 *this << ends;
00207
00208 if (fail()) {
00209 int pos0 = tellp();
00210 int pos1 = pos0 - 160;
00211 clear();
00212 if (pos1 >= 0) {
00213 seekp(pos1);
00214 *this << "\n\n WARNING!!! ATTEMPT TO INPUT PAST END OF BUFFER"
00215 << " IN StMessageManager!\n Buffer Size = " << pos0
00216 << ". IGNORING REMAINDER OF MESSAGE...";
00217 } else {
00218 seekp(0);
00219 myerr << "StMessage: ERROR!!! StMessageManager BUFFER TOO SMALL!"
00220 << endl;
00221 }
00222 *this << ends;
00223 }
00224
00225 BuildMessage(str(), curType, curOpt);
00226 building = 0;
00227
00228 } else {
00229
00230 if (gMessage) {
00231 gMessage->Print(-1);
00232 } else {
00233 myout << "No current message." << endl;
00234 }
00235 }
00236 }
00237
00238 int StMessageManager::PrintList(messVec* list) {
00239
00240
00241
00242 messVecIter current;
00243 int i=0;
00244 for (current=list->begin(); current!=list->end(); current++)
00245 {(*current)->Print(-1); i++;}
00246 return i;
00247 }
00248
00249 messVecIter StMessageManager::FindMessageIter(const char* s1, const char* s2,
00250 const char* s3, const char* s4, messVec* list) {
00251
00252
00253
00254
00255 if (!list) list = &messList;
00256 messVecIter current;
00257 const char* curMess;
00258 for (current=list->begin(); current!=list->end(); current++) {
00259 curMess = (*current)->GetMessage();
00260 if ((strstr(curMess,s1)) && (strstr(curMess,s2)) &&
00261 (strstr(curMess,s3)) && (strstr(curMess,s4))) return current;
00262 }
00263 return list->end();
00264 }
00265
00266 StMessage* StMessageManager::FindMessage(const char* s1, const char* s2,
00267 const char* s3, const char* s4, messVec* list) {
00268
00269
00270
00271
00272 messVecIter current = FindMessageIter(s1,s2,s3,s4,list);
00273 return (current!=list->end()) ? (*current) : 0 ;
00274 }
00275
00276 messVec* StMessageManager::FindMessageList(const char* s1, const char* s2,
00277 const char* s3, const char* s4, messVec* list) {
00278
00279
00280
00281
00282 size_t s1_len = strlen(s1);
00283 char* s1a = new char[(s1_len+1)];
00284 strcpy(s1a,s1);
00285 if ((s1_len==1) && (!list)) {
00286 int typeN = messTypeList->FindTypeNum(s1);
00287 if (typeN) {
00288 list = messCollection[typeN];
00289 *s1a = 0;
00290 s1_len = 0;
00291 }
00292 }
00293 if (!list) list = &messList;
00294 if (!((s1_len) || (strlen(s2)) || (strlen(s3)) || (strlen(s4))))
00295 return list;
00296 messVec* newList = new messVec();
00297 messVecIter current;
00298 const char* curMess;
00299 for (current=list->begin(); current!=list->end(); current++) {
00300 curMess = (*current)->GetMessage();
00301 if ((strstr(curMess,s1)) && (strstr(curMess,s2)) &&
00302 (strstr(curMess,s3)) && (strstr(curMess,s4)))
00303 newList->push_back(*current);
00304 }
00305 return newList;
00306 }
00307
00308 int StMessageManager::RemoveMessage(StMessage* mess) {
00309
00310
00311
00312 if (!mess) return 3;
00313 const char* curMess = mess->GetMessage();
00314 messVecIter current = FindMessageIter(curMess);
00315 if (current==messList.end()) return 1;
00316 messList.erase(current);
00317 int typeN = messTypeList->FindTypeNum(mess->GetType());
00318 current = FindMessageIter(curMess,emptyString,emptyString,
00319 emptyString,messCollection[typeN]);
00320 if (current==messCollection[typeN]->end()) return 2;
00321 messCollection[typeN]->erase(current);
00322 delete mess;
00323 if (mess==gMessage) gMessage = 0;
00324 return 0;
00325 }
00326
00327 void StMessageManager::Summary(size_t nTerms) {
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338 const size_t mmax = 81;
00339 size_t max = mmax - 12;
00340 size_t messmax = mmax - 1;
00341 size_t nMess = messList.size();
00342 intVector done;
00343 typedef StVector(char*) CharPtrVec;
00344 CharPtrVec mType;
00345 CharPtrVec messBlocks;
00346 StVector(CharPtrVec) toks;
00347 size_t i;
00348 size_t j;
00349 size_t k;
00350 int agree;
00351 char* temp;
00352 myout << " ***** StMessageManager message summary *****" << endl;
00353 for (i=0; i<nMess; i++) {
00354 done.push_back(0);
00355 temp = const_cast<char*> (messList[i]->GetType());
00356 mType.push_back(temp);
00357 toks.push_back(*(new CharPtrVec));
00358 messBlocks.push_back(new char[mmax]);
00359 temp = strncpy(messBlocks[i],(messList[i]->GetMessage()),messmax);
00360 temp = strtok(temp, " ");
00361 toks[i].push_back(temp);
00362 while (temp != NULL) {
00363 temp = strtok(NULL, " ");
00364 toks[i].push_back(temp);
00365 }
00366 for (j=toks[i].size(); j<nTerms; j++) toks[i].push_back(temp);
00367 }
00368 for (i=0; i<nMess; i++) {
00369 int count = 1;
00370 if (!(done[i])) {
00371 for (j=(i+1); j<nMess; j++) {
00372 if ((*(mType[i]))==(*(mType[j]))) {
00373 agree = 1;
00374 for (k=0; k<nTerms; k++) {
00375 if (toks[i][k] != NULL) {
00376 if ((toks[j][k] == NULL) ||
00377 strcmp(toks[i][k],toks[j][k])) agree = 0;
00378 }
00379 else if (toks[j][k] != NULL) agree = 0;
00380 }
00381 if (agree) {
00382 done[j] = 1;
00383 count++;
00384 }
00385 }
00386 }
00387 done[i] = 1;
00388 for (j = messList[i]->Print(max); j<max; j++) myout << ".";
00389 myout << "..";
00390 seekp(0);
00391 *this << count << ends;
00392 if (tellp() > 6) {
00393 myout << ">999999";
00394 } else {
00395 for (j=tellp(); j<6; j++) myout << ".";
00396 myout << " " << count << endl;
00397 }
00398 }
00399 mType[i] = NULL;
00400 memset(messBlocks[i],0,mmax);
00401 delete [] messBlocks[i];
00402 }
00403 MemorySummary();
00404 return;
00405 }
00406
00407 void StMessageManager::MemorySummary() {
00408
00409
00410
00411
00412 unsigned int gsize=0;
00413 size_t nMess = messList.size();
00414 for (size_t i=0; i<nMess; i++) {
00415 gsize += (messList[i]->GetMemoryUsage() + 2*sizeof(messList[i]));
00416 }
00417 printf(" ***** StMessageManager memory usage = %u bytes (%u kb) *****\n",
00418 gsize,(gsize/1024));
00419 return;
00420 }
00421
00422 int StMessageManager::AddType(const char* type, const char* text) {
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432 int typeN = messTypeList->AddType(type,text);
00433 if (typeN) {
00434 messVec* temp = new messVec();
00435 messCollection.push_back(temp);
00436 messCounter->AddType(type);
00437 }
00438 return typeN;
00439 }
00440
00441 void StMessageManager::PrintInfo() {
00442 printf("**************************************************************\n");
00443 printf("* $Id: StMessageManager.cxx,v 1.48 2009/06/22 22:36:01 fine Exp $\n");
00444
00445 printf("**************************************************************\n");
00446 }
00447
00448 void StMessageManager::SetLevel(Int_t)
00449 {
00450 fprintf(stderr,"StMessageManager class provides no implementation SetLevel method\n");
00451 }
00452
00453 Int_t StMessageManager::GetLevel(Int_t) const
00454 {
00455 fprintf(stderr,"StMessageManager class provides no implementation GetLevel method\n");
00456 return -999;
00457 }
00458
00459 const char *StMessageManager::GetName() const
00460 {
00461 fprintf(stderr,"StMessageManager class provides no implementation GetName method\n");
00462 return 0;
00463 }
00464
00465
00466
00467
00468 static StMessMgr* temp=StMessageManager::Instance();
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618