From 538ee5ebd89490777cf1022e89438bde7d3adcdb Mon Sep 17 00:00:00 2001 From: Olivier Matz Date: Thu, 1 Dec 2016 20:15:09 +0100 Subject: [PATCH] continue ! --- lib/Makefile | 3 +- lib/build/test | Bin 106896 -> 145552 bytes lib/ecoli_keyval.c | 231 ++++++++++++++++++++++++++++++++++++++++++++ lib/ecoli_keyval.h | 48 +++++++++ lib/ecoli_malloc.c | 10 ++ lib/ecoli_malloc.h | 4 + lib/ecoli_strvec.c | 2 + lib/ecoli_test.c | 4 +- lib/ecoli_test.h | 16 ++- lib/ecoli_tk.c | 80 +++++++++++++-- lib/ecoli_tk.h | 43 +++++++-- lib/ecoli_tk_int.c | 21 +--- lib/ecoli_tk_or.c | 3 + lib/ecoli_tk_seq.c | 3 + lib/ecoli_tk_str.c | 8 ++ lib/main-readline.c | 117 +++++++++++++++++++--- 16 files changed, 535 insertions(+), 58 deletions(-) create mode 100644 lib/ecoli_keyval.c create mode 100644 lib/ecoli_keyval.h diff --git a/lib/Makefile b/lib/Makefile index 28fce46..9bbd73b 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -34,6 +34,7 @@ CFLAGS = -g -O0 -Wall -Werror -W -fPIC CFLAGS += -I. srcs := ecoli_tk.c ecoli_malloc.c ecoli_log.c ecoli_strvec.c +srcs += ecoli_keyval.c srcs += ecoli_tk_str.c ecoli_tk_seq.c srcs += ecoli_tk_space.c ecoli_tk_or.c ecoli_test.c srcs += ecoli_tk_empty.c ecoli_tk_int.c @@ -44,7 +45,7 @@ shlib-y-$(O)libecoli.so := $(srcs) ldflags-$(O)test = -rdynamic exe-y-$(O)test = $(srcs) main.c -ldflags-$(O)readline = -lreadline +ldflags-$(O)readline = -lreadline -ltermcap exe-y-$(O)readline = $(srcs) main-readline.c include $(ECOLI)/mk/ecoli-post.mk diff --git a/lib/build/test b/lib/build/test index 3e62c758853c8078587bfebad7fa696ddb4b5ac2..e389ed25681e7c31cbaf9569e3d6dd08dce9392b 100755 GIT binary patch literal 145552 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 literal 106896 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 diff --git a/lib/ecoli_keyval.c b/lib/ecoli_keyval.c new file mode 100644 index 0000000..8275715 --- /dev/null +++ b/lib/ecoli_keyval.c @@ -0,0 +1,231 @@ +/* + * Copyright (c) 2016, Olivier MATZ + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the University of California, Berkeley nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include + +#include +#include +#include +#include + +struct ec_keyval { + size_t len; + struct ec_keyval_elt *vec; +}; + +struct ec_keyval_elt { + char *key; + void *val; + ec_keyval_elt_free_t free; +}; + +struct ec_keyval *ec_keyval_new(void) +{ + struct ec_keyval *keyval; + + keyval = ec_calloc(1, sizeof(*keyval)); + if (keyval == NULL) + return NULL; + + return keyval; +} + +static struct ec_keyval_elt *ec_keyval_lookup(const struct ec_keyval *keyval, + const char *key) +{ + struct ec_keyval_elt *elt; + size_t i; + + if (keyval == NULL || keyval->vec == NULL) + return NULL; + + for (i = 0; i < ec_keyval_len(keyval); i++) { + elt = &keyval->vec[i]; + if (strcmp(elt->key, key) == 0) + return elt; + } + + return NULL; +} + +static void ec_keyval_elt_free(struct ec_keyval_elt *elt) +{ + if (elt == NULL) + return; + + ec_free(elt->key); + if (elt->free != NULL) + elt->free(elt->val); +} + +void *ec_keyval_get(const struct ec_keyval *keyval, const char *key) +{ + struct ec_keyval_elt *elt; + + elt = ec_keyval_lookup(keyval, key); + if (elt == NULL) + return NULL; + + return elt->val; +} + +int ec_keyval_del(struct ec_keyval *keyval, const char *key) +{ + struct ec_keyval_elt *elt; + struct ec_keyval_elt *last = &keyval->vec[keyval->len - 1]; + + elt = ec_keyval_lookup(keyval, key); + if (elt == NULL) + return -ENOENT; + + ec_keyval_elt_free(elt); + + if (elt != last) + memcpy(elt, last, sizeof(*elt)); + + keyval->len--; + + return 0; +} + +int ec_keyval_set(struct ec_keyval *keyval, const char *key, void *val, + ec_keyval_elt_free_t free_cb) +{ + struct ec_keyval_elt *new_vec; + struct ec_keyval_elt *elt; + + assert(keyval != NULL); + assert(key != NULL); + + ec_keyval_del(keyval, key); + + new_vec = ec_realloc(keyval->vec, + sizeof(*keyval->vec) * (keyval->len + 1)); + if (new_vec == NULL) + return -ENOMEM; + + keyval->vec = new_vec; + + elt = &new_vec[keyval->len]; + elt->key = ec_strdup(key); + if (elt->key == NULL) + return -ENOMEM; + + elt->val = val; + elt->free = free_cb; + keyval->len++; + + return 0; +} + +void ec_keyval_free(struct ec_keyval *keyval) +{ + struct ec_keyval_elt *elt; + size_t i; + + if (keyval == NULL) + return; + + for (i = 0; i < ec_keyval_len(keyval); i++) { + elt = &keyval->vec[i]; + ec_keyval_elt_free(elt); + } + ec_free(keyval->vec); + ec_free(keyval); +} + +size_t ec_keyval_len(const struct ec_keyval *keyval) +{ + return keyval->len; +} + +void ec_keyval_dump(const struct ec_keyval *keyval, FILE *out) +{ + size_t i; + + if (keyval == NULL) { + fprintf(out, "empty keyval\n"); + return; + } + + fprintf(out, "keyval:\n"); + for (i = 0; i < ec_keyval_len(keyval); i++) { + fprintf(out, " %s: %p\n", + keyval->vec[i].key, + keyval->vec[i].val); + } +} + +static int ec_keyval_testcase(void) +{ + struct ec_keyval *keyval; + char *val; + + keyval = ec_keyval_new(); + if (keyval == NULL) { + ec_log(EC_LOG_ERR, "cannot create keyval\n"); + return -1; + } + + EC_TEST_ASSERT(ec_keyval_len(keyval) == 0); + ec_keyval_set(keyval, "key1", "val1", NULL); + ec_keyval_set(keyval, "key2", ec_strdup("val2"), ec_free2); + EC_TEST_ASSERT(ec_keyval_len(keyval) == 2); + + val = ec_keyval_get(keyval, "key1"); + EC_TEST_ASSERT(val != NULL && !strcmp(val, "val1")); + val = ec_keyval_get(keyval, "key2"); + EC_TEST_ASSERT(val != NULL && !strcmp(val, "val2")); + val = ec_keyval_get(keyval, "key3"); + EC_TEST_ASSERT(val == NULL); + + ec_keyval_set(keyval, "key1", "another_val1", NULL); + ec_keyval_set(keyval, "key2", ec_strdup("another_val2"), ec_free2); + EC_TEST_ASSERT(ec_keyval_len(keyval) == 2); + + val = ec_keyval_get(keyval, "key1"); + EC_TEST_ASSERT(val != NULL && !strcmp(val, "another_val1")); + val = ec_keyval_get(keyval, "key2"); + EC_TEST_ASSERT(val != NULL && !strcmp(val, "another_val2")); + + ec_keyval_del(keyval, "key1"); + EC_TEST_ASSERT(ec_keyval_len(keyval) == 1); + + ec_keyval_free(keyval); + + return 0; +} + +static struct ec_test ec_keyval_test = { + .name = "keyval", + .test = ec_keyval_testcase, +}; + +EC_REGISTER_TEST(ec_keyval_test); diff --git a/lib/ecoli_keyval.h b/lib/ecoli_keyval.h new file mode 100644 index 0000000..f0076cf --- /dev/null +++ b/lib/ecoli_keyval.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2016, Olivier MATZ + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of the University of California, Berkeley nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef ECOLI_KEYVAL_ +#define ECOLI_KEYVAL_ + +#include + +typedef void (*ec_keyval_elt_free_t)(void *); + +struct ec_keyval; + +struct ec_keyval *ec_keyval_new(void); + +void *ec_keyval_get(const struct ec_keyval *keyval, const char *key); +int ec_keyval_del(struct ec_keyval *keyval, const char *key); +int ec_keyval_set(struct ec_keyval *keyval, const char *key, void *val, + ec_keyval_elt_free_t free_cb); + +void ec_keyval_free(struct ec_keyval *keyval); +size_t ec_keyval_len(const struct ec_keyval *keyval); +void ec_keyval_dump(const struct ec_keyval *keyval, FILE *out); + +#endif diff --git a/lib/ecoli_malloc.c b/lib/ecoli_malloc.c index 0871247..0768cab 100644 --- a/lib/ecoli_malloc.c +++ b/lib/ecoli_malloc.c @@ -59,11 +59,21 @@ void *__ec_malloc(size_t size, const char *file, unsigned int line) return ec_malloc_handler.malloc(size, file, line); } +void *ec_malloc2(size_t size) +{ + return __ec_malloc(size, __FILE__, __LINE__); +} + void __ec_free(void *ptr, const char *file, unsigned int line) { ec_malloc_handler.free(ptr, file, line); } +void ec_free2(void *ptr) +{ + __ec_free(ptr, __FILE__, __LINE__); +} + void *__ec_calloc(size_t nmemb, size_t size, const char *file, unsigned int line) { diff --git a/lib/ecoli_malloc.h b/lib/ecoli_malloc.h index f5bdc39..76b63e0 100644 --- a/lib/ecoli_malloc.h +++ b/lib/ecoli_malloc.h @@ -59,6 +59,10 @@ char *__ec_strdup(const char *s, const char *file, unsigned int line); char *__ec_strndup(const char *s, size_t n, const char *file, unsigned int line); +/* XXX rename into ec_malloc, and change macro to uppercase */ +void *ec_malloc2(size_t size); +void ec_free2(void *ptr); + /* we use macros here to ensure the file/line stay correct when * debugging the standard malloc with valgrind */ diff --git a/lib/ecoli_strvec.c b/lib/ecoli_strvec.c index 17a10c8..da15502 100644 --- a/lib/ecoli_strvec.c +++ b/lib/ecoli_strvec.c @@ -150,3 +150,5 @@ void ec_strvec_dump(const struct ec_strvec *strvec, FILE *out) for (i = 0; i < ec_strvec_len(strvec); i++) fprintf(out, " %zd: %s\n", i, strvec->vec[i]); } + +/* XXX test case */ diff --git a/lib/ecoli_test.c b/lib/ecoli_test.c index 1408f5a..4a7de26 100644 --- a/lib/ecoli_test.c +++ b/lib/ecoli_test.c @@ -150,10 +150,10 @@ int ec_test_check_tk_complete(const struct ec_tk *tk, ...) } } - if (count != ec_completed_tk_count_match(c)) { + if (count != ec_completed_tk_count(c, EC_MATCH)) { ec_log(EC_LOG_ERR, "nb_completion (%d) does not match (%d)\n", - count, ec_completed_tk_count_match(c)); + count, ec_completed_tk_count(c, EC_MATCH)); ec_completed_tk_dump(stdout, c); ret = -1; } diff --git a/lib/ecoli_test.h b/lib/ecoli_test.h index c1246c4..40ddefa 100644 --- a/lib/ecoli_test.h +++ b/lib/ecoli_test.h @@ -70,14 +70,20 @@ int ec_test_all(void); /* expected == -1 means no match */ int ec_test_check_tk_parse(const struct ec_tk *tk, int expected, ...); -#define TEST_ERR() \ - ec_log(EC_LOG_ERR, "%s:%d: error: test failed\n", \ - __FILE__, __LINE__); \ +#define EC_TEST_ERR(fmt, ...) \ + ec_log(EC_LOG_ERR, "%s:%d: error: " fmt "\n", \ + __FILE__, __LINE__, ##__VA_ARGS__); \ + +#define EC_TEST_ASSERT(cond, args...) \ + do { \ + if (!(cond)) \ + EC_TEST_ERR("assertion failure: " #cond); \ + } while (0) #define EC_TEST_CHECK_TK_PARSE(tk, input, expected...) ({ \ int ret_ = ec_test_check_tk_parse(tk, input, expected); \ if (ret_) \ - TEST_ERR(); \ + EC_TEST_ERR("parse test failed"); \ ret_; \ }) @@ -86,7 +92,7 @@ int ec_test_check_tk_complete(const struct ec_tk *tk, ...); #define EC_TEST_CHECK_TK_COMPLETE(tk, args...) ({ \ int ret_ = ec_test_check_tk_complete(tk, args); \ if (ret_) \ - TEST_ERR(); \ + EC_TEST_ERR("complete test failed"); \ ret_; \ }) diff --git a/lib/ecoli_tk.c b/lib/ecoli_tk.c index e21df55..fec8492 100644 --- a/lib/ecoli_tk.c +++ b/lib/ecoli_tk.c @@ -33,12 +33,14 @@ #include #include +#include #include struct ec_tk *ec_tk_new(const char *id, const struct ec_tk_ops *ops, size_t size) { struct ec_tk *tk = NULL; + char buf[256]; // XXX assert(size >= sizeof(*tk)); @@ -46,17 +48,30 @@ struct ec_tk *ec_tk_new(const char *id, const struct ec_tk_ops *ops, if (tk == NULL) goto fail; + TAILQ_INIT(&tk->children); + tk->ops = ops; + if (id != NULL) { tk->id = ec_strdup(id); if (tk->id == NULL) goto fail; } - tk->ops = ops; + snprintf(buf, sizeof(buf), "<%s>", ops->typename); + tk->desc = ec_strdup(buf); // XXX ec_asprintf ? + if (tk->desc == NULL) + goto fail; + + tk->attrs = ec_keyval_new(); + if (tk->attrs == NULL) + goto fail; return tk; fail: + ec_free(tk->attrs); + ec_free(tk->desc); + ec_free(tk->id); ec_tk_free(tk); return NULL; } @@ -69,9 +84,43 @@ void ec_tk_free(struct ec_tk *tk) if (tk->ops != NULL && tk->ops->free_priv != NULL) tk->ops->free_priv(tk); ec_free(tk->id); + ec_free(tk->desc); + ec_free(tk->attrs); ec_free(tk); } +struct ec_tk *ec_tk_find(struct ec_tk *tk, const char *id) +{ + struct ec_tk *child, *ret; + const char *tk_id = ec_tk_id(tk); + + if (id != NULL && tk_id != NULL && !strcmp(tk_id, id)) + return tk; + + TAILQ_FOREACH(child, &tk->children, next) { + ret = ec_tk_find(child, id); + if (ret != NULL) + return ret; + } + + return NULL; +} + +struct ec_keyval *ec_tk_attrs(const struct ec_tk *tk) +{ + return tk->attrs; +} + +const char *ec_tk_id(const struct ec_tk *tk) +{ + return tk->id; +} + +struct ec_tk *ec_tk_parent(const struct ec_tk *tk) +{ + return tk->parent; +} + struct ec_parsed_tk *ec_tk_parse(const struct ec_tk *tk, const char *str) { struct ec_strvec *strvec = NULL; @@ -178,6 +227,7 @@ static void __ec_parsed_tk_dump(FILE *out, typename = parsed_tk->tk->ops->typename; } + /* XXX we only display the first token */ fprintf(out, "tk_type=%s, id=%s, s=<%s>\n", typename, id, s); TAILQ_FOREACH(child, &parsed_tk->children, next) @@ -450,13 +500,21 @@ const char *ec_completed_tk_smallest_start( return completed_tk->smallest_start; } -unsigned int ec_completed_tk_count_match( - const struct ec_completed_tk *completed_tk) +unsigned int ec_completed_tk_count( + const struct ec_completed_tk *completed_tk, + enum ec_completed_tk_filter_flags flags) { + unsigned int count = 0; + if (completed_tk == NULL) - return 0; + return count; + + if (flags & EC_MATCH) + count += completed_tk->count_match; + if (flags & EC_NO_MATCH) + count += (completed_tk->count - completed_tk->count_match); //XXX - return completed_tk->count_match; + return count; } struct ec_completed_tk_iter * @@ -493,11 +551,11 @@ const struct ec_completed_tk_elt *ec_completed_tk_iter_next( break; if (iter->cur->add == NULL && - (iter->flags & ITER_NO_MATCH)) + (iter->flags & EC_NO_MATCH)) break; if (iter->cur->add != NULL && - (iter->flags & ITER_MATCH)) + (iter->flags & EC_MATCH)) break; } while (iter->cur != NULL); @@ -509,3 +567,11 @@ void ec_completed_tk_iter_free(struct ec_completed_tk_iter *iter) { ec_free(iter); } + +const char *ec_tk_desc(const struct ec_tk *tk) +{ + if (tk->ops->desc != NULL) + return tk->ops->desc(tk); + + return tk->desc; +} diff --git a/lib/ecoli_tk.h b/lib/ecoli_tk.h index e243c08..5d1bafb 100644 --- a/lib/ecoli_tk.h +++ b/lib/ecoli_tk.h @@ -37,29 +37,49 @@ struct ec_tk; struct ec_parsed_tk; struct ec_strvec; +struct ec_keyval; typedef struct ec_parsed_tk *(*ec_tk_parse_t)(const struct ec_tk *tk, const struct ec_strvec *strvec); typedef struct ec_completed_tk *(*ec_tk_complete_t)(const struct ec_tk *tk, const struct ec_strvec *strvec); +typedef const char * (*ec_tk_desc_t)(const struct ec_tk *); typedef void (*ec_tk_free_priv_t)(struct ec_tk *); struct ec_tk_ops { const char *typename; ec_tk_parse_t parse; ec_tk_complete_t complete; + ec_tk_desc_t desc; ec_tk_free_priv_t free_priv; }; +TAILQ_HEAD(ec_tk_list, ec_tk); + struct ec_tk { const struct ec_tk_ops *ops; char *id; + char *desc; + struct ec_keyval *attrs; + /* XXX ensure parent and child are properly set in all nodes */ + struct ec_tk *parent; + + TAILQ_ENTRY(ec_tk) next; + struct ec_tk_list children; }; struct ec_tk *ec_tk_new(const char *id, const struct ec_tk_ops *ops, size_t priv_size); void ec_tk_free(struct ec_tk *tk); +/* XXX add more accessors */ +struct ec_keyval *ec_tk_attrs(const struct ec_tk *tk); +struct ec_tk *ec_tk_parent(const struct ec_tk *tk); +const char *ec_tk_id(const struct ec_tk *tk); + +struct ec_tk *ec_tk_find(struct ec_tk *tk, const char *id); + +/* XXX split this file ? */ TAILQ_HEAD(ec_parsed_tk_list, ec_parsed_tk); @@ -84,12 +104,12 @@ void ec_parsed_tk_set_match(struct ec_parsed_tk *parsed_tk, /* a NULL return value is an error, with errno set ENOTSUP: no ->parse() operation */ -struct ec_parsed_tk *ec_tk_parse(const struct ec_tk *token, const char *str); +struct ec_parsed_tk *ec_tk_parse(const struct ec_tk *tk, const char *str); /* mostly internal to tokens */ /* XXX it should not reset cache * ... not sure... it is used by tests */ -struct ec_parsed_tk *ec_tk_parse_tokens(const struct ec_tk *token, +struct ec_parsed_tk *ec_tk_parse_tokens(const struct ec_tk *tk, const struct ec_strvec *strvec); void ec_parsed_tk_add_child(struct ec_parsed_tk *parsed_tk, @@ -125,9 +145,9 @@ struct ec_completed_tk { * return a completed_tk object filled with elts * return NULL on error (nomem?) */ -struct ec_completed_tk *ec_tk_complete(const struct ec_tk *token, +struct ec_completed_tk *ec_tk_complete(const struct ec_tk *tk, const char *str); -struct ec_completed_tk *ec_tk_complete_tokens(const struct ec_tk *token, +struct ec_completed_tk *ec_tk_complete_tokens(const struct ec_tk *tk, const struct ec_strvec *strvec); struct ec_completed_tk *ec_completed_tk_new(void); struct ec_completed_tk_elt *ec_completed_tk_elt_new(const struct ec_tk *tk, @@ -147,14 +167,15 @@ struct ec_completed_tk *ec_tk_default_complete(const struct ec_tk *gen_tk, const char *ec_completed_tk_smallest_start( const struct ec_completed_tk *completed_tk); -unsigned int ec_completed_tk_count_match( - const struct ec_completed_tk *completed_tk); - enum ec_completed_tk_filter_flags { - ITER_MATCH = 1, - ITER_NO_MATCH, + EC_MATCH = 1, + EC_NO_MATCH = 2, }; +unsigned int ec_completed_tk_count( + const struct ec_completed_tk *completed_tk, + enum ec_completed_tk_filter_flags flags); + struct ec_completed_tk_iter { enum ec_completed_tk_filter_flags flags; const struct ec_completed_tk *completed_tk; @@ -169,4 +190,8 @@ const struct ec_completed_tk_elt *ec_completed_tk_iter_next( struct ec_completed_tk_iter *iter); void ec_completed_tk_iter_free(struct ec_completed_tk_iter *iter); + + +const char *ec_tk_desc(const struct ec_tk *tk); + #endif diff --git a/lib/ecoli_tk_int.c b/lib/ecoli_tk_int.c index f4cca45..57971ee 100644 --- a/lib/ecoli_tk_int.c +++ b/lib/ecoli_tk_int.c @@ -157,22 +157,12 @@ static int ec_tk_int_testcase(void) p = ec_tk_parse(tk, "0"); s = ec_parsed_tk_to_string(p); - if (s == NULL) { - TEST_ERR(); - } else { - if (ec_tk_int_getval(tk, s) != 0) - TEST_ERR(); - } + EC_TEST_ASSERT(s != NULL && ec_tk_int_getval(tk, s) == 0); ec_parsed_tk_free(p); p = ec_tk_parse(tk, "10"); s = ec_parsed_tk_to_string(p); - if (s == NULL) { - TEST_ERR(); - } else { - if (ec_tk_int_getval(tk, s) != 10) - TEST_ERR(); - } + EC_TEST_ASSERT(s != NULL && ec_tk_int_getval(tk, s) == 10); ec_parsed_tk_free(p); ec_tk_free(tk); @@ -189,12 +179,7 @@ static int ec_tk_int_testcase(void) p = ec_tk_parse(tk, "10"); s = ec_parsed_tk_to_string(p); - if (s == NULL) { - TEST_ERR(); - } else { - if (ec_tk_int_getval(tk, s) != 16) - TEST_ERR(); - } + EC_TEST_ASSERT(s != NULL && ec_tk_int_getval(tk, s) == 16); ec_parsed_tk_free(p); ec_tk_free(tk); diff --git a/lib/ecoli_tk_or.c b/lib/ecoli_tk_or.c index 2438679..2889147 100644 --- a/lib/ecoli_tk_or.c +++ b/lib/ecoli_tk_or.c @@ -191,6 +191,9 @@ int ec_tk_or_add(struct ec_tk *gen_tk, struct ec_tk *child) table[tk->len] = child; tk->len ++; + child->parent = gen_tk; + TAILQ_INSERT_TAIL(&gen_tk->children, child, next); + return 0; } diff --git a/lib/ecoli_tk_seq.c b/lib/ecoli_tk_seq.c index d7bf998..e606a09 100644 --- a/lib/ecoli_tk_seq.c +++ b/lib/ecoli_tk_seq.c @@ -221,6 +221,9 @@ int ec_tk_seq_add(struct ec_tk *gen_tk, struct ec_tk *child) table[tk->len] = child; tk->len ++; + child->parent = gen_tk; + TAILQ_INSERT_TAIL(&gen_tk->children, child, next); + return 0; } diff --git a/lib/ecoli_tk_str.c b/lib/ecoli_tk_str.c index 4fe3062..6c650d3 100644 --- a/lib/ecoli_tk_str.c +++ b/lib/ecoli_tk_str.c @@ -114,6 +114,13 @@ static struct ec_completed_tk *ec_tk_str_complete(const struct ec_tk *gen_tk, return completed_tk; } +static const char *ec_tk_str_desc(const struct ec_tk *gen_tk) +{ + struct ec_tk_str *tk = (struct ec_tk_str *)gen_tk; + + return tk->string; +} + static void ec_tk_str_free_priv(struct ec_tk *gen_tk) { struct ec_tk_str *tk = (struct ec_tk_str *)gen_tk; @@ -125,6 +132,7 @@ static const struct ec_tk_ops ec_tk_str_ops = { .typename = "str", .parse = ec_tk_str_parse, .complete = ec_tk_str_complete, + .desc = ec_tk_str_desc, .free_priv = ec_tk_str_free_priv, }; diff --git a/lib/main-readline.c b/lib/main-readline.c index 379c36e..8c5ffc5 100644 --- a/lib/main-readline.c +++ b/lib/main-readline.c @@ -33,6 +33,9 @@ #include #include +#include +#include + #include #include #include @@ -66,7 +69,7 @@ static char *my_completion_entry(const char *s, int state) return NULL; ec_completed_tk_iter_free(iter); - iter = ec_completed_tk_iter_new(c, ITER_MATCH); + iter = ec_completed_tk_iter_new(c, EC_MATCH); if (iter == NULL) return NULL; } @@ -92,16 +95,37 @@ static char **my_attempted_completion(const char *text, int start, int end) return rl_completion_matches(text, my_completion_entry); } +/* this function builds the help string */ +static char *get_tk_help(const struct ec_tk *tk) +{ + const struct ec_tk *tk2; + char *help = NULL; + char *tk_help = NULL; + + for (tk2 = tk; tk2 != NULL && tk_help == NULL; tk2 = ec_tk_parent(tk2)) + tk_help = ec_keyval_get(ec_tk_attrs(tk2), "help"); + + if (tk_help == NULL) + tk_help = ""; + + if (asprintf(&help, "%-20s %s", ec_tk_desc(tk), tk_help) < 0) + return NULL; + + return help; +} static int show_help(int ignore, int invoking_key) { + const struct ec_completed_tk_elt *elt; + struct ec_completed_tk_iter *iter; struct ec_completed_tk *c; char *line; + unsigned int count, i; + char **helps = NULL; (void)ignore; (void)invoking_key; - printf("\nhelp:\n"); line = strdup(rl_line_buffer); if (line == NULL) return 1; @@ -111,40 +135,100 @@ static int show_help(int ignore, int invoking_key) free(line); if (c == NULL) return 1; - ec_completed_tk_dump(stdout, c); + //ec_completed_tk_dump(stdout, c); + + count = ec_completed_tk_count(c, EC_MATCH | EC_NO_MATCH); + helps = calloc(count + 1, sizeof(char *)); + if (helps == NULL) + return 1; + + iter = ec_completed_tk_iter_new(c, EC_MATCH | EC_NO_MATCH); + if (iter == NULL) + goto fail; + + /* strangely, rl_display_match_list() expects first index at 1 */ + for (i = 1, elt = ec_completed_tk_iter_next(iter); + i <= count && elt != NULL; + i++, elt = ec_completed_tk_iter_next(iter)) { + helps[i] = get_tk_help(elt->tk); + } + ec_completed_tk_free(c); + rl_display_match_list(helps, count, 1000); + rl_forced_update_display(); return 0; + +fail: + free(helps); + // free helps[n] XXX + return 1; } -int main(void) +static int create_commands(void) { - struct ec_parsed_tk *p; -// const char *name; - char *line; + struct ec_tk *cmdlist = NULL, *cmd = NULL; - rl_bind_key('?', show_help); + cmdlist = ec_tk_or_new(NULL); + if (cmdlist == NULL) + goto fail; - commands = ec_tk_shlex_new(NULL, - ec_tk_seq_new_list(NULL, - ec_tk_str_new(NULL, "hello"), + cmd = ec_tk_seq_new_list(NULL, + ec_tk_str_new(NULL, "hello"), + ec_tk_or_new_list(NULL, ec_tk_or_new_list("name", ec_tk_str_new(NULL, "john"), ec_tk_str_new(NULL, "johnny"), ec_tk_str_new(NULL, "mike"), - ec_tk_int_new(NULL, 0, 10, 10), EC_TK_ENDLIST ), + ec_tk_int_new("int", 0, 10, 10), EC_TK_ENDLIST - ) + ), + EC_TK_ENDLIST + ); + ec_keyval_set(ec_tk_attrs(cmd), "help", "say hello to someone", NULL); + ec_keyval_set(ec_tk_attrs(ec_tk_find(cmd, "name")), + "help", "the name of the person", NULL); + ec_keyval_set(ec_tk_attrs(ec_tk_find(cmd, "int")), + "help", "an integer", NULL); + if (ec_tk_or_add(cmdlist, cmd) < 0) + goto fail; + + cmd = ec_tk_seq_new_list(NULL, + ec_tk_str_new(NULL, "bye"), + EC_TK_ENDLIST ); - if (commands == NULL) { - printf("cannot create token\n"); + ec_keyval_set(ec_tk_attrs(cmd), "help", "say bye to someone", NULL); + if (ec_tk_or_add(cmdlist, cmd) < 0) + goto fail; + + commands = ec_tk_shlex_new(NULL, cmdlist); + if (commands == NULL) + goto fail; + + return 0; + + fail: + fprintf(stderr, "cannot initialize tokens\n"); + ec_tk_free(cmd); + ec_tk_free(cmdlist); + return -1; +} + +int main(void) +{ + struct ec_parsed_tk *p; +// const char *name; + char *line; + + + if (create_commands() < 0) return 1; - } + rl_bind_key('?', show_help); rl_attempted_completion_function = my_attempted_completion; while (1) { @@ -161,4 +245,5 @@ int main(void) ec_tk_free(commands); return 0; + } -- 2.39.5