save
[protos/libecoli.git] / lib / main.c
index d3d35b3..25cc4ca 100644 (file)
@@ -29,6 +29,7 @@
 #include <stdio.h>
 #include <assert.h>
 #include <getopt.h>
+#include <limits.h>
 #include <execinfo.h>
 
 #include <ecoli_log.h>
 
 static int log_level = EC_LOG_INFO;
 static int alloc_fail_proba = 0;
+static int seed = 0;
 
 static const char ec_short_options[] =
        "h"  /* help */
        "l:" /* log-level */
        "r:" /* random-alloc-fail */
+       "s:" /* seed */
        ;
 
 #define EC_OPT_HELP "help"
 #define EC_OPT_LOG_LEVEL "log-level"
 #define EC_OPT_RANDOM_ALLOC_FAIL "random-alloc-fail"
+#define EC_OPT_SEED "seed"
 
 static const struct option ec_long_options[] = {
        {EC_OPT_HELP, 1, NULL, 'h'},
        {EC_OPT_LOG_LEVEL, 1, NULL, 'l'},
        {EC_OPT_RANDOM_ALLOC_FAIL, 1, NULL, 'r'},
+       {EC_OPT_SEED, 1, NULL, 's'},
        {NULL, 0, NULL, 0}
 };
 
 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"
                "      leaks or crashes in error cases. The probability is\n"
                "      between 0 and 100.\n"
+               "  -s <seed>\n"
+               "  --seed=<seed>\n"
+               "      Seeds the random number generator. Default is 0.\n"
                , prgname);
 }
 
@@ -93,9 +101,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) {
@@ -123,11 +131,24 @@ static void parse_args(int argc, char **argv)
                        }
                        break;
 
+               case 's': /* seed */
+                       if (parse_int(optarg, 0, INT_MAX, &seed, 10) < 0) {
+                               printf("Invalid seed value\n");
+                               usage(argv[0]);
+                               exit(1);
+                       }
+                       break;
+
                default:
                        usage(argv[0]);
-                       exit(1);
+                       return -1;
                }
        }
+
+       ret = optind - 1;
+       optind = 1;
+
+       return ret;
 }
 
 TAILQ_HEAD(debug_alloc_hdr_list, debug_alloc_hdr);
@@ -338,9 +359,16 @@ 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;
 
-       parse_args(argc, argv);
+       argc -= ret;
+       argv += ret;
+
+       srandom(seed);
 
        ec_log_register(debug_log, NULL);
 
@@ -351,7 +379,13 @@ int main(int argc, char **argv)
                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();