PageRenderTime 52ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/bbb-android-core/jni/iva/common/compatibility/error.cpp

https://github.com/dfsilva/mconf-mobile
C++ | 267 lines | 194 code | 55 blank | 18 comment | 29 complexity | 44c4d03c196f46bd1261242448a329c1 MD5 | raw file
Possible License(s): LGPL-3.0, GPL-3.0
  1. #include "common_leaks.h"
  2. #include <stdio.h>
  3. #include <string.h>
  4. #include <stdarg.h>
  5. #include "common_compatibility.h"
  6. #include "error.h"
  7. #include "error_int.h"
  8. #include <sstream>
  9. using namespace std;
  10. error_context_t errors;
  11. int error_init()
  12. {
  13. error_queue_init(&errors.items);
  14. return E_OK;
  15. }
  16. int error_end()
  17. {
  18. return error_queue_end(&errors.items);
  19. }
  20. int error_s(const char *file, const char *func, int line, int code, const char *description, ...)
  21. {
  22. va_list args;
  23. int error = E_OK;
  24. //#define AT __FILE__ ":" __FUNCTION__ "():" TOSTRING(__LINE__)
  25. stringstream ss;
  26. ss << file;
  27. ss << ":";
  28. ss << func;
  29. ss << "():";
  30. ss << line;
  31. va_start(args, description);
  32. error = error_addToQueue(ss.str().c_str(), code, ERROR_LEVEL_NORMAL, description, args);
  33. va_end(args);
  34. return error;
  35. }
  36. int warning_s(const char *file, const char *func, int line, int code, const char *description, ...)
  37. {
  38. va_list args;
  39. int error = E_OK;
  40. //#define AT __FILE__ ":" __FUNCTION__ "():" TOSTRING(__LINE__)
  41. stringstream ss;
  42. ss << file;
  43. ss << ":";
  44. ss << func;
  45. ss << "():";
  46. ss << line;
  47. va_start(args, description);
  48. error = error_addToQueue(ss.str().c_str(), code, ERROR_LEVEL_WARNING, description, args);
  49. va_end(args);
  50. return error;
  51. }
  52. int error_last(char **msg, int *level)
  53. {
  54. return error_queue_pop(&errors.items, msg, level);
  55. }
  56. /*************************************************************
  57. * Internas
  58. *************************************************************/
  59. int error_addToQueue(const char *location, int code, int level, const char *description,
  60. va_list args)
  61. {
  62. error_t error;
  63. char buffer[ERROR_MAX_MESSAGE_SIZE];
  64. memset(buffer, '\0', ERROR_MAX_MESSAGE_SIZE);
  65. error.code = code;
  66. error.level = level;
  67. if (location) {
  68. error.atStr = common_parseAtStr(location);
  69. } else {
  70. error.atStr = NULL;
  71. }
  72. if (description) {
  73. vsprintf(buffer, description, args);
  74. error.msg = buffer;
  75. //common_logprintf("Erro:[%s] - cod:[%d] - msg:\"%s\"\n", location, code, buffer);
  76. } else {
  77. error.msg = NULL;
  78. //common_logprintf("Erro:[%s] - cod:[%d]\n", location, code);
  79. }
  80. error_queue_push(&errors.items, &error);
  81. if (error.atStr) {
  82. free(error.atStr);
  83. }
  84. return E_OK;
  85. }
  86. int error_queue_init(error_queue_t *queue)
  87. {
  88. int i;
  89. if (!queue) {
  90. return E_NULL_PARAMETER;
  91. }
  92. pthread_mutex_init(&queue->mutex, NULL);
  93. pthread_mutex_lock(&queue->mutex);
  94. queue->nextItem = 0;
  95. for (i = 0; i < ERROR_QUEUE_COUNT; i++) {
  96. error_itemInit(&queue->items[i]);
  97. }
  98. pthread_mutex_unlock(&queue->mutex);
  99. return E_OK;
  100. }
  101. int error_queue_end(error_queue_t *queue)
  102. {
  103. int i;
  104. if (!queue) {
  105. return E_NULL_PARAMETER;
  106. }
  107. pthread_mutex_lock(&queue->mutex);
  108. for (i = 0; i < ERROR_QUEUE_COUNT; i++) {
  109. error_itemClear(&queue->items[i]);
  110. }
  111. queue->nextItem = 0;
  112. pthread_mutex_unlock(&queue->mutex);
  113. pthread_mutex_destroy(&queue->mutex);
  114. return E_OK;
  115. }
  116. int error_queue_push(error_queue_t *queue, error_t *error)
  117. {
  118. int ret;
  119. if (!queue) {
  120. return E_NULL_PARAMETER;
  121. }
  122. pthread_mutex_lock(&queue->mutex);
  123. // copia todo conteúdo de 'error' para dentro do novo item
  124. queue->items[queue->nextItem].code = error->code;
  125. queue->items[queue->nextItem].level = error->level;
  126. if (error->msg) {
  127. if (queue->items[queue->nextItem].msg) {
  128. free(queue->items[queue->nextItem].msg);
  129. }
  130. queue->items[queue->nextItem].msg = (char *)malloc(strlen(error->msg)+1);
  131. sprintf(queue->items[queue->nextItem].msg, "%s\0", error->msg);
  132. }
  133. if (error->atStr) {
  134. if (queue->items[queue->nextItem].atStr) {
  135. free(queue->items[queue->nextItem].atStr);
  136. }
  137. queue->items[queue->nextItem].atStr = (char *)malloc(strlen(error->atStr)+1);
  138. sprintf(queue->items[queue->nextItem].atStr, "%s\0", error->atStr);
  139. }
  140. if (error->level == ERROR_LEVEL_NORMAL) {
  141. common_logprintf("[ERRO] %06d: \"%s\" (at: %s)", error->code, error->msg, error->atStr);
  142. //common_logprintf("[ERRO] %06d: \"%s\"", error->code, error->msg);
  143. //common_logprintf(" at: \"%s\"\n", error->atStr);
  144. } else {
  145. common_logprintf("[warn] %06d: \"%s\"", error->code, error->msg);
  146. //common_logprintf(" at: \"%s\"\n", error->atStr);
  147. }
  148. // ajusta ponteiros
  149. queue->nextItem++;
  150. if (queue->nextItem == ERROR_QUEUE_COUNT) {
  151. queue->nextItem = 0;
  152. }
  153. ret = pthread_mutex_unlock(&queue->mutex);
  154. //printf("%d \n\n", ret);
  155. return E_OK;
  156. }
  157. int error_queue_pop(error_queue_t *queue, char **msg, int *level)
  158. {
  159. int ret;
  160. int lastItem;
  161. if (!queue) {
  162. return E_NULL_PARAMETER;
  163. }
  164. pthread_mutex_lock(&queue->mutex);
  165. // pega a posição do último erro
  166. lastItem = queue->nextItem-1;
  167. if (lastItem < 0) {
  168. lastItem = ERROR_QUEUE_COUNT-1;
  169. }
  170. // item sem código = erro inválido, não existente
  171. if (queue->items[lastItem].code == E_NONE) {
  172. ret = E_NONE;
  173. // erro válido
  174. } else {
  175. // preenche parâmetros solicitados
  176. if (queue->items[lastItem].msg && msg) {
  177. *msg = (char *)malloc(strlen(queue->items[lastItem].msg)+1);
  178. sprintf(*msg, "%s\0", queue->items[lastItem].msg);
  179. }
  180. if (level) {
  181. *level = queue->items[lastItem].level;
  182. }
  183. ret = queue->items[lastItem].code;
  184. // libera o item e atualiza a posição do próximo item
  185. error_itemClear(&queue->items[lastItem]);
  186. queue->nextItem = lastItem;
  187. }
  188. pthread_mutex_unlock(&queue->mutex);
  189. return ret; // código do erro
  190. }
  191. int error_itemClear(error_t *e)
  192. {
  193. e->code = E_NONE;
  194. e->level = ERROR_LEVEL_UNDEFINED;
  195. if (e->msg) {
  196. free(e->msg);
  197. e->msg = NULL;
  198. }
  199. if (e->atStr) {
  200. free(e->atStr);
  201. e->atStr = NULL;
  202. }
  203. return E_OK;
  204. }
  205. int error_itemInit(error_t *e)
  206. {
  207. e->code = E_NONE;
  208. e->level = ERROR_LEVEL_UNDEFINED;
  209. e->msg = NULL;
  210. e->atStr = NULL;
  211. return E_OK;
  212. }