All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
Message.cpp
Go to the documentation of this file.
1 // $Header: /tmp/svngaudi/tmp.jEpFh25751/Gaudi/GaudiKernel/src/Lib/Message.cpp,v 1.9 2008/02/20 19:16:23 hmd Exp $
2 #include <string>
3 #include <iostream>
4 #include <iomanip>
5 #include <cstdlib>
6 #include <cstdio>
7 #include <cctype>
9 #include "GaudiKernel/Message.h"
10 #include "GaudiKernel/Timing.h"
11 #include "GaudiKernel/Time.h"
12 
13 using namespace MSG;
14 
15 // Formatting string characters.
16 const char Message::FORMAT_PREFIX = '%';
17 const char Message::JUSTIFY_LEFT = 'L';
18 const char Message::JUSTIFY_RIGHT = 'R';
19 const char Message::MESSAGE = 'M';
20 const char Message::TYPE = 'T';
21 const char Message::TIME = 't';
22 const char Message::UTIME = 'u';
23 const char Message::SOURCE = 'S';
24 const char Message::FILL = 'F';
25 const char Message::WIDTH = 'W';
26 //const char* Message::DEFAULT_FORMAT = "% F%67W%L#############################################################################\n-----------------------------------------------------------------------------\nMessage follows...\nSource : %S\nType : %T\nMessage : %M\nEnd of message.\n-----------------------------------------------------------------------------\n";
27 const char* Message::DEFAULT_FORMAT = "% F%18W%S%7W%R%T %0W%M";
28 // Time format accepts anything that strftime does plus %f for milliseconds
29 const char* Message::DEFAULT_TIME_FORMAT = "%Y-%m-%d %H:%M:%S,%f";
30 
31 namespace {
32  // get the current time from the system and format it according to the format
33  inline std::string formattedTime (const std::string &fmt, bool universal = false )
34  {
35  return Gaudi::Time::current().format(!universal, fmt);
36  }
37 }
38 
39 //#############################################################################
40 // ---------------------------------------------------------------------------
41 // Routine: Constructor.
42 // Purpose:
43 // ---------------------------------------------------------------------------
44 //
46  m_message( "" ), m_source( "UNKNOWN" ), m_format( DEFAULT_FORMAT ),
47  m_time_format(DEFAULT_TIME_FORMAT), m_type( NIL ),
48  m_fill( ' ' ), m_width( 0 ), m_left( true )
49 {
50 }
51 
52 //#############################################################################
53 // ---------------------------------------------------------------------------
54 // Routine: Constructor.
55 // Purpose:
56 // ---------------------------------------------------------------------------
57 //
58 Message::Message ( const char* src, int type, const char* msg ) :
59  m_message( msg ), m_source( src ), m_format( DEFAULT_FORMAT ),
60  m_time_format(DEFAULT_TIME_FORMAT), m_type( type ),
61  m_fill( ' ' ), m_width( 0 ), m_left( true )
62 {
63 }
64 
65 //#############################################################################
66 // ---------------------------------------------------------------------------
67 // Routine: Constructor.
68 // Purpose:
69 // ---------------------------------------------------------------------------
70 //
71 Message::Message ( const std::string& src, int type, const std::string& msg ) :
72  m_message( msg ), m_source( src ), m_format( DEFAULT_FORMAT ),
73  m_time_format(DEFAULT_TIME_FORMAT), m_type( type ),
74  m_fill( ' ' ), m_width( 0 ), m_left( true )
75 {
76 }
77 
78 //#############################################################################
79 // ---------------------------------------------------------------------------
80 // Routine: getMessage
81 // Purpose: Get the message string.
82 // ---------------------------------------------------------------------------
83 //
84 const std::string& Message::getMessage() const
85 {
86  return m_message;
87 }
88 
89 //#############################################################################
90 // ---------------------------------------------------------------------------
91 // Routine: setMessage
92 // Purpose: Set the message string.
93 // ---------------------------------------------------------------------------
94 //
95 void Message::setMessage( const std::string& msg )
96 {
97  m_message = msg;
98 }
99 
100 //#############################################################################
101 // ---------------------------------------------------------------------------
102 // Routine: getType
103 // Purpose: Get the message type.
104 // ---------------------------------------------------------------------------
105 //
106 int Message::getType() const
107 {
108  return m_type;
109 }
110 
111 //#############################################################################
112 // ---------------------------------------------------------------------------
113 // Routine: setType
114 // Purpose: Set the message type.
115 // ---------------------------------------------------------------------------
116 //
117 void Message::setType( int msg_type )
118 {
119  m_type = msg_type;
120 }
121 
122 //#############################################################################
123 // ---------------------------------------------------------------------------
124 // Routine: getSource
125 // Purpose: Get the message source.
126 // ---------------------------------------------------------------------------
127 //
128 const std::string& Message::getSource() const
129 {
130  return m_source;
131 }
132 
133 //#############################################################################
134 // ---------------------------------------------------------------------------
135 // Routine: setSource
136 // Purpose: Set the message source.
137 // ---------------------------------------------------------------------------
138 //
139 void Message::setSource( const std::string& src )
140 {
141  m_source = src;
142 }
143 
144 //#############################################################################
145 // ---------------------------------------------------------------------------
146 // Routine: operator <<
147 // Purpose:Insert the message into a stream.
148 // ---------------------------------------------------------------------------
149 //
150 std::ostream& operator << ( std::ostream& stream, const Message& msg )
151 {
152  msg.makeFormattedMsg( msg.m_format );
153  stream << msg.m_formatted_msg;
154  return stream;
155 }
156 
157 //#############################################################################
158 // ---------------------------------------------------------------------------
159 // Routine: operator <
160 // Purpose: comparison operator needed for maps
161 // ---------------------------------------------------------------------------
162 //
164 {
165  return m_type < b.m_type ||
166  m_source < b.m_source ||
167  m_message < b.m_message;
168 }
169 
170 //#############################################################################
171 // ---------------------------------------------------------------------------
172 // Routine: operator ==
173 // Purpose: comparison op.
174 // ---------------------------------------------------------------------------
175 //
176 bool operator == ( const Message& a, const Message& b )
177 {
178  return a.m_source == b.m_source &&
179  a.m_type == b.m_type &&
180  a.m_message == b.m_message;
181 }
182 
183 //#############################################################################
184 // ---------------------------------------------------------------------------
185 // Routine:
186 // Purpose: Get the format string.
187 // ---------------------------------------------------------------------------
188 //
189 const std::string& Message::getFormat() const
190 {
191  return m_format;
192 }
193 
194 //#############################################################################
195 // ---------------------------------------------------------------------------
196 // Routine:
197 // Purpose: Get the default format string.
198 // ---------------------------------------------------------------------------
199 //
200 const std::string Message::getDefaultFormat()
201 {
202  return DEFAULT_FORMAT;
203 }
204 
205 
206 //#############################################################################
207 // ---------------------------------------------------------------------------
208 // Routine:
209 // Purpose: Set the format string -
210 // use isFormatted() to check for valid format.
211 // ---------------------------------------------------------------------------
212 //
213 void Message::setFormat( const std::string& format ) const
214 {
215  if ( format.empty() )
217  else
218  m_format = format;
219 }
220 
221 //#############################################################################
222 // ---------------------------------------------------------------------------
223 // Routine:
224 // Purpose: Get the time format string.
225 // ---------------------------------------------------------------------------
226 //
227 const std::string& Message::getTimeFormat() const
228 {
229  return m_time_format;
230 }
231 
232 //#############################################################################
233 // ---------------------------------------------------------------------------
234 // Routine:
235 // Purpose: Get the default time format string.
236 // ---------------------------------------------------------------------------
237 //
238 const std::string Message::getDefaultTimeFormat()
239 {
240  return DEFAULT_TIME_FORMAT ;
241 }
242 
243 
244 //#############################################################################
245 // ---------------------------------------------------------------------------
246 // Routine:
247 // Purpose: Set the time format string -
248 // use isFormatted() to check for valid format.
249 // ---------------------------------------------------------------------------
250 //
251 void Message::setTimeFormat( const std::string& timeFormat ) const
252 {
253  if ( timeFormat.empty() )
255  else
256  m_time_format = timeFormat;
257 }
258 
259 //#############################################################################
260 // ---------------------------------------------------------------------------
261 // Routine: makeFormattedMsg
262 // Purpose: This formats the message according to the format string.
263 // ---------------------------------------------------------------------------
264 //
265 void Message::makeFormattedMsg( const std::string& format ) const
266 {
267  m_formatted_msg = "";
268  std::string::const_iterator i = format.begin();
269  while( i != format.end() ) {
270 
271  // Output format string until format statement found.
272  while( i != format.end() && *i != FORMAT_PREFIX )
273  m_formatted_msg += *i++;
274 
275  // Test for end of format string.
276  if ( i == format.end() ) break;
277  i++;
278 
279  // Find type of formatting.
280  std::string this_format = "";
281  while( i != format.end() && *i != FORMAT_PREFIX &&
282  *i != MESSAGE && *i != TYPE && *i != SOURCE &&
283  *i != FILL && *i != WIDTH && *i != TIME && *i != UTIME &&
284  *i != JUSTIFY_LEFT && *i != JUSTIFY_RIGHT ) {
285  this_format += *i++;
286  }
287 
288  // Reached end of string with improper format.
289  if ( i == format.end() ) {
290  invalidFormat();
291  break;
292  }
293 
294  this_format += *i++;
295  decodeFormat( this_format );
296  }
297 }
298 
299 //#############################################################################
300 // ---------------------------------------------------------------------------
301 // Routine: decodeFormat
302 // Purpose: This the work horse that check for a valid format string.
303 // ---------------------------------------------------------------------------
304 //
305 void Message::decodeFormat( const std::string& format ) const
306 {
307  if ( ! format.empty() ) {
308  const char FORMAT_TYPE = format[ format.length() - 1 ];
309  const std::string FORMAT_PARAM = format.substr( 0, format.length() - 1 );
310 
311  // Now test the format.
312  std::string level;
313  switch( FORMAT_TYPE ) {
314  case FILL:
315  if ( FORMAT_PARAM.length() == 1 ) {
316  m_fill = FORMAT_PARAM[0];
317  }
318  else
319  invalidFormat();
320  break;
321 
322  case TIME:
323  {
324  const std::string& timeStr = formattedTime ( m_time_format ) ;
325  sizeField( timeStr );
326  }
327  break;
328 
329  case UTIME:
330  {
331  const std::string& timeStr = formattedTime ( m_time_format, true ) ;
332  sizeField( timeStr );
333  }
334  break;
335 
336  case MESSAGE:
337  sizeField( m_message );
338  break;
339 
340  case SOURCE:
341  sizeField( m_source );
342  break;
343 
344  case TYPE:
345  switch ( m_type ) {
346 #define SET(x) case x: level=#x; break
347  SET( NIL );
348  SET( VERBOSE );
349  SET( DEBUG );
350  SET( INFO );
351  SET( WARNING );
352  SET( ERROR );
353  SET( FATAL );
354  case ALWAYS: level="SUCCESS"; break;
355  default:
356  level = "UNKNOWN";
357  break;
358 #undef SET
359  }
360  sizeField( level );
361  break;
362 
364  case JUSTIFY_RIGHT: m_left = false; break;
365  case JUSTIFY_LEFT: m_left = true; break;
366  case WIDTH: setWidth( FORMAT_PARAM ); break;
367  default: invalidFormat(); break;
368  }
369  }
370  else
371  invalidFormat();
372 }
373 
374 //#############################################################################
375 // ---------------------------------------------------------------------------
376 // Routine: invalidFormat.
377 // Purpose: called when invalid format found.
378 // ---------------------------------------------------------------------------
379 //
380 
382 {
384 }
385 
386 //#############################################################################
387 // ---------------------------------------------------------------------------
388 // Routine: setWidth
389 // Purpose: Sets the minimum width of a stream field.
390 // ---------------------------------------------------------------------------
391 //
392 
393 void Message::setWidth( const std::string& formatArg ) const
394 {
395  // Check that the parameters are only digits.
396  bool only_digits = true;
397  for( std::string::const_iterator i = formatArg.begin();
398  i != formatArg.end(); i++ ) {
399 
400  if ( ! isdigit( *i ) ) {
401  only_digits = false;
402  invalidFormat();
403  break;
404  }
405  }
406 
407  // Convert string to int.
408  if ( only_digits ) {
409 #ifdef __GNUG__
410  m_width = atoi( formatArg.c_str() );
411 #else
412  m_width = atoi( formatArg.data() );
413 #endif
414  }
415 }
416 
417 //#############################################################################
418 // ---------------------------------------------------------------------------
419 // Routine: sizeField
420 // Purpose: Truncates or pads the text to m_width as necessary
421 // ---------------------------------------------------------------------------
422 //
423 
424 void Message::sizeField( const std::string& text ) const
425 {
426  std::string newText;
427  if ( m_width == 0 || m_width == static_cast<int>( text.length() ) ) {
428  newText = text;
429  }
430  else {
431 
432  // Truncate the text if it is too long.
433  if ( m_width < static_cast<int>( text.length() ) ) {
434  newText = text.substr( 0, m_width );
435  for ( int i = 0, j = newText.length()-1; i < 3 && j >= 0; i++, j-- )
436  newText[ j ] = '.';
437  }
438 
439  // Pad the text.
440  else {
441  newText = std::string( m_width, m_fill );
442  if ( m_left )
443  newText.replace( newText.begin(), newText.begin() + text.length(),
444  text.begin(), text.end() );
445  else
446  newText.replace( newText.end() - text.length(), newText.end(),
447  text.begin(), text.end() );
448  }
449  }
450 
451  m_formatted_msg += newText;
452 }
static const char TYPE
The character used to indicate that the message type should be printed.
Definition: Message.h:130
bool m_left
Justification.
Definition: Message.h:115
static const char MESSAGE
The character used to indicate that the message should be printed.
Definition: Message.h:127
const std::string & getFormat() const
Get the format string.
Definition: Message.cpp:189
char m_fill
The current fill character.
Definition: Message.h:109
static const char JUSTIFY_LEFT
The character used to indicate start of left text justification.
Definition: Message.h:121
GAUDI_API std::string format(const char *,...)
MsgStream format utility "a la sprintf(...)".
Definition: MsgStream.cpp:133
std::string m_formatted_msg
Formatted message.
Definition: Message.h:106
std::string m_time_format
Time format string.
Definition: Message.h:100
void decodeFormat(const std::string &format) const
Decode format.
Definition: Message.cpp:305
void setMessage(const std::string &msg)
Set the message string.
Definition: Message.cpp:95
void setWidth(const std::string &formatArg) const
Set the width of a stream.
Definition: Message.cpp:393
bool operator<(const Message &test)
Needed to build maps.
Definition: Message.cpp:163
bool operator==(const Message &a, const Message &b)
Insert the message into a stream.
Definition: Message.cpp:176
static Time current(void)
Returns the current time.
Definition: Time.cpp:114
std::string m_message
The message.
Definition: Message.h:91
void setType(int msg_type)
Set the message type.
Definition: Message.cpp:117
void setTimeFormat(const std::string &timeFormat) const
Set the time format string.
Definition: Message.cpp:251
static const char * DEFAULT_FORMAT
The default message format.
Definition: Message.h:153
int getType() const
Get the message type.
Definition: Message.cpp:106
#define SET(x)
Message()
Default constructor.
Definition: Message.cpp:45
void invalidFormat() const
Called when an invalid format string is encountered.
Definition: Message.cpp:381
string type
Definition: gaudirun.py:126
void setSource(const std::string &src)
Set the message source.
Definition: Message.cpp:139
static const std::string getDefaultTimeFormat()
Get the default time format string.
Definition: Message.cpp:238
std::ostream & operator<<(std::ostream &stream, const Message &msg)
Insert the message into a stream.
Definition: Message.cpp:150
static const char * DEFAULT_TIME_FORMAT
The default time format.
Definition: Message.h:156
static const std::string getDefaultFormat()
Get the default format string.
Definition: Message.cpp:200
int m_width
The current field width.
Definition: Message.h:112
static const char TIME
The character used to indicate that the message timestamp should be printed.
Definition: Message.h:133
std::string m_format
The format string.
Definition: Message.h:97
static const char JUSTIFY_RIGHT
The character used to indicate start of right text justification.
Definition: Message.h:124
static const char UTIME
The character used to indicate that the message timestamp should be printed in UTC time...
Definition: Message.h:137
The Message class.
Definition: Message.h:15
static const char FILL
The character used to indicate that the previous character is to be used for padding out fields if th...
Definition: Message.h:145
void makeFormattedMsg(const std::string &format) const
Format the message.
Definition: Message.cpp:265
void sizeField(const std::string &text) const
Truncate or pad the output string to the field width as necessary.
Definition: Message.cpp:424
const std::string & getSource() const
Get the message source.
Definition: Message.cpp:128
const std::string & getTimeFormat() const
Get the time format string.
Definition: Message.cpp:227
static const char FORMAT_PREFIX
The character used to prefix formatting commands.
Definition: Message.h:118
std::string m_source
The source.
Definition: Message.h:94
list i
Definition: ana.py:128
static const char WIDTH
The character used to indicate that the previous decimal characters should be taken as the field widt...
Definition: Message.h:150
static const char SOURCE
The character used to indicate that the message source should be printed.
Definition: Message.h:140
void setFormat(const std::string &msg) const
Set the format string.
Definition: Message.cpp:213
std::string format(bool local, std::string spec="%c") const
Format the time using strftime.
Definition: Time.cpp:280
const std::string & getMessage() const
Get the message string.
Definition: Message.cpp:84
int m_type
The type.
Definition: Message.h:103