head 1.27; access; symbols FSL_1_7_0:1.27 CFG_0_9_11:1.27 FSL_1_6_1:1.26 CFG_0_9_10:1.26 FSL_1_6_0:1.26 FSL_1_6b2:1.26 CFG_0_9_9:1.26 FSL_1_6b1:1.26 CFG_0_9_8:1.26 CFG_0_9_7:1.24 CFG_0_9_6:1.23 CFG_0_9_5:1.21 CFG_0_9_4:1.20 FSL_1_5_0:1.18 FSL_1_5a3:1.18 CFG_0_9_3:1.18 FSL_1_5a2:1.18 FSL_1_5a1:1.18 FSL_1_4_0:1.18 FSL_1_4b1:1.18 CFG_0_9_2:1.18 CFG_0_9_1:1.18 FSL_1_4a1:1.18 FSL_1_3_0:1.18 FSL_1_3b1:1.18 FSL_1_2_1:1.18 FSL_1_2_0:1.18 FSL_1_1_0:1.18 FSL_1_1b1:1.18 FSL_1_0_8:1.18 FSL_1_0_7:1.18 FSL_1_0_6:1.14 FSL_1_0_5:1.14 FSL_1_0_4:1.14 FSL_1_0_3:1.14 FSL_1_0_2:1.14 FSL_1_0_1:1.14 FSL_1_0_0:1.14 FSL_0_9_0:1.14 CFG_0_9_0:1.13 FSL_0_1_12:1.13 FSL_0_1_11:1.13 FSL_0_1_10:1.13 FSL_0_1_9:1.13 FSL_0_1_8:1.13 FSL_0_1_7:1.13 FSL_0_1_6:1.13 FSL_0_1_5:1.13 FSL_0_1_1:1.13; locks; strict; comment @ * @; 1.27 date 2006.08.10.19.35.57; author rse; state Exp; branches; next 1.26; commitid Isy241gp4yykKkIr; 1.26 date 2005.01.24.14.25.21; author rse; state Exp; branches; next 1.25; 1.25 date 2004.12.31.19.16.25; author rse; state Exp; branches; next 1.24; 1.24 date 2004.12.19.19.36.25; author rse; state Exp; branches; next 1.23; 1.23 date 2004.12.04.12.48.40; author rse; state Exp; branches; next 1.22; 1.22 date 2004.11.29.07.09.33; author rse; state Exp; branches; next 1.21; 1.21 date 2004.11.20.14.52.56; author rse; state Exp; branches; next 1.20; 1.20 date 2004.07.17.14.34.06; author rse; state Exp; branches; next 1.19; 1.19 date 2004.07.17.07.37.55; author rse; state Exp; branches; next 1.18; 1.18 date 2003.01.06.11.17.43; author rse; state Exp; branches; next 1.17; 1.17 date 2002.11.22.14.34.32; author rse; state Exp; branches; next 1.16; 1.16 date 2002.11.18.09.51.29; author rse; state Exp; branches; next 1.15; 1.15 date 2002.11.10.12.12.23; author rse; state Exp; branches; next 1.14; 1.14 date 2002.08.01.11.20.39; author rse; state Exp; branches; next 1.13; 1.13 date 2002.07.18.15.34.55; author rse; state Exp; branches; next 1.12; 1.12 date 2002.07.17.15.04.08; author rse; state Exp; branches; next 1.11; 1.11 date 2002.07.17.14.39.57; author rse; state Exp; branches; next 1.10; 1.10 date 2002.07.17.14.35.09; author rse; state Exp; branches; next 1.9; 1.9 date 2002.07.13.18.52.41; author rse; state Exp; branches; next 1.8; 1.8 date 2002.07.12.19.59.33; author rse; state Exp; branches; next 1.7; 1.7 date 2002.07.10.19.26.32; author rse; state Exp; branches; next 1.6; 1.6 date 2002.07.10.14.46.28; author rse; state Exp; branches; next 1.5; 1.5 date 2002.07.10.12.00.23; author rse; state Exp; branches; next 1.4; 1.4 date 2002.07.05.15.32.42; author rse; state Exp; branches; next 1.3; 1.3 date 2002.07.04.12.30.08; author rse; state Exp; branches; next 1.2; 1.2 date 2002.07.04.06.16.13; author rse; state Exp; branches; next 1.1; 1.1 date 2002.07.03.13.25.34; author rse; state Exp; branches; next ; desc @@ 1.27 log @cleanup source tree for status as of 2006 @ text @/* ** OSSP cfg - Configuration Parsing ** Copyright (c) 2002-2006 Ralf S. Engelschall ** Copyright (c) 2002-2006 The OSSP Project (http://www.ossp.org/) ** ** 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 CONTRACT, 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 #include #include #include #include #include "cfg_main.h" #include "cfg_node.h" #include "cfg_fmt.h" #include "cfg_global.h" /* create a configuration node */ cfg_rc_t cfg_node_create( cfg_t *cfg, cfg_node_t **node) { cfg_node_t *n; cfg_rc_t rc; /* argument sanity checking */ if (node == NULL) return CFG_ERR_ARG; /* allocate memory */ if ((rc = cfg_grid_alloc(cfg->grid_nodes, (void **)(void *)&n)) != CFG_OK) return rc; /* initialize node attributes */ n->owner = 0; n->parent = NULL; n->rbroth = NULL; n->child1 = NULL; n->type = CFG_NODE_TYPE_ARG; n->token = NULL; cfg_data_init(&n->data); n->srcname = NULL; n->srcpos = 0; *node = n; return CFG_OK; } /* destroy a configuration node */ cfg_rc_t cfg_node_destroy( cfg_t *cfg, cfg_node_t *node) { /* argument sanity checking */ if (node == NULL) return CFG_ERR_ARG; /* destroy memory */ if ((node->owner & CFG_NODE_ATTR_TOKEN) && node->token != NULL) free(node->token); 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; } /* clone a node */ cfg_rc_t cfg_node_clone( cfg_t *cfg, cfg_node_t *node, cfg_node_t **node2) { cfg_node_t *n; cfg_rc_t rc; /* argument sanity checking */ if (node == NULL || node2 == NULL) return CFG_ERR_ARG; /* allocate memory for new node */ if ((rc = cfg_grid_alloc(cfg->grid_nodes, (void **)(void *)&n)) != CFG_OK) 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->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; } /* set a node attribute */ cfg_rc_t cfg_node_set( cfg_t *cfg, cfg_node_t *node, cfg_node_attr_t attr, ...) { va_list ap; /* argument sanity checking */ if (node == NULL) return CFG_ERR_ARG; /* dispatch into individual attribute handling */ va_start(ap, 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; } case CFG_NODE_ATTR_LBROTH: { return CFG_ERR_USE; /* cannot be set, only get */ } 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_CHILDL: { return CFG_ERR_USE; /* cannot be set, only get */ } case CFG_NODE_ATTR_CHILDS: { return CFG_ERR_USE; /* cannot be set, only get */ } case CFG_NODE_ATTR_NODES: { return CFG_ERR_USE; /* cannot be set, only get */ } case CFG_NODE_ATTR_DEPTH: { return CFG_ERR_USE; /* cannot be set, only get */ } case CFG_NODE_ATTR_TYPE: { node->type = (cfg_node_type_t)va_arg(ap, cfg_node_type_t); break; } case CFG_NODE_ATTR_TOKEN: { 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 = 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: { 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 = value; if (attr & (CFG_ATTR_COPY|CFG_ATTR_GIFT)) node->owner |= CFG_NODE_ATTR_SRCNAME; break; } case CFG_NODE_ATTR_SRCPOS: { node->srcpos = (int)va_arg(ap, int); break; } default: return CFG_ERR_ARG; } va_end(ap); return CFG_OK; } /* INTERNAL: calculate number of nodes */ static int cfg_node_get_nodes( cfg_node_t *node) { int n; n = 0; if (node != NULL) { n++; if ((node = node->child1) != NULL) { n += cfg_node_get_nodes(node); if ((node = node->rbroth) != NULL) n += cfg_node_get_nodes(node); } } return n; } /* get a node attribute */ cfg_rc_t cfg_node_get( cfg_t *cfg, cfg_node_t *node, cfg_node_attr_t attr, ...) { va_list ap; /* argument sanity checking */ if (node == NULL) return CFG_ERR_ARG; /* dispatch into individual attribute handling */ va_start(ap, attr); switch (attr & ~(CFG_ATTR_LOAN|CFG_ATTR_GIFT|CFG_ATTR_COPY)) { case CFG_NODE_ATTR_PARENT: { cfg_node_t **n = (cfg_node_t **)va_arg(ap, void *); if (n == NULL) return CFG_ERR_ARG; *n = node->parent; break; } case CFG_NODE_ATTR_LBROTH: { cfg_node_t **np = (cfg_node_t **)va_arg(ap, void *); cfg_node_t *n; if (np == NULL) return CFG_ERR_ARG; *np = NULL; if ((n = node->parent) != NULL) { if ((n = n->child1) != NULL) { while (n->rbroth != node && n->rbroth != NULL) n = n->rbroth; if (n->rbroth == node) *np = n; } } break; } case CFG_NODE_ATTR_RBROTH: { cfg_node_t **n = (cfg_node_t **)va_arg(ap, void *); if (n == NULL) return CFG_ERR_ARG; *n = node->rbroth; break; } case CFG_NODE_ATTR_CHILD1: { cfg_node_t **n = (cfg_node_t **)va_arg(ap, void *); if (n == NULL) return CFG_ERR_ARG; *n = node->child1; break; } case CFG_NODE_ATTR_CHILDL: { cfg_node_t **n = (cfg_node_t **)va_arg(ap, void *); if (n == NULL) return CFG_ERR_ARG; if ((*n = node->child1) != NULL) while ((*n)->rbroth != NULL) *n = (*n)->rbroth; break; } case CFG_NODE_ATTR_CHILDS: { int *c = (int *)va_arg(ap, int *); cfg_node_t *n; if (c == NULL) return CFG_ERR_ARG; *c = 0; if ((n = node->child1) != NULL) { (*c)++; while (n->rbroth != NULL) { n = n->rbroth; (*c)++; } } break; } case CFG_NODE_ATTR_NODES: { int *k = (int *)va_arg(ap, int *); if (k == NULL) return CFG_ERR_ARG; *k = cfg_node_get_nodes(node); break; } case CFG_NODE_ATTR_DEPTH: { int *k = (int *)va_arg(ap, int *); cfg_node_t *n; if (k == NULL) return CFG_ERR_ARG; *k = 0; n = node; while ((n = n->parent) != NULL) (*k)++; break; } case CFG_NODE_ATTR_TYPE: { cfg_node_type_t *type = (cfg_node_type_t *)va_arg(ap, void *); if (type == NULL) return CFG_ERR_ARG; *type = node->type; break; } case CFG_NODE_ATTR_TOKEN: { char **token = (char **)va_arg(ap, char **); 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: { cfg_data_t **data = (cfg_data_t **)va_arg(ap, void *); if (data == NULL) return CFG_ERR_ARG; *data = &(node->data); break; } case CFG_NODE_ATTR_SRCNAME: { char **name = (char **)va_arg(ap, char **); 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: { int *pos = (int *)va_arg(ap, int *); if (pos == NULL) return CFG_ERR_ARG; *pos = node->srcpos; break; } default: return CFG_ERR_ARG; } va_end(ap); return CFG_OK; } /* get and/or set root node */ cfg_rc_t cfg_node_root( cfg_t *cfg, cfg_node_t *node, cfg_node_t **node_old) { /* argument sanity checking */ if (cfg == NULL || (node == NULL && node_old == NULL)) return CFG_ERR_ARG; /* optionally get old root node pointer */ if (node_old != NULL) *node_old = cfg->root; /* optionally set new root node pointer */ if (node != NULL) cfg->root = node; return CFG_OK; } /* forward declarations for internal stepping functions */ static cfg_rc_t cfg_node_select_step1( cfg_t *, cfg_node_t *, cfg_node_t ***, long *, const char *); static cfg_rc_t cfg_node_select_step2( cfg_t *, cfg_node_t *, cfg_node_t ***, long *, const char *, const char *, size_t, long, long, long *); /* INTERNAL: selection stepping function (part 3, matching node processing) */ static cfg_rc_t cfg_node_select_step3( cfg_t *cfg, cfg_node_t *node, cfg_node_t ***result_vec, long *result_len, const char *spec, const char *cpSel, size_t nSel, long nFilMin, long nFilMax, long *nFound) { cfg_rc_t rc; #if 0 fprintf(stderr, " step3: (1) cpSel=\"%s\", nSel=%d, spec=\"%s\", nFilMin=%ld, nFilMax=%ld, nFound=%ld\n", cpSel, nSel, spec, nFilMin, nFilMax, *nFound); #endif if (spec[0] == '\0') { /* end of selection, node found */ (*nFound)++; #if 0 fprintf(stderr, " step3: (2) found node!!\n"); fprintf(stderr, " step3: current node=0x%lx type=%s token=\"%s\"\n", (unsigned long)node, (node != NULL ? (node->type == CFG_NODE_TYPE_SEQ ? "SEQ" : (node->type == CFG_NODE_TYPE_DIR ? "DIR" : "ARG")) : "/.."), (node != NULL ? (node->token != NULL ? node->token : "") : "/..")); #endif if (nFilMin <= *nFound && *nFound <= nFilMax) { if (result_len != NULL) { (*result_len)++; if (result_vec != NULL) { if ((*result_vec = (cfg_node_t **)realloc(*result_vec, sizeof(cfg_node_t *)*((*result_len)+1))) == NULL) return CFG_ERR_SYS; (*result_vec)[(*result_len)-1] = node; (*result_vec)[(*result_len)] = NULL; } } } rc = CFG_OK; } else { /* start over with next step */ rc = cfg_node_select_step1(cfg, node, result_vec, result_len, spec); } return rc; } /* INTERNAL: selection stepping function (part 2, node matching) */ static cfg_rc_t cfg_node_select_step2( cfg_t *cfg, cfg_node_t *node, cfg_node_t ***result_vec, long *result_len, const char *spec, const char *cpSel, size_t nSel, long nFilMin, long nFilMax, long *nFound) { cfg_rc_t rc; char *token; cfg_node_t *node2; cfg_node_type_t type; #if 0 fprintf(stderr, " step2: (1) cpSel=\"%.*s\", nSel=%d, spec=\"%s\", nFilMin=%ld, nFilMax=%ld, nFound=%ld\n", nSel, cpSel, nSel, spec, nFilMin, nFilMax, *nFound); fprintf(stderr, " step2: current node=0x%lx type=%s token=\"%s\"\n", (unsigned long)node, (node != NULL ? (node->type == CFG_NODE_TYPE_SEQ ? "SEQ" : (node->type == CFG_NODE_TYPE_DIR ? "DIR" : "ARG")) : "/.."), (node != NULL ? (node->token != NULL ? node->token : "") : "/..")); #endif rc = CFG_OK; if (nSel == 1 && strncmp(cpSel, ".", nSel) == 0) { /* current node (no-op) */ #if 0 fprintf(stderr, " step2: search current node, starting at node 0x%lx\n", (unsigned long)node); #endif rc = cfg_node_select_step3(cfg, node, result_vec, result_len, spec, cpSel, nSel, nFilMin, nFilMax, nFound); } else if (nSel == 2 && strncmp(cpSel, "..", nSel) == 0) { /* parent node */ #if 0 fprintf(stderr, " step2: search parent node, starting at node 0x%lx\n", (unsigned long)node); #endif if (cfg_node_get(cfg, node, CFG_NODE_ATTR_PARENT, &node) == CFG_OK && node != NULL) rc = cfg_node_select_step3(cfg, node, result_vec, result_len, spec, cpSel, nSel, nFilMin, nFilMax, nFound); } else if (nSel == 4 && strncmp(cpSel, "....", nSel) == 0) { /* anchestor nodes */ #if 0 fprintf(stderr, " step2: search ancestor nodes, starting at node 0x%lx\n", (unsigned long)node); #endif while (cfg_node_get(cfg, node, CFG_NODE_ATTR_PARENT, &node) == CFG_OK && node != NULL) if ((rc = cfg_node_select_step3(cfg, node, result_vec, result_len, spec, cpSel, nSel, nFilMin, nFilMax, nFound)) != CFG_OK) break; } else if (nSel == 1 && strncmp(cpSel, "-", nSel) == 0) { /* previous sibling node */ #if 0 fprintf(stderr, " step2: search previous sibling node, starting at node 0x%lx\n", (unsigned long)node); #endif if ((rc = cfg_node_get(cfg, node, CFG_NODE_ATTR_LBROTH, &node)) == CFG_OK && node != NULL) rc = cfg_node_select_step3(cfg, node, result_vec, result_len, spec, cpSel, nSel, nFilMin, nFilMax, nFound); } else if (nSel == 2 && strncmp(cpSel, "--", nSel) == 0) { /* preceeding sibling nodes */ #if 0 fprintf(stderr, " step2: search preceeding sibling nodes, starting at node 0x%lx\n", (unsigned long)node); #endif while (cfg_node_get(cfg, node, CFG_NODE_ATTR_LBROTH, &node) == CFG_OK && node != NULL) if ((rc = cfg_node_select_step3(cfg, node, result_vec, result_len, spec, cpSel, nSel, nFilMin, nFilMax, nFound)) != CFG_OK) break; } else if (nSel == 1 && strncmp(cpSel, "+", nSel) == 0) { /* next sibling node */ #if 0 fprintf(stderr, " step2: search next sibling node, starting at node 0x%lx\n", (unsigned long)node); #endif if ((rc = cfg_node_get(cfg, node, CFG_NODE_ATTR_RBROTH, &node)) == CFG_OK && node != NULL) rc = cfg_node_select_step3(cfg, node, result_vec, result_len, spec, cpSel, nSel, nFilMin, nFilMax, nFound); } else if (nSel == 2 && strncmp(cpSel, "++", nSel) == 0) { /* following sibling nodes */ #if 0 fprintf(stderr, " step2: search following sibling nodes, starting at node 0x%lx\n", (unsigned long)node); #endif while (cfg_node_get(cfg, node, CFG_NODE_ATTR_RBROTH, &node) == CFG_OK && node != NULL) if ((rc = cfg_node_select_step3(cfg, node, result_vec, result_len, spec, cpSel, nSel, nFilMin, nFilMax, nFound)) != CFG_OK) break; } else if (nSel == 0 /* "//" */) { /* descendant nodes */ #if 0 fprintf(stderr, " step2: search descendant nodes, starting at node 0x%lx\n", (unsigned long)node); #endif #if 0 /* FIXME */ if ((rc = cfg_node_apply(cfg, node, NULL, NULL, cfg_node_select_step2_descendant, &descendant_ctx) cfg_rc_t cfg_node_select_step2_descendant(cfg_t *cfg, cfg_node_t *node, void *_ctx)); #endif if ((rc = cfg_node_get(cfg, node, CFG_NODE_ATTR_CHILD1, &node)) == CFG_OK && node != NULL) { do { if ((rc = cfg_node_select_step3(cfg, node, result_vec, result_len, spec, cpSel, nSel, nFilMin, nFilMax, nFound)) != CFG_OK) return rc; if ((rc = cfg_node_select_step2(cfg, node, result_vec, result_len, spec, cpSel, nSel, nFilMin, nFilMax, nFound)) != CFG_OK) return rc; } while ((rc = cfg_node_get(cfg, node, CFG_NODE_ATTR_RBROTH, &node)) == CFG_OK && node != NULL); } return CFG_OK; } else { /* child node */ #if 0 fprintf(stderr, " step2: search child nodes, starting at node 0x%lx\n", (unsigned long)node); #endif if ((rc = cfg_node_get(cfg, node, CFG_NODE_ATTR_CHILD1, &node)) == CFG_OK && node != NULL) { do { if ((rc = cfg_node_get(cfg, node, CFG_NODE_ATTR_TOKEN, &token)) != CFG_OK) continue; if ((rc = cfg_node_get(cfg, node, CFG_NODE_ATTR_TYPE, &type)) == CFG_OK && type == CFG_NODE_TYPE_DIR) { if ((rc = cfg_node_get(cfg, node, CFG_NODE_ATTR_CHILD1, &node2)) != CFG_OK || node2 == NULL) continue; if ((rc = cfg_node_get(cfg, node2, CFG_NODE_ATTR_TOKEN, &token)) != CFG_OK) continue; } if (token != NULL) { size_t l = strlen(token); #if 0 fprintf(stderr, " step2: compare child node: token \"%s\"\n", token); #endif if ( (l == 1 && nSel == 1 && token[0] == '*') || (l == nSel && strncmp(token, cpSel, nSel) == 0)) { if ((rc = cfg_node_select_step3(cfg, node, result_vec, result_len, spec, cpSel, nSel, nFilMin, nFilMax, nFound)) != CFG_OK) return rc; } } } while ((rc = cfg_node_get(cfg, node, CFG_NODE_ATTR_RBROTH, &node)) == CFG_OK && node != NULL); } return CFG_OK; } return rc; } /* INTERNAL: selection stepping function (part 1, selection parsing) */ static cfg_rc_t cfg_node_select_step1( cfg_t *cfg, cfg_node_t *node, cfg_node_t ***result_vec, long *result_len, const char *spec) { const char *cpSel; size_t nSel; long nFilMin, nFilMax; long n; const char *cp; char *cp2; cfg_rc_t rc; long nFound; #if 0 fprintf(stderr, " step1: (0) spec=\"%s\"\n", spec); #endif /* stop processing if spec is empty */ if (spec[0] == '\0') return CFG_OK; /* determine selection step information */ cpSel = spec; nSel = strcspn(cpSel, "[/"); cp = cpSel+nSel; nFilMin = 1; nFilMax = LONG_MAX; if (*cp == '[') { cp++; n = strtol(cp, &cp2, 10); if (cp2 > cp && n != 0) nFilMin = n; cp = cp2; if (*cp == ',') { cp++; n = strtol(cp, &cp2, 10); if (cp2 > cp && n != 0) nFilMax = n; cp = cp2; } else nFilMax = nFilMin; if (*cp != ']') { cfg_error_info(cfg, CFG_ERR_ARG, "invalid selection specification filter range"); return CFG_ERR_ARG; } cp++; } if (*cp == '/') cp++; spec = cp; #if 0 fprintf(stderr, " step1: (1) cpSel=\"%s\", nSel=%d, spec=\"%s\", nFilMin=%ld, nFilMax=%ld\n", cpSel, nSel, spec, nFilMin, nFilMax); #endif /* perform pre-selection if filter range is relative to last element */ if (nFilMin < 0 || nFilMax < 0) { nFound = 0; #if 0 fprintf(stderr, " step1: pre-selection start\n"); #endif if ((rc = cfg_node_select_step2(cfg, node, NULL, NULL, spec, cpSel, nSel, 1, LONG_MAX, &nFound)) != CFG_OK) return rc; #if 0 fprintf(stderr, " step1: (1b) cpSel=\"%s\", nSel=%d, spec=\"%s\", nFilMin=%ld, nFilMax=%ld nFound=%ld\n", cpSel, nSel, spec, nFilMin, nFilMax, nFound); fprintf(stderr, " step1: pre-selection end\n"); #endif if (nFound == 0) return CFG_OK; if (nFilMin < 0) { nFilMin = nFound + (nFilMin+1); if (nFilMin < 1) nFilMin = 1; } if (nFilMax < 0) { nFilMax = nFound + (nFilMax+1); if (nFilMax < 1) nFilMax = 1; } } #if 0 fprintf(stderr, " step1: (2) cpSel=\"%s\", nSel=%d, spec=\"%s\", nFilMin=%ld, nFilMax=%ld\n", cpSel, nSel, spec, nFilMin, nFilMax); #endif /* perform real selection */ nFound = 0; if ((rc = cfg_node_select_step2(cfg, node, result_vec, result_len, spec, cpSel, nSel, nFilMin, nFilMax, &nFound)) != CFG_OK) return rc; #if 0 fprintf(stderr, " step1: (3) cpSel=\"%s\", nSel=%d, spec=\"%s\", nFilMin=%ld, nFilMax=%ld nFound=%ld\n", cpSel, nSel, spec, nFilMin, nFilMax, nFound); #endif return CFG_OK; } /* select a node */ cfg_rc_t cfg_node_select( cfg_t *cfg, cfg_node_t *node, cfg_node_t ***result_vec, const char *fmt, ...) { cfg_rc_t rc; va_list ap; char *spec; char *cp; long result_len; /* argument sanity checking */ if (cfg == NULL || result_vec == NULL || fmt == NULL) return CFG_ERR_ARG; /* on-the-fly create or just take over specification string */ va_start(ap, fmt); spec = cfg_fmt_vasprintf(fmt, ap); va_end(ap); if (spec == NULL) return CFG_ERR_FMT; #if 0 fprintf(stderr, "select: (1) spec=\"%s\"\n", spec); #endif /* special cases for absolute (start from root-node) selection */ cp = spec; if (cp[0] == '/') { /* is same as */ if (node != NULL) return CFG_ERR_USE; node = cfg->root; cp++; } else if (node == NULL) { /* is same as */ node = cfg->root; } #if 0 fprintf(stderr, "select: (2) spec=\"%s\"\n", cp); #endif /* initialize result node array */ result_len = 0; if ((*result_vec = (cfg_node_t **)malloc(sizeof(cfg_node_t *)*(result_len+1))) == NULL) return CFG_ERR_SYS; (*result_vec)[result_len] = NULL; /* perform the selection stepping */ if ((rc = cfg_node_select_step1(cfg, node, result_vec, &result_len, cp)) != CFG_OK) { free(*result_vec); return rc; } #if 0 fprintf(stderr, "select: (3) result_len=%ld\n", result_len); #endif return CFG_OK; } /* return next matching node (iteration) */ 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_ERR_INT; } /* apply for each matching node (recursion) */ 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) { cfg_rc_t rc; cfg_node_t *child1; cfg_node_t *rbroth; /* argument sanity checking */ if (cfg == NULL) return CFG_ERR_ARG; /* 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; /* 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; } /* compare two nodes */ cfg_rc_t cfg_node_cmp( cfg_t *cfg, cfg_node_t *node, void *token) { /* argument sanity checking */ if (cfg == NULL || node == NULL || token == NULL) return CFG_ERR_NDE; if (node->token == NULL && token == NULL) return CFG_OK; if (node->token == NULL || token == NULL) return CFG_ERR_NDE; if (strcmp(node->token, (char *)token) == 0) return CFG_OK; return CFG_ERR_NDE; } /* link to nodes together */ 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; /* argument sanity checking */ 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; } /* unlink a node from others */ cfg_rc_t cfg_node_unlink( cfg_t *cfg, cfg_node_t *node) { cfg_node_t *n; /* argument sanity checking */ 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; } @ 1.26 log @Remove debugging fprintf's from (still broken) cfg_node_select() function. @ text @d3 2 a4 3 ** Copyright (c) 2002-2005 Ralf S. Engelschall ** Copyright (c) 2002-2005 The OSSP Project (http://www.ossp.org/) ** Copyright (c) 2002-2005 Cable & Wireless (http://www.cw.com/) @ 1.25 log @Adjust copyright messages for new year 2005. @ text @d430 1 d433 1 d438 1 d444 1 d481 1 d488 1 d493 1 d495 1 d500 1 d502 1 d508 1 d510 1 d517 1 d519 1 d525 1 d527 1 d534 1 d536 1 d542 1 d544 1 d551 1 d553 1 d570 1 d572 1 d585 1 d587 1 d617 1 d619 1 d656 1 d659 1 d664 1 d666 1 d669 1 d673 1 d688 1 d691 1 d698 1 d701 1 d731 1 d733 1 d748 1 d750 1 d763 1 d765 1 @ 1.24 log @Fixed cfg_node_get() function after recent introduction of LOAN/GIFT/COPY argument passing semantics. This inbreaks the Perl API's unpack() function. @ text @d3 3 a5 3 ** Copyright (c) 2002-2004 Ralf S. Engelschall ** Copyright (c) 2002-2004 The OSSP Project (http://www.ossp.org/) ** Copyright (c) 2002-2004 Cable & Wireless (http://www.cw.com/) @ 1.23 log @Plug remaining memory leaks by introducing the usual LOAN/GIFT/COPY argument passing semantics to cfg_node_{set,get} and using this to directly pass the allocated tokens from the scanner through the parser into the node tree. @ text @d256 1 a256 1 switch (attr) { @ 1.22 log @Fix optional DMalloc build support. @ text @d60 1 d85 1 a85 1 if (node->token != NULL) d87 1 a87 1 if (node->srcname != NULL) d89 1 d114 1 d119 9 a127 1 n->token = (node->token != NULL ? strdup(node->token) : NULL); d129 2 a130 2 n->srcname = (node->srcname != NULL ? strdup(node->srcname) : NULL); n->srcpos = node->srcpos; d152 1 a152 1 switch (attr) { d185 4 a188 1 if (node->token != NULL) d190 3 a192 3 node->token = (char *)va_arg(ap, char *); if (node->token != NULL) node->token = strdup(node->token); d199 4 a202 1 if (node->srcname != NULL) d204 3 a206 3 node->srcname = (char *)va_arg(ap, char *); if (node->srcname != NULL) node->srcname = strdup(node->srcname); d240 1 d348 4 d366 4 d750 2 d756 31 a786 4 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) d788 1 a788 11 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; } d852 1 a852 1 /* unlink a nodes from others */ @ 1.21 log @Change cfg_node_root() API function to be able to both set and/or get the root node. @ text @a36 1 #include "cfg_global.h" d40 1 @ 1.20 log @Fixed warnings under GCC 3.4/3.5. @ text @d361 1 a361 1 /* return root node */ d365 2 a366 1 cfg_node_t **node) d369 1 a369 1 if (cfg == NULL || node == NULL) d372 7 a378 2 /* just return the root pointer */ *node = cfg->root; @ 1.19 log @Adjust copyright messages for new year 2004. @ text @d56 1 a56 1 if ((rc = cfg_grid_alloc(cfg->grid_nodes, (void **)&n)) != CFG_OK) d108 1 a108 1 if ((rc = cfg_grid_alloc(cfg->grid_nodes, (void **)&n)) != CFG_OK) @ 1.18 log @update copyright messages for new year @ text @d3 3 a5 3 ** Copyright (c) 2002-2003 Ralf S. Engelschall ** Copyright (c) 2002-2003 The OSSP Project (http://www.ossp.org/) ** Copyright (c) 2002-2003 Cable & Wireless Deutschland (http://www.cw.com/de/) @ 1.17 log @more code cleanups to node sub-API @ text @d3 3 a5 3 ** Copyright (c) 1999-2002 Ralf S. Engelschall ** Copyright (c) 1999-2002 The OSSP Project (http://www.ossp.org/) ** Copyright (c) 2001-2002 Cable & Wireless Deutschland (http://www.cw.com/de/) @ 1.16 log @add Dmalloc support @ text @d42 5 a46 1 cfg_rc_t cfg_node_create(cfg_t *cfg, cfg_node_t **node) d51 1 d54 2 d58 2 a60 1 n->lbroth = NULL; a62 2 n->srcname = NULL; n->srcpos = 0; d66 2 d69 1 d73 5 a77 1 cfg_rc_t cfg_node_destroy(cfg_t *cfg, cfg_node_t *node) d79 1 d82 2 d89 1 d93 6 a98 1 cfg_rc_t cfg_node_clone(cfg_t *cfg, cfg_node_t *node, cfg_node_t **node2) d103 1 d106 2 d110 2 a112 1 n->lbroth = node->lbroth; a114 2 n->srcname = (node->srcname != NULL ? strdup(node->srcname) : NULL); n->srcpos = node->srcpos; d118 2 d121 1 d125 7 a131 1 cfg_rc_t cfg_node_set(cfg_t *cfg, cfg_node_t *node, cfg_node_attr_t attr, ...) d135 1 d138 2 d147 1 a147 1 return CFG_ERR_USE; d158 1 a158 1 return CFG_ERR_USE; d161 1 a161 1 return CFG_ERR_USE; d164 1 a164 1 return CFG_ERR_USE; d167 1 a167 13 return CFG_ERR_USE; } case CFG_NODE_ATTR_SRCNAME: { if (node->srcname != NULL) free(node->srcname); node->srcname = (char *)va_arg(ap, char *); if (node->srcname != NULL) node->srcname = strdup(node->srcname); break; } case CFG_NODE_ATTR_SRCPOS: { node->srcpos = (int)va_arg(ap, int); break; d184 12 d200 1 d204 4 a207 1 static int cfg_node_get_nodes(cfg_node_t *node) d223 6 a228 1 cfg_rc_t cfg_node_get(cfg_t *cfg, cfg_node_t *node, cfg_node_attr_t attr, ...) d232 1 d235 2 a317 14 case CFG_NODE_ATTR_SRCNAME: { char **name = (char **)va_arg(ap, char **); if (name == NULL) return CFG_ERR_ARG; *name = node->srcname; break; } case CFG_NODE_ATTR_SRCPOS: { int *pos = (int *)va_arg(ap, int *); if (pos == NULL) return CFG_ERR_ARG; *pos = node->srcpos; break; } d339 14 d357 1 d361 5 a365 1 cfg_rc_t cfg_node_root(cfg_t *cfg, cfg_node_t **node) d367 1 d370 2 d373 1 d377 1 d385 1 d398 2 a399 1 fprintf(stderr, "step3: (1) cpSel=\"%s\", nSel=%d, nFilMin=%ld, nFilMax=%ld, nFound=%ld\n", cpSel, nSel, nFilMin, nFilMax, *nFound); d403 6 a408 2 *nFound++; fprintf(stderr, "step3: found node=0x%lx!!\n", (unsigned long)node); d410 1 a410 1 if (result_len != NULL) d412 6 a417 5 if (result_vec != NULL) { if ((*result_vec = (cfg_node_t **)realloc(*result_vec, sizeof(cfg_node_t *)*((*result_len)+1))) == NULL) return CFG_ERR_SYS; (*result_vec)[(*result_len)-1] = node; (*result_vec)[(*result_len)] = NULL; d423 1 d429 1 d442 2 d445 6 a450 1 fprintf(stderr, "step2: (1) cpSel=\"%s\", nSel=%d, nFilMin=%ld, nFilMax=%ld, nFound=%ld\n", cpSel, nSel, nFilMin, nFilMax, *nFound); d452 2 a453 1 if (strncmp(cpSel, ".", nSel) == 0) { d455 2 a456 1 return cfg_node_select_step3(cfg, node, result_vec, result_len, spec, cpSel, nSel, nFilMin, nFilMax, nFound); d458 1 a458 1 else if (strncmp(cpSel, "..", nSel) == 0) { d460 3 a462 6 if ((node = node->parent) == NULL) return CFG_OK; if (node->type == CFG_NODE_TYPE_DIR) if ((node = node->parent) == NULL) return CFG_OK; return cfg_node_select_step3(cfg, node, result_vec, result_len, spec, cpSel, nSel, nFilMin, nFilMax, nFound); d464 1 a464 1 else if (strncmp(cpSel, "....", nSel) == 0) { d466 2 a467 4 while ((node = node->parent) != NULL) { if (node->type == CFG_NODE_TYPE_DIR) if ((node = node->parent) == NULL) break; d469 1 a469 3 return rc; } return CFG_OK; d471 1 a471 1 else if (strncmp(cpSel, "-", nSel) == 0) { d473 3 a475 3 if ((rc = cfg_node_get(cfg, node, CFG_NODE_ATTR_LBROTH, &node)) != CFG_OK) return CFG_OK; return cfg_node_select_step3(cfg, node, result_vec, result_len, spec, cpSel, nSel, nFilMin, nFilMax, nFound); d477 1 a477 1 else if (strncmp(cpSel, "--", nSel) == 0) { d479 2 a480 1 while ((rc = cfg_node_get(cfg, node, CFG_NODE_ATTR_LBROTH, &node)) == CFG_OK) d482 1 a482 2 return rc; return CFG_OK; d484 1 a484 1 else if (strncmp(cpSel, "+", nSel) == 0) { d486 3 a488 3 if ((rc = cfg_node_get(cfg, node, CFG_NODE_ATTR_RBROTH, &node)) != CFG_OK) return CFG_OK; return cfg_node_select_step3(cfg, node, result_vec, result_len, spec, cpSel, nSel, nFilMin, nFilMax, nFound); d490 1 a490 1 else if (strncmp(cpSel, "++", nSel) == 0) { d492 2 a493 1 while ((rc = cfg_node_get(cfg, node, CFG_NODE_ATTR_RBROTH, &node)) == CFG_OK) d495 1 a495 2 return rc; return CFG_OK; d497 1 a497 1 else if (nSel == 0) { d499 9 a507 2 if ((rc = cfg_node_get(cfg, node, CFG_NODE_ATTR_CHILD1, &node)) == CFG_OK) while ((rc = cfg_node_get(cfg, node, CFG_NODE_ATTR_RBROTH, &node)) == CFG_OK) d510 2 d516 19 a534 17 fprintf(stderr, "step2: child node 0x%lx\n", (unsigned long)node); if ((node = node->child1) == NULL) return CFG_OK; if (node->type == CFG_NODE_TYPE_DIR) if ((node = node->child1) == NULL) return CFG_OK; fprintf(stderr, "step2: child node 0x%lx\n", (unsigned long)node); do { if (node->token != NULL) { size_t l; token = node->token; l = strlen(token); fprintf(stderr, "step2: child node: \"%s\"\n", token); if ( (l == 1 && l == nSel && token[0] == '*') || (l == nSel && strncmp(token, cpSel, nSel) == 0)) { if ((rc = cfg_node_select_step3(cfg, node, result_vec, result_len, spec, cpSel, nSel, nFilMin, nFilMax, nFound)) != CFG_OK) return rc; d536 2 a537 2 } } while ((node = node->rbroth) != NULL); d543 1 d559 1 a559 1 fprintf(stderr, "step1(spec=\"%s\")\n", spec); d596 2 a597 1 fprintf(stderr, " step1: (1) cpSel=\"%s\", nSel=%d, nFilMin=%ld, nFilMax=%ld\n", cpSel, nSel, nFilMin, nFilMax); d601 18 a618 18 if (nFilMin == -1) nFilMin = LONG_MAX; if (nFilMax == -1) nFilMax = LONG_MAX; if (nFilMin < 0 || nFilMax < 0) { nFound = 0; if ((rc = cfg_node_select_step2(cfg, node, NULL, NULL, spec, cpSel, nSel, 1, LONG_MAX, &nFound)) != CFG_OK) return rc; if (nFilMin < 0) { nFilMin = nFound + nFilMin; if (nFilMin < 1) nFilMin = 1; } if (nFilMax < 0) { nFilMax = nFound + nFilMax; if (nFilMax < 1) nFilMax = 1; } d622 2 a623 1 fprintf(stderr, " step1: (2) cpSel=\"%s\", nSel=%d, nFilMin=%ld, nFilMax=%ld\n", cpSel, nSel, nFilMin, nFilMax); d630 3 d636 1 d651 1 d661 1 d663 1 a663 1 /* special case for absolute (start from root-node) selection */ d666 3 d672 2 a673 1 if (node == NULL) d675 2 d689 1 d694 1 d707 1 d719 1 d741 1 d748 1 d760 7 a766 1 cfg_rc_t cfg_node_link(cfg_t *cfg, cfg_node_t *node, cfg_node_attr_t attr, cfg_node_t *node2) d770 1 d801 5 a805 1 cfg_rc_t cfg_node_unlink(cfg_t *cfg, cfg_node_t *node) d809 1 d812 1 @ 1.15 log @remove trailing whitespaces @ text @d37 1 @ 1.14 log @get rid of warning @ text @d263 1 a263 1 *k = 0; d319 1 a319 1 static cfg_rc_t d322 1 a322 1 static cfg_rc_t d326 1 a326 1 static cfg_rc_t d328 3 a330 3 cfg_t *cfg, cfg_node_t *node, cfg_node_t ***result_vec, long *result_len, d362 1 a362 1 static cfg_rc_t d364 3 a366 3 cfg_t *cfg, cfg_node_t *node, cfg_node_t ***result_vec, long *result_len, d462 1 a462 1 static cfg_rc_t d464 3 a466 3 cfg_t *cfg, cfg_node_t *node, cfg_node_t ***result_vec, long *result_len, d484 1 a484 1 cpSel = spec; d551 4 a554 4 cfg_t *cfg, cfg_node_t *node, cfg_node_t ***result_vec, const char *fmt, d597 1 a597 1 cfg_rc_t d599 2 a600 2 cfg_t *cfg, cfg_node_t *node, d602 1 a602 1 void *cb_ctx_cmp, d609 1 a609 1 cfg_rc_t d611 2 a612 2 cfg_t *cfg, cfg_node_t *node, d628 1 a628 1 if ((rc = cfg_node_apply(cfg, node->child1, d633 1 a633 1 if ((rc = cfg_node_apply(cfg, node->rbroth, d643 2 a644 2 cfg_t *cfg, cfg_node_t *node, d672 1 a672 1 n->rbroth = node->rbroth; d687 1 a687 1 else @ 1.13 log @flush work of today: first cut for real cfg_node_select() @ text @d446 1 d448 1 a448 1 size_t l = strlen(token); @ 1.12 log @Ops, fix a typo I cannot imagine where it comes from... @ text @d35 1 d39 1 d319 16 a334 1 cfg_rc_t cfg_node_select(cfg_t *cfg, cfg_node_t *node, cfg_node_t **node2, const char *fmt, ...) d336 221 a556 2 #if 0 cfg_node_t *n; a557 2 char *cpB; char *cpE; d559 2 d562 1 a562 1 if (cfg == NULL || node == NULL || node2 == NULL || spec == NULL) d567 1 a567 1 spec = l2_util_vasprintf(fmt, ap); d569 11 d581 10 a590 12 /* enter the parsing loop */ cpE = spec; while (*cpE != '\0') { /* determine begin of parameter name */ cpB = cpE; if ((n = strspn(cpB, " \t\r\n")) > 0) cpB += n; /* determine end of parameter name */ cpE = cpB; if ((n = strspn(cpB, " \t\r\n")) > 0) cpB += n; d592 1 a592 1 #endif @ 1.11 log @now finally use the grid allocator for the tree nodes @ text @d23 1 a23 1 ** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRCFG, STRICT LIABILITY, @ 1.10 log @make available at least the recursive traversal function @ text @d42 1 d46 2 a47 2 if ((n = malloc(sizeof(cfg_node_t))) == NULL) return CFG_ERR_SYS; d69 1 a69 1 free(node); d76 1 d80 2 a81 2 if ((n = malloc(sizeof(cfg_node_t))) == NULL) return CFG_ERR_SYS; @ 1.9 log @implement more missing code @ text @d357 2 a358 16 #if 0 cfg_rc_t rc; if (cfg == 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; d372 1 a372 1 if (cfg == NULL || node == NULL || cb_fct_cb == NULL) d374 4 a377 6 node = NULL; if (node == NULL) if ((node = cfg->root) == NULL) return CFG_OK; do { if ((rc = cb_fct_cb(cfg, node, cb_ctx_cb)) != CFG_OK) d379 11 a389 3 } while ((rc = cfg_node_find(cfg, node, cb_fct_cmp, cb_ctx_cmp, &node)) == CFG_OK); if (rc != CFG_OK && rc != CFG_ERR_NDE) return rc; @ 1.8 log @just flush work of this evening @ text @d357 15 a371 1 /* FIXME */ a383 2 /* FIXME */ #if 0 d386 1 a386 1 if (cb_fct == NULL) d388 10 a397 10 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 d407 9 a415 2 /* FIXME */ return CFG_OK; @ 1.7 log @implement cfg_node_clone @ text @d51 2 a54 2 n->name = NULL; n->offset = 0; d66 2 a67 2 if (node->name != NULL) free(node->name); d84 2 d87 1 a87 9 if (node->token != NULL) n->token = strdup(node->token); else n->token = NULL; if (node->name != NULL) n->name = strdup(node->name); else n->name = NULL; n->offset = node->offset; a100 4 case CFG_NODE_ATTR_TYPE: { node->type = (cfg_node_type_t)va_arg(ap, cfg_node_type_t); break; } d105 3 d116 28 d145 2 d148 2 d162 16 a185 5 case CFG_NODE_ATTR_TYPE: { cfg_node_type_t *type = (cfg_node_type_t *)va_arg(ap, void *); *type = node->type; break; } d188 2 d193 16 d211 2 d218 2 d223 63 d288 2 d295 2 d315 1 a315 1 cfg_rc_t cfg_node_goto(cfg_t *cfg, cfg_node_t *node, const char *spec, cfg_node_t **node2) d317 6 d324 1 a324 1 if (cfg == NULL || node == NULL || spec == NULL || node2 == NULL) d326 18 a343 36 /* 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; } a344 2 if (*node2 == NULL) return CFG_ERR_GOT; a345 11 return CFG_OK; } cfg_rc_t cfg_node_select( cfg_t *cfg, cfg_node_t *node, const char *dotpath, cfg_node_t **node2) { /* FIXME */ @ 1.6 log @Step 2 in API overhauling and implementation filling. @ text @d48 1 d53 2 d66 2 d74 2 d78 18 a95 1 /* FIXME */ @ 1.5 log @Mega-change: full API overhauling. @ text @d43 2 d166 1 a166 1 cfg_rc_t cfg_node_goto(cfg_t *cfg, cfg_node_t **node, const char *spec) d169 1 a169 1 if (cfg == NULL || node == NULL || spec == NULL) @ 1.4 log @thanks to Dmalloc we can fix the memory holes @ text @d36 1 d39 1 a39 1 cfg_rc_t cfg_node_create(cfg_node_t **node) d48 1 a48 1 n->type = CFG_NODE_TYPE_TOK; d55 19 a73 1 cfg_rc_t cfg_node_set(cfg_node_t *node, cfg_node_attr_t attr, ...) d111 1 a111 1 cfg_rc_t cfg_node_get(cfg_node_t *node, cfg_node_attr_t attr, ...) d156 9 a164 1 cfg_rc_t cfg_node_goto(cfg_node_t *node, cfg_node_goto_t id, cfg_node_t **node2) a165 1 cfg_node_t *n; d167 1 a167 1 if (node == NULL || node2 == NULL) d169 3 d208 24 d235 39 a273 1 cfg_rc_t cfg_node_link(cfg_node_t *node, cfg_node_link_t id, cfg_node_t *node2) d279 1 a279 1 if (id == CFG_NODE_LINK_RBROTH) { d290 1 a290 1 else if (id == CFG_NODE_LINK_CHILD1) { d301 3 d307 1 a307 1 cfg_rc_t cfg_node_unlink(cfg_node_t *node) a325 28 return CFG_OK; } cfg_rc_t cfg_node_apply(cfg_node_t *node, void (*cb_fct)(void *, cfg_node_t *), void *cb_ctx) { 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; } return CFG_OK; } cfg_rc_t cfg_node_destroy(cfg_node_t *node) { if (node == NULL) return CFG_ERR_ARG; if (node->token != NULL) free(node->token); free(node); @ 1.3 log @add a new cfg_node_goto() function @ text @d257 2 @ 1.2 log @split out cfg_data_t stuff into seperate object to get better abstraction for this @ text @a43 1 n->type = CFG_NODE_TYPE_NN; d47 1 d134 45 @ 1.1 log @Add this first cut for the forthcoming OSSP cfg library to CVS. This is work in progress and still not ready for use anywhere. @ text @d49 1 a49 2 n->data.t = CFG_DATA_TYPE_LONG; n->data.u.l = 0; d83 1 a83 10 node->data.t = (cfg_data_type_t)va_arg(ap, cfg_data_type_t); switch (node->data.t) { case CFG_DATA_TYPE_PTR: node->data.u.p = (void *)va_arg(ap, void *); break; case CFG_DATA_TYPE_CHAR: node->data.u.c = (char )va_arg(ap, int ); break; case CFG_DATA_TYPE_INT: node->data.u.i = (int )va_arg(ap, int ); break; case CFG_DATA_TYPE_LONG: node->data.u.l = (long )va_arg(ap, long ); break; case CFG_DATA_TYPE_FLOAT: node->data.u.f = (float )va_arg(ap, double); break; case CFG_DATA_TYPE_DOUBLE: node->data.u.d = (double)va_arg(ap, double); break; default: return CFG_ERR_ARG; } d101 1 a101 1 cfg_node_type_t *type = (cfg_node_type_t *)va_arg(ap, cfg_node_type_t *); d106 1 a106 1 cfg_node_t **n = (cfg_node_t **)va_arg(ap, cfg_node_t **); d111 1 a111 1 cfg_node_t **n = (cfg_node_t **)va_arg(ap, cfg_node_t **); d116 1 a116 1 cfg_node_t **n = (cfg_node_t **)va_arg(ap, cfg_node_t **); d126 3 a128 11 cfg_data_type_t *type = (cfg_data_type_t *)va_arg(ap, cfg_data_type_t *); *type = node->data.t; switch (node->data.t) { case CFG_DATA_TYPE_PTR: *((void **)va_arg(ap, void **)) = node->data.u.p; break; case CFG_DATA_TYPE_CHAR: *((char *)va_arg(ap, int *)) = node->data.u.c; break; case CFG_DATA_TYPE_INT: *((int *)va_arg(ap, int *)) = node->data.u.i; break; case CFG_DATA_TYPE_LONG: *((long *)va_arg(ap, long *)) = node->data.u.l; break; case CFG_DATA_TYPE_DOUBLE: *((double *)va_arg(ap, double *)) = node->data.u.d; break; case CFG_DATA_TYPE_FLOAT: *((float *)va_arg(ap, double *)) = node->data.u.f; break; default: return CFG_ERR_ARG; } @