Code

Fix for #167 - rrdcreate is arguably missing a check for 'step>=1' for RRAs with...
[rrdtool-all.git] / program / src / rrd_graph.c
index 74884bb9aec1ddd625f6ed23e99673d9b7aee6f0..4d747d08bc41b71514fa92cfc2d5c12116f7fe61 100644 (file)
@@ -1,5 +1,5 @@
 /****************************************************************************
- * RRDtool 1.2.25  Copyright by Tobi Oetiker, 1997-2007
+ * RRDtool 1.2.27  Copyright by Tobi Oetiker, 1997-2008
  ****************************************************************************
  * rrd__graph.c  produce graphs from data in rrdfiles
  ****************************************************************************/
@@ -51,7 +51,7 @@ xlab_t xlab[] = {
     {10,                0,   TMT_MINUTE,5,  TMT_MINUTE,20, TMT_MINUTE,20,        0,"%H:%M"},
     {30,                0,   TMT_MINUTE,10, TMT_HOUR,1,    TMT_HOUR,1,           0,"%H:%M"},
     {60,                0,   TMT_MINUTE,30, TMT_HOUR,2,    TMT_HOUR,2,           0,"%H:%M"},
-    {60,          24*3600,   TMT_MINUTE,30, TMT_HOUR,2,    TMT_HOUR,4,           0,"%a %H:%M"},
+    {60,          24*3600,   TMT_MINUTE,30, TMT_HOUR,2,    TMT_HOUR,6,           0,"%a %H:%M"},
     {180,               0,   TMT_HOUR,1,    TMT_HOUR,6,    TMT_HOUR,6,           0,"%H:%M"},
     {180,         24*3600,   TMT_HOUR,1,    TMT_HOUR,6,    TMT_HOUR,12,          0,"%a %H:%M"},
     /*{300,             0,   TMT_HOUR,3,    TMT_HOUR,12,   TMT_HOUR,12,    12*3600,"%a %p"},  this looks silly*/
@@ -423,7 +423,7 @@ expand_range(image_desc_t *im)
                     im->minval = sensiblevalues[i]*(im->magfact);
                 
                 if (-sensiblevalues[i-1]<=scaled_min &&
-                -sensiblevalues[i]>=scaled_min)
+                    -sensiblevalues[i]>=scaled_min)
                     im->minval = -sensiblevalues[i-1]*(im->magfact);
                 
                 if (sensiblevalues[i-1] >= scaled_max &&
@@ -497,11 +497,14 @@ apply_gridfit(image_desc_t *im)
     double new_range = factor * (im->maxval - im->minval);
     double gridstep = im->ygrid_scale.gridstep;
     double minor_y, minor_y_px, minor_y_px_frac;
+
+
     if (im->maxval > 0.0)
       im->maxval = im->minval + new_range;
     else
       im->minval = im->maxval - new_range;
     ytr(im,DNAN); /* reset precalc */
+
     /* make sure first minor gridline is on integer pixel y coord */
     minor_y = gridstep * floor(im->minval / gridstep);
     while (minor_y < im->minval)
@@ -1007,6 +1010,35 @@ data_calc( image_desc_t *im){
     return 0;
 }
 
+static int AlmostEqual2sComplement (float A, float B, int maxUlps)
+{
+
+    int aInt = *(int*)&A;
+    int bInt = *(int*)&B;
+    int intDiff;
+    /* Make sure maxUlps is non-negative and small enough that the
+       default NAN won't compare as equal to anything.  */
+
+    /* assert(maxUlps > 0 && maxUlps < 4 * 1024 * 1024); */
+
+    /* Make aInt lexicographically ordered as a twos-complement int */
+
+    if (aInt < 0)
+        aInt = 0x80000000l - aInt;
+
+    /* Make bInt lexicographically ordered as a twos-complement int */
+
+    if (bInt < 0)
+        bInt = 0x80000000l - bInt;
+
+    intDiff = abs(aInt - bInt);
+
+    if (intDiff <= maxUlps)
+        return 1;
+
+    return 0;
+}
+
 /* massage data so, that we get one value for each x coordinate in the graph */
 int
 data_proc( image_desc_t *im ){
@@ -1126,18 +1158,28 @@ data_proc( image_desc_t *im ){
             im->maxval = maxval;
     }
     /* make sure min is smaller than max */
-    if (im->minval > im->maxval) {
+    if (im->minval > im->maxval ) {             
+        if (im->maxval > 0)
             im->minval = 0.99 * im->maxval;
+        else 
+            im->minval = 1.01 * im->maxval;
     }
                       
     /* make sure min and max are not equal */
-    if (im->minval == im->maxval) {
-        im->maxval *= 1.01; 
+   if (  AlmostEqual2sComplement(im->minval,im->maxval,4)) {
+        if (im->maxval > 0)
+           im->maxval *= 1.01; 
+        else 
+           im->maxval *= 0.99;
+
         if (! im->logarithmic) {
-            im->minval *= 0.99;
+            if (im->minval > 0)
+               im->minval *= 0.99;
+            else 
+               im->minval *= 1.01;
         }
         /* make sure min and max are not both zero */
-        if (im->maxval == 0.0) {
+        if (AlmostEqual2sComplement(im->maxval,0,4)) {
             im->maxval = 1.0;
         }
     }
@@ -1745,34 +1787,6 @@ double frexp10(double x, double *e) {
     return mnt;
 }
 
-static int AlmostEqual2sComplement (float A, float B, int maxUlps)
-{
-
-    int aInt = *(int*)&A;
-    int bInt = *(int*)&B;
-    int intDiff;
-    /* Make sure maxUlps is non-negative and small enough that the
-       default NAN won't compare as equal to anything.  */
-
-    /* assert(maxUlps > 0 && maxUlps < 4 * 1024 * 1024); */
-
-    /* Make aInt lexicographically ordered as a twos-complement int */
-
-    if (aInt < 0)
-        aInt = 0x80000000l - aInt;
-
-    /* Make bInt lexicographically ordered as a twos-complement int */
-
-    if (bInt < 0)
-        bInt = 0x80000000l - bInt;
-
-    intDiff = abs(aInt - bInt);
-
-    if (intDiff <= maxUlps)
-        return 1;
-
-    return 0;
-}
 
 /* logaritmic horizontal grid */
 int
@@ -3484,20 +3498,27 @@ rrd_graph_options(int argc, char *argv[],image_desc_t *im)
         case 'n':{
             char prop[15];
             double size = 1;
-            char font[1024] = "";
-
+            int end;
             if(sscanf(optarg,
-                                "%10[A-Z]:%lf:%1000s",
-                                prop,&size,font) >= 2){
+                                "%10[A-Z]:%lf%n",
+                                prop,&size,&end) >= 2){                                
                 int sindex,propidx;
                 if((sindex=text_prop_conv(prop)) != -1){
                   for (propidx=sindex;propidx<TEXT_PROP_LAST;propidx++){                        
                         if (size > 0){
                               im->text_prop[propidx].size=size;              
+                      }        
+                       if (strlen(optarg) > end){
+                          if (optarg[end] == ':'){
+                             strncpy(im->text_prop[propidx].font,optarg+end+1,255);
+                             im->text_prop[propidx].font[255] = '\0';
+                          } else {
+                             rrd_set_error("expected : after font size in '%s'",optarg);
+                            return;
+                          }
                       }
-                       if (strlen(font) > 0){
-                          strcpy(im->text_prop[propidx].font,font);
-                      }
+                      /* only run the for loop for DEFAULT (0) for
+                         all others, we break here. woodo programming */
                       if (propidx==sindex && sindex != 0) break;
                   }
                 } else {
@@ -3770,17 +3791,17 @@ int gdi;
 {
     graph_desc_t        *src,*dst;
     rrd_value_t                *data;
-    long                step,steps;
+    long                step,steps,end;
 
     dst = &im->gdes[gdi];
     src = &im->gdes[dst->vidx];
     data = src->data + src->ds;
-    steps = (src->end - src->start) / src->step;
-
+    end = (src->end_orig % src->step) == 0 ? src->end_orig : (src->end_orig + src->step - src->end_orig % src->step);
+    steps = (end - src->start) / src->step;
 #if 0
 printf("DEBUG: start == %lu, end == %lu, %lu steps\n"
     ,src->start
-    ,src->end
+    ,src->end_orig
     ,steps
     );
 #endif