log.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. #include "ik/log.h"
  2. #include "ik/memory.h"
  3. #include "ik/ordered_vector.h"
  4. #include <stdarg.h>
  5. #include <string.h>
  6. #include <stdio.h>
  7. typedef struct log_t
  8. {
  9. ordered_vector_t listeners; /* list of ik_log_cb_func */
  10. ordered_vector_t message_buffer;
  11. } log_t;
  12. static log_t* g_log = NULL;
  13. static void log_stdout_callback(const char* msg)
  14. {
  15. puts(msg);
  16. }
  17. /* ------------------------------------------------------------------------- */
  18. void
  19. ik_log_init(enum ik_log_e options)
  20. {
  21. if (g_log != NULL)
  22. return;
  23. g_log = (log_t*)MALLOC(sizeof *g_log);
  24. if (g_log == NULL)
  25. return;
  26. ordered_vector_construct(&g_log->listeners, sizeof(ik_log_cb_func));
  27. ordered_vector_construct(&g_log->message_buffer, sizeof(char));
  28. if (options == IK_LOG_STDOUT)
  29. ik_log_register_listener(log_stdout_callback);
  30. }
  31. /* ------------------------------------------------------------------------- */
  32. void
  33. ik_log_deinit(void)
  34. {
  35. if (g_log == NULL)
  36. return;
  37. ordered_vector_clear_free(&g_log->message_buffer);
  38. ordered_vector_clear_free(&g_log->listeners);
  39. FREE(g_log);
  40. g_log = NULL;
  41. }
  42. /* ------------------------------------------------------------------------- */
  43. void
  44. ik_log_register_listener(ik_log_cb_func callback)
  45. {
  46. if (g_log != NULL)
  47. ordered_vector_push(&g_log->listeners, &callback);
  48. }
  49. /* ------------------------------------------------------------------------- */
  50. void
  51. ik_log_unregister_listener(ik_log_cb_func callback)
  52. {
  53. if (g_log == NULL)
  54. return;
  55. ORDERED_VECTOR_FOR_EACH(&g_log->listeners, ik_log_cb_func, registered_callback)
  56. if (callback == *registered_callback)
  57. {
  58. ordered_vector_erase_element(&g_log->listeners, registered_callback);
  59. return;
  60. }
  61. ORDERED_VECTOR_END_EACH
  62. }
  63. /* ------------------------------------------------------------------------- */
  64. void
  65. ik_log_message(const char* fmt, ...)
  66. {
  67. va_list va;
  68. uintptr_t msg_len;
  69. if (g_log == NULL)
  70. return;
  71. va_start(va, fmt);
  72. msg_len = vsnprintf(NULL, 0, fmt, va);
  73. va_end(va);
  74. if (ordered_vector_resize(&g_log->message_buffer, (msg_len + 1) * sizeof(char)) < 0)
  75. return;
  76. va_start(va, fmt);
  77. vsprintf((char*)g_log->message_buffer.data, fmt, va);
  78. va_end(va);
  79. ORDERED_VECTOR_FOR_EACH(&g_log->listeners, ik_log_cb_func, callback)
  80. (*callback)((char*)g_log->message_buffer.data);
  81. ORDERED_VECTOR_END_EACH
  82. }