EDepSimLogManager.cc
Go to the documentation of this file.
1 #include <vector>
2 #include <sstream>
3 #include <fstream>
4 #include <time.h>
5 
6 #include "EDepSimLog.hh"
7 
10 std::ostream* EDepSim::LogManager::fDebugStream = NULL;
11 std::ostream* EDepSim::LogManager::fLogStream = NULL;
12 std::map<std::string,EDepSim::LogManager::ErrorPriority> EDepSim::LogManager::fErrorTraces;
13 std::map<std::string,EDepSim::LogManager::LogPriority> EDepSim::LogManager::fLogTraces;
15 
17 
21 }
22 
25  if (elem == fErrorTraces.end()) return fErrorPriority;
26  return elem->second;
27 }
28 
29 namespace {
30  std::string MakeTimeStamp() {
31  std::string stamp = "Unknown Time";
32  time_t t = time(NULL);
33  struct tm *local = localtime(&t);
34  if (!local) return stamp;
35  char localTime[80];
36  if (!strftime(localTime,sizeof(localTime),"%c",local)) return stamp;
37  struct tm *utc = gmtime(&t);
38  if (!utc) return stamp;
39  char utcTime[80];
40  if (!strftime(utcTime,sizeof(utcTime),"%Y-%m-%d %H:%M (UTC)",utc))
41  return stamp;
42  stamp = localTime;
43  stamp += " [";
44  stamp += utcTime;
45  stamp += "]";
46  return stamp;
47  }
48 }
49 
52  if (!fDebugStream) return;
53  std::ofstream* ofile = dynamic_cast<std::ofstream*>(err);
54  if (ofile && !(ofile->is_open())) {
55  fDebugStream = NULL;
56  EDepSimSevere("Debug stream is not open.");
57  }
59  << "##################################################"
60  << std::endl
61  << "# ERROR LOG STARTS AT: " << MakeTimeStamp()
62  << std::endl
63  << "##################################################"
64  << std::endl
65  << std::endl;
66 }
67 
71 }
72 
76 }
77 
80  if (elem == fLogTraces.end()) return fLogPriority;
81  return elem->second;
82 }
83 
84 void EDepSim::LogManager::SetLogStream(std::ostream* log) {
86  if (!fLogStream) return;
87  std::ofstream* ofile = dynamic_cast<std::ofstream*>(log);
88  if (ofile && !(ofile->is_open())) {
89  fLogStream = NULL;
90  EDepSimSevere("Log stream is not open.");
91  }
93  << "##################################################"
94  << std::endl
95  << "# LOG STARTS AT: " << MakeTimeStamp()
96  << std::endl
97  << "##################################################"
98  << std::endl
99  << std::endl;
100 }
101 
103  if (!EDepSim::LogManager::fLogStream) return std::cout;
105 }
106 
109 }
110 
113 }
114 
117 }
118 
121 }
122 
123 
125  if (fIndentation<1) return "";
126  std::string indent = "";
127  for (int i=0; i<fIndentation; ++i) {
128  indent += "..";
129  }
130  indent += " ";
131  return indent;
132 }
133 
134 namespace {
135  bool TranslateLogLevel(const std::string& name,
137  if (name == "QuietLevel") {
139  return true;
140  }
141  if (name == "LogLevel") {
143  return true;
144  }
145  if (name == "InfoLevel") {
147  return true;
148  }
149  if (name == "VerboseLevel") {
151  return true;
152  }
153  return false;
154  }
155 
156  bool TranslateErrorLevel(const std::string& name,
158  if (name == "SilentLevel") {
160  return true;
161  }
162  if (name == "ErrorLevel") {
164  return true;
165  }
166  if (name == "SevereLevel") {
168  return true;
169  }
170  if (name == "WarnLevel") {
172  return true;
173  }
174  if (name == "DebugLevel") {
176  return true;
177  }
178  if (name == "TraceLevel") {
180  return true;
181  }
182  return false;
183  }
184 
185  std::ostream* StreamPointer(const std::string& name) {
186  if (name == "STDCOUT") return &std::cout;
187  if (name == "STDCERR") return &std::cerr;
188  if (name[0] != '"') return NULL;
189  if (name[name.size()-1] != '"') return NULL;
190  std::string file = name.substr(1,name.size()-2);
191  std::ofstream* output = new std::ofstream(file.c_str(),
192  std::ios::out|std::ios::app);
193  if (output->is_open()) return output;
194  return NULL;
195  }
196 
197  bool ReadConfigurationFile(const char* config) {
198  std::ifstream input(config);
199  if (!input.is_open()) return false;
200 
201  int inputLine = 0;
202  for (;;) {
204  std::getline(input,line);
205  if (input.eof()) break;
206 
207  // Save the current line number and cache the value so error
208  // messages can be printed later.
209  std::string cache(line);
210  ++inputLine;
211 
212  // Strip the comments out of the file.
213  std::string::size_type position = line.find("#");
214  if (position != std::string::npos) line.erase(position);
215 
216  // Strip the white space at the beginning of the line.
217  line.erase(0,line.find_first_not_of("\t "));
218 
219  // Skip lines that are too short.
220  if (line.size()==0) continue;
221 
222  // Split the line into fields and a value.
223  position = line.find("=");
224  if (position == std::string::npos) {
225  // Houston, we have a problem... There isn't a value.
226  std::cerr << "WARNING: " << config << ":" << inputLine << ": "
227  << "Configuration line missing an '='"
228  << std::endl;
229  std::cerr << " Line: <" << cache << ">"
230  << std::endl;
231  std::cerr << " Configuration line has been skip" << std::endl;
232  continue;
233  }
234 
235  // Split the value off the end of the line.
236  std::string value = line.substr(position+1);
237  line.erase(position);
238 
239  // Strip the white space at the beginning of the value.
240  value.erase(0,value.find_first_not_of("\t "));
241 
242  // Strip the white space at the end of the value.
243  position = value.find_last_not_of("\t ");
244  if (position != std::string::npos) value.erase(position+1);
245 
246  // Strip the white space at the end of the fields.
247  position = line.find_last_not_of("\t ");
248  if (position != std::string::npos) line.erase(position+1);
249 
250  // Split the remaining line in to fields.
251  std::vector<std::string> fields;
252  for (;;) {
253  position = line.find(".");
254  if (position == std::string::npos) {
255  fields.push_back(line);
256  break;
257  }
258  fields.push_back(line.substr(0,position));
259  line.erase(0,position+1);
260  }
261 
262  // Process the fields and value.
263  if (fields.size() == 2
264  && fields[0] == "log"
265  && fields[1] == "file") {
266  // Set the log file name.
267  std::ostream* str = StreamPointer(value);
268  if (!str) {
269  std::cerr << "WARNING: " << config << ":"
270  << inputLine << ": "
271  << "Cannot open log stream."
272  << std::endl;
273  std::cerr << " Line: <" << cache << ">"
274  << std::endl;
275  std::cerr << " Configuration line has been skip"
276  << std::endl;
277  continue;
278  }
280  }
281  else if (fields.size() == 2
282  && fields[0] == "error"
283  && fields[1] == "file") {
284  // Set the error file name.
285  std::ostream* str = StreamPointer(value);
286  if (!str) {
287  std::cerr << "WARNING: " << config << ":"
288  << inputLine << ": "
289  << "Cannot open error stream."
290  << std::endl;
291  std::cerr << " Line: <" << cache << ">"
292  << std::endl;
293  std::cerr << " Configuration line has been skip"
294  << std::endl;
295  continue;
296  }
298  }
299  else if (fields.size() == 3
300  && fields[0] == "log"
301  && fields[1] == "default"
302  && fields[2] == "level") {
303  // Set the default log level.
305  if (!TranslateLogLevel(value,level)) {
306  std::cerr << "WARNING: " << config << ":"
307  << inputLine << ": "
308  << "Unknown log level name."
309  << std::endl;
310  std::cerr << " Line: <" << cache << ">"
311  << std::endl;
312  std::cerr << " Configuration line has been skip"
313  << std::endl;
314  continue;
315  }
317  }
318  else if (fields.size() == 3
319  && fields[0] == "error"
320  && fields[1] == "default"
321  && fields[2] == "level") {
322  // Set the default error level.
324  if (!TranslateErrorLevel(value,level)) {
325  std::cerr << "WARNING: " << config << ":"
326  << inputLine << ": "
327  << "Unknown error level name."
328  << std::endl;
329  std::cerr << " Line: <" << cache << ">"
330  << std::endl;
331  std::cerr << " Configuration line has been skip"
332  << std::endl;
333  continue;
334  }
336  }
337  else if (fields.size() == 3
338  && fields[0] == "log"
339  && fields[2] == "level") {
340  // Set the log level.
342  if (!TranslateLogLevel(value,level)) {
343  std::cerr << "WARNING: " << config << ":"
344  << inputLine << ": "
345  << "Unknown log level name."
346  << std::endl;
347  std::cerr << " Line: <" << cache << ">"
348  << std::endl;
349  std::cerr << " Configuration line has been skip"
350  << std::endl;
351  continue;
352  }
353  EDepSim::LogManager::SetLogLevel(fields[1].c_str(),level);
354  }
355  else if (fields.size() == 3
356  && fields[0] == "error"
357  && fields[2] == "level") {
358  // Set the error level.
360  if (!TranslateErrorLevel(value,level)) {
361  std::cerr << "WARNING: " << config << ":"
362  << inputLine << ": "
363  << "Unknown error level name."
364  << std::endl;
365  std::cerr << " Line: <" << cache << ">"
366  << std::endl;
367  std::cerr << " Configuration line has been skip"
368  << std::endl;
369  continue;
370  }
371  EDepSim::LogManager::SetDebugLevel(fields[1].c_str(),level);
372  }
373  else {
374  std::cerr << "WARNING: " << config << ":" << inputLine << ": "
375  << "Unknown command."
376  << std::endl;
377  std::cerr << " Line: <" << cache << ">"
378  << std::endl;
379  std::cerr << " Configuration line has been skip" << std::endl;
380  }
381  }
382 
383  return true;
384  }
385 }
386 
388  // Try to read a local configuration file.
389  ReadConfigurationFile("./edeplog.config");
390  if (conf) {
391  bool success = ReadConfigurationFile(conf);
392  if (!success) EDepSimLog("EDepSim::Log configuration file was not read.");
393  }
394 }
static QCString name
Definition: declinfo.cpp:673
#define EDepSimLog(outStream)
Definition: EDepSimLog.hh:717
intermediate_table::iterator iterator
static void SetIndentation(int i)
Set the indentation level for a log message.
static ErrorPriority GetDebugLevel()
Get the current debugging level;.
Definition: EDepSimLog.hh:417
static std::ostream & GetLogStream()
Return the stream associated with the log file.
static void SetLogLevel(LogPriority level)
Set the default logging level.
Definition: EDepSimLog.hh:426
static ErrorPriority fErrorPriority
Definition: EDepSimLog.hh:459
static std::map< std::string, ErrorPriority > fErrorTraces
Definition: EDepSimLog.hh:463
static std::string MakeIndent()
[Internal method] Make an indentation for a log message.
std::string string
Definition: nybbler.cc:12
Definition: conf.py:1
static std::map< std::string, LogPriority > fLogTraces
Definition: EDepSimLog.hh:464
#define EDepSimSevere(outStream)
Definition: EDepSimLog.hh:539
static LogPriority fLogPriority
Definition: EDepSimLog.hh:460
tm
Definition: demo.py:21
static void ResetIndentation()
Reset the indentation to zero.
static std::ostream * fLogStream
Definition: EDepSimLog.hh:462
M::value_type trace(const M &m)
static int input(void)
Definition: code.cpp:15695
static Config * config
Definition: config.cpp:1054
static void SetLogStream(std::ostream *log)
Set the output stream to be used for log messages.
static void DecreaseIndentation()
Decrease the indentation level.
static int max(int a, int b)
void err(const char *fmt,...)
Definition: message.cpp:226
static void SetDebugLevel(ErrorPriority level)
Definition: EDepSimLog.hh:411
static void IncreaseIndentation()
Increase the indentation level.
static std::ostream & GetDebugStream()
Return the stream associated with the error file.
void line(double t, double *p, double &x, double &y, double &z)
static void SetDebugStream(std::ostream *err)
Set the output stream to be used for error messages.
static LogPriority GetLogLevel()
Get the current logging level;.
Definition: EDepSimLog.hh:432
static int fIndentation
Definition: EDepSimLog.hh:465
static void Configure(const char *conf=NULL)
static std::ostream * fDebugStream
Definition: EDepSimLog.hh:461
static QCString str
QTextStream & endl(QTextStream &s)