#include <ecoli_malloc.h>
#include <ecoli_strvec.h>
#include <ecoli_keyval.h>
+#include <ecoli_log.h>
#include <ecoli_tk.h>
struct ec_tk *ec_tk_new(const char *id, const struct ec_tk_ops *ops,
assert(size >= sizeof(*tk));
+ ec_log(EC_LOG_DEBUG, "create node type=%s id=%s\n", ops->typename, id);
+
tk = ec_calloc(1, size);
if (tk == NULL)
goto fail;
TAILQ_INIT(&tk->children);
tk->ops = ops;
+ tk->refcnt = 1;
if (id != NULL) {
tk->id = ec_strdup(id);
return tk;
fail:
- ec_free(tk->attrs);
- ec_free(tk->desc);
- ec_free(tk->id);
ec_tk_free(tk);
return NULL;
}
if (tk == NULL)
return;
+ assert(tk->refcnt > 0);
+
+ if (--tk->refcnt > 0)
+ return;
+
if (tk->ops != NULL && tk->ops->free_priv != NULL)
tk->ops->free_priv(tk);
ec_free(tk->id);
ec_free(tk);
}
+struct ec_tk *ec_tk_clone(struct ec_tk *tk)
+{
+ if (tk != NULL)
+ tk->refcnt++;
+ return tk;
+}
+
struct ec_tk *ec_tk_find(struct ec_tk *tk, const char *id)
{
struct ec_tk *child, *ret;
return tk->parent;
}
-struct ec_parsed_tk *ec_tk_parse(const struct ec_tk *tk, const char *str)
+struct ec_parsed_tk *ec_tk_parse(struct ec_tk *tk, const char *str)
{
struct ec_strvec *strvec = NULL;
struct ec_parsed_tk *parsed_tk;
return NULL;
}
-struct ec_parsed_tk *ec_tk_parse_tokens(const struct ec_tk *tk,
+struct ec_parsed_tk *ec_tk_parse_tokens(struct ec_tk *tk,
const struct ec_strvec *strvec)
{
struct ec_parsed_tk *parsed_tk;
+ int ret;
+
+ /* build the node if required */
+ if (tk->ops->build != NULL) {
+ if ((tk->flags & EC_TK_F_BUILT) == 0) {
+ ret = tk->ops->build(tk);
+ if (ret < 0) {
+ errno = -ret;
+ return NULL;
+ }
+ }
+ }
+ tk->flags |= EC_TK_F_BUILT;
if (tk->ops->parse == NULL) {
errno = ENOTSUP;
const struct ec_parsed_tk *parsed_tk, size_t indent)
{
struct ec_parsed_tk *child;
+ const struct ec_strvec *vec;
size_t i;
- const char *s, *id = "None", *typename = "None";
-
- /* XXX enhance */
- for (i = 0; i < indent; i++)
- fprintf(out, " ");
+ const char *id = "None", *typename = "None";
- s = ec_parsed_tk_to_string(parsed_tk);
if (parsed_tk->tk != NULL) {
if (parsed_tk->tk->id != NULL)
id = parsed_tk->tk->id;
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);
+ /* XXX remove this debug hack */
+ if (!strcmp(typename, "str") || !strcmp(typename, "int"))
+ fprintf(out, ">>> ");
+ else
+ fprintf(out, " ");
+
+ /* XXX enhance */
+ for (i = 0; i < indent; i++) {
+ if (i % 2)
+ fprintf(out, " ");
+ else
+ fprintf(out, "|");
+ }
+
+ fprintf(out, "tk_type=%s id=%s vec=[", typename, id);
+ vec = ec_parsed_tk_strvec(parsed_tk);
+ for (i = 0; i < ec_strvec_len(vec); i++)
+ fprintf(out, "%s<%s>",
+ i == 0 ? "" : ",",
+ ec_strvec_val(vec, i));
+ fprintf(out, "]\n");
TAILQ_FOREACH(child, &parsed_tk->children, next)
__ec_parsed_tk_dump(out, child, indent + 2);
void ec_parsed_tk_dump(FILE *out, const struct ec_parsed_tk *parsed_tk)
{
+ fprintf(out, "------------------- dump:\n");
+
if (parsed_tk == NULL) {
fprintf(out, "parsed_tk is NULL, error in parse\n");
return;
return NULL;
}
-/* XXX return NUL if it matches several tokens?
- or add a parameter to join() the tokens ? */
-const char *ec_parsed_tk_to_string(const struct ec_parsed_tk *parsed_tk)
+const struct ec_strvec *ec_parsed_tk_strvec(
+ const struct ec_parsed_tk *parsed_tk)
{
if (parsed_tk == NULL || parsed_tk->strvec == NULL)
return NULL;
- return ec_strvec_val(parsed_tk->strvec, 0);
+ return parsed_tk->strvec;
}
/* number of parsed tokens */