dynamic log types
[protos/libecoli.git] / lib / main.c
index deffea3..56bc9d9 100644 (file)
 #include <ecoli_test.h>
 #include <ecoli_malloc.h>
 
+EC_LOG_TYPE_REGISTER(main);
+
 #define COUNT_OF(x) ((sizeof(x)/sizeof(0[x])) / \
                ((size_t)(!(sizeof(x) % sizeof(0[x])))))
 
 static int log_level = EC_LOG_INFO;
 static int alloc_fail_proba = 0;
 static int seed = 0;
+static size_t alloc_success = 0;
 
 static const char ec_short_options[] =
        "h"  /* help */
@@ -65,13 +68,13 @@ static const struct option ec_long_options[] = {
 
 static void usage(const char *prgname)
 {
-       printf("%s [options]\n"
+       printf("%s [options] [test1 test2 test3...]\n"
                "  -h\n"
                "  --"EC_OPT_HELP"\n"
                "      Show this help.\n"
                "  -l <level>\n"
                "  --"EC_OPT_LOG_LEVEL"=<level>\n"
-               "      Set log level (0 = no log, 6 = verbose).\n"
+               "      Set log level (0 = no log, 7 = verbose).\n"
                "  -r <probability>\n"
                "  --"EC_OPT_RANDOM_ALLOC_FAIL"=<probability>\n"
                "      Cause malloc to fail randomly. This helps to debug\n"
@@ -101,9 +104,9 @@ parse_int(const char *s, int min, int max, int *ret, unsigned int base)
        return 0;
 }
 
-static void parse_args(int argc, char **argv)
+static int parse_args(int argc, char **argv)
 {
-       int opt;
+       int ret, opt;
 
        while ((opt = getopt_long(argc, argv, ec_short_options,
                                ec_long_options, NULL)) != EOF) {
@@ -141,9 +144,14 @@ static void parse_args(int argc, char **argv)
 
                default:
                        usage(argv[0]);
-                       exit(1);
+                       return -1;
                }
        }
+
+       ret = optind - 1;
+       optind = 1;
+
+       return ret;
 }
 
 TAILQ_HEAD(debug_alloc_hdr_list, debug_alloc_hdr);
@@ -193,9 +201,11 @@ static void *debug_malloc(size_t size, const char *file, unsigned int line)
                ftr->cookie = 0x87654321;
        }
 
-       ec_log(EC_LOG_DEBUG, "%s:%d: info: malloc(%zd) -> %p\n",
+       EC_LOG(EC_LOG_DEBUG, "%s:%d: info: malloc(%zd) -> %p\n",
                file, line, size, ret);
 
+       if (ret)
+               alloc_success++;
        return ret;
 }
 
@@ -207,21 +217,21 @@ static void debug_free(void *ptr, const char *file, unsigned int line)
        (void)file;
        (void)line;
 
-       ec_log(EC_LOG_DEBUG, "%s:%d: info: free(%p)\n", file, line, ptr);
+       EC_LOG(EC_LOG_DEBUG, "%s:%d: info: free(%p)\n", file, line, ptr);
 
        if (ptr == NULL)
                return;
 
        hdr = (ptr - sizeof(*hdr));
        if (hdr->cookie != 0x12345678) {
-               ec_log(EC_LOG_ERR, "%s:%d: error: free(%p): bad start cookie\n",
+               EC_LOG(EC_LOG_ERR, "%s:%d: error: free(%p): bad start cookie\n",
                        file, line, ptr);
                abort();
        }
 
        ftr = (ptr + hdr->size);
        if (ftr->cookie != 0x87654321) {
-               ec_log(EC_LOG_ERR, "%s:%d: error: free(%p): bad end cookie\n",
+               EC_LOG(EC_LOG_ERR, "%s:%d: error: free(%p): bad end cookie\n",
                        file, line, ptr);
                abort();
        }
@@ -232,7 +242,7 @@ static void debug_free(void *ptr, const char *file, unsigned int line)
        }
 
        if (h == NULL) {
-               ec_log(EC_LOG_ERR, "%s:%d: error: free(%p): bad ptr\n",
+               EC_LOG(EC_LOG_ERR, "%s:%d: error: free(%p): bad ptr\n",
                        file, line, ptr);
                abort();
        }
@@ -252,7 +262,7 @@ static void *debug_realloc(void *ptr, size_t size, const char *file,
        if (ptr != NULL) {
                hdr =  (ptr - sizeof(*hdr));
                if (hdr->cookie != 0x12345678) {
-                       ec_log(EC_LOG_ERR,
+                       EC_LOG(EC_LOG_ERR,
                                "%s:%d: error: realloc(%p): bad start cookie\n",
                                file, line, ptr);
                        abort();
@@ -260,7 +270,7 @@ static void *debug_realloc(void *ptr, size_t size, const char *file,
 
                ftr = (ptr + hdr->size);
                if (ftr->cookie != 0x87654321) {
-                       ec_log(EC_LOG_ERR,
+                       EC_LOG(EC_LOG_ERR,
                                "%s:%d: error: realloc(%p): bad end cookie\n",
                                file, line, ptr);
                        abort();
@@ -272,7 +282,7 @@ static void *debug_realloc(void *ptr, size_t size, const char *file,
                }
 
                if (h == NULL) {
-                       ec_log(EC_LOG_ERR, "%s:%d: error: realloc(%p): bad ptr\n",
+                       EC_LOG(EC_LOG_ERR, "%s:%d: error: realloc(%p): bad ptr\n",
                                file, line, ptr);
                        abort();
                }
@@ -305,9 +315,11 @@ static void *debug_realloc(void *ptr, size_t size, const char *file,
                ftr->cookie = 0x87654321;
        }
 
-       ec_log(EC_LOG_DEBUG, "%s:%d: info: realloc(%p, %zd) -> %p\n",
+       EC_LOG(EC_LOG_DEBUG, "%s:%d: info: realloc(%p, %zd) -> %p\n",
                file, line, ptr, size, ret);
 
+       if (ret)
+               alloc_success++;
        return ret;
 }
 
@@ -317,33 +329,37 @@ static int debug_alloc_dump_leaks(void)
        int i;
        char **buffer;
 
+       EC_LOG(EC_LOG_INFO, "%zd successful allocations\n", alloc_success);
+
        if (TAILQ_EMPTY(&debug_alloc_hdr_list))
                return 0;
 
        TAILQ_FOREACH(hdr, &debug_alloc_hdr_list, next) {
-               ec_log(EC_LOG_ERR,
+               EC_LOG(EC_LOG_ERR,
                        "%s:%d: error: memory leak size=%zd ptr=%p\n",
                        hdr->file, hdr->line, hdr->size, hdr + 1);
                buffer = backtrace_symbols(hdr->stack, hdr->stacklen);
                if (buffer == NULL) {
                        for (i = 0; i < hdr->stacklen; i++)
-                               ec_log(EC_LOG_ERR, "  %p\n", hdr->stack[i]);
+                               EC_LOG(EC_LOG_ERR, "  %p\n", hdr->stack[i]);
                } else {
                        for (i = 0; i < hdr->stacklen; i++)
-                               ec_log(EC_LOG_ERR, "  %s\n",
+                               EC_LOG(EC_LOG_ERR, "  %s\n",
                                        buffer ? buffer[i] : "unknown");
                }
                free(buffer);
        }
 
-       ec_log(EC_LOG_ERR,
+       EC_LOG(EC_LOG_ERR,
                "  missing static syms, use: addr2line -f -e <prog> <addr>\n");
 
        return -1;
 }
 
-static int debug_log(unsigned int level, void *opaque, const char *str)
+static int debug_log(int type, unsigned int level, void *opaque,
+               const char *str)
 {
+       (void)type;
        (void)opaque;
 
        if (level > (unsigned int)log_level)
@@ -354,21 +370,33 @@ static int debug_log(unsigned int level, void *opaque, const char *str)
 
 int main(int argc, char **argv)
 {
-       int ret, leaks;
+       int i, ret = 0, leaks;
+
+       ret = parse_args(argc, argv);
+       if (ret < 0)
+               return 1;
+
+       argc -= ret;
+       argv += ret;
 
-       parse_args(argc, argv);
        srandom(seed);
 
-       ec_log_register(debug_log, NULL);
+       if (0) ec_log_fct_register(debug_log, NULL);
 
        /* register a new malloc to track memleaks */
        TAILQ_INIT(&debug_alloc_hdr_list);
        if (ec_malloc_register(debug_malloc, debug_free, debug_realloc) < 0) {
-               ec_log(EC_LOG_ERR, "cannot register new malloc\n");
+               EC_LOG(EC_LOG_ERR, "cannot register new malloc\n");
                return -1;
        }
 
-       ret = ec_test_all();
+       ret = 0;
+       if (argc <= 1) {
+               ret = ec_test_all();
+       } else {
+               for (i = 1; i < argc; i++)
+                       ret |= ec_test_one(argv[i]);
+       }
 
        ec_malloc_unregister();
        leaks = debug_alloc_dump_leaks();