api documentation for ec_parse
[protos/libecoli.git] / src / ecoli_yaml.c
index 84007d5..4843ef0 100644 (file)
@@ -13,7 +13,7 @@
 #include <yaml.h>
 
 #include <ecoli_malloc.h>
-#include <ecoli_keyval.h>
+#include <ecoli_dict.h>
 #include <ecoli_node.h>
 #include <ecoli_config.h>
 #include <ecoli_yaml.h>
@@ -360,12 +360,20 @@ parse_ec_node(struct enode_table *table,
        const yaml_node_pair_t *pair;
        const char *key_str, *value_str;
        struct ec_node *enode = NULL;
+       char *value_dup = NULL;
+       size_t i;
 
        if (ynode->type != YAML_MAPPING_NODE) {
                fprintf(stderr, "Ecoli node should be a yaml mapping node\n");
                goto fail;
        }
 
+       /* if it's an anchor, the node may be already parsed, reuse it */
+       for (i = 0; i < table->len; i++) {
+               if (table->pair[i].ynode == ynode)
+                       return ec_node_clone(table->pair[i].enode);
+       }
+
        for (pair = ynode->data.mapping.pairs.start;
             pair < ynode->data.mapping.pairs.top; pair++) {
                key = document->nodes.start + pair->key - 1; // XXX -1 ?
@@ -458,7 +466,7 @@ parse_ec_node(struct enode_table *table,
        config = NULL; /* freed */
 
        if (help != NULL) {
-               if (ec_keyval_set(ec_node_attrs(enode), "help", help,
+               if (ec_dict_set(ec_node_attrs(enode), "help", help,
                                        ec_free_func) < 0) {
                        fprintf(stderr, "Failed to set help\n");
                        help = NULL;
@@ -468,7 +476,24 @@ parse_ec_node(struct enode_table *table,
        }
 
        /* add attributes (all as string) */
-       //XXX
+       if (attrs != NULL) {
+               for (pair = attrs->data.mapping.pairs.start;
+                    pair < attrs->data.mapping.pairs.top; pair++) {
+                       key = document->nodes.start + pair->key - 1;
+                       value = document->nodes.start + pair->value - 1;
+                       key_str = (const char *)key->data.scalar.value;
+                       value_str = (const char *)value->data.scalar.value;
+                       value_dup = ec_strdup(value_str);
+                       if (value_dup == NULL)
+                               goto fail;
+                       if (ec_dict_set(ec_node_attrs(enode), key_str,
+                                               value_dup, ec_free_func) < 0) {
+                               value_dup = NULL;
+                               goto fail;
+                       }
+                       value_dup = NULL;
+               }
+       }
 
        return enode;
 
@@ -476,6 +501,7 @@ fail:
        ec_node_free(enode);
        ec_config_free(config);
        ec_free(help);
+       ec_free(value_dup);
 
        return NULL;
 }