ossp-pkg/cfg/cfg_node.c
1.6
/*
** OSSP cfg - Configuration Parsing
** Copyright (c) 1999-2002 Ralf S. Engelschall <rse@engelschall.com>
** Copyright (c) 1999-2002 The OSSP Project (http://www.ossp.org/)
** Copyright (c) 2001-2002 Cable & Wireless Deutschland (http://www.cw.com/de/)
**
** This file is part of OSSP cfg, a configuration parsing
** library which can be found at http://www.ossp.org/pkg/lib/cfg/.
**
** Permission to use, copy, modify, and distribute this software for
** any purpose with or without fee is hereby granted, provided that
** the above copyright notice and this permission notice appear in all
** copies.
**
** THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 AUTHORS AND COPYRIGHT HOLDERS AND THEIR
** 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 CONTRCFG, 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.
**
** cfg_node.c: configuration nodes
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <unistd.h>
#include "cfg_main.h"
#include "cfg_node.h"
cfg_rc_t cfg_node_create(cfg_t *cfg, cfg_node_t **node)
{
cfg_node_t *n;
if (node == NULL)
return CFG_ERR_ARG;
if ((n = malloc(sizeof(cfg_node_t))) == NULL)
return CFG_ERR_SYS;
n->parent = NULL;
n->rbroth = NULL;
n->child1 = NULL;
n->type = CFG_NODE_TYPE_ARG;
n->token = NULL;
cfg_data_init(&n->data);
*node = n;
return CFG_OK;
}
cfg_rc_t cfg_node_destroy(cfg_t *cfg, cfg_node_t *node)
{
if (node == NULL)
return CFG_ERR_ARG;
if (node->token != NULL)
free(node->token);
free(node);
return CFG_OK;
}
cfg_rc_t cfg_node_clone(cfg_t *cfg, cfg_node_t *node, cfg_node_t **node2)
{
if (node == NULL || node2 == NULL)
return CFG_ERR_ARG;
/* FIXME */
return CFG_OK;
}
cfg_rc_t cfg_node_set(cfg_t *cfg, cfg_node_t *node, cfg_node_attr_t attr, ...)
{
va_list ap;
if (node == NULL)
return CFG_ERR_ARG;
va_start(ap, attr);
switch (attr) {
case CFG_NODE_ATTR_TYPE: {
node->type = (cfg_node_type_t)va_arg(ap, cfg_node_type_t);
break;
}
case CFG_NODE_ATTR_PARENT: {
node->parent = (cfg_node_t *)va_arg(ap, cfg_node_t *);
break;
}
case CFG_NODE_ATTR_RBROTH: {
node->rbroth = (cfg_node_t *)va_arg(ap, cfg_node_t *);
break;
}
case CFG_NODE_ATTR_CHILD1: {
node->child1 = (cfg_node_t *)va_arg(ap, cfg_node_t *);
break;
}
case CFG_NODE_ATTR_TOKEN: {
node->token = (char *)va_arg(ap, char *);
break;
}
case CFG_NODE_ATTR_DATA: {
return CFG_ERR_USE;
}
default:
return CFG_ERR_ARG;
}
va_end(ap);
return CFG_OK;
}
cfg_rc_t cfg_node_get(cfg_t *cfg, cfg_node_t *node, cfg_node_attr_t attr, ...)
{
va_list ap;
if (node == NULL)
return CFG_ERR_ARG;
va_start(ap, attr);
switch (attr) {
case CFG_NODE_ATTR_TYPE: {
cfg_node_type_t *type = (cfg_node_type_t *)va_arg(ap, void *);
*type = node->type;
break;
}
case CFG_NODE_ATTR_PARENT: {
cfg_node_t **n = (cfg_node_t **)va_arg(ap, void *);
*n = node->parent;
break;
}
case CFG_NODE_ATTR_RBROTH: {
cfg_node_t **n = (cfg_node_t **)va_arg(ap, void *);
*n = node->rbroth;
break;
}
case CFG_NODE_ATTR_CHILD1: {
cfg_node_t **n = (cfg_node_t **)va_arg(ap, void *);
*n = node->child1;
break;
}
case CFG_NODE_ATTR_TOKEN: {
char **token = (char **)va_arg(ap, char **);
*token = node->token;
break;
}
case CFG_NODE_ATTR_DATA: {
cfg_data_t **data = (cfg_data_t **)va_arg(ap, void *);
*data = &(node->data);
break;
}
default:
return CFG_ERR_ARG;
}
va_end(ap);
return CFG_OK;
}
cfg_rc_t cfg_node_root(cfg_t *cfg, cfg_node_t **node)
{
if (cfg == NULL || node == NULL)
return CFG_ERR_ARG;
*node = cfg->root;
return CFG_OK;
}
cfg_rc_t cfg_node_goto(cfg_t *cfg, cfg_node_t *node, const char *spec, cfg_node_t **node2)
{
if (cfg == NULL || node == NULL || spec == NULL || node2 == NULL)
return CFG_ERR_ARG;
/* FIXME */
#if 0
cfg_node_t *n;
*node2 = NULL;
switch (id) {
case CFG_NODE_GOTO_PARENT: {
*node2 = node->parent;
break;
}
case CFG_NODE_GOTO_LBROTH: {
if ((n = node->parent) != NULL) {
if ((n = n->child1) != NULL) {
while (n->rbroth != node && n->rbroth != NULL)
n = n->rbroth;
if (n->rbroth == node)
*node2 = n;
}
}
break;
}
case CFG_NODE_GOTO_RBROTH: {
*node2 = node->rbroth;
break;
}
case CFG_NODE_GOTO_CHILD1: {
*node2 = node->child1;
break;
}
case CFG_NODE_GOTO_CHILDL: {
if ((n = node->child1) != NULL) {
while (n->rbroth != NULL)
n = n->rbroth;
*node2 = n;
}
break;
}
}
if (*node2 == NULL)
return CFG_ERR_GOT;
#endif
return CFG_OK;
}
cfg_rc_t
cfg_node_select(
cfg_t *cfg,
cfg_node_t *node,
const char *dotpath,
cfg_node_t **node2)
{
/* FIXME */
return CFG_OK;
}
cfg_rc_t
cfg_node_find(
cfg_t *cfg,
cfg_node_t *node,
cfg_rc_t (*cb_fct_cmp)(cfg_t *, cfg_node_t *, void *),
void *cb_ctx_cmp,
cfg_node_t **cont)
{
/* FIXME */
return CFG_OK;
}
cfg_rc_t
cfg_node_apply(
cfg_t *cfg,
cfg_node_t *node,
cfg_rc_t (*cb_fct_cmp)(cfg_t *, cfg_node_t *, void *),
void *cb_ctx_cmp,
cfg_rc_t (*cb_fct_cb)(cfg_t *, cfg_node_t *, void *),
void *cb_ctx_cb)
{
/* FIXME */
#if 0
cfg_rc_t rc;
if (cb_fct == NULL)
return CFG_ERR_ARG;
if (node != NULL) {
cb_fct(cb_ctx, node);
if (node->child1 != NULL)
if ((rc = cfg_node_apply(node->child1, cb_fct, cb_ctx)) != CFG_OK)
return rc;
if (node->rbroth != NULL)
if ((rc = cfg_node_apply(node->rbroth, cb_fct, cb_ctx)) != CFG_OK)
return rc;
}
#endif
return CFG_OK;
}
cfg_rc_t
cfg_node_cmp(
cfg_t *cfg,
cfg_node_t *node,
void *token)
{
/* FIXME */
return CFG_OK;
}
cfg_rc_t cfg_node_link(cfg_t *cfg, cfg_node_t *node, cfg_node_attr_t attr, cfg_node_t *node2)
{
cfg_node_t *n;
if (node == NULL || node2 == NULL)
return CFG_ERR_ARG;
if (attr == CFG_NODE_ATTR_RBROTH) {
/* make node a rbroth */
n = node2;
n->parent = node->parent;
while (n->rbroth != NULL) {
n->parent = node->parent;
n = n->rbroth;
}
n->rbroth = node->rbroth;
node->rbroth = node2;
}
else if (attr == CFG_NODE_ATTR_CHILD1) {
/* make node a child1 */
n = node2;
n->parent = node;
while (n->rbroth != NULL) {
n->parent = node;
n = n->rbroth;
}
n->rbroth = node->child1;
node->child1 = node2;
}
/* FIXME more linkage possibilities */
else
return CFG_ERR_ARG;
return CFG_OK;
}
cfg_rc_t cfg_node_unlink(cfg_t *cfg, cfg_node_t *node)
{
cfg_node_t *n;
if (node == NULL)
return CFG_ERR_ARG;
if (node->parent == NULL)
return CFG_OK;
if (node->parent->child1 == node) {
/* node was a child1 */
node->parent->child1 = node->rbroth;
}
else {
/* node was a rbroth */
n = node->parent->child1;
while (n->rbroth != node)
n = n->rbroth;
n->rbroth = node->rbroth;
}
return CFG_OK;
}