--- cfg_node.c 2002/07/17 15:04:08 1.12
+++ cfg_node.c 2002/07/18 15:34:55 1.13
@@ -32,9 +32,11 @@
#include <stdlib.h>
#include <stdarg.h>
#include <unistd.h>
+#include <limits.h>
#include "cfg_main.h"
#include "cfg_node.h"
+#include "cfg_fmt.h"
cfg_rc_t cfg_node_create(cfg_t *cfg, cfg_node_t **node)
{
@@ -314,37 +316,280 @@
return CFG_OK;
}
-cfg_rc_t cfg_node_select(cfg_t *cfg, cfg_node_t *node, cfg_node_t **node2, const char *fmt, ...)
+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 *);
+
+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)
{
-#if 0
- cfg_node_t *n;
+ cfg_rc_t rc;
+
+ fprintf(stderr, "step3: (1) cpSel=\"%s\", nSel=%d, nFilMin=%ld, nFilMax=%ld, nFound=%ld\n", cpSel, nSel, nFilMin, nFilMax, *nFound);
+
+ if (spec[0] == '\0') {
+ /* end of selection, node found */
+ *nFound++;
+ fprintf(stderr, "step3: found node=0x%lx!!\n", (unsigned long)node);
+ 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 {
+ rc = cfg_node_select_step1(cfg, node, result_vec, result_len, spec);
+ }
+ return rc;
+}
+
+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;
+
+ fprintf(stderr, "step2: (1) cpSel=\"%s\", nSel=%d, nFilMin=%ld, nFilMax=%ld, nFound=%ld\n", cpSel, nSel, nFilMin, nFilMax, *nFound);
+
+ if (strncmp(cpSel, ".", nSel) == 0) {
+ /* current node (no-op) */
+ return cfg_node_select_step3(cfg, node, result_vec, result_len, spec, cpSel, nSel, nFilMin, nFilMax, nFound);
+ }
+ else if (strncmp(cpSel, "..", nSel) == 0) {
+ /* parent node */
+ 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);
+ }
+ else if (strncmp(cpSel, "....", nSel) == 0) {
+ /* anchestor nodes */
+ while ((node = node->parent) != NULL) {
+ if (node->type == CFG_NODE_TYPE_DIR)
+ if ((node = node->parent) == NULL)
+ break;
+ if ((rc = cfg_node_select_step3(cfg, node, result_vec, result_len, spec, cpSel, nSel, nFilMin, nFilMax, nFound)) != CFG_OK)
+ return rc;
+ }
+ return CFG_OK;
+ }
+ else if (strncmp(cpSel, "-", nSel) == 0) {
+ /* previous sibling node */
+ 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);
+ }
+ else if (strncmp(cpSel, "--", nSel) == 0) {
+ /* preceeding sibling nodes */
+ while ((rc = cfg_node_get(cfg, node, CFG_NODE_ATTR_LBROTH, &node)) == CFG_OK)
+ if ((rc = cfg_node_select_step3(cfg, node, result_vec, result_len, spec, cpSel, nSel, nFilMin, nFilMax, nFound)) != CFG_OK)
+ return rc;
+ return CFG_OK;
+ }
+ else if (strncmp(cpSel, "+", nSel) == 0) {
+ /* next sibling node */
+ 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);
+ }
+ else if (strncmp(cpSel, "++", nSel) == 0) {
+ /* following sibling nodes */
+ while ((rc = cfg_node_get(cfg, node, CFG_NODE_ATTR_RBROTH, &node)) == CFG_OK)
+ if ((rc = cfg_node_select_step3(cfg, node, result_vec, result_len, spec, cpSel, nSel, nFilMin, nFilMax, nFound)) != CFG_OK)
+ return rc;
+ return CFG_OK;
+ }
+ else if (nSel == 0) {
+ /* descendant nodes */
+ 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)
+ if ((rc = cfg_node_select_step2(cfg, node, result_vec, result_len, spec, cpSel, nSel, nFilMin, nFilMax, nFound)) != CFG_OK)
+ return rc;
+ return CFG_OK;
+ }
+ else {
+ /* child node */
+ 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) {
+ token = node->token;
+ size_t 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;
+ }
+ }
+ } while ((node = node->rbroth) != NULL);
+ return CFG_OK;
+ }
+ return rc;
+}
+
+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;
+
+ fprintf(stderr, "step1(spec=\"%s\")\n", spec);
+
+ /* 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;
+
+ fprintf(stderr, " step1: (1) cpSel=\"%s\", nSel=%d, nFilMin=%ld, nFilMax=%ld\n", cpSel, nSel, nFilMin, nFilMax);
+
+ /* perform pre-selection if filter range is relative to last element */
+ if (nFilMin < 0 || nFilMax < 0) {
+ 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;
+ }
+ }
+ }
+
+ fprintf(stderr, " step1: (2) cpSel=\"%s\", nSel=%d, nFilMin=%ld, nFilMax=%ld\n", cpSel, nSel, nFilMin, nFilMax);
+
+ /* 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;
+
+ return CFG_OK;
+}
+
+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 *cpB;
- char *cpE;
char *spec;
+ char *cp;
+ long result_len;
- if (cfg == NULL || node == NULL || node2 == NULL || spec == NULL)
+ 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 = l2_util_vasprintf(fmt, ap);
+ spec = cfg_fmt_vasprintf(fmt, ap);
va_end(ap);
+ if (spec == NULL)
+ return CFG_ERR_FMT;
+
+ /* special case for absolute (start from root-node) selection */
+ cp = spec;
+ if (cp[0] == '/') {
+ node = cfg->root;
+ cp++;
+ }
+ if (node == NULL)
+ node = cfg->root;
- /* 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;
+ /* 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;
}
-#endif
+
return CFG_OK;
}
|