]> git.ipfire.org Git - thirdparty/rrdtool-1.x.git/commitdiff
Refactor all DS definition parsing code. It was not reusable and tied
authorPeter Stamfest <peter@stamfest.at>
Mon, 24 Feb 2014 07:19:44 +0000 (08:19 +0100)
committerPeter Stamfest <peter@stamfest.at>
Wed, 26 Feb 2014 10:27:43 +0000 (11:27 +0100)
too much to the rrd_t data structure.

src/Makefile.am
src/rrd_create.c
src/rrd_create.h [new file with mode: 0644]
src/rrd_restore.c
src/rrd_rpncalc.c
src/rrd_rpncalc.h

index 79e3e1310f5170d1fe79156d17b2327cfd1a1c93..b4b9289d13aabc54b7a45525e8279a54f2aab3c8 100644 (file)
@@ -64,7 +64,7 @@ noinst_HEADERS = \
        rrd_config_bottom.h rrd_i18n.h \
        rrd_format.h rrd_tool.h rrd_xport.h rrd.h rrd_rpncalc.h \
        rrd_hw.h rrd_hw_math.h rrd_hw_update.h \
-       rrd_restore.h \
+       rrd_restore.h rrd_create.h \
        fnv.h rrd_graph.h \
        rrd_is_thread_safe.h
 
index e9094c68e26520265781a2d45db717d7efac3eb1..e629a89a894661c6cd098d1aceff21d553e965c7 100644 (file)
@@ -13,6 +13,7 @@
 #include "rrd_hw.h"
 #include "rrd_client.h"
 #include "rrd_config.h"
+#include "rrd_create.h"
 
 #include "rrd_is_thread_safe.h"
 
@@ -28,8 +29,7 @@ int       create_hw_contingent_rras(
     unsigned long hashed_name);
 void      parseGENERIC_DS(
     const char *def,
-    rrd_t *rrd,
-    int ds_idx);
+    ds_def_t *ds_def);
 
 static void rrd_free2(
     rrd_t *rrd);        /* our onwn copy, immmune to mmap */
@@ -138,6 +138,59 @@ int rrd_create(
     return rc;
 }
 
+
+int parseDS(const char *def, 
+           ds_def_t *ds_def,
+           void *key_hash,
+            long (*lookup)(void *, char *)
+           ) 
+{
+    char      dummychar1[2], dummychar2[2];
+    int       offset;
+
+    /* extract the name and type */
+    switch (sscanf(def,
+                  DS_NAM_FMT "%1[:]" DST_FMT "%1[:]%n",
+                  ds_def->ds_nam,
+                  dummychar1,
+                  ds_def->dst,
+                  dummychar2, &offset)) {
+    case 0:
+    case 1:
+       rrd_set_error("Invalid DS name in [%s]", def);
+       return -1;
+    case 2:
+    case 3:
+       rrd_set_error("Invalid DS type in [%s]", def);
+       return -1;
+    case 4:    /* (%n may or may not be counted) */
+    case 5:
+       break;
+    default:
+       rrd_set_error("invalid DS format");
+       return -1;
+    }
+
+    /* parse the remainder of the arguments */
+    switch (dst_conv(ds_def->dst)) {
+    case DST_COUNTER:
+    case DST_ABSOLUTE:
+    case DST_GAUGE:
+    case DST_DERIVE:
+       parseGENERIC_DS(def + offset, ds_def);
+       break;
+    case DST_CDEF:
+       parseCDEF_DS(def + offset, ds_def, key_hash, lookup);
+       break;
+    default:
+       rrd_set_error("invalid DS type specified");
+       return -1;
+    }
+    return 0;
+}
+
+
+
 /* #define DEBUG */
 /* For backwards compatibility with previous API.  Use rrd_create_r2 if you
    need to have the no_overwrite parameter.                                */
