OpenLexocad  27.1
Log.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <QTextStream>
4 #include <string>
5 
6 
7 #define LOGGING_ENABLED
8 
9 namespace Base
10 {
11  enum LOGLEVEL
12  {
13  D_OFF = 0,
14  D_FATAL = 1,
15  D_ERROR = 2,
16  D_WARN = 3,
17  D_INFO = 4,
18  D_DEBUG = 5,
19  D_ALL = 6
20  };
21 
22  LX_BASE_EXPORT void setLogLevel(LOGLEVEL);
23  LX_BASE_EXPORT LOGLEVEL getLogLevel();
24 
25  class LX_BASE_EXPORT LastError
26  {
27  public:
28  static LastError& Instance();
29  LastError& setError(std::string& where, std::string& msg);
30  LastError& setError(const char* where, const char* msg, ...);
31  LastError& append(std::string& msg);
32  std::string getError();
33  std::string getErrorMsg();
34  LastError();
35  ~LastError();
36 
37  private:
38  std::string m_where;
39  std::string m_msg;
40  int m_msgID = -1;
41  };
42 
43  #define LASTERROR(msg, ...) Base::LastError::Instance().setError(__FUNCTION__, msg, __VA_ARGS__)
44  #define CLEARLASTERROR() Base::LastError::Instance().setError("", "")
45 
46  class LX_BASE_EXPORT ScopedLogger
47  {
48  public:
49  ScopedLogger(LOGLEVEL level, const std::string& s);
50  ~ScopedLogger();
51 
52  static int getIndent();
53 
54  class ScopedLoggerP;
55  ScopedLoggerP* _piml;
56  };
57 
58 
60  {
61  public:
62  virtual LogBaseClass& space() = 0;
63  virtual LogBaseClass& nospace() = 0;
64  virtual LogBaseClass& maybeSpace() = 0;
65  virtual LogBaseClass& operator<<(QChar t) = 0;
66  virtual LogBaseClass& operator<<(bool t) = 0;
67  virtual LogBaseClass& operator<<(char t) = 0;
68  virtual LogBaseClass& operator<<(signed short t) = 0;
69  virtual LogBaseClass& operator<<(unsigned short t) = 0;
70  virtual LogBaseClass& operator<<(signed int t) = 0;
71  virtual LogBaseClass& operator<<(unsigned int t) = 0;
72  virtual LogBaseClass& operator<<(signed long t) = 0;
73  virtual LogBaseClass& operator<<(unsigned long t) = 0;
74  virtual LogBaseClass& operator<<(qint64 t) = 0;
75  virtual LogBaseClass& operator<<(quint64 t) = 0;
76  virtual LogBaseClass& operator<<(float t) = 0;
77  virtual LogBaseClass& operator<<(double t) = 0;
78  virtual LogBaseClass& operator<<(const char* t) = 0;
79  virtual LogBaseClass& operator<<(const QString& t) = 0;
80  virtual LogBaseClass& operator<<(const QStringRef& t) = 0;
81  virtual LogBaseClass& operator<<(const QLatin1String& t) = 0;
82  virtual LogBaseClass& operator<<(const QByteArray& t) = 0;
83  virtual LogBaseClass& operator<<(const void* t) = 0;
84  virtual LogBaseClass& operator<<(QTextStreamFunction f) = 0;
85  virtual LogBaseClass& operator<<(QTextStreamManipulator m) = 0;
86 
87 
88  };
89 
91  {
92  public:
93  inline NoDebugClass& operator<<(QTextStreamFunction) { return *this; }
94  inline NoDebugClass& operator<<(QTextStreamManipulator) { return *this; }
95  inline NoDebugClass& space() { return *this; }
96  inline NoDebugClass& nospace() { return *this; }
97  inline NoDebugClass& maybeSpace() { return *this; }
98  inline NoDebugClass& quote() { return *this; }
99  inline NoDebugClass& noquote() { return *this; }
100  inline NoDebugClass& maybeQuote(const char = '"') { return *this; }
101 
102  template<typename T>
103  inline NoDebugClass& operator<<(const T&) { return *this; }
104  };
105 
106 
107  class LogClass : public LogBaseClass
108  {
109  struct Stream
110  {
111  Stream(QIODevice* device) : ts(device), ref(1), type(QtDebugMsg), space(true), message_output(false) {}
112  Stream(QString* string) : ts(string, QIODevice::WriteOnly), ref(1), type(QtDebugMsg), space(true), message_output(false) {}
113  Stream(QtMsgType t) : ts(&buffer, QIODevice::WriteOnly), ref(1), type(t), space(true), message_output(true) {}
114  QTextStream ts;
115  QString buffer;
116  int ref;
117  QtMsgType type;
118  bool space;
119  bool message_output;
120  } * stream;
121 
122  LOGLEVEL mylevel;
123  #if QT_VERSION >= 0x050000
124  QMessageLogContext context;
125  #endif
126 
127 
128  public:
129  inline LogClass(QIODevice* device) : stream(new Stream(device)) {}
130  inline LogClass(QString* string) : stream(new Stream(string)) {}
131  inline LogClass(LOGLEVEL level, QtMsgType t) : mylevel(level), stream(new Stream(t)) {}
132  inline LogClass(const LogClass& o) : stream(o.stream) { ++stream->ref; }
133  inline LogClass& operator=(const QDebug& other);
134  inline ~LogClass()
135  {
136  if (!--stream->ref)
137  {
138  if (stream->message_output && !stream->buffer.isEmpty())
139  {
140  if (mylevel <= getLogLevel())
141  {
142  char buf2[6000];
143  if (mylevel == D_ALL)
144  sprintf_s(buf2, 6000, "ALL: %*s", ScopedLogger::getIndent() * 2, "");
145  if (mylevel == D_DEBUG)
146  sprintf_s(buf2, 6000, "DEBUG: %*s", ScopedLogger::getIndent() * 2, "");
147  if (mylevel == D_ERROR)
148  sprintf_s(buf2, 6000, "ERROR: %*s", ScopedLogger::getIndent() * 2, "");
149  if (mylevel == D_FATAL)
150  sprintf_s(buf2, 6000, "FATAL: %*s", ScopedLogger::getIndent() * 2, "");
151  if (mylevel == D_WARN)
152  sprintf_s(buf2, 6000, "%*s", ScopedLogger::getIndent() * 2, "");
153  if (mylevel == D_INFO)
154  sprintf_s(buf2, 6000, "INFO: %*s", ScopedLogger::getIndent() * 2, "");
155  if (mylevel == D_OFF)
156  sprintf_s(buf2, 6000, "OFF: %*s", ScopedLogger::getIndent() * 2, "");
157 
158  QString msg = QString(buf2) + QString(stream->buffer);
159  QMessageLogContext context;
160  qt_message_output(stream->type, context, msg);
161  }
162  }
163  delete stream;
164  }
165  }
166  inline LogClass& space()
167  {
168  stream->space = true;
169  stream->ts << " ";
170  return *this;
171  }
172  inline LogClass& nospace()
173  {
174  stream->space = false;
175  return *this;
176  }
178  {
179  if (stream->space)
180  stream->ts << " ";
181  return *this;
182  }
183 
184  inline LogClass& operator<<(QChar t)
185  {
186  stream->ts << "\'" << t << "\'";
187  return maybeSpace();
188  }
189  inline LogClass& operator<<(bool t)
190  {
191  stream->ts << (bool(t) ? "true" : "false");
192  return maybeSpace();
193  }
194  inline LogClass& operator<<(char t)
195  {
196  stream->ts << t;
197  return maybeSpace();
198  }
199  inline LogClass& operator<<(signed short t)
200  {
201  stream->ts << t;
202  return maybeSpace();
203  }
204  inline LogClass& operator<<(unsigned short t)
205  {
206  stream->ts << t;
207  return maybeSpace();
208  }
209  inline LogClass& operator<<(signed int t)
210  {
211  stream->ts << t;
212  return maybeSpace();
213  }
214  inline LogClass& operator<<(unsigned int t)
215  {
216  stream->ts << t;
217  return maybeSpace();
218  }
219  inline LogClass& operator<<(signed long t)
220  {
221  stream->ts << t;
222  return maybeSpace();
223  }
224  inline LogClass& operator<<(unsigned long t)
225  {
226  stream->ts << t;
227  return maybeSpace();
228  }
229  inline LogClass& operator<<(qint64 t)
230  {
231  stream->ts << QString::number(t);
232  return maybeSpace();
233  }
234  inline LogClass& operator<<(quint64 t)
235  {
236  stream->ts << QString::number(t);
237  return maybeSpace();
238  }
239  inline LogClass& operator<<(float t)
240  {
241  stream->ts << t;
242  return maybeSpace();
243  }
244  inline LogClass& operator<<(double t)
245  {
246  stream->ts << t;
247  return maybeSpace();
248  }
249  inline LogClass& operator<<(const char* t)
250  {
251  stream->ts << qPrintable(t);
252  return maybeSpace();
253  }
254  inline LogClass& operator<<(const QString& t)
255  {
256  stream->ts << t;
257  return maybeSpace();
258  }
259  inline LogClass& operator<<(const QStringRef& t) { return operator<<(t.toString()); }
260  inline LogClass& operator<<(const QLatin1String& t)
261  {
262  stream->ts << t.latin1();
263  return maybeSpace();
264  }
265  inline LogClass& operator<<(const QByteArray& t)
266  {
267  stream->ts << t;
268  return maybeSpace();
269  }
270  inline LogClass& operator<<(const void* t)
271  {
272  stream->ts << t;
273  return maybeSpace();
274  }
275  inline LogClass& operator<<(QTextStreamFunction f)
276  {
277  stream->ts << f;
278  return *this;
279  }
280 
281  inline LogClass& operator<<(QTextStreamManipulator m)
282  {
283  stream->ts << m;
284  return *this;
285  }
286 
287  static bool is_activated;
288  };
289 
290 #ifdef LOGGING_ENABLED
291  void LogV(LOGLEVEL level, const QString& s, va_list ap);
292  LX_BASE_EXPORT LogClass Log(Base::LOGLEVEL level);
293  LX_BASE_EXPORT LogClass Log(Base::LOGLEVEL level, const char* msg, ...);
294 #endif
295 
296 
297  #define LOGCOMMAND_DEBUG(x) Base::ScopedLogger _____scopedLogger(Base::D_DEBUG, x);
298  #define LOGCOMMAND_INFO(x) Base::ScopedLogger _____scopedLogger(Base::D_INFO, x);
299  #define LOGCOMMAND(x) Base::ScopedLogger _____scopedLogger(Base::D_WARN, x);
300  #define LOGCOMMAND_WARN(x) Base::ScopedLogger _____scopedLogger(Base::D_WARN, x);
301  #define cUserDebug(...) \
302  if (Base::Settings::getInstance()->getDebugUser()) \
303  { \
304  cWarn( __VA_ARGS__); \
305  }
306  #define LOGVAR(var) cDebug() << QString("%1 = %2").arg(#var).arg(var);
307 
308  class LX_BASE_EXPORT AssertSingleton
309  {
310  public:
312  {
313  static AssertSingleton instance;
314  // volatile int dummy{};
315  return instance;
316  }
317 
318  void setCallBack( std::function<bool(std::string)> f ) { mCallback = f; }
319  bool callCallBack(std::string s) { if(mCallback) return mCallback(s); return false; }
320 
321  private:
322  std::function<bool(std::string)> mCallback;
323  AssertSingleton()= default;
324  ~AssertSingleton()= default;
325  AssertSingleton(const AssertSingleton&)= delete;
326  AssertSingleton& operator=(const AssertSingleton&)= delete;
327 
328  };
329 
330  class LX_BASE_EXPORT Logger
331  {
332  public:
333  static Logger& instance();
334  static void log( const char* format, ... );
335  static void log( QString s );
336 
337 
338  private:
339  Logger(QString path) : logFilePath(path) {}
340  ~Logger() {}
341 
342  QString logFilePath;
343  };
344 
345  class LX_BASE_EXPORT ScopedLog
346  {
347  public:
348  ScopedLog(QString a) : m_msg(a) {}
350  QString m_msg;
351  };
352 
353 #define myLog(a) Logger::instance().writeToLog(a);
354 #define myLogAtFinish(a) ScopedLog(a);
355 
356 
357 
358 
359 } // namespace Core
360 
361 #ifdef LOGGING_ENABLED
362 
363 #define cAssert(condition, message) \
364 do { \
365  if (! (condition)) { \
366  std::stringstream ss;\
367  ss << "Assertion: `" #condition << "` --> '" << message << "' failed in \n" << __FILE__ << ":" << __LINE__ << "\n"; \
368  std::cerr << ss.str();\
369  if( Base::AssertSingleton::getInstance().callCallBack(ss.str())) exit(1);\
370  } \
371 } while (false)
372 
373 
374 LX_BASE_EXPORT void cDebuggerBreak(char* message);
375 LX_BASE_EXPORT Base::LogClass cDebug();
376 LX_BASE_EXPORT Base::LogClass cInfo();
377 LX_BASE_EXPORT Base::LogClass cError();
378 LX_BASE_EXPORT Base::LogClass cWarn();
379 
380 LX_BASE_EXPORT Base::LogClass cDebug(const QString s);
381 LX_BASE_EXPORT Base::LogClass cInfo(const QString s);
382 LX_BASE_EXPORT Base::LogClass cError(const QString s);
383 LX_BASE_EXPORT Base::LogClass cWarn(const QString s);
384 
385 LX_BASE_EXPORT Base::LogClass cDebug(const char* msg, ...);
386 LX_BASE_EXPORT Base::LogClass cInfo(const char* msg, ...);
387 LX_BASE_EXPORT Base::LogClass cError(const char* msg, ...);
388 LX_BASE_EXPORT Base::LogClass cWarn(const char* msg, ...);
389 
390 
391 
392 #else
393 
394 LX_CORE_EXPORT Base::NoDebugClass noDebug();
395 LX_CORE_EXPORT void noDebug(const char*, ...);
396 LX_CORE_EXPORT void noDebug(const QString &);
397 
398 #define cAssert(condition, message) do { } while (false)
399 #define cDebug while(false) noDebug
400 #define cInfo while(false) noDebug
401 #define cError while(false) noDebug
402 #define cWarn while(false) noDebug
403 
404 
405 #endif
LX_BASE_EXPORT LOGLEVEL getLogLevel()
NoDebugClass & nospace()
Definition: Log.h:96
LogClass & operator<<(unsigned int t)
Definition: Log.h:214
Definition: Log.h:59
LogClass & operator<<(char t)
Definition: Log.h:194
LX_BASE_EXPORT Base::LogClass cInfo()
LX_BASE_EXPORT Base::LogClass cDebug()
QString m_msg
Definition: Log.h:350
~LogClass()
Definition: Log.h:134
Definition: Log.h:25
static bool is_activated
Definition: Log.h:287
LogClass & operator<<(const QStringRef &t)
Definition: Log.h:259
LX_BASE_EXPORT Base::LogClass cError()
LogClass & operator<<(const QByteArray &t)
Definition: Log.h:265
LogClass & operator<<(signed int t)
Definition: Log.h:209
LogClass(LOGLEVEL level, QtMsgType t)
Definition: Log.h:131
Definition: Log.h:345
Definition: Log.h:15
Definition: Log.h:19
Definition: Log.h:13
NoDebugClass & operator<<(const T &)
Definition: Log.h:103
static Logger & instance()
LogClass & operator<<(quint64 t)
Definition: Log.h:234
static void log(const char *format,...)
NoDebugClass & operator<<(QTextStreamFunction)
Definition: Log.h:93
LogClass & operator=(const QDebug &other)
static int getIndent()
virtual LogBaseClass & nospace()=0
Definition: Log.h:18
LogClass & nospace()
Definition: Log.h:172
void LogV(LOGLEVEL level, const QString &s, va_list ap)
LogClass & operator<<(bool t)
Definition: Log.h:189
LogClass & operator<<(signed short t)
Definition: Log.h:199
LogClass & operator<<(float t)
Definition: Log.h:239
LogClass & operator<<(QTextStreamFunction f)
Definition: Log.h:275
Definition: Log.h:46
~ScopedLog()
Definition: Log.h:349
LX_BASE_EXPORT void cDebuggerBreak(char *message)
LX_BASE_EXPORT LogClass Log(Base::LOGLEVEL level)
Definition: Log.h:90
LogClass & space()
Definition: Log.h:166
ScopedLoggerP * _piml
Definition: Log.h:54
NoDebugClass & space()
Definition: Log.h:95
LogClass & operator<<(QTextStreamManipulator m)
Definition: Log.h:281
NoDebugClass & maybeQuote(const char='"')
Definition: Log.h:100
bool callCallBack(std::string s)
Definition: Log.h:319
Definition: Log.h:14
static AssertSingleton & getInstance()
Definition: Log.h:311
LogClass & operator<<(signed long t)
Definition: Log.h:219
NoDebugClass & maybeSpace()
Definition: Log.h:97
LogClass & operator<<(unsigned long t)
Definition: Log.h:224
LogClass & operator<<(QChar t)
Definition: Log.h:184
LogClass & operator<<(const QLatin1String &t)
Definition: Log.h:260
LogClass(const LogClass &o)
Definition: Log.h:132
LogClass & operator<<(const void *t)
Definition: Log.h:270
LogClass & maybeSpace()
Definition: Log.h:177
LogClass & operator<<(unsigned short t)
Definition: Log.h:204
NoDebugClass & operator<<(QTextStreamManipulator)
Definition: Log.h:94
LOGLEVEL
Definition: Log.h:11
virtual LogBaseClass & maybeSpace()=0
void setCallBack(std::function< bool(std::string)> f)
Definition: Log.h:318
NoDebugClass & noquote()
Definition: Log.h:99
LogClass & operator<<(qint64 t)
Definition: Log.h:229
LogClass & operator<<(double t)
Definition: Log.h:244
Definition: Log.h:107
Definition: Log.h:16
LX_BASE_EXPORT void setLogLevel(LOGLEVEL)
Definition: AbstractXMLReader.h:5
virtual LogBaseClass & space()=0
NoDebugClass & quote()
Definition: Log.h:98
LogClass & operator<<(const char *t)
Definition: Log.h:249
Definition: Log.h:308
LX_BASE_EXPORT Base::LogClass cWarn()
ScopedLog(QString a)
Definition: Log.h:348
virtual LogBaseClass & operator<<(QChar t)=0
LogClass(QIODevice *device)
Definition: Log.h:129
Definition: Log.h:330
LogClass & operator<<(const QString &t)
Definition: Log.h:254
LogClass(QString *string)
Definition: Log.h:130
Definition: Log.h:17