Re: Discuss regarding Ticket 263
Jean-Edouard Babin <[email protected]>
| Newsgroups | gmane.comp.db.rrdtool.devel |
|---|---|
| Message-ID | <[email protected]> |
Hi Tobi, Here is a patch. I added a int instead of a bool as it seems that int is used for booleans everywhere in the code. I called fct1 time_clean. I tried to catch as much formatter as possible but of course as strftime() formatter's are not the same depending of OS my code can't handle this very well... I hope my code is not too much ugly.. I did not practice C for a while. Best regards, On Wed, May 19, 2010 at 12:38 AM, Tobias Oetiker <[email protected]> wrote: > Hi Jean-Edouard, > > the when part of the system simply does not make sense all the time > ... eg for AVERAGE ... > > how about having boolean flag in the structure called 'never' when > this is true your fct1 function would be called ... > > cheers > tobi > > > Today Jean-Edouard Babin wrote: > >> Hello, >> >> Yesterday I opened a new ticked >> http://oss.oetiker.ch/rrdtool-trac/ticket/263 because I got a wrong >> output when printing time of an empty VDEF. (time is 1st Jan 1970) >> I just find out why, in function vdef_calc of rrd_graph.c, cases >> (VDEF_MAXIMUM, VDEF_AVERAGE, VDEF_FIRST, ...) set dst->vf.when to 0 if >> value is unknow (which is my case). >> >> I would be happy to try to do a patch, but I would like to discuss how >> to do it before doing something. (I don't want to do something that >> will not be commited because it's not a proper solution) >> >> vdef struct is currently as follow: >> >> typedef struct vdef_t { >> enum vdef_op_en op; >> double param; /* parameter for function, if applicable */ >> double val; /* resulting value */ >> time_t when; /* timestamp, if applicable */ >> } vdef_t; >> >> My idea would be to add a new 'isnull' boolean variable to the struct, >> so that in print_calc I could add some test on isnull be able to run >> something else that strftime (let's say fct1()) when isnull is true. >> fct1() would replace each %X values by '-'. >> So "GPRINT:maxabc2: Reach 100% @ %c :strftime" would print "Reach >> 100% @ -", "GPRINT:maxabc2: Reach 100% @ %Y/%m/%d :strftime" would >> print "Reach 100% @ -/-/-" >> >> Do you have any comments about this idea ? >> >> _______________________________________________ >> rrd-developers mailing list >> [email protected] >> https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers >> >> > > -- > Tobi Oetiker, OETIKER+PARTNER AG, Aarweg 15 CH-4600 Olten, Switzerland > http://it.oetiker.ch [email protected] ++41 62 775 9902 / sb: -9900 > -- Jean-Edouard Babin _______________________________________________ rrd-developers mailing list [email protected] https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers
rrdtool_time.patch
(application/octet-stream, 9.6 KB)
diff -u rrdtool-1.4.3.org/src/rrd_graph.c rrdtool-1.4.3/src/rrd_graph.c
--- rrdtool-1.4.3.org/src/rrd_graph.c 2010-05-18 23:13:17.000000000 +0200
+++ rrdtool-1.4.3/src/rrd_graph.c 2010-05-19 19:06:14.708422167 +0200
@@ -1590,8 +1590,12 @@
if (im->gdes[i].strftm) {
prline.u_str = (char*)malloc((FMT_LEG_LEN + 2) * sizeof(char));
- strftime(prline.u_str,
- FMT_LEG_LEN, im->gdes[i].format, &tmvdef);
+ if (im->gdes[vidx].vf.never == 1) {
+ time_clean(prline.u_str, im->gdes[i].format);
+ } else {
+ strftime(prline.u_str,
+ FMT_LEG_LEN, im->gdes[i].format, &tmvdef);
+ }
} else if (bad_format(im->gdes[i].format)) {
rrd_set_error
("bad format for PRINT in '%s'", im->gdes[i].format);
@@ -1608,8 +1612,12 @@
/* GF_GPRINT */
if (im->gdes[i].strftm) {
- strftime(im->gdes[i].legend,
- FMT_LEG_LEN, im->gdes[i].format, &tmvdef);
+ if (im->gdes[vidx].vf.never == 1) {
+ time_clean(im->gdes[i].legend, im->gdes[i].format);
+ } else {
+ strftime(im->gdes[i].legend,
+ FMT_LEG_LEN, im->gdes[i].format, &tmvdef);
+ }
} else {
if (bad_format(im->gdes[i].format)) {
rrd_set_error
@@ -4843,6 +4851,7 @@
gdes->vf.param = param;
gdes->vf.val = DNAN; /* undefined */
gdes->vf.when = 0; /* undefined */
+ gdes->vf.never = 1;
} else {
rrd_set_error
("Parameter '%f' out of range in VDEF '%s'\n",
@@ -4864,6 +4873,7 @@
gdes->vf.param = DNAN;
gdes->vf.val = DNAN;
gdes->vf.when = 0;
+ gdes->vf.never = 1;
} else {
rrd_set_error
("Function '%s' needs no parameter in VDEF '%s'\n",
@@ -4909,6 +4919,7 @@
field = round((dst->vf.param * (double)(steps - 1)) / 100.0);
dst->vf.val = array[field];
dst->vf.when = 0; /* no time component */
+ dst->vf.never = 1;
free(array);
#if 0
for (step = 0; step < steps; step++)
@@ -4942,6 +4953,7 @@
field = round( dst->vf.param * (double)(nancount - 1) / 100.0);
dst->vf.val = array[field];
dst->vf.when = 0; /* no time component */
+ dst->vf.never = 1;
free(array);
}
break;
@@ -4952,15 +4964,18 @@
if (step == steps) {
dst->vf.val = DNAN;
dst->vf.when = 0;
+ dst->vf.never = 1;
} else {
dst->vf.val = data[step * src->ds_cnt];
dst->vf.when = src->start + (step + 1) * src->step;
+ dst->vf.never = 0;
}
while (step != steps) {
if (finite(data[step * src->ds_cnt])) {
if (data[step * src->ds_cnt] > dst->vf.val) {
dst->vf.val = data[step * src->ds_cnt];
dst->vf.when = src->start + (step + 1) * src->step;
+ dst->vf.never = 0;
}
}
step++;
@@ -4983,9 +4998,11 @@
if (dst->vf.op == VDEF_TOTAL) {
dst->vf.val = sum * src->step;
dst->vf.when = 0; /* no time component */
+ dst->vf.never = 1;
} else if (dst->vf.op == VDEF_AVERAGE) {
dst->vf.val = sum / cnt;
dst->vf.when = 0; /* no time component */
+ dst->vf.never = 1;
} else {
average = sum / cnt;
sum = 0.0;
@@ -4996,10 +5013,12 @@
}
dst->vf.val = pow(sum / cnt, 0.5);
dst->vf.when = 0; /* no time component */
+ dst->vf.never = 1;
};
} else {
dst->vf.val = DNAN;
dst->vf.when = 0;
+ dst->vf.never = 1;
}
}
break;
@@ -5010,15 +5029,18 @@
if (step == steps) {
dst->vf.val = DNAN;
dst->vf.when = 0;
+ dst->vf.never = 1;
} else {
dst->vf.val = data[step * src->ds_cnt];
dst->vf.when = src->start + (step + 1) * src->step;
+ dst->vf.never = 0;
}
while (step != steps) {
if (finite(data[step * src->ds_cnt])) {
if (data[step * src->ds_cnt] < dst->vf.val) {
dst->vf.val = data[step * src->ds_cnt];
dst->vf.when = src->start + (step + 1) * src->step;
+ dst->vf.never = 0;
}
}
step++;
@@ -5034,10 +5056,12 @@
step++;
if (step == steps) { /* all entries were NaN */
dst->vf.val = DNAN;
- dst->vf.when = 10;
+ dst->vf.when = 0;
+ dst->vf.never = 1;
} else {
dst->vf.val = data[step * src->ds_cnt];
dst->vf.when = src->start + step * src->step;
+ dst->vf.never = 0;
}
break;
case VDEF_LAST:
@@ -5051,9 +5075,11 @@
if (step < 0) { /* all entries were NaN */
dst->vf.val = DNAN;
dst->vf.when = 0;
+ dst->vf.never = 1;
} else {
dst->vf.val = data[step * src->ds_cnt];
dst->vf.when = src->start + (step + 1) * src->step;
+ dst->vf.never = 0;
}
break;
case VDEF_LSLSLOPE:
@@ -5091,16 +5117,20 @@
if (dst->vf.op == VDEF_LSLSLOPE) {
dst->vf.val = slope;
dst->vf.when = 0;
+ dst->vf.never = 1;
} else if (dst->vf.op == VDEF_LSLINT) {
dst->vf.val = y_intercept;
dst->vf.when = 0;
+ dst->vf.never = 1;
} else if (dst->vf.op == VDEF_LSLCORREL) {
dst->vf.val = correl;
dst->vf.when = 0;
+ dst->vf.never = 1;
};
} else {
dst->vf.val = DNAN;
dst->vf.when = 0;
+ dst->vf.never = 1;
}
}
break;
@@ -5149,3 +5179,59 @@
im->grinfo = im->grinfo_current;
}
}
+
+void time_clean(
+ char *result,
+ char *format)
+{
+ int j, jj;
+
+ jj = 0;
+ for(j = 0; j < FMT_LEG_LEN - 1; j++) { /* we don't need to parse the last char */
+ if (format[j] == '%') {
+ if ((format[j+1] == 'A') || (format[j+1] == 'a') ||
+ (format[j+1] == 'B') || (format[j+1] == 'b') ||
+ (format[j+1] == 'C') || (format[j+1] == 'c') ||
+ (format[j+1] == 'D') || (format[j+1] == 'd') ||
+ (format[j+1] == 'E') || (format[j+1] == 'e') ||
+ (format[j+1] == 'F') ||
+ (format[j+1] == 'G') || (format[j+1] == 'g') ||
+ (format[j+1] == 'H') || (format[j+1] == 'h') ||
+ (format[j+1] == 'I') ||
+ (format[j+1] == 'j') ||
+ (format[j+1] == 'k') ||
+ (format[j+1] == 'l') ||
+ (format[j+1] == 'M') || (format[j+1] == 'm') ||
+ (format[j+1] == 'O') ||
+ (format[j+1] == 'P') || (format[j+1] == 'p') ||
+ (format[j+1] == 'R') || (format[j+1] == 'r') ||
+ (format[j+1] == 'S') || (format[j+1] == 's') ||
+ (format[j+1] == 'T') ||
+ (format[j+1] == 'U') || (format[j+1] == 'u') ||
+ (format[j+1] == 'V') || (format[j+1] == 'v') ||
+ (format[j+1] == 'W') || (format[j+1] == 'w') ||
+ (format[j+1] == 'X') || (format[j+1] == 'x') ||
+ (format[j+1] == 'Y') || (format[j+1] == 'y') ||
+ (format[j+1] == 'Z') || (format[j+1] == 'z') ||
+ (format[j+1] == '+')) {
+ result[jj++] = '-';
+ j++; /* We skip the following char */
+ } else if (format[j+1] == '%') {
+ result[jj++] = '%';
+ j++; /* We skip the following char */
+ } else if (format[j+1] == 'n') {
+ result[jj++] = '\r';
+ result[jj++] = '\n';
+ j++; /* We skip the following char */
+ } else if (format[j+1] == 't') {
+ result[jj++] = '\t';
+ j++; /* We skip the following char */
+ } else {
+ result[jj++] = format[j];
+ }
+ } else {
+ result[jj++] = format[j];
+ }
+ }
+ result[jj] = '\0'; /* We must force the end of the string */
+}
diff -u rrdtool-1.4.3.org/src/rrd_graph.h rrdtool-1.4.3/src/rrd_graph.h
--- rrdtool-1.4.3.org/src/rrd_graph.h 2010-01-20 20:47:04.000000000 +0100
+++ rrdtool-1.4.3/src/rrd_graph.h 2010-05-19 18:57:12.927785718 +0200
@@ -112,6 +112,7 @@
double param; /* parameter for function, if applicable */
double val; /* resulting value */
time_t when; /* timestamp, if applicable */
+ int never; /* boolean, indicate that when value mean never */
} vdef_t;
typedef struct xlab_t {
@@ -485,3 +486,7 @@
image_desc_t *im,
char *key,
rrd_info_type_t type, rrd_infoval_t value);
+
+void time_clean(
+ char *result,
+ char *format);