fork download
  1. #include <limits.h>
  2. #include <stdarg.h>
  3. #include <stdint.h>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <time.h>
  8. #include <fcntl.h>
  9. #include <ctype.h>
  10. #include <math.h>
  11. #include <sysexits.h>
  12. #include <dirent.h>
  13. #include <unistd.h>
  14. #include <sys/time.h>
  15.  
  16. #define DEV
  17.  
  18. static char *log_level_names[] = {
  19. "ERROR",
  20. "WARN",
  21. "INFO",
  22. "L3",
  23. "L4",
  24. "L5",
  25. "L6",
  26. "L7",
  27. "DEBUG",
  28. "DEBUGEXT"
  29. };
  30.  
  31. int g_log_level = 10;
  32. int logfd;
  33.  
  34. const char *get_log_level_name(int log_level)
  35. {
  36. return log_level_names[log_level];
  37. }
  38.  
  39. void tlog(int level, const char *file, int line, const char *fun, const char *fmt, ...)
  40. {
  41. va_list args;
  42.  
  43. if (level > g_log_level)
  44. return;
  45.  
  46. char timebuf[64] = "error?";
  47. struct tm ct;
  48. struct timeval tv = {0, 0};
  49.  
  50. gettimeofday(&tv, NULL);
  51. localtime_r(&tv.tv_sec, &ct);
  52.  
  53. if (logfd <= 0)
  54. return;
  55.  
  56. char logline[2048];
  57.  
  58. strftime(timebuf, sizeof(timebuf), "%H:%M:%S", &ct);
  59.  
  60. if (fun)
  61. snprintf(logline, sizeof(logline) - 1, "[%s.%06lu] %s:%d:%s [%s] ", timebuf, tv.tv_usec, file, line, fun, get_log_level_name(level));
  62. else
  63. snprintf(logline, sizeof(logline) - 1, "[%s.%06lu] [%s] ", timebuf, tv.tv_usec, get_log_level_name(level));
  64.  
  65. int line_len = strlen(logline);
  66.  
  67. va_start(args, fmt);
  68. vsnprintf(logline + line_len, sizeof(logline) - line_len - 2, fmt, args);
  69. va_end(args);
  70.  
  71. line_len = strlen(logline);
  72.  
  73. logline[line_len++] = '\n';
  74.  
  75. /* Disable the warning locally */
  76. #pragma GCC diagnostic push
  77. #pragma GCC diagnostic ignored "-Wunused-result"
  78. write(logfd, logline, line_len);
  79. #pragma GCC diagnostic pop
  80. }
  81.  
  82. #ifndef __FILENAME__
  83. #define __FILENAME__ __FILE__
  84. #endif
  85.  
  86. #define LDEBUGEX 9
  87. #define LDEBUG 8
  88.  
  89. #define LINFO 2
  90. #define LWARN 1
  91. #define LERROR 0
  92.  
  93. #define LOGL(level, fmt, ...) tlog(level, __FILENAME__, __LINE__, __FUNCTION__, fmt, ##__VA_ARGS__)
  94.  
  95. #define LOG(fmt, ...) LOGL(LINFO, fmt, ##__VA_ARGS__)
  96. #define LOG_S(fmt, ...) slog(__FILENAME__, __LINE__, __FUNCTION__, fmt, ##__VA_ARGS__)
  97.  
  98. #define GI2P(x) GINT_TO_POINTER((x))
  99. #define GP2I(x) GPOINTER_TO_INT((x))
  100.  
  101. #define DO_PRAGMA(x) _Pragma(#x)
  102. #define TODO(x) DO_PRAGMA(message "TODO: " #x)
  103.  
  104. #define DEBUGEX(fmt, ...) LOGL(LDEBUGEX, fmt, ##__VA_ARGS__)
  105. #define DEBUG(fmt, ...) LOGL(LDEBUG, fmt, ##__VA_ARGS__)
  106. #define INFO(fmt, ...) LOGL(LINFO, fmt, ##__VA_ARGS__)
  107. #define ERR(exit_code, fmt, ...) \
  108.   do { \
  109.   char *err_str = strerror(errno);\
  110.   LOGL(LERROR, fmt ": %s", ##__VA_ARGS__, err_str); \
  111.   exit(exit_code); \
  112.   } while (0)
  113. #define ERRX(exit_code, fmt, ...) \
  114.   do { \
  115.   LOGL(LERROR, fmt, ##__VA_ARGS__); \
  116.   exit(exit_code); \
  117.   } while (0)
  118. #define WARN(fmt, ...) \
  119.   do { \
  120.   char *err_str = strerror(errno);\
  121.   LOGL(LWARN, fmt": [%d] %s", ##__VA_ARGS__, errno, err_str); \
  122.   } while (0)
  123. #define WARNX(fmt, ...) \
  124.   do { \
  125.   LOGL(LWARN, fmt, ##__VA_ARGS__); \
  126.   } while (0)
  127.  
  128.  
  129. #ifdef DEV
  130. #define mfree(p) {DEBUGEX("FREE: [%#lX]", p); free((p));}
  131. #define mfree_s(p) {LOG_S("*** [DEBUG] FREE: [%#lX]", (p)); free((p));}
  132. #define mmalloc(size) ({void *_nptr_ = malloc((size)); DEBUGEX("MALLOC: [%#lX], size %ld", _nptr_, (size)); _nptr_; })
  133. #define mcalloc(nmemb, size) ({void *_nptr_ = calloc((nmemb), (size)); DEBUGEX("CALLOC: [%#lX], nmemb %ld, size %ld", _nptr_, (nmemb), (size)); _nptr_; })
  134. #define mrealloc(ptr, size) ({ void *_nptr_; DEBUGEX("REALLOC before: [%#lX]", (ptr)); \
  135.   _nptr_ = realloc((ptr), (size)); DEBUGEX("REALLOC after: [%#lX], size [%ld]", _nptr_, (size)); _nptr_; })
  136. #else
  137. #define mfree(p) free((p))
  138. #define mfree_s(p) free((p))
  139. #define mmalloc(size) malloc((size))
  140. #define mcalloc(nmemb, size) calloc((nmemb), (size))
  141. #define mrealloc(ptr, size) realloc((ptr), (size))
  142. #endif
  143.  
  144. #define nmemb 1
  145. #define size 32
  146. int main()
  147. {
  148. logfd = STDOUT_FILENO;
  149. void *_nptr_ = calloc((nmemb), (size));
  150. LOGL(LDEBUGEX, "CALLOC: %#lX nmemb %ld, size %ld", _nptr_, (nmemb), (size));
  151. free(_nptr_);
  152.  
  153. return 0;
  154. }
  155.  
Success #stdin #stdout 0s 2376KB
stdin
Standard input is empty
stdout
[09:13:46.871052] prog.c:150:main [DEBUGEXT] CALLOC: 0X824B008 nmemb 1, size 32