support for dashed lines in graphs
[rrdtool.git] / src / rrd_graph_helper.c
index 8b9e9ca..d4b3732 100644 (file)
@@ -174,7 +174,7 @@ int rrd_parse_find_gf(
     case GF_LINE:
         if (c1 == ':') {
             gdp->linewidth = 1;
     case GF_LINE:
         if (c1 == ':') {
             gdp->linewidth = 1;
-            dprintf("- using default width of 1\n");
+            dprintf("- using default width of 1\n");
         } else {
             i = 0;
             sscanf(&line[*eaten], "%lf:%n", &gdp->linewidth, &i);
         } else {
             i = 0;
             sscanf(&line[*eaten], "%lf:%n", &gdp->linewidth, &i);
@@ -183,7 +183,7 @@ int rrd_parse_find_gf(
                               &line[*eaten], line);
                 return 1;
             } else {
                               &line[*eaten], line);
                 return 1;
             } else {
-                dprintf("- scanned width %f\n", gdp->linewidth);
+                dprintf("- scanned width %f\n", gdp->linewidth);
                 if (isnan(gdp->linewidth)) {
                     rrd_set_error
                         ("LINE width '%s' is not a number in line '%s'\n",
                 if (isnan(gdp->linewidth)) {
                     rrd_set_error
                         ("LINE width '%s' is not a number in line '%s'\n",
@@ -740,28 +740,110 @@ int rrd_parse_PVHLAST(
     (*eaten)++;         /* after colon */
 
     /* PART, HRULE, VRULE and TICK cannot be stacked. */
     (*eaten)++;         /* after colon */
 
     /* PART, HRULE, VRULE and TICK cannot be stacked. */
-    if ((gdp->gf == GF_HRULE)
-        || (gdp->gf == GF_VRULE)
-        || (gdp->gf == GF_TICK)
-        )
-        return 0;
+    if ((gdp->gf != GF_HRULE)
+        && (gdp->gf != GF_VRULE)
+        && (gdp->gf != GF_TICK)) {
 
 
-    dprintf("- parsing '%s'\n", &line[*eaten]);
-    if (line[*eaten] != '\0') {
-        dprintf("- still more, should be STACK\n");
+        dprintf("- parsing '%s', looking for STACK\n", &line[*eaten]);
         j = scan_for_col(&line[*eaten], 5, tmpstr);
         j = scan_for_col(&line[*eaten], 5, tmpstr);
-        if (line[*eaten + j] != '\0' && line[*eaten + j] != ':') {
-            /* not 5 chars */
-            rrd_set_error("STACK expected and not found");
-            return 1;
-        }
         if (!strcmp("STACK", tmpstr)) {
             dprintf("- found STACK\n");
             gdp->stack = 1;
             (*eaten) += j;
         if (!strcmp("STACK", tmpstr)) {
             dprintf("- found STACK\n");
             gdp->stack = 1;
             (*eaten) += j;
-        } else {
-            rrd_set_error("STACK expected and not found");
-            return 1;
+            if (line[*eaten] == ':') {
+                (*eaten) += 1;
+            } else if (line[*eaten] == '\0') {
+                dprintf("- done parsing line\n");
+                return 0;
+            } else {
+                dprintf("- found %s instead of just STACK\n", &line[*eaten]);
+                rrd_set_error("STACK expected but %s found", &line[*eaten]);
+                return 1;
+            }
+        } else
+            dprintf("- not STACKing\n");
+    }
+
+    dprintf("- still more, should be DASHED[:...]\n");
+    dprintf("- parsing '%s'\n", &line[*eaten]);
+    if (line[*eaten] != '\0') {
+        // parse dash arguments here. Possible options:
+        // DASHED
+        // DASHED:dashes=n_on,n_off,n_on,n_off
+        // DASHED:dashes=n_on,n_off,n_on,n_off:dash-offset=offset
+        // start with DASHED
+        j = scan_for_col(&line[*eaten], 6, tmpstr);
+        if (!strcmp("DASHED", tmpstr)) {
+            dprintf("- found %s\n", tmpstr);
+            // initialise all required variables we need for dashed lines
+            // using default dash length of 5 pixels
+            gdp->dash = 1;
+            gdp->p_dashes = (double *) malloc(sizeof(double));
+            gdp->p_dashes[0] = 5;
+            gdp->ndash = 1;
+            gdp->offset = 0;
+            (*eaten) += j;
+            if (line[*eaten] == ':')
+                (*eaten) += 1;
+        }
+        if (line[*eaten] == '\0') {
+            dprintf("- done parsing line\n");
+            return 0;
+        }
+        // DASHED:dashes=n_on,n_off,n_on,n_off
+        // allowing 64 characters for definition of dash style
+        j = scan_for_col(&line[*eaten], 64, tmpstr);
+        if (sscanf(tmpstr, "dashes=%s", tmpstr)) {
+            char      csv[64];
+            char     *pch;
+            float     dsh;
+
+            strcpy(csv, tmpstr);
+            int       count = 0;
+
+            pch = strtok(tmpstr, ",");
+            while (pch != NULL) {
+                pch = strtok(NULL, ",");
+                count++;
+            }
+            dprintf("- %d dash values found: ", count);
+            gdp->ndash = count;
+            if (gdp->p_dashes != NULL)
+                free(gdp->p_dashes);
+            gdp->p_dashes = (double *) malloc(sizeof(double) * count);
+            pch = strtok(csv, ",");
+            count = 0;
+            while (pch != NULL) {
+                if (sscanf(pch, "%f", &dsh)) {
+                    gdp->p_dashes[count] = (double) dsh;
+                    dprintf("%.1f ", gdp->p_dashes[count]);
+                    count++;
+                }
+                pch = strtok(NULL, ",");
+            }
+            dprintf("\n");
+            (*eaten) += j;
+            if (line[*eaten] == ':')
+                (*eaten) += 1;
+        }
+        if (line[*eaten] == '\0') {
+            dprintf("- done parsing line\n");
+            return 0;
+        }
+        // DASHED:dashes=n_on,n_off,n_on,n_off:dash-offset=offset
+        // allowing 16 characters for dash-offset=....
+        // => 4 characters for the offset value
+        j = scan_for_col(&line[*eaten], 16, tmpstr);
+        if (sscanf(tmpstr, "dash-offset=%lf", &gdp->offset)) {
+            dprintf("- found %s\n", tmpstr);
+            gdp->dash = 1;
+            (*eaten) += j;
+            if (line[*eaten] == ':')
+                (*eaten) += 1;
+        }
+        if (line[*eaten] == '\0') {
+            dprintf("- done parsing line\n");
+            return 0;
         }
     }
     if (line[*eaten] == '\0') {
         }
     }
     if (line[*eaten] == '\0') {