From 7284aef1f5f33a170cbd04aee7ed0a43608982d6 Mon Sep 17 00:00:00 2001 From: Olivier Matz Date: Thu, 9 Nov 2017 17:46:52 +0100 Subject: [PATCH] dynamic log types --- lib/ecoli_completed.h | 1 + lib/ecoli_keyval.c | 4 +- lib/ecoli_log.c | 77 +++++++++++++++++++++++++++++++++----- lib/ecoli_log.h | 34 +++++++++++++---- lib/ecoli_node.c | 7 +++- lib/ecoli_node_cmd.c | 6 ++- lib/ecoli_node_empty.c | 6 ++- lib/ecoli_node_expr.c | 4 +- lib/ecoli_node_expr_test.c | 2 + lib/ecoli_node_file.c | 4 +- lib/ecoli_node_int.c | 10 +++-- lib/ecoli_node_many.c | 10 +++-- lib/ecoli_node_once.c | 6 ++- lib/ecoli_node_option.c | 6 ++- lib/ecoli_node_or.c | 6 ++- lib/ecoli_node_re.c | 4 +- lib/ecoli_node_re_lex.c | 10 +++-- lib/ecoli_node_seq.c | 6 ++- lib/ecoli_node_sh_lex.c | 16 +++----- lib/ecoli_node_space.c | 6 ++- lib/ecoli_node_str.c | 10 +++-- lib/ecoli_node_subset.c | 6 ++- lib/ecoli_node_weakref.c | 2 + lib/ecoli_parsed.h | 5 ++- lib/ecoli_test.c | 22 +++++++---- lib/ecoli_test.h | 4 +- lib/ecoli_vec.c | 4 +- lib/main-readline.c | 1 - lib/main.c | 38 ++++++++++--------- lib/todo.txt | 3 -- 30 files changed, 223 insertions(+), 97 deletions(-) diff --git a/lib/ecoli_completed.h b/lib/ecoli_completed.h index 16c79a6..1627cfe 100644 --- a/lib/ecoli_completed.h +++ b/lib/ecoli_completed.h @@ -46,6 +46,7 @@ struct ec_completed_item { const struct ec_node *node; char *str; char *display; + /* XXX add a keyval (attrs) */ /* reverse order: [0] = last, [len-1] = root */ const struct ec_node **path; diff --git a/lib/ecoli_keyval.c b/lib/ecoli_keyval.c index c1d881f..a47ded9 100644 --- a/lib/ecoli_keyval.c +++ b/lib/ecoli_keyval.c @@ -35,6 +35,8 @@ #include #include +EC_LOG_TYPE_REGISTER(keyval); + struct ec_keyval_elt { char *key; void *val; @@ -195,7 +197,7 @@ static int ec_keyval_testcase(void) keyval = ec_keyval(); if (keyval == NULL) { - ec_log(EC_LOG_ERR, "cannot create keyval\n"); + EC_LOG(EC_LOG_ERR, "cannot create keyval\n"); return -1; } diff --git a/lib/ecoli_log.c b/lib/ecoli_log.c index 53c3acb..3b9d69e 100644 --- a/lib/ecoli_log.c +++ b/lib/ecoli_log.c @@ -31,20 +31,28 @@ #include #include +#include #include static ec_log_t ec_log_fct = ec_log_default; static void *ec_log_opaque; -int ec_log_default(unsigned int level, void *opaque, const char *str) +struct ec_log_type { + char *name; + unsigned int level; +}; + +static struct ec_log_type *log_types; +static size_t log_types_len; + +int ec_log_default(int type, unsigned int level, void *opaque, const char *str) { (void)opaque; - (void)level; - return printf("%s", str); + return printf("[%d] %-12s %s", level, ec_log_name(type), str); } -int ec_log_register(ec_log_t usr_log, void *opaque) +int ec_log_fct_register(ec_log_t usr_log, void *opaque) { if (usr_log == NULL) return -1; @@ -55,12 +63,63 @@ int ec_log_register(ec_log_t usr_log, void *opaque) return 0; } -void ec_log_unregister(void) +void ec_log_fct_unregister(void) { ec_log_fct = NULL; } -int ec_vlog(unsigned int level, const char *format, va_list ap) +static int +ec_log_lookup(const char *name) +{ + size_t i; + + for (i = 0; i < log_types_len; i++) { + if (log_types[i].name == NULL) + continue; + if (strcmp(name, log_types[i].name) == 0) + return i; + } + + return -1; +} + +const char * +ec_log_name(int type) +{ + if (type < 0 || (unsigned int)type >= log_types_len) + return "unknown"; + return log_types[type].name; +} + +int +ec_log_type_register(const char *name) +{ + struct ec_log_type *new_types; + char *copy; + int id; + + id = ec_log_lookup(name); + if (id >= 0) + return id; + + new_types = ec_realloc(log_types, + sizeof(*new_types) * (log_types_len + 1)); + if (new_types == NULL) + return -ENOMEM; + log_types = new_types; + + copy = ec_strdup(name); + if (copy == NULL) + return -ENOMEM; + + id = log_types_len++; + log_types[id].name = copy; + log_types[id].level = EC_LOG_DEBUG; + + return id; +} + +int ec_vlog(int type, unsigned int level, const char *format, va_list ap) { char *s; int ret; @@ -74,19 +133,19 @@ int ec_vlog(unsigned int level, const char *format, va_list ap) if (ret < 0) return ret; - ret = ec_log_fct(level, ec_log_opaque, s); + ret = ec_log_fct(type, level, ec_log_opaque, s); free(s); return ret; } -int ec_log(unsigned int level, const char *format, ...) +int ec_log(int type, unsigned int level, const char *format, ...) { va_list ap; int ret; va_start(ap, format); - ret = ec_vlog(level, format, ap); + ret = ec_vlog(type, level, format, ap); va_end(ap); return ret; diff --git a/lib/ecoli_log.h b/lib/ecoli_log.h index 089254f..e117af1 100644 --- a/lib/ecoli_log.h +++ b/lib/ecoli_log.h @@ -39,19 +39,39 @@ #include +#define EC_LOG_TYPE_REGISTER(name) \ + static int name##_log_type; \ + static int local_log_type; \ + __attribute__((constructor, used)) \ + static void ec_log_register_##name(void) \ + { \ + local_log_type = ec_log_type_register(#name); \ + name##_log_type = local_log_type; \ + } + + /* return -1 on error, len(s) on success */ -typedef int (*ec_log_t)(unsigned int level, void *opaque, const char *str); +typedef int (*ec_log_t)(int type, unsigned int level, void *opaque, + const char *str); + +int ec_log_fct_register(ec_log_t usr_log, void *opaque); +void ec_log_fct_unregister(void); -int ec_log_register(ec_log_t usr_log, void *opaque); -void ec_log_unregister(void); +int ec_log_type_register(const char *name); + +const char *ec_log_name(int type); /* same api than printf */ -int ec_log(unsigned int level, const char *format, ...) - __attribute__((format(__printf__, 2, 3))); +int ec_log(int type, unsigned int level, const char *format, ...) + __attribute__((format(__printf__, 3, 4))); + +int ec_vlog(int type, unsigned int level, const char *format, va_list ap); -int ec_vlog(unsigned int level, const char *format, va_list ap); +/* to use the macros, the user must have called EC_LOG_TYPE_REGISTER */ +#define EC_LOG(level, args...) ec_log(local_log_type, level, args) +#define EC_VLOG(level, fmt, ap) ec_vlog(local_log_type, level, fmt, ap) /* default log handler for the library, use printf */ -int ec_log_default(unsigned int level, void *opaque, const char *str); +int ec_log_default(int type, unsigned int level, void *opaque, const char *str); #endif diff --git a/lib/ecoli_node.c b/lib/ecoli_node.c index 8ff05ab..6cd95d7 100644 --- a/lib/ecoli_node.c +++ b/lib/ecoli_node.c @@ -38,6 +38,8 @@ #include #include +EC_LOG_TYPE_REGISTER(node); + static struct ec_node_type_list node_type_list = TAILQ_HEAD_INITIALIZER(node_type_list); @@ -78,7 +80,7 @@ struct ec_node *__ec_node(const struct ec_node_type *type, const char *id) struct ec_node *node = NULL; char buf[256]; // XXX - ec_log(EC_LOG_DEBUG, "create node type=%s id=%s\n", + EC_LOG(EC_LOG_DEBUG, "create node type=%s id=%s\n", type->name, id); node = ec_calloc(1, type->size); @@ -117,7 +119,8 @@ struct ec_node *ec_node(const char *typename, const char *id) type = ec_node_type_lookup(typename); if (type == NULL) { - ec_log(EC_LOG_ERR, "type=%s does not exist\n", typename); + EC_LOG(EC_LOG_ERR, "type=%s does not exist\n", + typename); return NULL; } diff --git a/lib/ecoli_node_cmd.c b/lib/ecoli_node_cmd.c index 9f14ae2..db08cbf 100644 --- a/lib/ecoli_node_cmd.c +++ b/lib/ecoli_node_cmd.c @@ -53,6 +53,8 @@ #include #include +EC_LOG_TYPE_REGISTER(node_cmd); + struct ec_node_cmd { struct ec_node gen; char *cmd_str; /* the command string. */ @@ -505,7 +507,7 @@ static int ec_node_cmd_testcase(void) ec_node_int("y", 20, 30, 10) ); if (node == NULL) { - ec_log(EC_LOG_ERR, "cannot create node\n"); + EC_LOG(EC_LOG_ERR, "cannot create node\n"); return -1; } ret |= EC_TEST_CHECK_PARSE(node, 2, "command", "1"); @@ -518,7 +520,7 @@ static int ec_node_cmd_testcase(void) node = EC_NODE_CMD(NULL, "good morning [count] bob|bobby|michael", ec_node_int("count", 0, 10, 10)); if (node == NULL) { - ec_log(EC_LOG_ERR, "cannot create node\n"); + EC_LOG(EC_LOG_ERR, "cannot create node\n"); return -1; } ret |= EC_TEST_CHECK_PARSE(node, 4, "good", "morning", "1", "bob"); diff --git a/lib/ecoli_node_empty.c b/lib/ecoli_node_empty.c index e513d6b..5e220aa 100644 --- a/lib/ecoli_node_empty.c +++ b/lib/ecoli_node_empty.c @@ -39,6 +39,8 @@ #include #include +EC_LOG_TYPE_REGISTER(node_empty); + struct ec_node_empty { struct ec_node gen; }; @@ -70,7 +72,7 @@ static int ec_node_empty_testcase(void) node = ec_node("empty", NULL); if (node == NULL) { - ec_log(EC_LOG_ERR, "cannot create node\n"); + EC_LOG(EC_LOG_ERR, "cannot create node\n"); return -1; } ret |= EC_TEST_CHECK_PARSE(node, 0, "foo"); @@ -81,7 +83,7 @@ static int ec_node_empty_testcase(void) /* never completes */ node = ec_node("empty", NULL); if (node == NULL) { - ec_log(EC_LOG_ERR, "cannot create node\n"); + EC_LOG(EC_LOG_ERR, "cannot create node\n"); return -1; } ret |= EC_TEST_CHECK_COMPLETE(node, diff --git a/lib/ecoli_node_expr.c b/lib/ecoli_node_expr.c index e15c296..24bdfd9 100644 --- a/lib/ecoli_node_expr.c +++ b/lib/ecoli_node_expr.c @@ -47,6 +47,8 @@ #include #include +EC_LOG_TYPE_REGISTER(node_expr); + struct ec_node_expr { struct ec_node gen; @@ -91,7 +93,7 @@ static void ec_node_expr_free_priv(struct ec_node *gen_node) struct ec_node_expr *node = (struct ec_node_expr *)gen_node; unsigned int i; - ec_log(EC_LOG_DEBUG, "free %p %p %p\n", node, node->child, node->val_node); + EC_LOG(EC_LOG_DEBUG, "free %p %p %p\n", node, node->child, node->val_node); ec_node_free(node->val_node); for (i = 0; i < node->bin_ops_len; i++) diff --git a/lib/ecoli_node_expr_test.c b/lib/ecoli_node_expr_test.c index c0e149a..748256b 100644 --- a/lib/ecoli_node_expr_test.c +++ b/lib/ecoli_node_expr_test.c @@ -40,6 +40,8 @@ #include #include +EC_LOG_TYPE_REGISTER(node_expr); + struct my_eval_result { int val; }; diff --git a/lib/ecoli_node_file.c b/lib/ecoli_node_file.c index 51badf7..0a78cba 100644 --- a/lib/ecoli_node_file.c +++ b/lib/ecoli_node_file.c @@ -45,6 +45,8 @@ #include #include +EC_LOG_TYPE_REGISTER(node_file); + struct ec_node_file { struct ec_node gen; }; @@ -277,7 +279,7 @@ static int ec_node_file_testcase(void) node = ec_node("file", NULL); if (node == NULL) { - ec_log(EC_LOG_ERR, "cannot create node\n"); + EC_LOG(EC_LOG_ERR, "cannot create node\n"); return -1; } /* any string matches */ diff --git a/lib/ecoli_node_int.c b/lib/ecoli_node_int.c index 635b549..b685f16 100644 --- a/lib/ecoli_node_int.c +++ b/lib/ecoli_node_int.c @@ -43,6 +43,8 @@ #include #include +EC_LOG_TYPE_REGISTER(node_int); + struct ec_node_int { struct ec_node gen; bool check_min; @@ -156,7 +158,7 @@ static int ec_node_int_testcase(void) node = ec_node_int(NULL, 0, 256, 0); if (node == NULL) { - ec_log(EC_LOG_ERR, "cannot create node\n"); + EC_LOG(EC_LOG_ERR, "cannot create node\n"); return -1; } ret |= EC_TEST_CHECK_PARSE(node, 1, "0"); @@ -179,7 +181,7 @@ static int ec_node_int_testcase(void) node = ec_node_int(NULL, -1, LLONG_MAX, 16); if (node == NULL) { - ec_log(EC_LOG_ERR, "cannot create node\n"); + EC_LOG(EC_LOG_ERR, "cannot create node\n"); return -1; } ret |= EC_TEST_CHECK_PARSE(node, 1, "0"); @@ -196,7 +198,7 @@ static int ec_node_int_testcase(void) node = ec_node_int(NULL, LLONG_MIN, 0, 10); if (node == NULL) { - ec_log(EC_LOG_ERR, "cannot create node\n"); + EC_LOG(EC_LOG_ERR, "cannot create node\n"); return -1; } ret |= EC_TEST_CHECK_PARSE(node, 1, "0"); @@ -209,7 +211,7 @@ static int ec_node_int_testcase(void) /* test completion */ node = ec_node_int(NULL, 0, 10, 0); if (node == NULL) { - ec_log(EC_LOG_ERR, "cannot create node\n"); + EC_LOG(EC_LOG_ERR, "cannot create node\n"); return -1; } ret |= EC_TEST_CHECK_COMPLETE(node, diff --git a/lib/ecoli_node_many.c b/lib/ecoli_node_many.c index 8746269..b40b3bd 100644 --- a/lib/ecoli_node_many.c +++ b/lib/ecoli_node_many.c @@ -43,6 +43,8 @@ #include #include +EC_LOG_TYPE_REGISTER(node_many); + struct ec_node_many { struct ec_node gen; unsigned int min; @@ -224,7 +226,7 @@ static int ec_node_many_testcase(void) node = ec_node_many(NULL, ec_node_str(NULL, "foo"), 0, 0); if (node == NULL) { - ec_log(EC_LOG_ERR, "cannot create node\n"); + EC_LOG(EC_LOG_ERR, "cannot create node\n"); return -1; } ret |= EC_TEST_CHECK_PARSE(node, 0); @@ -236,7 +238,7 @@ static int ec_node_many_testcase(void) node = ec_node_many(NULL, ec_node_str(NULL, "foo"), 1, 0); if (node == NULL) { - ec_log(EC_LOG_ERR, "cannot create node\n"); + EC_LOG(EC_LOG_ERR, "cannot create node\n"); return -1; } ret |= EC_TEST_CHECK_PARSE(node, -1, "bar"); @@ -247,7 +249,7 @@ static int ec_node_many_testcase(void) node = ec_node_many(NULL, ec_node_str(NULL, "foo"), 1, 2); if (node == NULL) { - ec_log(EC_LOG_ERR, "cannot create node\n"); + EC_LOG(EC_LOG_ERR, "cannot create node\n"); return -1; } ret |= EC_TEST_CHECK_PARSE(node, -1, "bar"); @@ -260,7 +262,7 @@ static int ec_node_many_testcase(void) /* test completion */ node = ec_node_many(NULL, ec_node_str(NULL, "foo"), 2, 4); if (node == NULL) { - ec_log(EC_LOG_ERR, "cannot create node\n"); + EC_LOG(EC_LOG_ERR, "cannot create node\n"); return -1; } ret |= EC_TEST_CHECK_COMPLETE(node, diff --git a/lib/ecoli_node_once.c b/lib/ecoli_node_once.c index d52e099..54aa67b 100644 --- a/lib/ecoli_node_once.c +++ b/lib/ecoli_node_once.c @@ -44,6 +44,8 @@ #include #include +EC_LOG_TYPE_REGISTER(node_once); + struct ec_node_once { struct ec_node gen; struct ec_node *child; @@ -176,7 +178,7 @@ static int ec_node_once_testcase(void) ), 0, 0 ); if (node == NULL) { - ec_log(EC_LOG_ERR, "cannot create node\n"); + EC_LOG(EC_LOG_ERR, "cannot create node\n"); return -1; } ret |= EC_TEST_CHECK_PARSE(node, 0); @@ -201,7 +203,7 @@ static int ec_node_once_testcase(void) ec_node_str(NULL, "titi") ); if (node == NULL) { - ec_log(EC_LOG_ERR, "cannot create node\n"); + EC_LOG(EC_LOG_ERR, "cannot create node\n"); return -1; } ret |= EC_TEST_CHECK_COMPLETE(node, diff --git a/lib/ecoli_node_option.c b/lib/ecoli_node_option.c index ee2c4b1..1dcdd88 100644 --- a/lib/ecoli_node_option.c +++ b/lib/ecoli_node_option.c @@ -41,6 +41,8 @@ #include #include +EC_LOG_TYPE_REGISTER(node_option); + struct ec_node_option { struct ec_node gen; struct ec_node *child; @@ -122,7 +124,7 @@ static int ec_node_option_testcase(void) node = ec_node_option(NULL, ec_node_str(NULL, "foo")); if (node == NULL) { - ec_log(EC_LOG_ERR, "cannot create node\n"); + EC_LOG(EC_LOG_ERR, "cannot create node\n"); return -1; } ret |= EC_TEST_CHECK_PARSE(node, 1, "foo"); @@ -134,7 +136,7 @@ static int ec_node_option_testcase(void) /* test completion */ node = ec_node_option(NULL, ec_node_str(NULL, "foo")); if (node == NULL) { - ec_log(EC_LOG_ERR, "cannot create node\n"); + EC_LOG(EC_LOG_ERR, "cannot create node\n"); return -1; } ret |= EC_TEST_CHECK_COMPLETE(node, diff --git a/lib/ecoli_node_or.c b/lib/ecoli_node_or.c index 391d84e..963f970 100644 --- a/lib/ecoli_node_or.c +++ b/lib/ecoli_node_or.c @@ -42,6 +42,8 @@ #include #include +EC_LOG_TYPE_REGISTER(node_or); + struct ec_node_or { struct ec_node gen; struct ec_node **table; @@ -200,7 +202,7 @@ static int ec_node_or_testcase(void) ec_node_str(NULL, "bar") ); if (node == NULL) { - ec_log(EC_LOG_ERR, "cannot create node\n"); + EC_LOG(EC_LOG_ERR, "cannot create node\n"); return -1; } ret |= EC_TEST_CHECK_PARSE(node, 1, "foo"); @@ -221,7 +223,7 @@ static int ec_node_or_testcase(void) ec_node_str(NULL, "titi") ); if (node == NULL) { - ec_log(EC_LOG_ERR, "cannot create node\n"); + EC_LOG(EC_LOG_ERR, "cannot create node\n"); return -1; } ret |= EC_TEST_CHECK_COMPLETE(node, diff --git a/lib/ecoli_node_re.c b/lib/ecoli_node_re.c index 5bcc407..7444aa7 100644 --- a/lib/ecoli_node_re.c +++ b/lib/ecoli_node_re.c @@ -40,6 +40,8 @@ #include #include +EC_LOG_TYPE_REGISTER(node_re); + struct ec_node_re { struct ec_node gen; char *re_str; @@ -146,7 +148,7 @@ static int ec_node_re_testcase(void) node = ec_node_re(NULL, "fo+|bar"); if (node == NULL) { - ec_log(EC_LOG_ERR, "cannot create node\n"); + EC_LOG(EC_LOG_ERR, "cannot create node\n"); return -1; } ret |= EC_TEST_CHECK_PARSE(node, 1, "foo"); diff --git a/lib/ecoli_node_re_lex.c b/lib/ecoli_node_re_lex.c index 2de1c64..669c9fb 100644 --- a/lib/ecoli_node_re_lex.c +++ b/lib/ecoli_node_re_lex.c @@ -17,6 +17,8 @@ #include #include +EC_LOG_TYPE_REGISTER(node_re_lex); + struct regexp_pattern { char *pattern; regex_t r; @@ -65,7 +67,7 @@ tokenize(struct regexp_pattern *table, size_t table_len, const char *str) c = dup[pos.rm_eo + off]; dup[pos.rm_eo + off] = '\0'; - ec_log(EC_LOG_DEBUG, "re_lex match <%s>\n", &dup[off]); + EC_LOG(EC_LOG_DEBUG, "re_lex match <%s>\n", &dup[off]); if (ec_strvec_add(strvec, &dup[off]) < 0) goto fail; @@ -175,7 +177,7 @@ int ec_node_re_lex_add(struct ec_node *gen_node, const char *pattern, int keep) ret = regcomp(&table[node->len].r, pattern, REG_EXTENDED); if (ret != 0) { - ec_log(EC_LOG_ERR, + EC_LOG(EC_LOG_ERR, "Regular expression <%s> compilation failed: %d\n", pattern, ret); if (ret == REG_ESPACE) @@ -232,7 +234,7 @@ static int ec_node_re_lex_testcase(void) ) ); if (node == NULL) { - ec_log(EC_LOG_ERR, "cannot create node\n"); + EC_LOG(EC_LOG_ERR, "cannot create node\n"); return -1; } @@ -244,7 +246,7 @@ static int ec_node_re_lex_testcase(void) ret |= ec_node_re_lex_add(node, "\\+", 1); ret |= ec_node_re_lex_add(node, "[ ]+", 0); if (ret != 0) { - ec_log(EC_LOG_ERR, "cannot add regexp to node\n"); + EC_LOG(EC_LOG_ERR, "cannot add regexp to node\n"); ec_node_free(node); return -1; } diff --git a/lib/ecoli_node_seq.c b/lib/ecoli_node_seq.c index 7b22709..9240e4f 100644 --- a/lib/ecoli_node_seq.c +++ b/lib/ecoli_node_seq.c @@ -46,6 +46,8 @@ #include #include +EC_LOG_TYPE_REGISTER(node_seq); + struct ec_node_seq { struct ec_node gen; struct ec_node **table; @@ -293,7 +295,7 @@ static int ec_node_seq_testcase(void) ec_node_str(NULL, "bar") ); if (node == NULL) { - ec_log(EC_LOG_ERR, "cannot create node\n"); + EC_LOG(EC_LOG_ERR, "cannot create node\n"); return -1; } ret |= EC_TEST_CHECK_PARSE(node, 2, "foo", "bar"); @@ -312,7 +314,7 @@ static int ec_node_seq_testcase(void) ec_node_str(NULL, "bar") ); if (node == NULL) { - ec_log(EC_LOG_ERR, "cannot create node\n"); + EC_LOG(EC_LOG_ERR, "cannot create node\n"); return -1; } ret |= EC_TEST_CHECK_COMPLETE(node, diff --git a/lib/ecoli_node_sh_lex.c b/lib/ecoli_node_sh_lex.c index 1da0a90..87b3175 100644 --- a/lib/ecoli_node_sh_lex.c +++ b/lib/ecoli_node_sh_lex.c @@ -45,6 +45,8 @@ #include #include +EC_LOG_TYPE_REGISTER(node_sh_lex); + struct ec_node_sh_lex { struct ec_node gen; struct ec_node *child; @@ -157,8 +159,6 @@ static struct ec_strvec *tokenize(const char *str, int completion, char *word = NULL, *concat = NULL, *tmp; int last_is_space = 1; -// printf("str=%s\n", str); - strvec = ec_strvec(); if (strvec == NULL) goto fail; @@ -167,7 +167,6 @@ static struct ec_strvec *tokenize(const char *str, int completion, len = eat_spaces(&str[off]); if (len > 0) last_is_space = 1; -// printf("space=%zd\n", len); off += len; len = 0; @@ -176,12 +175,10 @@ static struct ec_strvec *tokenize(const char *str, int completion, last_is_space = 0; if (str[suboff] == '"' || str[suboff] == '\'') { sublen = eat_quoted_str(&str[suboff]); -// printf("sublen=%zd\n", sublen); word = unquote_str(&str[suboff], sublen, allow_missing_quote, missing_quote); } else { sublen = eat_str(&str[suboff]); -// printf("sublen=%zd\n", sublen); if (sublen == 0) break; word = ec_strndup(&str[suboff], sublen); @@ -189,7 +186,6 @@ static struct ec_strvec *tokenize(const char *str, int completion, if (word == NULL) goto fail; -// printf("word=%s\n", word); len += sublen; suboff += sublen; @@ -302,8 +298,8 @@ ec_node_sh_lex_complete(const struct ec_node *gen_node, goto fail; // printf("new:%s\n", ec_strvec_val(new_vec, 0)); - // XXX: complete should add the quotes for !EC_PARTIAL: use another - // completed object + // XXX: complete should add the quotes for !EC_PARTIAL + // XXX: if no quotes, replace " " by "\ " ret = ec_node_complete_child(node->child, completed, parsed, new_vec); if (ret < 0) goto fail; @@ -368,7 +364,7 @@ static int ec_node_sh_lex_testcase(void) ) ); if (node == NULL) { - ec_log(EC_LOG_ERR, "cannot create node\n"); + EC_LOG(EC_LOG_ERR, "cannot create node\n"); return -1; } ret |= EC_TEST_CHECK_PARSE(node, 1, "foo bar"); @@ -390,7 +386,7 @@ static int ec_node_sh_lex_testcase(void) ) ); if (node == NULL) { - ec_log(EC_LOG_ERR, "cannot create node\n"); + EC_LOG(EC_LOG_ERR, "cannot create node\n"); return -1; } ret |= EC_TEST_CHECK_COMPLETE(node, diff --git a/lib/ecoli_node_space.c b/lib/ecoli_node_space.c index 48ffb6e..0552d1b 100644 --- a/lib/ecoli_node_space.c +++ b/lib/ecoli_node_space.c @@ -39,6 +39,8 @@ #include #include +EC_LOG_TYPE_REGISTER(node_space); + struct ec_node_space { struct ec_node gen; }; @@ -83,7 +85,7 @@ static int ec_node_space_testcase(void) node = ec_node("space", NULL); if (node == NULL) { - ec_log(EC_LOG_ERR, "cannot create node\n"); + EC_LOG(EC_LOG_ERR, "cannot create node\n"); return -1; } ret |= EC_TEST_CHECK_PARSE(node, 1, " "); @@ -96,7 +98,7 @@ static int ec_node_space_testcase(void) /* test completion */ node = ec_node("space", NULL); if (node == NULL) { - ec_log(EC_LOG_ERR, "cannot create node\n"); + EC_LOG(EC_LOG_ERR, "cannot create node\n"); return -1; } /* never completes whatever the input */ diff --git a/lib/ecoli_node_str.c b/lib/ecoli_node_str.c index 0069c83..483f63c 100644 --- a/lib/ecoli_node_str.c +++ b/lib/ecoli_node_str.c @@ -39,6 +39,8 @@ #include #include +EC_LOG_TYPE_REGISTER(node_str); + struct ec_node_str { struct ec_node gen; char *string; @@ -186,7 +188,7 @@ static int ec_node_str_testcase(void) /* XXX use EC_NO_ID instead of NULL */ node = ec_node_str(NULL, "foo"); if (node == NULL) { - ec_log(EC_LOG_ERR, "cannot create node\n"); + EC_LOG(EC_LOG_ERR, "cannot create node\n"); return -1; } ret |= EC_TEST_CHECK_PARSE(node, 1, "foo"); @@ -198,7 +200,7 @@ static int ec_node_str_testcase(void) node = ec_node_str(NULL, "Здравствуйте"); if (node == NULL) { - ec_log(EC_LOG_ERR, "cannot create node\n"); + EC_LOG(EC_LOG_ERR, "cannot create node\n"); return -1; } ret |= EC_TEST_CHECK_PARSE(node, 1, "Здравствуйте"); @@ -211,7 +213,7 @@ static int ec_node_str_testcase(void) /* an empty string node always matches */ node = ec_node_str(NULL, ""); if (node == NULL) { - ec_log(EC_LOG_ERR, "cannot create node\n"); + EC_LOG(EC_LOG_ERR, "cannot create node\n"); return -1; } ret |= EC_TEST_CHECK_PARSE(node, 1, ""); @@ -222,7 +224,7 @@ static int ec_node_str_testcase(void) /* test completion */ node = ec_node_str(NULL, "foo"); if (node == NULL) { - ec_log(EC_LOG_ERR, "cannot create node\n"); + EC_LOG(EC_LOG_ERR, "cannot create node\n"); return -1; } ret |= EC_TEST_CHECK_COMPLETE(node, diff --git a/lib/ecoli_node_subset.c b/lib/ecoli_node_subset.c index 1bd7a12..1803b4d 100644 --- a/lib/ecoli_node_subset.c +++ b/lib/ecoli_node_subset.c @@ -44,6 +44,8 @@ #include #include +EC_LOG_TYPE_REGISTER(node_subset); + struct ec_node_subset { struct ec_node gen; struct ec_node **table; @@ -356,7 +358,7 @@ static int ec_node_subset_testcase(void) ec_node_str(NULL, "toto") ); if (node == NULL) { - ec_log(EC_LOG_ERR, "cannot create node\n"); + EC_LOG(EC_LOG_ERR, "cannot create node\n"); return -1; } ret |= EC_TEST_CHECK_PARSE(node, 0); @@ -380,7 +382,7 @@ static int ec_node_subset_testcase(void) ec_node_str(NULL, "titi") ); if (node == NULL) { - ec_log(EC_LOG_ERR, "cannot create node\n"); + EC_LOG(EC_LOG_ERR, "cannot create node\n"); return -1; } ret |= EC_TEST_CHECK_COMPLETE(node, diff --git a/lib/ecoli_node_weakref.c b/lib/ecoli_node_weakref.c index 73da26b..eacec4c 100644 --- a/lib/ecoli_node_weakref.c +++ b/lib/ecoli_node_weakref.c @@ -43,6 +43,8 @@ #include #include +EC_LOG_TYPE_REGISTER(node_weakref); + struct ec_node_weakref { struct ec_node gen; struct ec_node *child; diff --git a/lib/ecoli_parsed.h b/lib/ecoli_parsed.h index 637059a..1a246ce 100644 --- a/lib/ecoli_parsed.h +++ b/lib/ecoli_parsed.h @@ -39,6 +39,7 @@ TAILQ_HEAD(ec_parsed_list, ec_parsed); /* node == NULL + empty children list means "no match" + XXX still valid? */ struct ec_parsed { TAILQ_ENTRY(ec_parsed) next; @@ -46,6 +47,7 @@ struct ec_parsed { struct ec_parsed *parent; const struct ec_node *node; struct ec_strvec *strvec; + /* XXX add a keyval (attrs) */ }; struct ec_parsed *ec_parsed(void); @@ -56,7 +58,8 @@ const struct ec_strvec *ec_parsed_strvec(const struct ec_parsed *parsed); /* XXX we could use a cache to store possible completions or match: the * cache would be per-node, and would be reset for each call to parse() - * or complete() ? */ + * or complete() ? ... not sure, since parse result can depend on state + */ /* a NULL return value is an error, with errno set ENOTSUP: no ->parse() operation */ diff --git a/lib/ecoli_test.c b/lib/ecoli_test.c index 291417d..53cdf62 100644 --- a/lib/ecoli_test.c +++ b/lib/ecoli_test.c @@ -41,6 +41,8 @@ static struct ec_test_list test_list = TAILQ_HEAD_INITIALIZER(test_list); +EC_LOG_TYPE_REGISTER(test); + /* register a driver */ void ec_test_register(struct ec_test *test) { @@ -76,7 +78,7 @@ int ec_test_check_parse(struct ec_node *tk, int expected, ...) p = ec_node_parse_strvec(tk, vec); ec_parsed_dump(stdout, p); /* XXX only for debug */ if (p == NULL) { - ec_log(EC_LOG_ERR, "parsed is NULL\n"); + EC_LOG(EC_LOG_ERR, "parsed is NULL\n"); } if (ec_parsed_matches(p)) match = ec_parsed_len(p); @@ -85,7 +87,7 @@ int ec_test_check_parse(struct ec_node *tk, int expected, ...) if (expected == match) { ret = 0; } else { - ec_log(EC_LOG_ERR, + EC_LOG(EC_LOG_ERR, "tk parsed len (%d) does not match expected (%d)\n", match, expected); } @@ -152,7 +154,7 @@ int ec_test_check_complete(struct ec_node *tk, ...) } if (item == NULL) { - ec_log(EC_LOG_ERR, + EC_LOG(EC_LOG_ERR, "completion <%s> not in list\n", s); ret = -1; } @@ -161,7 +163,7 @@ int ec_test_check_complete(struct ec_node *tk, ...) /* check if we have more completions (or less) than expected */ if (count != ec_completed_count(c, EC_MATCH)) { - ec_log(EC_LOG_ERR, + EC_LOG(EC_LOG_ERR, "nb_completion (%d) does not match (%d)\n", count, ec_completed_count(c, EC_MATCH)); ec_completed_dump(stdout, c); @@ -186,21 +188,25 @@ static int launch_test(const char *name) if (name != NULL && strcmp(name, test->name)) continue; - ec_log(EC_LOG_INFO, "== starting test %-20s\n", test->name); + EC_LOG(EC_LOG_INFO, "== starting test %-20s\n", + test->name); count++; if (test->test() == 0) { - ec_log(EC_LOG_INFO, "== test %-20s success\n", + EC_LOG(EC_LOG_INFO, + "== test %-20s success\n", test->name); } else { - ec_log(EC_LOG_INFO, "== test %-20s failed\n", + EC_LOG(EC_LOG_INFO, + "== test %-20s failed\n", test->name); ret = -1; } } if (name != NULL && count == 0) { - ec_log(EC_LOG_WARNING, "== test %s not found\n", name); + EC_LOG(EC_LOG_WARNING, + "== test %s not found\n", name); ret = -1; } diff --git a/lib/ecoli_test.h b/lib/ecoli_test.h index 0115837..1fa8480 100644 --- a/lib/ecoli_test.h +++ b/lib/ecoli_test.h @@ -74,10 +74,10 @@ int ec_test_one(const char *name); int ec_test_check_parse(struct ec_node *node, int expected, ...); #define EC_TEST_ERR(fmt, ...) \ - ec_log(EC_LOG_ERR, "%s:%d: error: " fmt "\n", \ + EC_LOG(EC_LOG_ERR, "%s:%d: error: " fmt "\n", \ __FILE__, __LINE__, ##__VA_ARGS__); \ -#define EC_TEST_ASSERT(cond, args...) \ +#define EC_TEST_ASSERT(cond) \ do { \ if (!(cond)) \ EC_TEST_ERR("assertion failure: " #cond); \ diff --git a/lib/ecoli_vec.c b/lib/ecoli_vec.c index 8038b31..001891e 100644 --- a/lib/ecoli_vec.c +++ b/lib/ecoli_vec.c @@ -37,6 +37,8 @@ #include #include +EC_LOG_TYPE_REGISTER(vec); + struct ec_vec { size_t len; size_t size; @@ -223,7 +225,7 @@ static void str_free(void *elt) } #define GOTO_FAIL do { \ - ec_log(EC_LOG_ERR, "%s:%d: test failed\n", \ + EC_LOG(EC_LOG_ERR, "%s:%d: test failed\n", \ __FILE__, __LINE__); \ goto fail; \ } while(0) diff --git a/lib/main-readline.c b/lib/main-readline.c index a63adfc..8fecad4 100644 --- a/lib/main-readline.c +++ b/lib/main-readline.c @@ -205,7 +205,6 @@ static int show_help(int ignore, int invoking_key) helps[i++] = get_node_help(compnode); } - ec_completed_dump(stdout, c); ec_completed_free(c); rl_display_match_list(helps, count + match, 1000); /* XXX 1000 */ diff --git a/lib/main.c b/lib/main.c index 51b0946..56bc9d9 100644 --- a/lib/main.c +++ b/lib/main.c @@ -36,6 +36,8 @@ #include #include +EC_LOG_TYPE_REGISTER(main); + #define COUNT_OF(x) ((sizeof(x)/sizeof(0[x])) / \ ((size_t)(!(sizeof(x) % sizeof(0[x]))))) @@ -199,7 +201,7 @@ 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) @@ -215,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(); } @@ -240,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(); } @@ -260,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(); @@ -268,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(); @@ -280,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(); } @@ -313,7 +315,7 @@ 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) @@ -327,35 +329,37 @@ static int debug_alloc_dump_leaks(void) int i; char **buffer; - ec_log(EC_LOG_INFO, "%zd successful allocations\n", alloc_success); + 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 \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) @@ -377,12 +381,12 @@ int main(int argc, char **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; } diff --git a/lib/todo.txt b/lib/todo.txt index 8d56dc5..37a61d7 100644 --- a/lib/todo.txt +++ b/lib/todo.txt @@ -9,9 +9,6 @@ X tk_re cleanup / rework ================ -- ec_completed_item_update() -- ec_completed_item_set_display_value() - - add_no_match - add_partial_match - check XXX in code -- 2.39.5