dynamic log types
authorOlivier Matz <zer0@droids-corp.org>
Thu, 9 Nov 2017 16:46:52 +0000 (17:46 +0100)
committerOlivier Matz <zer0@droids-corp.org>
Thu, 9 Nov 2017 16:46:52 +0000 (17:46 +0100)
30 files changed:
lib/ecoli_completed.h
lib/ecoli_keyval.c
lib/ecoli_log.c
lib/ecoli_log.h
lib/ecoli_node.c
lib/ecoli_node_cmd.c
lib/ecoli_node_empty.c
lib/ecoli_node_expr.c
lib/ecoli_node_expr_test.c
lib/ecoli_node_file.c
lib/ecoli_node_int.c
lib/ecoli_node_many.c
lib/ecoli_node_once.c
lib/ecoli_node_option.c
lib/ecoli_node_or.c
lib/ecoli_node_re.c
lib/ecoli_node_re_lex.c
lib/ecoli_node_seq.c
lib/ecoli_node_sh_lex.c
lib/ecoli_node_space.c
lib/ecoli_node_str.c
lib/ecoli_node_subset.c
lib/ecoli_node_weakref.c
lib/ecoli_parsed.h
lib/ecoli_test.c
lib/ecoli_test.h
lib/ecoli_vec.c
lib/main-readline.c
lib/main.c
lib/todo.txt

index 16c79a6..1627cfe 100644 (file)
@@ -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;
index c1d881f..a47ded9 100644 (file)
@@ -35,6 +35,8 @@
 #include <ecoli_test.h>
 #include <ecoli_keyval.h>
 
+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;
        }
 
index 53c3acb..3b9d69e 100644 (file)
 #include <string.h>
 #include <errno.h>
 
+#include <ecoli_malloc.h>
 #include <ecoli_log.h>
 
 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;
index 089254f..e117af1 100644 (file)
 
 #include <stdarg.h>
 
+#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
index 8ff05ab..6cd95d7 100644 (file)
@@ -38,6 +38,8 @@
 #include <ecoli_log.h>
 #include <ecoli_node.h>
 
+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;
        }
 
index 9f14ae2..db08cbf 100644 (file)
@@ -53,6 +53,8 @@
 #include <ecoli_node_re_lex.h>
 #include <ecoli_node_cmd.h>
 
+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");
index e513d6b..5e220aa 100644 (file)
@@ -39,6 +39,8 @@
 #include <ecoli_completed.h>
 #include <ecoli_node_empty.h>
 
+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,
index e15c296..24bdfd9 100644 (file)
@@ -47,6 +47,8 @@
 #include <ecoli_node_weakref.h>
 #include <ecoli_node_expr.h>
 
+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++)
index c0e149a..748256b 100644 (file)
@@ -40,6 +40,8 @@
 #include <ecoli_node_re_lex.h>
 #include <ecoli_node_expr.h>
 
+EC_LOG_TYPE_REGISTER(node_expr);
+
 struct my_eval_result {
        int val;
 };
index 51badf7..0a78cba 100644 (file)
@@ -45,6 +45,8 @@
 #include <ecoli_completed.h>
 #include <ecoli_node_file.h>
 
+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 */
index 635b549..b685f16 100644 (file)
@@ -43,6 +43,8 @@
 #include <ecoli_node_int.h>
 #include <ecoli_test.h>
 
+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,
index 8746269..b40b3bd 100644 (file)
@@ -43,6 +43,8 @@
 #include <ecoli_node_option.h>
 #include <ecoli_node_many.h>
 
+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,
index d52e099..54aa67b 100644 (file)
@@ -44,6 +44,8 @@
 #include <ecoli_node_many.h>
 #include <ecoli_node_once.h>
 
+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,
index ee2c4b1..1dcdd88 100644 (file)
@@ -41,6 +41,8 @@
 #include <ecoli_node_str.h>
 #include <ecoli_test.h>
 
+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,
index 391d84e..963f970 100644 (file)
@@ -42,6 +42,8 @@
 #include <ecoli_node_str.h>
 #include <ecoli_test.h>
 
+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,
index 5bcc407..7444aa7 100644 (file)
@@ -40,6 +40,8 @@
 #include <ecoli_completed.h>
 #include <ecoli_node_re.h>
 
+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");
index 2de1c64..669c9fb 100644 (file)
@@ -17,6 +17,8 @@
 #include <ecoli_node_int.h>
 #include <ecoli_node_re_lex.h>
 
+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;
        }
index 7b22709..9240e4f 100644 (file)
@@ -46,6 +46,8 @@
 #include <ecoli_node_many.h>
 #include <ecoli_node_seq.h>
 
+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,
index 1da0a90..87b3175 100644 (file)
@@ -45,6 +45,8 @@
 #include <ecoli_node_option.h>
 #include <ecoli_node_sh_lex.h>
 
+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,
index 48ffb6e..0552d1b 100644 (file)
@@ -39,6 +39,8 @@
 #include <ecoli_completed.h>
 #include <ecoli_node_space.h>
 
+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 */
index 0069c83..483f63c 100644 (file)
@@ -39,6 +39,8 @@
 #include <ecoli_completed.h>
 #include <ecoli_node_str.h>
 
+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,
index 1bd7a12..1803b4d 100644 (file)
@@ -44,6 +44,8 @@
 #include <ecoli_node_or.h>
 #include <ecoli_test.h>
 
+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,
index 73da26b..eacec4c 100644 (file)
@@ -43,6 +43,8 @@
 #include <ecoli_node_option.h>
 #include <ecoli_node_weakref.h>
 
+EC_LOG_TYPE_REGISTER(node_weakref);
+
 struct ec_node_weakref {
        struct ec_node gen;
        struct ec_node *child;
index 637059a..1a246ce 100644 (file)
@@ -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
 */
index 291417d..53cdf62 100644 (file)
@@ -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;
        }
 
index 0115837..1fa8480 100644 (file)
@@ -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);       \
index 8038b31..001891e 100644 (file)
@@ -37,6 +37,8 @@
 #include <ecoli_test.h>
 #include <ecoli_vec.h>
 
+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)
index a63adfc..8fecad4 100644 (file)
@@ -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 */
index 51b0946..56bc9d9 100644 (file)
@@ -36,6 +36,8 @@
 #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])))))
 
@@ -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 <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)
@@ -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;
        }
 
index 8d56dc5..37a61d7 100644 (file)
@@ -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