From: Olivier Matz Date: Tue, 15 Nov 2016 17:52:55 +0000 (+0100) Subject: save X-Git-Url: http://git.droids-corp.org/?p=protos%2Flibecoli.git;a=commitdiff_plain;h=dbfba3a1bed2a7ff465ba08a363618265bcd2be5 save --- diff --git a/lib/build/test b/lib/build/test index 6484b70..3e62c75 100755 Binary files a/lib/build/test and b/lib/build/test differ diff --git a/lib/ecoli_test.c b/lib/ecoli_test.c index c859d07..3cce2da 100644 --- a/lib/ecoli_test.c +++ b/lib/ecoli_test.c @@ -144,183 +144,11 @@ out: return ret; } -TAILQ_HEAD(debug_alloc_hdr_list, debug_alloc_hdr); -static struct debug_alloc_hdr_list debug_alloc_hdr_list = - TAILQ_HEAD_INITIALIZER(debug_alloc_hdr_list); - -struct debug_alloc_hdr { - TAILQ_ENTRY(debug_alloc_hdr) next; - const char *file; - unsigned int line; - size_t size; - unsigned int cookie; -}; - -struct debug_alloc_ftr { - unsigned int cookie; -} __attribute__((packed)); - -static void *debug_malloc(size_t size, const char *file, unsigned int line) -{ - struct debug_alloc_hdr *hdr; - struct debug_alloc_ftr *ftr; - size_t new_size = size + sizeof(*hdr) + sizeof(*ftr); - void *ret; - - hdr = malloc(new_size); - if (hdr == NULL) { - ret = NULL; - } else { - hdr->file = file; - hdr->line = line; - hdr->size = size; - hdr->cookie = 0x12345678; - TAILQ_INSERT_TAIL(&debug_alloc_hdr_list, hdr, next); - ret = hdr + 1; - ftr = (struct debug_alloc_ftr *)( - (char *)hdr + size + sizeof(*hdr)); - ftr->cookie = 0x12345678; - } - - ec_log(EC_LOG_INFO, "%s:%d: info: malloc(%zd) -> %p\n", - file, line, size, ret); - - return ret; -} - -static void debug_free(void *ptr, const char *file, unsigned int line) -{ - struct debug_alloc_hdr *hdr, *h; - struct debug_alloc_ftr *ftr; - - (void)file; - (void)line; - - ec_log(EC_LOG_INFO, "%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", - file, line, ptr); - abort(); - } - - ftr = (ptr + hdr->size); - if (ftr->cookie != 0x12345678) { - ec_log(EC_LOG_ERR, "%s:%d: error: free(%p): bad end cookie\n", - file, line, ptr); - abort(); - } - - TAILQ_FOREACH(h, &debug_alloc_hdr_list, next) { - if (h == hdr) - break; - } - - if (h == NULL) { - ec_log(EC_LOG_ERR, "%s:%d: error: free(%p): bad ptr\n", - file, line, ptr); - abort(); - } - - TAILQ_REMOVE(&debug_alloc_hdr_list, hdr, next); - free(hdr); -} - -void *debug_realloc(void *ptr, size_t size, const char *file, unsigned int line) -{ - struct debug_alloc_hdr *hdr, *h; - struct debug_alloc_ftr *ftr; - size_t new_size = size + sizeof(*hdr) + sizeof(unsigned int); - void *ret; - - if (ptr != NULL) { - hdr = (ptr - sizeof(*hdr)); - if (hdr->cookie != 0x12345678) { - ec_log(EC_LOG_ERR, - "%s:%d: error: realloc(%p): bad start cookie\n", - file, line, ptr); - abort(); - } - - ftr = (ptr + hdr->size); - if (ftr->cookie != 0x12345678) { - ec_log(EC_LOG_ERR, - "%s:%d: error: realloc(%p): bad end cookie\n", - file, line, ptr); - abort(); - } - - TAILQ_FOREACH(h, &debug_alloc_hdr_list, next) { - if (h == hdr) - break; - } - - if (h == NULL) { - ec_log(EC_LOG_ERR, "%s:%d: error: realloc(%p): bad ptr\n", - file, line, ptr); - abort(); - } - - TAILQ_REMOVE(&debug_alloc_hdr_list, h, next); - hdr = realloc(hdr, new_size); - if (hdr == NULL) { - TAILQ_INSERT_TAIL(&debug_alloc_hdr_list, h, next); - ret = NULL; - } else { - ret = hdr + 1; - } - } else { - hdr = realloc(NULL, new_size); - if (hdr == NULL) - ret = NULL; - else - ret = hdr + 1; - } - - if (hdr != NULL) { - hdr->file = file; - hdr->line = line; - hdr->size = size; - hdr->cookie = 0x12345678; - TAILQ_INSERT_TAIL(&debug_alloc_hdr_list, hdr, next); - ftr = (struct debug_alloc_ftr *)( - (char *)hdr + size + sizeof(*hdr)); - ftr->cookie = 0x12345678; - } - - ec_log(EC_LOG_INFO, "%s:%d: info: realloc(%p, %zd) -> %p\n", - file, line, ptr, size, ret); - - return ret; -} - -void debug_alloc_dump(void) -{ - struct debug_alloc_hdr *hdr; - - TAILQ_FOREACH(hdr, &debug_alloc_hdr_list, next) { - ec_log(EC_LOG_ERR, "%s:%d: error: memory leak size=%zd ptr=%p\n", - hdr->file, hdr->line, hdr->size, hdr + 1); - } -} - int ec_test_all(void) { struct ec_test *test; int ret = 0; - TAILQ_INIT(&debug_alloc_hdr_list); - - /* register a new malloc to trac memleaks */ - if (ec_malloc_register(debug_malloc, debug_free, debug_realloc) < 0) { - ec_log(EC_LOG_ERR, "cannot register new malloc\n"); - return -1; - } - TAILQ_FOREACH(test, &test_list, next) { if (test->test() == 0) { ec_log(EC_LOG_INFO, "== test %-20s success\n", @@ -332,8 +160,5 @@ int ec_test_all(void) } } - ec_malloc_unregister(); - debug_alloc_dump(); - return ret; } diff --git a/lib/ecoli_tk_shlex.c b/lib/ecoli_tk_shlex.c index 7b62c0c..3384557 100644 --- a/lib/ecoli_tk_shlex.c +++ b/lib/ecoli_tk_shlex.c @@ -176,6 +176,40 @@ static char **tokenize(const char *str, int add_empty) return NULL; } +/* XXX broken: how to support that: + shlex( + str("toto"), + many(str("titi")), + ) + + that would match: + toto + toto titi + toto titi titi ... + + --> maybe we should not try to create/match the spaces automatically + + it would become: + + shlex( + option(space()), auto? + str("toto"), + many( + space(), + str("titi coin"), + ), + option(space()), auto? + ) + + -> the goal of shlex would only be to unquote + -> the creation of auto-spaces would be in another token shcmd + + cmd = shcmd_new() + shcmd_add_tk("ip", tk_ip_new()) + shcmd_set_syntax("show ") + + + */ static struct ec_parsed_tk *ec_tk_shlex_parse(const struct ec_tk *gen_tk, const char *str) { diff --git a/lib/main.c b/lib/main.c index 601508a..a2d101b 100644 --- a/lib/main.c +++ b/lib/main.c @@ -28,54 +28,238 @@ #include #include #include +#include #include -#include -#include -#include -#include +#include -static void test(void) +static const char ec_short_options[] = + "h" /* help */ + ; + +enum { + /* long options */ + EC_OPT_LONG_MIN_NUM = 256, +#define EC_OPT_HELP "help" + EC_OPT_HELP_NUM, +}; + +static const struct option ec_long_options[] = { + {EC_OPT_HELP, 1, NULL, EC_OPT_HELP_NUM}, + {NULL, 0, NULL, 0} +}; + +static void usage(const char *prgname) +{ + printf("%s [options]\n" + " --"EC_OPT_HELP": show this help\n" + , prgname); +} + +static void parse_args(int argc, char **argv) +{ + int opt; + + while ((opt = getopt_long(argc, argv, ec_short_options, + ec_long_options, NULL)) != EOF) { + + switch (opt) { + case 'h': /* help */ + case EC_OPT_HELP_NUM: + usage(argv[0]); + exit(0); + + default: + usage(argv[0]); + exit(1); + } + } +} + +TAILQ_HEAD(debug_alloc_hdr_list, debug_alloc_hdr); +static struct debug_alloc_hdr_list debug_alloc_hdr_list = + TAILQ_HEAD_INITIALIZER(debug_alloc_hdr_list); + +struct debug_alloc_hdr { + TAILQ_ENTRY(debug_alloc_hdr) next; + const char *file; + unsigned int line; + size_t size; + unsigned int cookie; +}; + +struct debug_alloc_ftr { + unsigned int cookie; +} __attribute__((packed)); + +static void *debug_malloc(size_t size, const char *file, unsigned int line) +{ + struct debug_alloc_hdr *hdr; + struct debug_alloc_ftr *ftr; + size_t new_size = size + sizeof(*hdr) + sizeof(*ftr); + void *ret; + + hdr = malloc(new_size); + if (hdr == NULL) { + ret = NULL; + } else { + hdr->file = file; + hdr->line = line; + hdr->size = size; + hdr->cookie = 0x12345678; + TAILQ_INSERT_TAIL(&debug_alloc_hdr_list, hdr, next); + ret = hdr + 1; + ftr = (struct debug_alloc_ftr *)( + (char *)hdr + size + sizeof(*hdr)); + ftr->cookie = 0x12345678; + } + + ec_log(EC_LOG_INFO, "%s:%d: info: malloc(%zd) -> %p\n", + file, line, size, ret); + + return ret; +} + +static void debug_free(void *ptr, const char *file, unsigned int line) { - struct ec_tk *seq; - struct ec_parsed_tk *p; - const char *name; - - seq = ec_tk_seq_new_list(NULL, - ec_tk_str_new(NULL, "hello"), - ec_tk_space_new(NULL), - ec_tk_or_new_list("name", - ec_tk_str_new(NULL, "john"), - ec_tk_str_new(NULL, "mike"), - EC_TK_ENDLIST), - EC_TK_ENDLIST); - if (seq == NULL) { - printf("cannot create token\n"); + struct debug_alloc_hdr *hdr, *h; + struct debug_alloc_ftr *ftr; + + (void)file; + (void)line; + + ec_log(EC_LOG_INFO, "%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", + file, line, ptr); + abort(); + } + + ftr = (ptr + hdr->size); + if (ftr->cookie != 0x12345678) { + ec_log(EC_LOG_ERR, "%s:%d: error: free(%p): bad end cookie\n", + file, line, ptr); + abort(); + } + + TAILQ_FOREACH(h, &debug_alloc_hdr_list, next) { + if (h == hdr) + break; + } + + if (h == NULL) { + ec_log(EC_LOG_ERR, "%s:%d: error: free(%p): bad ptr\n", + file, line, ptr); + abort(); + } + + TAILQ_REMOVE(&debug_alloc_hdr_list, hdr, next); + free(hdr); +} + +void *debug_realloc(void *ptr, size_t size, const char *file, unsigned int line) +{ + struct debug_alloc_hdr *hdr, *h; + struct debug_alloc_ftr *ftr; + size_t new_size = size + sizeof(*hdr) + sizeof(unsigned int); + void *ret; + + if (ptr != NULL) { + hdr = (ptr - sizeof(*hdr)); + if (hdr->cookie != 0x12345678) { + ec_log(EC_LOG_ERR, + "%s:%d: error: realloc(%p): bad start cookie\n", + file, line, ptr); + abort(); + } + + ftr = (ptr + hdr->size); + if (ftr->cookie != 0x12345678) { + ec_log(EC_LOG_ERR, + "%s:%d: error: realloc(%p): bad end cookie\n", + file, line, ptr); + abort(); + } + + TAILQ_FOREACH(h, &debug_alloc_hdr_list, next) { + if (h == hdr) + break; + } + + if (h == NULL) { + ec_log(EC_LOG_ERR, "%s:%d: error: realloc(%p): bad ptr\n", + file, line, ptr); + abort(); + } + + TAILQ_REMOVE(&debug_alloc_hdr_list, h, next); + hdr = realloc(hdr, new_size); + if (hdr == NULL) { + TAILQ_INSERT_TAIL(&debug_alloc_hdr_list, h, next); + ret = NULL; + } else { + ret = hdr + 1; + } + } else { + hdr = realloc(NULL, new_size); + if (hdr == NULL) + ret = NULL; + else + ret = hdr + 1; + } + + if (hdr != NULL) { + hdr->file = file; + hdr->line = line; + hdr->size = size; + hdr->cookie = 0x12345678; + TAILQ_INSERT_TAIL(&debug_alloc_hdr_list, hdr, next); + ftr = (struct debug_alloc_ftr *)( + (char *)hdr + size + sizeof(*hdr)); + ftr->cookie = 0x12345678; } - /* ok */ - p = ec_tk_parse(seq, "hello mike"); - ec_parsed_tk_dump(stdout, p); - name = ec_parsed_tk_to_string(ec_parsed_tk_find_first(p, "name")); - printf("parsed with name=%s\n", name); - ec_parsed_tk_free(p); - - /* ko */ - p = ec_tk_parse(seq, "hello robert"); - ec_parsed_tk_dump(stdout, p); - name = ec_parsed_tk_to_string(ec_parsed_tk_find_first(p, "name")); - printf("parsed with name=%s\n", name); - ec_parsed_tk_free(p); - - ec_tk_free(seq); + ec_log(EC_LOG_INFO, "%s:%d: info: realloc(%p, %zd) -> %p\n", + file, line, ptr, size, ret); + + return ret; +} + +void debug_alloc_dump(void) +{ + struct debug_alloc_hdr *hdr; + + TAILQ_FOREACH(hdr, &debug_alloc_hdr_list, next) { + ec_log(EC_LOG_ERR, "%s:%d: error: memory leak size=%zd ptr=%p\n", + hdr->file, hdr->line, hdr->size, hdr + 1); + } } -int main(void) +int main(int argc, char **argv) { - ec_test_all(); + int ret; + + parse_args(argc, argv); + + TAILQ_INIT(&debug_alloc_hdr_list); + /* register a new malloc to track memleaks */ + if (ec_malloc_register(debug_malloc, debug_free, debug_realloc) < 0) { + ec_log(EC_LOG_ERR, "cannot register new malloc\n"); + return -1; + } + + ret = ec_test_all(); + + ec_malloc_unregister(); + debug_alloc_dump(); - test(); + if (ret != 0) + printf("tests failed\n"); return 0; }