Wed, 06 Feb 2013 14:35:15 +0100
Fixed map tests + added some formatting options to logger
test/logging_tests.c | file | annotate | diff | comparison | revisions | |
test/map_tests.c | file | annotate | diff | comparison | revisions | |
ucx/logging.c | file | annotate | diff | comparison | revisions | |
ucx/logging.h | file | annotate | diff | comparison | revisions |
1.1 --- a/test/logging_tests.c Wed Feb 06 14:31:44 2013 +0100 1.2 +++ b/test/logging_tests.c Wed Feb 06 14:35:15 2013 +0100 1.3 @@ -8,20 +8,23 @@ 1.4 char buffer[100]; 1.5 FILE *stream = tmpfile(); 1.6 1.7 - UcxLogger *logger = ucx_logger_new(stream, UCX_LOGGER_INFO); 1.8 + UcxLogger *logger = ucx_logger_new(stream, 1.9 + UCX_LOGGER_INFO, UCX_LOGGER_SOURCE | UCX_LOGGER_LEVEL); 1.10 1.11 UCX_TEST_BEGIN 1.12 - ucx_logger_info(logger, ST("[INFO:] allright\n")); 1.13 - ucx_logger_trace(logger, ST("[TRACE:] dont log this!\n")); 1.14 - ucx_logger_error(logger, ST("[ERROR:] error!\n")); 1.15 + ucx_logger_info(logger, ST("allright")); 1.16 + ucx_logger_trace(logger, ST("dont log this!")); 1.17 + ucx_logger_error(logger, ST("error!")); 1.18 fseek(stream, 0, SEEK_SET); 1.19 int r = fread(buffer, 1, 100, stream); 1.20 - 1.21 - UCX_TEST_ASSERT(r == 33 && strncmp(buffer, 1.22 - "[INFO:] allright\n[ERROR:] error!\n", 33) == 0, "incorrect logs"); 1.23 + 1.24 + size_t expected_length = 73; 1.25 + UCX_TEST_ASSERT(r == expected_length && strncmp(buffer, 1.26 + "[INFO] logging_tests.c:15 - allright\n" 1.27 + "[ERROR] logging_tests.c:17 - error!\n", expected_length) == 0, "incorrect logs"); 1.28 1.29 UCX_TEST_END 1.30 1.31 - free(logger); 1.32 + ucx_logger_free(logger); 1.33 fclose(stream); 1.34 }
2.1 --- a/test/map_tests.c Wed Feb 06 14:31:44 2013 +0100 2.2 +++ b/test/map_tests.c Wed Feb 06 14:35:15 2013 +0100 2.3 @@ -33,36 +33,38 @@ 2.4 td[0] = 10; td[1] = 42; td[2] = 70; td[3] = 11200; td[4] = 80000; 2.5 2.6 UCX_TEST_BEGIN 2.7 - ucx_map_cstr_put(map, "Key2", &td[2]); /* 0 */ 2.8 - ucx_map_cstr_put(map, "Key0", &td[0]); /* 0 */ 2.9 - ucx_map_cstr_put(map, "Key1", &td[1]); /* 3 */ 2.10 - ucx_map_cstr_put(map, "KeY3", &td[3]); /* 2 */ 2.11 - ucx_map_cstr_put(map, "KEY4", &td[4]); /* 0 */ 2.12 + ucx_map_cstr_put(map, "Key2", &td[2]); /* 3.2 */ 2.13 + ucx_map_cstr_put(map, "Key0", &td[0]); /* 0.0 */ 2.14 + ucx_map_cstr_put(map, "Key1", &td[1]); /* 3.0 */ 2.15 + ucx_map_cstr_put(map, "KeY3", &td[3]); /* 3.1 */ 2.16 + ucx_map_cstr_put(map, "KEY4", &td[4]); /* 1.0 */ 2.17 2.18 UCX_TEST_ASSERT(*((int*)map->map[0]->data) == td[0], "failed Key0"); 2.19 - UCX_TEST_ASSERT(map->map[0]->next != NULL, "no list at slot 0"); 2.20 - UCX_TEST_ASSERT(*((int*)map->map[0]->next->data) == td[2], "failed Key2"); 2.21 - UCX_TEST_ASSERT(map->map[0]->next->next != NULL, "list corrupt at slot 0"); 2.22 - UCX_TEST_ASSERT(*((int*)map->map[0]->next->next->data) == td[4], 2.23 - "failed Key4") 2.24 - UCX_TEST_ASSERT(map->map[0]->next->next->next == NULL, 2.25 - "slot 0 not terminated") 2.26 + UCX_TEST_ASSERT(*((int*)map->map[1]->data) == td[4], "failed KEY4"); 2.27 + UCX_TEST_ASSERT(*((int*)map->map[3]->data) == td[1], "failed Key1"); 2.28 + 2.29 + UCX_TEST_ASSERT(map->map[3]->next != NULL, "no list at slot 3"); 2.30 + UCX_TEST_ASSERT(map->map[3]->next->next != NULL, "list corrupt at slot 3"); 2.31 + UCX_TEST_ASSERT(*((int*)map->map[3]->next->data) == td[3], 2.32 + "failed KeY3") 2.33 + UCX_TEST_ASSERT(*((int*)map->map[3]->next->next->data) == td[2], 2.34 + "failed KeY2"); 2.35 2.36 - UCX_TEST_ASSERT(map->map[1] == NULL, "slot 1 not terminated"); 2.37 + UCX_TEST_ASSERT(map->map[0]->next == NULL, "slot 0 not terminated"); 2.38 + UCX_TEST_ASSERT(map->map[1]->next == NULL, "slot 1 not terminated"); 2.39 + UCX_TEST_ASSERT(map->map[2] == NULL, "slot 2 not empty"); 2.40 + UCX_TEST_ASSERT(map->map[3]->next->next->next == NULL, 2.41 + "slot 3 not terminated") 2.42 2.43 - UCX_TEST_ASSERT(*((int*)map->map[2]->data) == td[3], "failed KeY3"); 2.44 - UCX_TEST_ASSERT(map->map[2]->next == NULL, "slot 2 not terminated"); 2.45 - 2.46 - UCX_TEST_ASSERT(*((int*)map->map[3]->data) == td[1], "failed Key1"); 2.47 - 2.48 - ucx_map_cstr_put(map, "Key0", &td[3]); /* 0 */ 2.49 + ucx_map_cstr_put(map, "KeY3", &td[4]); /* replace 3.1 */ 2.50 2.51 - UCX_TEST_ASSERT(*((int*)map->map[0]->data) == td[3], "overwrite failed"); 2.52 - UCX_TEST_ASSERT(*((int*)map->map[0]->next->data) == td[2], 2.53 + UCX_TEST_ASSERT(*((int*)map->map[3]->data) == td[1], 2.54 "overwrite failed") 2.55 - UCX_TEST_ASSERT(*((int*)map->map[0]->next->next->data) == td[4], 2.56 + UCX_TEST_ASSERT(*((int*)map->map[3]->next->data) == td[4], 2.57 + "overwrite failed"); 2.58 + UCX_TEST_ASSERT(*((int*)map->map[3]->next->next->data) == td[2], 2.59 "overwrite failed") 2.60 - UCX_TEST_ASSERT(map->map[0]->next->next->next == NULL, "overwrite failed"); 2.61 + UCX_TEST_ASSERT(map->map[3]->next->next->next == NULL, "overwrite failed"); 2.62 2.63 UCX_TEST_END 2.64 ucx_map_free(map); 2.65 @@ -74,11 +76,11 @@ 2.66 int td[5]; 2.67 td[0] = 10; td[1] = 42; td[2] = 70; td[3] = 11200; td[4] = 80000; 2.68 2.69 - ucx_map_cstr_put(map, "Key2", &td[2]); /* 0 */ 2.70 - ucx_map_cstr_put(map, "Key0", &td[0]); /* 0 */ 2.71 - ucx_map_cstr_put(map, "Key1", &td[1]); /* 3 */ 2.72 - ucx_map_cstr_put(map, "KeY3", &td[3]); /* 2 */ 2.73 - ucx_map_cstr_put(map, "KEY4", &td[4]); /* 0 */ 2.74 + ucx_map_cstr_put(map, "Key2", &td[2]); 2.75 + ucx_map_cstr_put(map, "Key0", &td[0]); 2.76 + ucx_map_cstr_put(map, "Key1", &td[1]); 2.77 + ucx_map_cstr_put(map, "KeY3", &td[3]); 2.78 + ucx_map_cstr_put(map, "KEY4", &td[4]); 2.79 UCX_TEST_BEGIN 2.80 2.81 td[0] = *((int*)ucx_map_cstr_get(map, "Key0"));
3.1 --- a/ucx/logging.c Wed Feb 06 14:31:44 2013 +0100 3.2 +++ b/ucx/logging.c Wed Feb 06 14:35:15 2013 +0100 3.3 @@ -1,20 +1,63 @@ 3.4 #include "logging.h" 3.5 #include <stdlib.h> 3.6 +#include <string.h> 3.7 3.8 -UcxLogger *ucx_logger_new(FILE *stream, unsigned int level) { 3.9 +UcxLogger *ucx_logger_new(FILE *stream, unsigned int level, unsigned int mask) { 3.10 UcxLogger *logger = (UcxLogger*) malloc(sizeof(UcxLogger)); 3.11 if (logger != NULL) { 3.12 logger->stream = stream; 3.13 logger->level = level; 3.14 + logger->mask = mask; 3.15 + logger->levels = ucx_map_new(8); 3.16 + 3.17 + unsigned int l; 3.18 + l = UCX_LOGGER_ERROR; 3.19 + ucx_map_int_put(logger->levels, l, "[ERROR]"); 3.20 + l = UCX_LOGGER_WARN; 3.21 + ucx_map_int_put(logger->levels, l, "[WARNING]"); 3.22 + l = UCX_LOGGER_INFO; 3.23 + ucx_map_int_put(logger->levels, l, "[INFO]"); 3.24 + l = UCX_LOGGER_TRACE; 3.25 + ucx_map_int_put(logger->levels, l, "[TRACE]"); 3.26 } 3.27 3.28 return logger; 3.29 } 3.30 3.31 +void ucx_logger_free(UcxLogger *logger) { 3.32 + ucx_map_free(logger->levels); 3.33 + free(logger); 3.34 +} 3.35 + 3.36 void ucx_logger_log(UcxLogger *logger, unsigned int level, 3.37 - const sstr_t message) { 3.38 + const sstr_t message, const char* file, const unsigned int line) { 3.39 if (level <= logger->level) { 3.40 - fwrite(message.ptr, 1, message.length, logger->stream); 3.41 + size_t n = message.length; 3.42 + if ((logger->mask & UCX_LOGGER_SOURCE) > 0) { 3.43 + n += strlen(file); 3.44 + n += 10; // line 3.45 + } 3.46 + // TODO: add k bytes for timestamp 3.47 + n += 16; // extra space for fill characters (:, -, etc.) 3.48 + 3.49 + char msg[n]; 3.50 + off_t k = 0; 3.51 + 3.52 + if ((logger->mask & UCX_LOGGER_LEVEL) > 0) { 3.53 + k += sprintf(msg+k, "%s ", (char*) 3.54 + ucx_map_int_get(logger->levels, level)); 3.55 + } 3.56 + // TODO: timestamp 3.57 + if ((logger->mask & UCX_LOGGER_SOURCE) > 0) { 3.58 + k += sprintf(msg+k, "%s:%d ", file, line); 3.59 + } 3.60 + 3.61 + msg[k++] = '-'; msg[k++] = ' '; msg[k] = 0; 3.62 + strncat(msg, message.ptr, message.length); 3.63 + k += message.length; 3.64 + msg[k++] = '\n'; 3.65 + 3.66 + fwrite(msg, 1, k, logger->stream); 3.67 fflush(logger->stream); 3.68 } 3.69 }
4.1 --- a/ucx/logging.h Wed Feb 06 14:31:44 2013 +0100 4.2 +++ b/ucx/logging.h Wed Feb 06 14:35:15 2013 +0100 4.3 @@ -2,6 +2,7 @@ 4.4 #define LOGGING_H 4.5 4.6 #include "ucx.h" 4.7 +#include "map.h" 4.8 #include "string.h" 4.9 #include <stdio.h> 4.10 4.11 @@ -10,25 +11,35 @@ 4.12 #endif 4.13 4.14 /* leave enough space for custom log levels */ 4.15 -#define UCX_LOGGER_ERROR 0x00 4.16 -#define UCX_LOGGER_WARN 0x10 4.17 -#define UCX_LOGGER_INFO 0x20 4.18 -#define UCX_LOGGER_TRACE 0x30 4.19 +#define UCX_LOGGER_ERROR 0x00 4.20 +#define UCX_LOGGER_WARN 0x10 4.21 +#define UCX_LOGGER_INFO 0x20 4.22 +#define UCX_LOGGER_TRACE 0x30 4.23 + 4.24 +#define UCX_LOGGER_LEVEL 0x01 4.25 +#define UCX_LOGGER_TIMESTAMP 0x02 4.26 +#define UCX_LOGGER_SOURCE 0x04 4.27 4.28 typedef struct { 4.29 FILE *stream; 4.30 unsigned int level; 4.31 + unsigned int mask; 4.32 + UcxMap* levels; 4.33 } UcxLogger; 4.34 4.35 -UcxLogger *ucx_logger_new(FILE *stream, unsigned int level); 4.36 -/* neither provide a free function nor a parameter for an allocator */ 4.37 +UcxLogger *ucx_logger_new(FILE *stream, unsigned int level, unsigned int mask); 4.38 +void ucx_logger_free(UcxLogger* logger); 4.39 4.40 void ucx_logger_log(UcxLogger *logger, unsigned int level, 4.41 - const sstr_t message); 4.42 -#define ucx_logger_error(l,m) ucx_logger_log(l, UCX_LOGGER_ERROR, m) 4.43 -#define ucx_logger_info(l,m) ucx_logger_log(l, UCX_LOGGER_INFO, m) 4.44 -#define ucx_logger_warn(l,m) ucx_logger_log(l, UCX_LOGGER_WARN, m) 4.45 -#define ucx_logger_trace(l,m) ucx_logger_log(l, UCX_LOGGER_TRACE, m) 4.46 + const sstr_t message, const char* file, const unsigned int line); 4.47 +#define ucx_logger_error(l,m) \ 4.48 + ucx_logger_log(l, UCX_LOGGER_ERROR, m, __FILE__, __LINE__) 4.49 +#define ucx_logger_info(l,m) \ 4.50 + ucx_logger_log(l, UCX_LOGGER_INFO, m, __FILE__, __LINE__) 4.51 +#define ucx_logger_warn(l,m) \ 4.52 + ucx_logger_log(l, UCX_LOGGER_WARN, m, __FILE__, __LINE__) 4.53 +#define ucx_logger_trace(l,m) \ 4.54 + ucx_logger_log(l, UCX_LOGGER_TRACE, m, __FILE__, __LINE__) 4.55 4.56 #ifdef __cplusplus 4.57 }