Manticore  Version 1.0
Physics of Molecular Clouds
Log.h
Go to the documentation of this file.
1 
8 #ifndef MUTILS_LOG_H
9 #define MUTILS_LOG_H
10 
11 #include <cerrno>
12 #include <cstdio>
13 #include <cstring>
14 #include <string>
15 
23 #define MU_MESSAGE(lev, src, msg, ...) do { \
24  if ((lev) <= mutils::Log::level) { \
25  bool db = (mutils::Log::level >= mutils::Log::DEBUG); \
26  mutils::cxxfprintf(mutils::Log::stream, "%s: %s:%0*d: " msg "\n", \
27  mutils::Log::name(lev), (db ? (src) : ""), \
28  (db ? 1 : 4), __LINE__, ## __VA_ARGS__); \
29  } \
30  } while (0)
31 
40 #define MU_MESSAGE_IF(lev, cond, src, msg, ...) do { \
41  if (cond) { MU_MESSAGE(lev, src, msg, ## __VA_ARGS__); } \
42  } while (0)
43 
54 #define MU_MESSAGE_RTN(lev, rtn, cond, src, msg, ...) do { \
55  if (cond) { \
56  MU_MESSAGE(lev, src, msg, ## __VA_ARGS__); \
57  return (rtn); \
58  } \
59  } while (0)
60 
61 
68 #define MU_DEBUG(src, msg, ...) \
69  MU_MESSAGE(mutils::Log::DEBUG, src, msg, ## __VA_ARGS__)
70 
78 #define MU_DEBUG_IF(cond, src, msg, ...) \
79  MU_MESSAGE_IF(mutils::Log::DEBUG, cond, src, msg, ## __VA_ARGS__)
80 
90 #define MU_DEBUG_RTN(rtn, cond, src, msg, ...) \
91  MU_MESSAGE_RTN(mutils::Log::DEBUG, rtn, cond, src, msg, ## __VA_ARGS__)
92 
93 
100 #define MU_INFO(src, msg, ...) \
101  MU_MESSAGE(mutils::Log::INFO, src, msg, ## __VA_ARGS__)
102 
110 #define MU_INFO_IF(cond, src, msg, ...) \
111  MU_MESSAGE_IF(mutils::Log::INFO, cond, src, msg, ## __VA_ARGS__)
112 
122 #define MU_INFO_RTN(rtn, cond, src, msg, ...) \
123  MU_MESSAGE_RTN(mutils::Log::INFO, rtn, cond, src, msg, ## __VA_ARGS__)
124 
125 
132 #define MU_WARN(src, msg, ...) \
133  MU_MESSAGE(mutils::Log::WARN, src, msg, ## __VA_ARGS__)
134 
142 #define MU_WARN_IF(cond, src, msg, ...) \
143  MU_MESSAGE_IF(mutils::Log::WARN, cond, src, msg, ## __VA_ARGS__)
144 
154 #define MU_WARN_RTN(rtn, cond, src, msg, ...) \
155  MU_MESSAGE_RTN(mutils::Log::WARN, rtn, cond, src, msg, ## __VA_ARGS__)
156 
157 
164 #define MU_ERROR(src, msg, ...) \
165  MU_MESSAGE(mutils::Log::ERROR, src, msg, ## __VA_ARGS__)
166 
174 #define MU_ERROR_IF(cond, src, msg, ...) \
175  MU_MESSAGE_IF(mutils::Log::ERROR, cond, src, msg, ## __VA_ARGS__)
176 
186 #define MU_ERROR_RTN(rtn, cond, src, msg, ...) \
187  MU_MESSAGE_RTN(mutils::Log::ERROR, rtn, cond, src, msg, ## __VA_ARGS__)
188 
189 
198 #define MU_ERRNO_IF(cond, src, msg, ...) \
199  MU_MESSAGE_IF(mutils::Log::ERROR, cond, src, msg ": %s", \
200  ## __VA_ARGS__, strerror(errno))
201 
213 #define MU_ERRNO_RTN(rtn, cond, src, msg, ...) \
214  MU_MESSAGE_RTN(mutils::Log::ERROR, rtn, cond, src, msg ": %s", \
215  ## __VA_ARGS__, strerror(errno))
216 
217 
219 namespace mutils {
220 
222 inline const char *Cform(const std::string &s) { return s.c_str(); }
223 
225 template<typename T>inline T *Cform(T *p) { return p; }
226 
228 inline double Cform(double i) { return i; }
229 
231 inline unsigned long Cform(unsigned long long i) { return i; }
232 
234 inline unsigned long Cform(unsigned long i) { return i; }
235 
237 inline unsigned long Cform(unsigned i) { return i; }
238 
240 inline long Cform(long long i) { return i; }
241 
243 inline long Cform(long i) { return i; }
244 
246 inline long Cform(int i) { return i; }
247 
249 inline int Cform(unsigned char i) { return i; }
250 
252 inline int Cform(char i) { return i; }
253 
272 template<typename... Args>
273 inline int cxxprintf(Args&&... args) { return printf(Cform(args)...); }
274 
283 template<typename... Args>
284 inline int cxxfprintf(FILE *f, Args&&... args)
285 { return fprintf(f, Cform(args)...); }
286 
296 template<typename... Args>
297 inline int cxxsnprintf(char *buf, size_t len, Args&&... args)
298 { return snprintf(buf, len, Cform(args)...); }
299 
311 inline FILE *cxxfopen(const std::string &file, const char *mode)
312 {
313  return (file == "-" ? (*mode == 'r' ? stdin : stdout) :
314  file == "!" ? stderr : fopen(file.c_str(), mode));
315 }
316 
325 inline int cxxfclose(FILE *fp)
326 { return (fp == stdin || fp == stdout || fp == stderr ? 0 : fclose(fp)); }
327 
328 
344 struct Log {
345  // Message logging levels.
346  static constexpr int
347  ERROR = 0,
348  WARN = 1,
349  INFO = 2,
350  DEBUG = 3;
351 
355  static const char *name(int lev = mutils::Log::level) {
356  if (lev <= ERROR) { return "ERROR"; }
357  switch (lev) {
358  case WARN: return "WARN";
359  case INFO: return "INFO";
360  }
361  return "DEBUG";
362  }
363 
368  static void setLevel(const std::string &str)
369  {
370  for (int l=ERROR; l<=DEBUG; l++) {
371  if (str == name(l)) { level = l; }
372  }
373  }
374 
380  static int setStream(const std::string &fname, bool append = true)
381  {
382  FILE *f = cxxfopen(fname, append ? "ab" : "wb");
383  if (f) {
384  if (stream) { cxxfclose(stream); }
385  file = fname;
386  stream = f;
387  }
388  return (f ? 0 : -1);
389  }
390 
401  template <typename... Args>
402  static int message(int lev, Args&&... args)
403  { return (lev <= level ? cxxfprintf(stream, args...) : 0); }
404 
407  template <typename... Args>
408  static int error(Args&&... args)
409  { return message(ERROR, args...); }
410 
413  template <typename... Args>
414  static int warn(Args&&... args)
415  { return message(WARN, args...); }
416 
419  template <typename... Args>
420  static int info(Args&&... args)
421  { return message(INFO, args...); }
422 
425  template <typename... Args>
426  static int debug(Args&&... args)
427  { return message(DEBUG, args...); }
428 
430  static int level;
431 
433  static FILE *stream;
434 
436  static std::string file;
437 };
438 
439 } // namespace mutils
440 
441 #endif // MUTILS_LOG_H
int cxxfclose(FILE *fp)
Standardized fclose().
Definition: Log.h:325
static std::string file
Message log file name.
Definition: Log.h:436
static FILE * stream
Message log file stream.
Definition: Log.h:433
int cxxprintf(Args &&... args)
C printf() with type conversion (not safety).
Definition: Log.h:273
static constexpr int WARN
Warning condition.
Definition: Log.h:348
static const char * name(int lev=mutils::Log::level)
Standard logging level name string.
Definition: Log.h:355
static int error(Args &&... args)
Logs a message at level ERROR.
Definition: Log.h:408
const char * Cform(const std::string &s)
Converts input to well-defined type for stdio.
Definition: Log.h:222
static int warn(Args &&... args)
Logs a message at level WARN.
Definition: Log.h:414
static constexpr int INFO
Informational message.
Definition: Log.h:349
int cxxsnprintf(char *buf, size_t len, Args &&... args)
C snprintf() with type conversion (not safety).
Definition: Log.h:297
static int level
Message logging level for output to stream.
Definition: Log.h:430
static int setStream(const std::string &fname, bool append=true)
Sets the logging stream.
Definition: Log.h:380
MathUtils package.
Definition: CommandLine.cc:10
static constexpr int DEBUG
Verbose information.
Definition: Log.h:350
static int message(int lev, Args &&... args)
Logs a message.
Definition: Log.h:402
int cxxfprintf(FILE *f, Args &&... args)
C fprintf() with type conversion (not safety).
Definition: Log.h:284
static constexpr int ERROR
Error condition.
Definition: Log.h:347
static void setLevel(const std::string &str)
Sets logging level from name string.
Definition: Log.h:368
static int info(Args &&... args)
Logs a message at level INFO.
Definition: Log.h:420
Logging facility.
Definition: Log.h:344
static int debug(Args &&... args)
Logs a message at level DEBUG.
Definition: Log.h:426
FILE * cxxfopen(const std::string &file, const char *mode)
Standardized fopen().
Definition: Log.h:311