logger.h 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. #ifndef LOGGER_H
  2. #define LOGGER_H
  3. /* LOGGER RETURN CODE */
  4. #define LOGGER_RC_TYPE unsigned char
  5. extern __thread LOGGER_RC_TYPE logger_errno;
  6. #define LOGGER_RC_OK ((LOGGER_RC_TYPE) 0L) /* No Error */
  7. #define LOGGER_RC_EFM ((LOGGER_RC_TYPE) 1L) /* Failed to malloc */
  8. #define LOGGER_RC_EVN ((LOGGER_RC_TYPE) 2L) /* Value is Null */
  9. #if defined(LOGGER_TYPEDEF) || defined(TYPEDEFS)
  10. typedef struct str str_st;
  11. #endif /* LOGGER_TYPEDEF || TYPEDEFS */
  12. enum logger_level {
  13. LL_TRACE,
  14. LL_DEBUG,
  15. LL_INFO,
  16. LL_WARN,
  17. LL_ERROR,
  18. LL_FATAL
  19. };
  20. typedef void (*_print_like)(const char *, ...);
  21. struct logger {
  22. _print_like trace;
  23. _print_like debug;
  24. _print_like info;
  25. _print_like warn;
  26. _print_like error;
  27. _print_like fatal;
  28. };
  29. struct logger* logger_create(enum logger_level lvl);
  30. LOGGER_RC_TYPE logger_destroy(struct logger *logger);
  31. #if defined(LOGGER_IMP) || defined(IMPLEMENTATIONS)
  32. #include <stdio.h>
  33. #include <stdlib.h>
  34. #include <stdarg.h>
  35. #if defined(LOGGER_LOG) || defined(LOGS)
  36. #define __LOG(OUT, PFX, TXT) fprintf(OUT, PFX" %s: %s", __func__, TXT)
  37. #define LOG_ERROR(TXT) __LOG(stderr, "[ERROR]", TXT)
  38. #else
  39. #define LOG_ERROR(TXT) ;
  40. #endif /* LOGGER_LOG */
  41. #define TEST_FOR_NULL(POINTER) \
  42. if ( POINTER == NULL ) { \
  43. LOG_ERROR("Null Pointer Not Expected"); \
  44. logger_errno = LOGGER_RC_EVN; \
  45. return logger_errno; \
  46. }
  47. #define CHECK_MALLOC(POINTER, STR_RC) \
  48. if ( POINTER == NULL ) { \
  49. LOG_ERROR("Failed to malloc"); \
  50. logger_errno = LOGGER_RC_EFM; \
  51. return STR_RC; \
  52. }
  53. static void nop(const char *format, ...) {(void) format;}
  54. __attribute__((format(printf, 1, 2)))
  55. static void trace(const char *format, ...) {
  56. va_list vargs;
  57. va_start(vargs, format);
  58. fprintf(stdout, "[TRACE] ");
  59. vfprintf(stdout, format, vargs);
  60. }
  61. __attribute__((format(printf, 1, 2)))
  62. static void debug(const char *format, ...) {
  63. va_list vargs;
  64. va_start(vargs, format);
  65. fprintf(stdout, "[DEBUG] ");
  66. vfprintf(stdout, format, vargs);
  67. }
  68. __attribute__((format(printf, 1, 2)))
  69. static void info(const char *format, ...) {
  70. va_list vargs;
  71. va_start(vargs, format);
  72. fprintf(stdout, "[INFO] ");
  73. vfprintf(stdout, format, vargs);
  74. }
  75. __attribute__((format(printf, 1, 2)))
  76. static void warn(const char *format, ...) {
  77. va_list vargs;
  78. va_start(vargs, format);
  79. fprintf(stdout, "[WARN] ");
  80. vfprintf(stdout, format, vargs);
  81. }
  82. __attribute__((format(printf, 1, 2)))
  83. static void error(const char *format, ...) {
  84. va_list vargs;
  85. va_start(vargs, format);
  86. fprintf(stderr, "[ERROR] ");
  87. vfprintf(stderr, format, vargs);
  88. }
  89. __attribute__((format(printf, 1, 2)))
  90. static void fatal(const char *format, ...) {
  91. va_list vargs;
  92. va_start(vargs, format);
  93. fprintf(stderr, "[FATAL] ");
  94. vfprintf(stderr, format, vargs);
  95. }
  96. struct logger* logger_create(enum logger_level lvl) {
  97. logger_errno = LOGGER_RC_OK;
  98. struct logger *ret = malloc(sizeof(struct logger));
  99. CHECK_MALLOC(ret, NULL)
  100. ret->trace = *nop;
  101. ret->debug = *nop;
  102. ret->info = *nop;
  103. ret->warn = *nop;
  104. ret->error = *nop;
  105. ret->fatal = *nop;
  106. switch (lvl) {
  107. case LL_TRACE:
  108. ret->trace = *trace;
  109. /* fall through */
  110. case LL_DEBUG:
  111. ret->debug = *debug;
  112. /* fall through */
  113. case LL_INFO:
  114. ret->info = *info;
  115. /* fall through */
  116. case LL_WARN:
  117. ret->warn = *warn;
  118. /* fall through */
  119. case LL_ERROR:
  120. ret->error = *error;
  121. /* fall through */
  122. case LL_FATAL:
  123. ret->fatal = *fatal;
  124. }
  125. return ret;
  126. }
  127. LOGGER_RC_TYPE logger_destroy(struct logger *logger) {
  128. logger_errno = LOGGER_RC_OK;
  129. TEST_FOR_NULL(logger);
  130. free(logger);
  131. return LOGGER_RC_OK;
  132. }
  133. #undef LOG_ERROR
  134. #undef TEST_FOR_NULL
  135. #undef CHECK_MALLOC
  136. #endif /* LOGGER_IMP || IMPLEMENTATIONS */
  137. #endif /* LOGGER_H */