Fixed map tests + added some formatting options to logger

Wed, 06 Feb 2013 14:35:15 +0100

author
Mike Becker <universe@uap-core.de>
date
Wed, 06 Feb 2013 14:35:15 +0100
changeset 80
0125e4089f88
parent 79
cf3757c60c8f
child 81
86a23238d8a1

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
--- a/test/logging_tests.c	Wed Feb 06 14:31:44 2013 +0100
+++ b/test/logging_tests.c	Wed Feb 06 14:35:15 2013 +0100
@@ -8,20 +8,23 @@
     char buffer[100];
     FILE *stream = tmpfile();
 
-    UcxLogger *logger = ucx_logger_new(stream, UCX_LOGGER_INFO);
+    UcxLogger *logger = ucx_logger_new(stream,
+            UCX_LOGGER_INFO, UCX_LOGGER_SOURCE | UCX_LOGGER_LEVEL);
     
     UCX_TEST_BEGIN
-    ucx_logger_info(logger, ST("[INFO:] allright\n"));
-    ucx_logger_trace(logger, ST("[TRACE:] dont log this!\n"));
-    ucx_logger_error(logger, ST("[ERROR:] error!\n"));
+    ucx_logger_info(logger, ST("allright"));
+    ucx_logger_trace(logger, ST("dont log this!"));
+    ucx_logger_error(logger, ST("error!"));
     fseek(stream, 0, SEEK_SET);
     int r = fread(buffer, 1, 100, stream);
-
-    UCX_TEST_ASSERT(r == 33 && strncmp(buffer,
-            "[INFO:] allright\n[ERROR:] error!\n", 33) == 0, "incorrect logs");
+    
+    size_t expected_length = 73;
+    UCX_TEST_ASSERT(r == expected_length && strncmp(buffer,
+            "[INFO] logging_tests.c:15 - allright\n"
+            "[ERROR] logging_tests.c:17 - error!\n", expected_length) == 0, "incorrect logs");
 
     UCX_TEST_END
 
-    free(logger);
+    ucx_logger_free(logger);
     fclose(stream);
 }
--- a/test/map_tests.c	Wed Feb 06 14:31:44 2013 +0100
+++ b/test/map_tests.c	Wed Feb 06 14:35:15 2013 +0100
@@ -33,36 +33,38 @@
     td[0] = 10; td[1] = 42; td[2] = 70; td[3] = 11200; td[4] = 80000;
 
     UCX_TEST_BEGIN
-    ucx_map_cstr_put(map, "Key2", &td[2]); /* 0 */
-    ucx_map_cstr_put(map, "Key0", &td[0]); /* 0 */
-    ucx_map_cstr_put(map, "Key1", &td[1]); /* 3 */
-    ucx_map_cstr_put(map, "KeY3", &td[3]); /* 2 */
-    ucx_map_cstr_put(map, "KEY4", &td[4]); /* 0 */
+    ucx_map_cstr_put(map, "Key2", &td[2]); /* 3.2 */
+    ucx_map_cstr_put(map, "Key0", &td[0]); /* 0.0 */
+    ucx_map_cstr_put(map, "Key1", &td[1]); /* 3.0 */
+    ucx_map_cstr_put(map, "KeY3", &td[3]); /* 3.1 */
+    ucx_map_cstr_put(map, "KEY4", &td[4]); /* 1.0 */
     
     UCX_TEST_ASSERT(*((int*)map->map[0]->data) == td[0], "failed Key0");
-    UCX_TEST_ASSERT(map->map[0]->next != NULL, "no list at slot 0");
-    UCX_TEST_ASSERT(*((int*)map->map[0]->next->data) == td[2], "failed Key2");
-    UCX_TEST_ASSERT(map->map[0]->next->next != NULL, "list corrupt at slot 0");
-    UCX_TEST_ASSERT(*((int*)map->map[0]->next->next->data) == td[4],
-            "failed Key4")
-    UCX_TEST_ASSERT(map->map[0]->next->next->next == NULL,
-            "slot 0 not terminated")
-
-    UCX_TEST_ASSERT(map->map[1] == NULL, "slot 1 not terminated");
+    UCX_TEST_ASSERT(*((int*)map->map[1]->data) == td[4], "failed KEY4");
+    UCX_TEST_ASSERT(*((int*)map->map[3]->data) == td[1], "failed Key1");
+    
+    UCX_TEST_ASSERT(map->map[3]->next != NULL, "no list at slot 3");
+    UCX_TEST_ASSERT(map->map[3]->next->next != NULL, "list corrupt at slot 3");
+    UCX_TEST_ASSERT(*((int*)map->map[3]->next->data) == td[3],
+            "failed KeY3")
+    UCX_TEST_ASSERT(*((int*)map->map[3]->next->next->data) == td[2],
+            "failed KeY2");
 
