--- cfg_node.c 2004/11/29 07:09:33 1.22
+++ cfg_node.c 2004/12/04 12:48:40 1.23
@@ -57,6 +57,7 @@
return rc;
/* initialize node attributes */
+ n->owner = 0;
n->parent = NULL;
n->rbroth = NULL;
n->child1 = NULL;
@@ -81,10 +82,11 @@
return CFG_ERR_ARG;
/* destroy memory */
- if (node->token != NULL)
+ if ((node->owner & CFG_NODE_ATTR_TOKEN) && node->token != NULL)
free(node->token);
- if (node->srcname != NULL)
+ if ((node->owner & CFG_NODE_ATTR_SRCNAME) && node->srcname != NULL)
free(node->srcname);
+ cfg_data_kill(&node->data);
cfg_grid_free(cfg->grid_nodes, node);
return CFG_OK;
@@ -109,14 +111,23 @@
return rc;
/* clone node attributes */
+ n->owner = node->owner;
n->parent = node->parent;
n->rbroth = node->rbroth;
n->child1 = node->child1;
n->type = node->type;
- n->token = (node->token != NULL ? strdup(node->token) : NULL);
- cfg_data_copy(&node->data, &n->data);
- n->srcname = (node->srcname != NULL ? strdup(node->srcname) : NULL);
n->srcpos = node->srcpos;
+ if (node->owner & CFG_NODE_ATTR_TOKEN)
+ n->token = (node->token != NULL ? strdup(node->token) : NULL);
+ else
+ n->token = node->token;
+ if (node->owner & CFG_NODE_ATTR_SRCNAME)
+ n->srcname = (node->srcname != NULL ? strdup(node->srcname) : NULL);
+ else
+ n->srcname = node->srcname;
+ cfg_data_copy(&node->data, &n->data);
+
+ /* store result */
*node2 = n;
return CFG_OK;
@@ -138,7 +149,7 @@
/* dispatch into individual attribute handling */
va_start(ap, attr);
- switch (attr) {
+ switch (attr & ~(CFG_ATTR_LOAN|CFG_ATTR_GIFT|CFG_ATTR_COPY)) {
case CFG_NODE_ATTR_PARENT: {
node->parent = (cfg_node_t *)va_arg(ap, cfg_node_t *);
break;
@@ -171,22 +182,28 @@
break;
}
case CFG_NODE_ATTR_TOKEN: {
- if (node->token != NULL)
+ char *value = (char *)va_arg(ap, char *);
+ if (attr & CFG_ATTR_COPY)
+ value = strdup(value);
+ if (node->owner & CFG_NODE_ATTR_TOKEN && node->token != NULL)
free(node->token);
- node->token = (char *)va_arg(ap, char *);
- if (node->token != NULL)
- node->token = strdup(node->token);
+ node->token = value;
+ if (attr & (CFG_ATTR_COPY|CFG_ATTR_GIFT))
+ node->owner |= CFG_NODE_ATTR_TOKEN;
break;
}
case CFG_NODE_ATTR_DATA: {
return CFG_ERR_USE;
}
case CFG_NODE_ATTR_SRCNAME: {
- if (node->srcname != NULL)
+ char *value = (char *)va_arg(ap, char *);
+ if (attr & CFG_ATTR_COPY)
+ value = strdup(value);
+ if (node->owner & CFG_NODE_ATTR_SRCNAME && node->srcname != NULL)
free(node->srcname);
- node->srcname = (char *)va_arg(ap, char *);
- if (node->srcname != NULL)
- node->srcname = strdup(node->srcname);
+ node->srcname = value;
+ if (attr & (CFG_ATTR_COPY|CFG_ATTR_GIFT))
+ node->owner |= CFG_NODE_ATTR_SRCNAME;
break;
}
case CFG_NODE_ATTR_SRCPOS: {
@@ -220,6 +237,7 @@
return n;
}
+/* get a node attribute */
cfg_rc_t
cfg_node_get(
cfg_t *cfg,
@@ -327,6 +345,10 @@
if (token == NULL)
return CFG_ERR_ARG;
*token = node->token;
+ if (attr & CFG_ATTR_COPY)
+ *token = strdup(*token);
+ if (attr & CFG_ATTR_GIFT)
+ node->token = NULL;
break;
}
case CFG_NODE_ATTR_DATA: {
@@ -341,6 +363,10 @@
if (name == NULL)
return CFG_ERR_ARG;
*name = node->srcname;
+ if (attr & CFG_ATTR_COPY)
+ *name = strdup(*name);
+ if (attr & CFG_ATTR_GIFT)
+ node->srcname = NULL;
break;
}
case CFG_NODE_ATTR_SRCPOS: {
@@ -721,26 +747,45 @@
void *cb_ctx_cb)
{
cfg_rc_t rc;
+ cfg_node_t *child1;
+ cfg_node_t *rbroth;
/* argument sanity checking */
if (cfg == NULL)
return CFG_ERR_ARG;
- if (node != NULL) {
- if ((rc = cb_fct_cmp(cfg, node, cb_ctx_cmp)) == CFG_OK)
- cb_fct_cb(cfg, node, cb_ctx_cb);
- if (rc != CFG_ERR_NDE)
+
+ /* short-circuit processing */
+ if (node == NULL)
+ return CFG_OK;
+
+ /* remember traversing informations from child and brother
+ (important in case the callbacks destroy it) */
+ child1 = node->child1;
+ rbroth = node->rbroth;
+
+ /* check whether the node matches */
+ if (cb_fct_cmp != NULL)
+ rc = cb_fct_cmp(cfg, node, cb_ctx_cmp);
+ else
+ rc = CFG_OK;
+
+ /* if node matched, apply optional callback on node */
+ if (rc == CFG_OK && cb_fct_cb != NULL)
+ if ((rc = cb_fct_cb(cfg, node, cb_ctx_cb)) != CFG_OK)
return rc;
- if (node->child1 != NULL)
- if ((rc = cfg_node_apply(cfg, node->child1,
- cb_fct_cmp, cb_ctx_cmp,
- cb_fct_cb, cb_ctx_cb)) != CFG_OK)
- return rc;
- if (node->rbroth != NULL)
- if ((rc = cfg_node_apply(cfg, node->rbroth,
- cb_fct_cmp, cb_ctx_cmp,
- cb_fct_cb, cb_ctx_cb)) != CFG_OK)
- return rc;
- }
+
+ /* recursively apply on child and brother nodes */
+ if (child1 != NULL)
+ if ((rc = cfg_node_apply(cfg, child1,
+ cb_fct_cmp, cb_ctx_cmp,
+ cb_fct_cb, cb_ctx_cb)) != CFG_OK)
+ return rc;
+ if (rbroth != NULL)
+ if ((rc = cfg_node_apply(cfg, rbroth,
+ cb_fct_cmp, cb_ctx_cmp,
+ cb_fct_cb, cb_ctx_cb)) != CFG_OK)
+ return rc;
+
return CFG_OK;
}
@@ -804,7 +849,7 @@
return CFG_OK;
}
-/* unlink a nodes from others */
+/* unlink a node from others */
cfg_rc_t
cfg_node_unlink(
cfg_t *cfg,
|