Code

prepare for the release of rrdtool-1.2.30
[rrdtool-all.git] / program / src / rrd_graph_helper.c
index bca17d0526766459fdf70c9fa11df4f79cc99ff6..ca457ff0d9ead14732e0796673a5bee9cc4cb6e2 100644 (file)
@@ -1,5 +1,5 @@
 /****************************************************************************
- * RRDtool 1.2.11  Copyright by Tobi Oetiker, 1997-2005
+ * RRDtool 1.2.30  Copyright by Tobi Oetiker, 1997-2009
  ****************************************************************************
  * rrd_graph_helper.c  commandline parser functions 
  *                     this code initially written by Alex van den Bogaerdt
@@ -133,6 +133,10 @@ rrd_parse_find_gf(const char *const line, unsigned int *const eaten, graph_desc_
            rrd_set_error("Malformed '%s' command in line '%s'\n",&line[*eaten],line);
            return 1;
     }
+    if (line[*eaten] == '\0') {
+       rrd_set_error("Expected some arguments after '%s'\n",line);
+       return 1;
+    }
     return 0;
 }
 
@@ -256,7 +260,7 @@ int
 rrd_parse_print(const char *const line, unsigned int *const eaten, graph_desc_t *const gdp, image_desc_t *const im) {
     /* vname:CF:format in case of DEF-based vname
     ** vname:CF:format in case of CDEF-based vname
-    ** vname:format in case of VDEF-based vname
+    ** vname:format[:strftime] in case of VDEF-based vname
     */
     if ((gdp->vidx=rrd_parse_find_vname(line,eaten,gdp,im))<0) return 1;
  
@@ -279,6 +283,11 @@ rrd_parse_print(const char *const line, unsigned int *const eaten, graph_desc_t
        get the format at this juncture */
     strcpy(gdp->format,gdp->legend);
     gdp->legend[0]='\0';       
+    /* this is a very crud test, parsing :style flags should be in a function */
+    if (im->gdes[gdp->vidx].gf == GF_VDEF && strcmp(line+(*eaten),":strftime")==0){
+       gdp->strftm = 1;
+        (*eaten)+=strlen(":strftime");
+    }
     return 0;
 }
 