-    UCX_TEST_ASSERT(*((int*)map->map[2]->data) == td[3], "failed KeY3");
-    UCX_TEST_ASSERT(map->map[2]->next == NULL, "slot 2 not terminated");
+    UCX_TEST_ASSERT(map->map[0]->next == NULL, "slot 0 not terminated");
+    UCX_TEST_ASSERT(map->map[1]->next == NULL, "slot 1 not terminated");
+    UCX_TEST_ASSERT(map->map[2] == NULL, "slot 2 not empty");
+    UCX_TEST_ASSERT(map->map[3]->next->next->next == NULL,
+            "slot 3 not terminated")
 
-    UCX_TEST_ASSERT(*((int*)map->map[3]->data) == td[1], "failed Key1");
-
-    ucx_map_cstr_put(map, "Key0", &td[3]); /* 0 */
+    ucx_map_cstr_put(map, "KeY3", &td[4]); /* replace 3.1 */
     
-    UCX_TEST_ASSERT(*((int*)map->map[0]->data) == td[3], "overwrite failed");
-    UCX_TEST_ASSERT(*((int*)map->map[0]->next->data) == td[2],
+    UCX_TEST_ASSERT(*((int*)map->map[3]->data) == td[1],
             "overwrite failed")
-    UCX_TEST_ASSERT(*((int*)map->map[0]->next->next->data) == td[4], 
+    UCX_TEST_ASSERT(*((int*)map->map[3]->next->data) == td[4],
+            "overwrite failed");
+    UCX_TEST_ASSERT(*((int*)map->map[3]->next->next->data) == td[2], 
             "overwrite failed")
-    UCX_TEST_ASSERT(map->map[0]->next->next->next == NULL, "overwrite failed");
+    UCX_TEST_ASSERT(map->map[3]->next->next->next == NULL, "overwrite failed");
     
     UCX_TEST_END
     ucx_map_free(map);
@@ -74,11 +76,11 @@
     int td[5];
     td[0] = 10; td[1] = 42; td[2] = 70; td[3] = 11200; td[4] = 80000;
 
-    ucx_map_cstr_put(map, "Key2", &td[2]); /* 0 */
-    ucx_map_cstr_put(map, "Key0", &td[0]); /* 0 */
-    ucx_map_cstr_put(map, "Key1", &td[1]); /* 3 */
-    ucx_map_cstr_put(map, "KeY3", &td[3]); /* 2 */
-    ucx_map_cstr_put(map, "KEY4", &td[4]); /* 0 */
+    ucx_map_cstr_put(map, "Key2", &td[2]);
+    ucx_map_cstr_put(map, "Key0", &td[0]);
+    ucx_map_cstr_put(map, "Key1", &td[1]);
+    ucx_map_cstr_put(map, "KeY3", &td[3]);
+    ucx_map_cstr_put(map, "KEY4", &td[4]);
     UCX_TEST_BEGIN
 
     td[0] = *((int*)ucx_map_cstr_get(map, "Key0"));
--- a/ucx/logging.c	Wed Feb 06 14:31:44 2013 +0100
+++ b/ucx/logging.c	Wed Feb 06 14:35:15 2013 +0100
@@ -1,20 +1,63 @@
 #include "logging.h"
 #include <stdlib.h>
+#include <string.h>
 
-UcxLogger *ucx_logger_new(FILE *stream, unsigned int level) {
+UcxLogger *ucx_logger_new(FILE *stream, unsigned int level, unsigned int mask) {
     UcxLogger *logger = (UcxLogger*) malloc(sizeof(UcxLogger));
     if (logger != NULL) {
         logger->stream = stream;
         logger->level = level;
+        logger->mask = mask;
+        logger->levels = ucx_map_new(8);
+        
+        unsigned int l;
+        l = UCX_LOGGER_ERROR;
+        ucx_map_int_put(logger->levels, l, "[ERROR]");
+        l = UCX_LOGGER_WARN;
+        ucx_map_int_put(logger->levels, l, "[WARNING]");
+        l = UCX_LOGGER_INFO;
+        ucx_map_int_put(logger->levels, l, "[INFO]");
+        l = UCX_LOGGER_TRACE;
+        ucx_map_int_put(logger->levels, l, "[TRACE]");
     }
 
     return logger;
 }
 
+void ucx_logger_free(UcxLogger *logger) {
+    ucx_map_free(logger->levels);
+    free(logger);
+}
+
 void ucx_logger_log(UcxLogger *logger, unsigned int level,
-        const sstr_t message) {
+        const sstr_t message, const char* file, const unsigned int line) {
     if (level <= logger->level) {
-        fwrite(message.ptr, 1, message.length, logger->stream);
+        size_t n = message.length;
+        if ((logger->mask & UCX_LOGGER_SOURCE) > 0) {
+            n += strlen(file);
+            n += 10; // line
+        }
+        // TODO: add k bytes for timestamp
+        n += 16; // extra space for fill characters (:, -, etc.)
+        
+        char msg[n];
+        off_t k = 0;
+        
+        if ((logger->mask & UCX_LOGGER_LEVEL) > 0) {
+            k += sprintf(msg+k, "%s ", (char*)
+                    ucx_map_int_get(logger->levels, level));
+        }
+        // TODO: timestamp
+        if ((logger->mask & UCX_LOGGER_SOURCE) > 0) {
+            k += sprintf(msg+k, "%s:%d ", file, line);
+        }
+        
+        msg[k++] = '-'; msg[k++] = ' '; msg[k] = 0;
+        strncat(msg, message.ptr, message.length);
+        k += message.length;
+        msg[k++] = '\n';
+        
+        fwrite(msg, 1, k, logger->stream);
         fflush(logger->stream);
     }
 }
--- a/ucx/logging.h	Wed Feb 06 14:31:44 2013 +0100
+++ b/ucx/logging.h	Wed Feb 06 14:35:15 2013 +0100
@@ -2,6 +2,7 @@
 #define LOGGING_H
 
 #include "ucx.h"
+#include "map.h"
 #include "string.h"
 #include <stdio.h>
 
@@ -10,25 +11,35 @@
 #endif
 
 /* leave enough space for custom log levels */
-#define UCX_LOGGER_ERROR    0x00
-#define UCX_LOGGER_WARN     0x10
-#define UCX_LOGGER_INFO     0x20
-#define UCX_LOGGER_TRACE    0x30
+#define UCX_LOGGER_ERROR        0x00
+#define UCX_LOGGER_WARN         0x10
+#define UCX_LOGGER_INFO         0x20
+#define UCX_LOGGER_TRACE        0x30
+
+#define UCX_LOGGER_LEVEL        0x01
+#define UCX_LOGGER_TIMESTAMP    0x02
+#define UCX_LOGGER_SOURCE       0x04
 
 typedef struct {
     FILE *stream;
     unsigned int level;
+    unsigned int mask;
+    UcxMap* levels;
 } UcxLogger;
 
-UcxLogger *ucx_logger_new(FILE *stream, unsigned int level);
-/* neither provide a free function nor a parameter for an allocator */
+UcxLogger *ucx_logger_new(FILE *stream, unsigned int level, unsigned int mask);
+void ucx_logger_free(UcxLogger* logger);
 
 void ucx_logger_log(UcxLogger *logger, unsigned int level,
-        const sstr_t message);
-#define ucx_logger_error(l,m) ucx_logger_log(l, UCX_LOGGER_ERROR, m)
-#define ucx_logger_info(l,m) ucx_logger_log(l, UCX_LOGGER_INFO, m)
-#define ucx_logger_warn(l,m) ucx_logger_log(l, UCX_LOGGER_WARN, m)
-#define ucx_logger_trace(l,m) ucx_logger_log(l, UCX_LOGGER_TRACE, m)
+        const sstr_t message, const char* file, const unsigned int line);
+#define ucx_logger_error(l,m) \
+    ucx_logger_log(l, UCX_LOGGER_ERROR, m, __FILE__, __LINE__)
+#define ucx_logger_info(l,m) \
+    ucx_logger_log(l, UCX_LOGGER_INFO, m, __FILE__, __LINE__)
+#define ucx_logger_warn(l,m) \
+    ucx_logger_log(l, UCX_LOGGER_WARN, m, __FILE__, __LINE__)
+#define ucx_logger_trace(l,m) \
+    ucx_logger_log(l, UCX_LOGGER_TRACE, m, __FILE__, __LINE__)
 
 #ifdef __cplusplus
 }

mercurial