fix cmd node
[protos/libecoli.git] / lib / main.c
index d716fec..6482991 100644 (file)
 #include <getopt.h>
 #include <limits.h>
 #include <execinfo.h>
+#include <errno.h>
 
+#include <ecoli_init.h>
 #include <ecoli_log.h>
 #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,7 +70,7 @@ 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"
@@ -101,9 +106,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 +146,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);
@@ -171,9 +181,10 @@ static void *debug_malloc(size_t size, const char *file, unsigned int line)
        struct debug_alloc_ftr *ftr;
        size_t new_size = size + sizeof(*hdr) + sizeof(*ftr);
        void *ret;
+       int r = random();
+       static int seq;
 
-
-       if (alloc_fail_proba != 0 && (random() % 100) < alloc_fail_proba)
+       if (alloc_fail_proba != 0 && (r % 100) < alloc_fail_proba)
                hdr = NULL;
        else
                hdr = malloc(new_size);
@@ -193,9 +204,13 @@ 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",
-               file, line, size, ret);
+       EC_LOG(EC_LOG_DEBUG, "%s:%d: info: malloc(%zd) -> %p seq=%d\n",
+               file, line, size, ret, seq++);
+       if (seq == 100)
+               printf("here\n");
 
+       if (ret)
+               alloc_success++;
        return ret;
 }
 
@@ -207,21 +222,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 +247,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 +267,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 +275,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 +287,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 +320,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,60 +334,82 @@ 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)
                return 0;
 
-       return printf("%s", str);
+       if (printf("%s", str) < 0)
+               return -1;
+
+       return 0;
 }
 
 int main(int argc, char **argv)
 {
-       int ret, leaks;
+       int i, ret = 0, leaks;
 
-       parse_args(argc, argv);
-       srandom(seed);
+       ret = parse_args(argc, argv);
+       if (ret < 0)
+               return 1;
+
+       argc -= ret;
+       argv += ret;
 
-       ec_log_register(debug_log, NULL);
+       srandom(seed);
 
        /* 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");
-               return -1;
+               EC_LOG(EC_LOG_ERR, "cannot register new malloc\n");
+               return 1;
        }
 
-       ret = ec_test_all();
+       if (ec_init() < 0) {
+               fprintf(stderr, "cannot init ecoli: %s\n", strerror(errno));
+               return 1;
+       }
+       ec_log_fct_register(debug_log, NULL);
+
+       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();
 
        if (alloc_fail_proba == 0 && ret != 0) {