@@ -160,9 +213,7 @@ int rrd_create_r2(
 {
     rrd_t     rrd;
     long      i;
-    int       offset;
     char     *token;
-    char      dummychar1[2], dummychar2[2];
     unsigned short token_idx, error_flag, period = 0;
     unsigned long hashed_name;
 
@@ -205,8 +256,6 @@ int rrd_create_r2(
      * arrays. */
     hashed_name = FnvHash(filename);
     for (i = 0; i < argc; i++) {
-        unsigned int ii;
-
         if (strncmp(argv[i], "DS:", 3) == 0) {
             size_t    old_size = sizeof(ds_def_t) * (rrd.stat_head->ds_cnt);
 
@@ -218,61 +267,25 @@ int rrd_create_r2(
                 return (-1);
             }
             memset(&rrd.ds_def[rrd.stat_head->ds_cnt], 0, sizeof(ds_def_t));
-            /* extract the name and type */
-            switch (sscanf(&argv[i][3],
-                           DS_NAM_FMT "%1[:]" DST_FMT "%1[:]%n",
-                           rrd.ds_def[rrd.stat_head->ds_cnt].ds_nam,
-                           dummychar1,
-                           rrd.ds_def[rrd.stat_head->ds_cnt].dst,
-                           dummychar2, &offset)) {
-            case 0:
-            case 1:
-                rrd_set_error("Invalid DS name in [%s]",&argv[i][3]);
-                break;
-            case 2:
-            case 3:
-                rrd_set_error("Invalid DS type in [%s]",&argv[i][3]);
-                break;
-            case 4:    /* (%n may or may not be counted) */
-            case 5:    /* check for duplicate datasource names */
-                for (ii = 0; ii < rrd.stat_head->ds_cnt; ii++)
-                    if (strcmp(rrd.ds_def[rrd.stat_head->ds_cnt].ds_nam,
-                               rrd.ds_def[ii].ds_nam) == 0)
-                        rrd_set_error("Duplicate DS name: %s",
-                                      rrd.ds_def[ii].ds_nam);
-                /* DS_type may be valid or not. Checked later */
-                break;
-            default:
-                rrd_set_error("invalid DS format");
-            }
-            if (rrd_test_error()) {
-                rrd_free2(&rrd);
-                return -1;
-            }
 
-            /* parse the remainder of the arguments */
-            switch (dst_conv(rrd.ds_def[rrd.stat_head->ds_cnt].dst)) {
-            case DST_COUNTER:
-            case DST_ABSOLUTE:
-            case DST_GAUGE:
-            case DST_DERIVE:
-                parseGENERIC_DS(&argv[i][offset + 3], &rrd,
-                                rrd.stat_head->ds_cnt);
-                break;
-            case DST_CDEF:
-                parseCDEF_DS(&argv[i][offset + 3], &rrd,
-                             rrd.stat_head->ds_cnt);
-                break;
-            default:
-                rrd_set_error("invalid DS type specified");
-                break;
-            }
+           parseDS(argv[i] + 3, rrd.ds_def + rrd.stat_head->ds_cnt,
+                   &rrd, lookup_DS);
+
+           /* check for duplicate DS name */
+
+           if (lookup_DS(&rrd, rrd.ds_def[rrd.stat_head->ds_cnt].ds_nam) 
+               >= 0) {
+               rrd_set_error("Duplicate DS name: %s",
+                             rrd.ds_def[rrd.stat_head->ds_cnt].ds_nam);
+           }
+           
+           rrd.stat_head->ds_cnt++;
 
             if (rrd_test_error()) {
                 rrd_free2(&rrd);
                 return -1;
             }
-            rrd.stat_head->ds_cnt++;
+           
         } else if (strncmp(argv[i], "RRA:", 4) == 0) {
             char     *argvcopy;
             char     *tokptr = "";
@@ -618,8 +631,7 @@ int rrd_create_r2(
 
 void parseGENERIC_DS(
     const char *def,
-    rrd_t *rrd,
-    int ds_idx)
+    ds_def_t *ds_def)
 {
     char      minstr[DS_NAM_SIZE], maxstr[DS_NAM_SIZE];
     char     *old_locale;
@@ -633,23 +645,24 @@ void parseGENERIC_DS(
      */
     old_locale = setlocale(LC_NUMERIC, NULL);
     setlocale(LC_NUMERIC, "C");
+
     if (sscanf(def, "%lu:%18[^:]:%18[^:]",
-               &(rrd->ds_def[ds_idx].par[DS_mrhb_cnt].u_cnt),
+               &(ds_def->par[DS_mrhb_cnt].u_cnt),
                minstr, maxstr) == 3) {
         if (minstr[0] == 'U' && minstr[1] == 0)
-            rrd->ds_def[ds_idx].par[DS_min_val].u_val = DNAN;
+            ds_def->par[DS_min_val].u_val = DNAN;
         else
-            rrd->ds_def[ds_idx].par[DS_min_val].u_val = atof(minstr);
+            ds_def->par[DS_min_val].u_val = atof(minstr);
 
         if (maxstr[0] == 'U' && maxstr[1] == 0)
-            rrd->ds_def[ds_idx].par[DS_max_val].u_val = DNAN;
+            ds_def->par[DS_max_val].u_val = DNAN;
         else
-            rrd->ds_def[ds_idx].par[DS_max_val].u_val = atof(maxstr);
+            ds_def->par[DS_max_val].u_val = atof(maxstr);
 
-        if (!isnan(rrd->ds_def[ds_idx].par[DS_min_val].u_val) &&
-            !isnan(rrd->ds_def[ds_idx].par[DS_max_val].u_val) &&
-            rrd->ds_def[ds_idx].par[DS_min_val].u_val
-            >= rrd->ds_def[ds_idx].par[DS_max_val].u_val) {
+        if (!isnan(ds_def->par[DS_min_val].u_val) &&
+            !isnan(ds_def->par[DS_max_val].u_val) &&
+            ds_def->par[DS_min_val].u_val
+            >= ds_def->par[DS_max_val].u_val) {
             rrd_set_error("min must be less than max in DS definition");
             setlocale(LC_NUMERIC, old_locale);
             return;
diff --git a/src/rrd_create.h b/src/rrd_create.h
new file mode 100644 (file)
index 0000000..89a82f6
--- /dev/null
@@ -0,0 +1,25 @@
+/****************************************************************************
+ * RRDtool 1.4.8  Copyright by Tobi Oetiker, 1997-2013
+ ****************************************************************************
+ * rrd_create.h
+ ****************************************************************************/
+#ifdef  __cplusplus
+extern    "C" {
+#endif
+
+#ifndef _RRD_CREATE_H
+#define _RRD_CREATE_H
+
+#include "rrd.h"
+
+int parseDS(const char *def, 
+           ds_def_t *ds_def,
+           void *key_hash,
+           long (*lookup)(void *, char *)); 
+
+#endif
+
+
+#ifdef  __cplusplus
+}
+#endif
index 1fb02e212d787a623baf3da136a050e19a009d9e..1ab92d8a9f04a28541b9507f882af341cd663193 100644 (file)
@@ -859,7 +859,8 @@ static int parse_tag_ds_cdef(
     if (cdef != NULL){
         /* We're always working on the last DS that has been added to the structure
          * when we get here */
-        parseCDEF_DS((char *)cdef, rrd, rrd->stat_head->ds_cnt - 1);
+        parseCDEF_DS((char *)cdef, rrd->ds_def + rrd->stat_head->ds_cnt - 1,
+                    rrd, lookup_DS);
         xmlFree(cdef);
         if (rrd_test_error())
             return -1;
index 3ac63872589eb0a3c18beea92e6e441fd694c625..0da4b071bc7a5771ab75cfae2a8ab350b6f9cadf 100644 (file)
@@ -218,16 +218,17 @@ short addop2str(
     return 0;
 }
 
-void parseCDEF_DS(
-    const char *def,
-    rrd_t *rrd,
-    int ds_idx)
+void parseCDEF_DS(const char *def,
+                 ds_def_t *ds_def,
+                 void *key_hash,
+                 long (*lookup) (void *, char *)
+                 )
 {
     rpnp_t   *rpnp = NULL;
     rpn_cdefds_t *rpnc = NULL;
     short     count, i;
 
-    rpnp = rpn_parse((void *) rrd, def, &lookup_DS);
+    rpnp = rpn_parse(key_hash, def, lookup);
     if (rpnp == NULL) {
         rrd_set_error("failed to parse computed data source");
         return;
@@ -252,7 +253,7 @@ void parseCDEF_DS(
         return;
     }
     /* copy the compact rpn representation over the ds_def par array */
-    memcpy((void *) &(rrd->ds_def[ds_idx].par[DS_cdef]),
+    memcpy((void *) &(ds_def->par[DS_cdef]),
            (void *) rpnc, count * sizeof(rpn_cdefds_t));
     free(rpnp);
     free(rpnc);
index dd9f109e27b4548dbcb95ea4e1437ed44bb54314..26b52cb4bfe1f5f3900186028562d038552b7a4f 100644 (file)
@@ -58,8 +58,10 @@ void      rpnstack_free(
 
 void      parseCDEF_DS(
     const char *def,
-    rrd_t *rrd,
-    int ds_idx);
+    ds_def_t *ds_def,
+    void *key_hash,
+    long (*lookup) (void *, char *));
+
 long      lookup_DS(
     void *rrd_vptr,
     char *ds_name);