OSSP CVS Repository

ossp - Difference in ossp-pkg/cfg/cfg_node.c versions 1.12 and 1.13
Not logged in
[Honeypot]  [Browse]  [Home]  [Login]  [Reports
[Search]  [Ticket]  [Timeline
  [History

ossp-pkg/cfg/cfg_node.c 1.12 -> 1.13

--- 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;
 }
 

CVSTrac 2.0.1