log.c 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. #include <log.h>
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <stdbool.h>
  5. #include <stdarg.h>
  6. #include <time.h>
  7. // escape codes for different colors on the terminal
  8. #define FG_RED "\033[31m"
  9. #define FG_YELLOW "\033[33m"
  10. #define FG_BLUE "\033[34m"
  11. #define FG_PURPLE "\033[35m"
  12. #define TEXT_BOLD "\033[1m"
  13. #define COLOR_END "\033[0m" // reset colors to default
  14. static FILE *_logging_files[16] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
  15. NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
  16. static int _log_current_mode, _current_log_file = 1;
  17. FILE *set_log_file(char *filename)
  18. {
  19. if (_current_log_file+1 > 16) return NULL; // we only support 16 different files
  20. _logging_files[_current_log_file++] = fopen(filename, "a+");
  21. return _logging_files[_current_log_file];
  22. }
  23. void set_log_mode(int mode)
  24. {
  25. _log_current_mode = mode;
  26. }
  27. void get_log_mode()
  28. {
  29. return _log_current_mode;
  30. }
  31. // this function is headache-inducing.
  32. void _print_log(int loglevel, char *file, const char *func, char *clock, int line, char *msg, ...)
  33. {
  34. _logging_files[0] = stdout;
  35. va_list args;
  36. va_start(args, msg);
  37. // append the varargs to the buffer we want to print.
  38. // this is so that our pipe chars don't get fucked later.
  39. // also, make sure we don't get an invalid loglevel.
  40. char buffer[strlen(msg) + 1024];
  41. vsnprintf(buffer, strlen(msg)+1024, msg, args);
  42. if (loglevel < 0 || loglevel > 3) loglevel = LOG_INVALID;
  43. // set console color for printing the tag
  44. switch (loglevel) {
  45. case LOG_CRITICAL:
  46. printf(TEXT_BOLD FG_RED);
  47. break;
  48. case LOG_ERROR:
  49. printf(FG_RED);
  50. break;
  51. case LOG_WARNING:
  52. printf(FG_YELLOW);
  53. break;
  54. case LOG_INFO:
  55. printf(FG_BLUE);
  56. break;
  57. case LOG_INVALID:
  58. printf(FG_PURPLE);
  59. break;
  60. }
  61. // print the log tag
  62. int i;
  63. for (i=0; i < 16; i++)
  64. if (_logging_files[i])
  65. fprintf(_logging_files[i], "%s", log_tags[_log_current_mode][loglevel]);
  66. else break;
  67. printf(COLOR_END);
  68. if (_log_current_mode == LOG_VERBOSE) {
  69. for (i=0; i < 16; i++)
  70. if (_logging_files[i])
  71. fprintf(_logging_files[i],
  72. "%s() (%s:%d) at %s |\t",
  73. func, file, line, clock);
  74. else break;
  75. }
  76. // print the first line
  77. char *to_print = strtok(buffer, "\n");
  78. for (i = 0; i < 16; i++)
  79. if (_logging_files[i])
  80. fprintf(_logging_files[i], "%s\n", to_print);
  81. else break;
  82. // for these next lines, add a pipe and tab once.
  83. while (to_print = strtok(NULL, "\n")) {
  84. for (i = 0; i < 16; i++)
  85. if (_logging_files[i])
  86. fprintf(_logging_files[i], "%s\n", to_print);
  87. else break;
  88. }
  89. }