StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
StMessage.cxx
1 // //
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 // //
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 char space = ' ';
25 static char tab = '\t';
26 
27 int StMessage::repeats=1;
28 static std::ostringstream lastMessBuffer;
29 
30 #ifdef __ROOT__
31 ClassImp(StMessage)
32 #endif
33 
34 //_____________________________________________________________________________
35 StMessage::StMessage(const char *mess, const char *ty, const char* opt) {
36  time(&messTime);
37  *type = *ty;
38  type[1] = 0;
39  SetOptions(opt);
40 // location = "Unknown";
41 // runNumber = 0;
42  int len = strlen(mess);
43  while (mess[--len] == space) {} // remove trailing spaces
44  message = new char[(++len + 1)];
45  for (int i=0;i<len;i++) {
46  message[i]=mess[i];
47  if (mess[i]=='\n') continue;
48  if (mess[i]=='\t') continue;
49  if (!iscntrl(mess[i])) continue;
50  assert(0);
51  }
52  message[len]=0;
53  Print(0);
54 }
55 //_____________________________________________________________________________
56 StMessage::~StMessage() {
57  delete [] message;
58 }
59 //_____________________________________________________________________________
60 int StMessage::Print(int nChars) {
61 //_nChars_:___mode__:_printing_
62 // <0 : view : as intended, no limits, use options
63 // =0 : normal : as intended, use limits, use options
64 // >0 : summary : stdout upto nChars/first endofline, no limits, no options
65  static const char* leader = "St";
66  static const char* insert0 = "";
67  static const char* insert1 = ": ";
68  static const char* insert2 = " <";
69  static const char* insert3 = ">";
70  static const char* endofline = "\n";
71  int printIt=1;
72  if (!nChars) {
73  printIt = messCounter->CheckLimit(message,type);
74  }
75  std::ostringstream messBuffer;
76  if (printIt) {
77  const char* insert;
78  if (!(option & kMessOptP)) {
79  if (!(option & kMessOptS)) messBuffer << leader; // "No St" option
80  const char* temp(StMessTypeList::Instance()->Text(type));
81  if (temp) messBuffer << temp;
82  insert = insert1;
83  } else insert = insert0;
84  if ((nChars != 0) && (strchr(message,tab))) { // If nChars, replace
85  char* message2 = new char[strlen(message)+1]; // tabs with spaces
86  char* m0 = message;
87  char* m1 = message2;
88  while (*m0) { // Go to end of string
89  if (*m0==tab) *m1 = space; // tab => space,
90  else *m1 = *m0; // otherwise copy
91  m0++; m1++;
92  }
93  *m1 = 0;
94  messBuffer << insert << message2; // ": ",message
95  delete [] message2;
96  } else {
97  messBuffer << insert << message; // ": ",message
98  }
99  if (nChars<=0) {
100  if (option & kMessOptT) { // "time" option
101  char* temp2 = (ctime(&messTime) + 4); // First 4 are day
102  *(temp2 + 20) = 0; // 24th is end-line
103  messBuffer << insert2 << temp2 << insert3 ; // " (",time,")"
104  }
105  messBuffer << endofline; // "\n" end-line
106  }
107  }
108  bool addedMessageFlag = false;
109  std::string addedMessage;
110  if (nChars == 0) {
111  addedMessageFlag = true;
112  addedMessage = messCounter->str(); // Any limit message
113  } else {
114  if (nChars>0) {
115  if (messBuffer.tellp() >= nChars)
116  messBuffer.seekp(nChars-1); // set end-of-string at nChars
117  int noReturns = strcspn(messBuffer.str().c_str(),endofline);
118  if (noReturns < messBuffer.tellp()) messBuffer.seekp(noReturns);
119  } else
120  nChars = 0;
121  }
122  if (!repeats) {
123  if (!strcmp(messBuffer.str().c_str(),lastMessBuffer.str().c_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 (addedMessageFlag) myout << addedMessage;
133  myout.flush();
134  }
135  if ((option & kMessOptE) && (nChars == 0)) {
136  myerr << messBuffer.str();
137  if (addedMessageFlag) 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 //_____________________________________________________________________________
187 // $Id: StMessage.cxx,v 1.29 2016/06/14 06:24:54 genevb Exp $
188 // $Log: StMessage.cxx,v $
189 // Revision 1.29 2016/06/14 06:24:54 genevb
190 // Very old cut-and-paste typo (Coverity)
191 //
192 // Revision 1.28 2012/06/11 15:05:34 fisyak
193 // std namespace
194 //
195 // Revision 1.27 2004/04/02 22:17:14 genevb
196 // Added protected Ignore/AllowRepeats() for friend StBFChain class
197 //
198 // Revision 1.26 2004/03/01 17:52:13 fisyak
199 // Add include for assert (osf required)
200 //
201 // Revision 1.25 2004/01/28 00:09:14 genevb
202 // Messages (except Debug) default to no time-date stamp
203 //
204 // Revision 1.24 2003/10/01 20:06:50 genevb
205 // Initialize and test ostrstream buffer sizes (support for gcc before 3.2)
206 //
207 // Revision 1.23 2003/09/25 21:18:14 genevb
208 // Changed option storage
209 //
210 // Revision 1.22 2003/09/22 01:30:41 perev
211 // some cleanup
212 //
213 // Revision 1.21 2003/09/02 17:59:20 perev
214 // gcc 3.2 updates + WarnOff
215 //
216 // Revision 1.20 2001/05/14 20:53:20 genevb
217 // Add features to examine memory use, switch from TDatime to time_t
218 //
219 // Revision 1.19 2000/01/05 19:53:46 genevb
220 // Fixed CC5 warnings, and several other small improvements under the hood
221 //
222 // Revision 1.18 1999/12/28 21:29:55 porter
223 // added 'using std::vector' and a (char*) cast to allow compilation
224 // using solaris CC5. Many warnings of const char* vs char* still
225 // exist but will await Gene's return to fix these
226 //
227 // Revision 1.17 1999/09/16 15:50:25 genevb
228 // Fixed a bug in over-writing memory when calling from FORTRAN, use char=0 instead of strcpy
229 //
230 // Revision 1.16 1999/09/14 15:42:03 genevb
231 // Some bug fixes, workaround for nulls in strings
232 //
233 // Revision 1.15 1999/09/11 23:12:23 fisyak
234 // Add cast for HP
235 //
236 // Revision 1.14 1999/09/10 21:05:55 genevb
237 // Some workarounds for RedHat6.0
238 //
239 // Revision 1.13 1999/08/10 22:07:35 genevb
240 // Added QAInfo message types
241 //
242 // Revision 1.12 1999/07/22 00:17:47 genevb
243 // make messBuffer static
244 //
245 // Revision 1.11 1999/07/15 05:15:06 genevb
246 // Fixed an odd bug with seekp(0) on an empty stream buffer
247 //
248 // Revision 1.10 1999/07/08 22:58:18 genevb
249 // Created an abstract interface with StMessMgr.h hiding template implementation from others, a few other small fixes
250 //
251 // Revision 1.9 1999/07/01 01:24:46 genevb
252 // Fixed FORTRAN character string bug on linux, removed a memory leak from Summary()
253 //
254 // Revision 1.7 1999/06/30 04:18:45 genevb
255 // Fixes: summary wrap-around, unsigned ints, last character of message, <> for time; no KNOWN remaining bugs
256 //
257 // Revision 1.6 1999/06/29 23:32:41 genevb
258 // Handle multi-line calls to fortran routines better
259 //
260 // Revision 1.5 1999/06/29 19:17:14 genevb
261 // Lots of fixes..
262 //
263 // Revision 1.3 1999/06/26 00:24:52 genevb
264 // Fixed const type mismatches
265 //
266 // Revision 1.2 1999/06/24 16:30:41 genevb
267 // Fixed some memory leaks
268 //
269 // Revision 1.1 1999/06/23 15:17:46 genevb
270 // Introduction of StMessageManager
271 //
272 // Revision 1.0 1999/01/27 10:28:29 genevb
273 //