@@ -287,7 +296,7 @@ rrd_parse_print(const char *const line, unsigned int *const eaten, graph_desc_t
 int
 rrd_parse_shift(const char *const line, unsigned int *const eaten, graph_desc_t *const gdp, image_desc_t *const im) {
     int i;
-
+    long time_tmp = 0;
     if ((gdp->vidx=rrd_parse_find_vname(line,eaten,gdp,im))<0) return 1;
 
     switch (im->gdes[gdp->vidx].gf) {
@@ -318,7 +327,8 @@ rrd_parse_shift(const char *const line, unsigned int *const eaten, graph_desc_t
        }
     } else {
        rrd_clear_error();
-       i=0; sscanf(&line[*eaten],"%li%n",&gdp->shval,&i);
+       i=0; sscanf(&line[*eaten],"%li%n",&time_tmp,&i);
+    gdp->shval = time_tmp;
        if (i!=(int)strlen(&line[*eaten])) {
            rrd_set_error("Not a valid offset: %s in line %s",&line[*eaten],line);
            return 1;
@@ -368,6 +378,7 @@ rrd_parse_PVHLAST(const char *const line, unsigned int *const eaten, graph_desc_
     int i,j,k;
     int colorfound=0;
     char tmpstr[MAX_VNAME_LEN + 10];   /* vname#RRGGBBAA\0 */
+    long time_tmp = 0;
     static int spacecnt = 0;
 
     if (spacecnt == 0) {        
@@ -434,7 +445,8 @@ rrd_parse_PVHLAST(const char *const line, unsigned int *const eaten, graph_desc_
        dprintf("- it is not an existing vname\n");
        switch (gdp->gf) {
            case GF_VRULE:
-               k=0;sscanf(tmpstr,"%li%n",&gdp->xrule,&k);
+               k=0;sscanf(tmpstr,"%li%n",&time_tmp,&k);
+        gdp->xrule = time_tmp;
                if (((j!=0)&&(k==j))||((j==0)&&(k==i))) {
                    dprintf("- found time: %li\n",gdp->xrule);
                } else {
@@ -445,9 +457,9 @@ rrd_parse_PVHLAST(const char *const line, unsigned int *const eaten, graph_desc_
            default:
                k=0;sscanf(tmpstr,"%lf%n",&gdp->yrule,&k);
                if (((j!=0)&&(k==j))||((j==0)&&(k==i))) {
-                   dprintf("- found number: %f\n",gdp->yrule);
+                   dprintf("- found number: %lf\n",gdp->yrule);
                } else {
-                   dprintf("- is is not a valid number: %li\n",gdp->xrule);
+                   dprintf("- is is not a valid number: %lf\n",gdp->yrule);
                    rrd_set_error("parameter '%s' does not represent a number in line %s\n",tmpstr,line);
                    return 1;
                }
@@ -594,6 +606,10 @@ rrd_parse_make_vname(const char *const line, unsigned int *const eaten, graph_de
        rrd_set_error("Cannot parse vname from '%s'",line);
        return 1;
     }
+    if (line[*eaten+i] == '\0') {
+        rrd_set_error("String ends after the = sign on '%s'", line);
+        return 1;
+    }
     dprintf("- found candidate '%s'\n",tmpstr);
 
     if ((gdp->vidx=find_var(im,tmpstr))>=0) {
@@ -624,7 +640,7 @@ rrd_parse_def(const char *const line, unsigned int *const eaten, graph_desc_t *c
     dprintf("- from line '%s'\n",line);
 
     if (rrd_parse_make_vname(line,eaten,gdp,im)) return 1;
-    i=scan_for_col(&line[*eaten],254,gdp->rrd);
+    i=scan_for_col(&line[*eaten],sizeof(gdp->rrd)-1,gdp->rrd);
     if (line[*eaten+i]!=':') {
        rrd_set_error("Problems reading database name");
        return 1;
@@ -776,6 +792,9 @@ rrd_parse_cdef(const char *const line, unsigned int *const eaten, graph_desc_t *
 void
 rrd_graph_script(int argc, char *argv[], image_desc_t *const im, int optno) {
     int i;
+    /* save state for STACK backward compat function */
+    enum gf_en     last_gf=GF_PRINT;
+    float          last_linewidth=0.0;
 
     for (i=optind+optno;i<argc;i++) {
        graph_desc_t *gdp;
@@ -788,7 +807,7 @@ rrd_graph_script(int argc, char *argv[], image_desc_t *const im, int optno) {
 #endif
 
        if (rrd_parse_find_gf(argv[i],&eaten,gdp)) return;
-
+        
        switch (gdp->gf) {
            case GF_SHIFT:      /* vname:value */
                if (rrd_parse_shift(argv[i],&eaten,gdp,im)) return;
@@ -797,13 +816,13 @@ rrd_graph_script(int argc, char *argv[], image_desc_t *const im, int optno) {
                if (rrd_parse_xport(argv[i],&eaten,gdp,im)) return;
                break;
            case GF_PRINT:      /* vname:CF:format -or- vname:format */
+               im->prt_c++;            
            case GF_GPRINT:     /* vname:CF:format -or- vname:format */
                if (rrd_parse_print(argv[i],&eaten,gdp,im)) return;
                break;
             case GF_COMMENT:   /* text */
                if (rrd_parse_legend(argv[i],&eaten,gdp)) return;
                break;
-           case GF_STACK:      /* vname-or-value[#color[:legend]] */           
 #ifdef WITH_PIECHART
            case GF_PART:       /* value[#color[:legend]] */
 #endif
@@ -812,7 +831,20 @@ rrd_graph_script(int argc, char *argv[], image_desc_t *const im, int optno) {
            case GF_LINE:       /* vname-or-value[#color[:legend]][:STACK] */
            case GF_AREA:       /* vname-or-value[#color[:legend]][:STACK] */
            case GF_TICK:       /* vname#color[:num[:legend]] */
-               if (rrd_parse_PVHLAST(argv[i],&eaten,gdp,im)) return;
+               if (rrd_parse_PVHLAST(argv[i],&eaten,gdp,im))return;
+                last_gf = gdp->gf;
+                last_linewidth = gdp->linewidth;
+               break;
+           case GF_STACK:      /* vname-or-value[#color[:legend]] */           
+               if (rrd_parse_PVHLAST(argv[i],&eaten,gdp,im))return;
+                if (last_gf == GF_LINE || last_gf == GF_AREA){
+                   gdp->gf = last_gf;
+                   gdp->linewidth = last_linewidth;
+                } else {
+                   rrd_set_error("STACK must follow LINE or AREA! command:\n%s",
+                        &argv[i][eaten],argv[i]);
+                   return;
+                }
                break;
        /* data acquisition */
            case GF_DEF:        /* vname=x:DS:CF:[:step=#][:start=#][:end=#] */