error.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. #define _BSD_SOURCE
  2. #define _DEFAULT_SOURCE
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <stdarg.h>
  6. #include <string.h>
  7. #include "export.h"
  8. #include "error.h"
  9. #define PCILIB_LOGGER_HISTORY 16
  10. void pcilib_print_error(void *arg, const char *file, int line, pcilib_log_priority_t prio, const char *msg, va_list va) {
  11. size_t size = strlen(msg) + strlen(file) + 64;
  12. char *stmp = alloca(size * sizeof(char*));
  13. if (stmp) {
  14. sprintf(stmp, "%s [%s:%d]\n", msg, file, line);
  15. vprintf(stmp, va);
  16. } else {
  17. // Bad for multithreading...
  18. vprintf(msg, va);
  19. printf(" [%s:%d]\n", file, line);
  20. }
  21. }
  22. static void *pcilib_logger_argument = NULL;
  23. static pcilib_log_priority_t pcilib_logger_min_prio = PCILIB_LOG_WARNING;
  24. static pcilib_logger_t pcilib_logger = pcilib_print_error;
  25. static char *pcilib_logger_history[PCILIB_LOGGER_HISTORY] = {0};
  26. static int pcilib_logger_history_pointer = 0;
  27. static int pcilib_log_check_history(pcilib_log_flags_t flags, const char *msg) {
  28. int i;
  29. if ((flags&PCILIB_LOG_ONCE) == 0)
  30. return 0;
  31. for (i = 0; ((i < PCILIB_LOGGER_HISTORY)&&(pcilib_logger_history[i])); i++) {
  32. if (!strcmp(msg, pcilib_logger_history[i]))
  33. return -1;
  34. }
  35. if (pcilib_logger_history[pcilib_logger_history_pointer])
  36. free(pcilib_logger_history[pcilib_logger_history_pointer]);
  37. pcilib_logger_history[pcilib_logger_history_pointer] = strdup(msg);
  38. if (++pcilib_logger_history_pointer == PCILIB_LOGGER_HISTORY)
  39. pcilib_logger_history_pointer = 0;
  40. return 0;
  41. }
  42. void pcilib_log_message(const char *file, int line, pcilib_log_flags_t flags, pcilib_log_priority_t prio, const char *msg, ...) {
  43. va_list va;
  44. if ((!prio)||(prio >= pcilib_logger_min_prio)) {
  45. if (pcilib_log_check_history(flags, msg))
  46. return;
  47. va_start(va, msg);
  48. pcilib_logger(pcilib_logger_argument, file, line, prio, msg, va);
  49. va_end(va);
  50. }
  51. }
  52. void pcilib_log_vmessage(const char *file, int line, pcilib_log_flags_t flags, pcilib_log_priority_t prio, const char *msg, va_list va) {
  53. if ((!prio)||(prio >= pcilib_logger_min_prio)) {
  54. if (pcilib_log_check_history(flags, msg))
  55. return;
  56. pcilib_logger(pcilib_logger_argument, file, line, prio, msg, va);
  57. }
  58. }
  59. int pcilib_set_logger(pcilib_log_priority_t min_prio, pcilib_logger_t logger, void *arg) {
  60. pcilib_logger_min_prio = min_prio;
  61. pcilib_logger_argument = arg;
  62. if (logger) pcilib_logger = logger;
  63. else logger = pcilib_print_error;
  64. return 0;
  65. }
  66. pcilib_logger_t pcilib_get_logger() {
  67. return pcilib_logger;
  68. }
  69. pcilib_log_priority_t pcilib_get_log_level() {
  70. return pcilib_logger_min_prio;
  71. }
  72. void* pcilib_get_logger_context() {
  73. return pcilib_logger_argument;
  74. }