]> git.droids-corp.org - protos/libecoli.git/commitdiff
fix cmd node
authorOlivier Matz <zer0@droids-corp.org>
Thu, 8 Mar 2018 20:52:45 +0000 (21:52 +0100)
committerOlivier Matz <zer0@droids-corp.org>
Thu, 8 Mar 2018 20:52:45 +0000 (21:52 +0100)
lib/ecoli_node_cmd.c
lib/ecoli_node_expr.c
lib/ecoli_node_seq.h
lib/ecoli_parsed.c
lib/ecoli_test.h
lib/main.c
lib/todo.txt

index f479c3ffff5992716f0b531c12e1608d8c45f2d1..ba1469b2d1570d5cdd0b6fb32b5aee209d284f0f 100644 (file)
@@ -104,7 +104,7 @@ ec_node_cmd_eval_var(void **result, void *userctx,
                        return -ENOMEM;
        }
 
-       //printf("eval var %s %p\n", str, eval);
+       //printf("eval var %s %p\n", str, eval); //XXX
        *result = eval;
 
        return 0;
@@ -165,10 +165,17 @@ ec_node_cmd_eval_bin_op(void **result, void *userctx, void *operand1,
 
        /* get parsed string vector, it should contain only one str */
        vec = ec_parsed_strvec(operator);
-       if (ec_strvec_len(vec) != 1)
+       if (ec_strvec_len(vec) > 1)
                return -EINVAL;
 
-       if (!strcmp(ec_strvec_val(vec, 0), "|")) {
+       if (ec_strvec_len(vec) == 0) {
+               out = EC_NODE_SEQ(EC_NO_ID, ec_node_clone(in1), ec_node_clone(in2));
+               if (out == NULL)
+                       return -EINVAL;
+               ec_node_free(in1);
+               ec_node_free(in2);
+               *result = out;
+       } else if (!strcmp(ec_strvec_val(vec, 0), "|")) {
                out = EC_NODE_OR(EC_NO_ID, ec_node_clone(in1), ec_node_clone(in2));
                if (out == NULL)
                        return -EINVAL;
@@ -250,7 +257,7 @@ static const struct ec_node_expr_eval_ops test_ops = {
 static int ec_node_cmd_build(struct ec_node_cmd *node)
 {
        struct ec_node *expr = NULL, *lex = NULL, *cmd = NULL;
-       struct ec_parsed *p = NULL, *child;
+       struct ec_parsed *p = NULL;
        void *result;
        int ret;
 
@@ -273,6 +280,9 @@ static int ec_node_cmd_build(struct ec_node_cmd *node)
        if (ret < 0)
                goto fail;
        ret = ec_node_expr_add_bin_op(expr, ec_node_str(EC_NO_ID, "|"));
+       if (ret < 0)
+               goto fail;
+       ret = ec_node_expr_add_bin_op(expr, ec_node("empty", EC_NO_ID));
        if (ret < 0)
                goto fail;
        ret = ec_node_expr_add_post_op(expr, ec_node_str(EC_NO_ID, "+"));
@@ -290,10 +300,9 @@ static int ec_node_cmd_build(struct ec_node_cmd *node)
        if (ret < 0)
                goto fail;
 
-       /* prepend a lexer and a "many" to the expression node */
+       /* prepend a lexer to the expression node */
        ret = -ENOMEM;
-       lex = ec_node_re_lex(EC_NO_ID,
-               ec_node_many(EC_NO_ID, ec_node_clone(expr), 1, 0));
+       lex = ec_node_re_lex(EC_NO_ID, ec_node_clone(expr));
        if (lex == NULL)
                goto fail;
 
@@ -324,29 +333,18 @@ static int ec_node_cmd_build(struct ec_node_cmd *node)
                goto fail;
        if (!ec_parsed_has_child(p))
                goto fail;
-       if (!ec_parsed_has_child(ec_parsed_get_first_child(p)))
-               goto fail;
 
-       ret = -ENOMEM;
-       cmd = ec_node("seq", EC_NO_ID);
-       if (cmd == NULL)
+       ret = ec_node_expr_eval(&result, expr, ec_parsed_get_first_child(p),
+                               &test_ops, node);
+       if (ret < 0)
                goto fail;
 
-       EC_PARSED_FOREACH_CHILD(child, ec_parsed_get_first_child(p)) {
-               ret = ec_node_expr_eval(&result, expr, child,
-                       &test_ops, node);
-               if (ret < 0)
-                       goto fail;
-               ret = ec_node_seq_add(cmd, result);
-               if (ret < 0)
-                       goto fail;
-       }
        ec_parsed_free(p);
        p = NULL;
 
        node->expr = expr;
        node->lex = lex;
-       node->cmd = cmd;
+       node->cmd = result;
 
        return 0;
 
@@ -544,6 +542,17 @@ static int ec_node_cmd_testcase(void)
 
        ec_node_free(node);
 
+       node = EC_NODE_CMD(EC_NO_ID, "[foo [bar]]");
+       if (node == NULL) {
+               EC_LOG(EC_LOG_ERR, "cannot create node\n");
+               return -1;
+       }
+       ret |= EC_TEST_CHECK_PARSE(node, 0);
+       ret |= EC_TEST_CHECK_PARSE(node, 1, "foo");
+       ret |= EC_TEST_CHECK_PARSE(node, 2, "foo", "bar");
+       ret |= EC_TEST_CHECK_PARSE(node, 0, "x");
+       ec_node_free(node);
+
        return ret;
 }
 /* LCOV_EXCL_STOP */
index 9fb48a7b8d751a151efc9c5fd69d278fbd514f9e..2be8f558850f05fbadac4614e63fed574c09b235 100644 (file)
@@ -135,6 +135,20 @@ static int ec_node_expr_build(struct ec_node_expr *node)
                        node->post_ops_len == 0)
                return -EINVAL;
 
+       /*
+        * Example of created grammar:
+        *
+        * pre_op = "!"
+        * post_op = "^"
+        * post = val |
+        *        pre_op expr |
+        *        "(" expr ")"
+        * term = post post_op*
+        * prod = term ( "*" term )*
+        * sum = prod ( "+" prod )*
+        * expr = sum
+        */
+
        /* create the object, we will initialize it later: this is
         * needed because we have a circular dependency */
        ret = -ENOMEM;
index 741539cda71c279db6a811069ed75aca38987bc0..449ffb80ba2bcb166ba182914e267d0f4f624e5a 100644 (file)
@@ -41,7 +41,6 @@ struct ec_node *__ec_node_seq(const char *id, ...);
 struct ec_node *ec_node_seq(const char *id);
 
 /* child is consumed */
-// XXX add_child?
 int ec_node_seq_add(struct ec_node *node, struct ec_node *child);
 
 #endif
index b4b59e817efa5acf1e513ad38befebd397d3cac2..5588dc6912129a6eefb9963dbed488f63de8e1f0 100644 (file)
 
 TAILQ_HEAD(ec_parsed_list, ec_parsed);
 
-/* XXX idea for parse: maintain a "cursor" ?
-struct ec_parsed {
-   struct ec_parsed_tree *root;
-   stuct ec_parsed_tree *cursor;
-};
-*/
-
 struct ec_parsed {
        TAILQ_ENTRY(ec_parsed) next;
        struct ec_parsed_list children;
index 1cebe951bd319820be43bda7c01fa383f86d14e8..fa3fe6cbdc3af28edd4c6b2046ef245bf9397f0e 100644 (file)
@@ -78,6 +78,7 @@ int ec_test_check_parse(struct ec_node *node, int expected, ...);
                __FILE__, __LINE__, ##__VA_ARGS__);                     \
 
 /* XXX this is not an assert, it does not abort */
+// XXX use it instead of ec_log to have the file:line
 #define EC_TEST_ASSERT_STR(cond, fmt, ...)                             \
        do {                                                            \
                if (!(cond))                                            \
index 1a6a0d322b608565293472b0767aa07b341863aa..64829918955e34f779152a0f00c7538b48a75fb0 100644 (file)
@@ -182,6 +182,7 @@ static void *debug_malloc(size_t size, const char *file, unsigned int line)
        size_t new_size = size + sizeof(*hdr) + sizeof(*ftr);
        void *ret;
        int r = random();
+       static int seq;
 
        if (alloc_fail_proba != 0 && (r % 100) < alloc_fail_proba)
                hdr = NULL;
@@ -203,9 +204,9 @@ 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 [rand=%d]\n",
-               file, line, size, ret, r);
-       if (r == 976499400)
+       EC_LOG(EC_LOG_DEBUG, "%s:%d: info: malloc(%zd) -> %p seq=%d\n",
+               file, line, size, ret, seq++);
+       if (seq == 100)
                printf("here\n");
 
        if (ret)
index 7a739307f8428bf62bb24328994b78f2ede72529..8076ac8bdef175ba2eb72497118755d02d668eb8 100644 (file)
@@ -377,3 +377,25 @@ int main(void)
 
        return 0;
 }
+
+
+----
+
+
+expr expr expr
+
+[toto] | tutu
+
+[toto [titi]]
+
+
+
+pre_op = "!"
+post_op = "^"
+post = val |
+       pre_op expr |
+       "(" expr ")"
+term = post post_op*
+prod = term ( "*" term )*
+sum = prod ( "+" prod )*
+expr = sum