Mark Plaksin <[EMAIL PROTECTED]> writes: > Tobias Oetiker <[EMAIL PROTECTED]> writes: > >> I am trying to save you from carrying TWO variables all through your >> code (grinfoc and grinfoh) this is not beautiful one variable should >> be enough. You might even want to add it to image_desc and take >> it out only at the very end ... since image_desc is already being >> carried through all the functions ... > > Ha! I finally get it! Build the list "backwards" and you only need to > keep track of the head. I've known about linked lists for many years > but have never done much with them. It took reading an intro from > Stanford for me to get it :) (http://cslibrary.stanford.edu/103/) > > Attached is a new patch. I think it does what you want except for this: > >> c) the data returning path for size and PRINT info still uses the >> original interface. this is fine for the rrd_graph function but >> for the rrd_graph_info function it should be integrated ...
Here's a patch which address that too. Now that it's done I don't think I understood what you were asking for! With this change instead of getting "100x400" as output you get two lines: ysize = 100 xsize = 400 That uses the new interface for dumping graph data but I can hear you saying that this is going to break existing code. So if I didn't get it right please have patience and try to explain it to me again :)
diff -u -ur rrdtool-trunk/doc/rrdgraph.pod rrdtool-trunk-happy/doc/rrdgraph.pod --- rrdtool-trunk/doc/rrdgraph.pod 2007-08-16 10:28:34.000000000 -0400 +++ rrdtool-trunk-happy/doc/rrdgraph.pod 2007-12-13 09:48:57.000000000 -0500 @@ -153,6 +153,11 @@ Gridfitting is turned off for PDF, EPS, SVG output by default. +[B<-k>|B<--force-scale> I<min>:I<max>] + +Force scale (sKale) of graph. I<min> is the lowest number on the y-axis, +I<max> is the highest. Can be used in conjunction with I<-p scale>. + =item Grid =over 4 @@ -391,6 +396,28 @@ Adds the given string as a watermark, horizontally centred, at the bottom of the graph. +[B<-p>|B<--print-info> I<DATA[:DATA]...> + +Print extra information about the graph. DATA can be one of I<scale>, +I<coords>, or I<all>. Normally rrdgraph only prints the size of the image. +B<--print-info> data is displayed before the size. + +I<scale> shows the minimum and maximum Y values on the graph. For +example: + + scale_min = 0.0000000000e+00 + scale_max = 9.9000000000e+01 + +I<coords> prints the x and y origins and the size of the graph itself. +For example: + + xorigin = 51 + yorigin = 122 + xsize = 400 + ysize = 100 + +I<all> prints all extra information (currently just scale and coords). + =item Data and variables B<DEF:>I<vname>B<=>I<rrdfile>B<:>I<ds-name>B<:>I<CF>[B<:step=>I<step>][B<:start=>I<time>][B<:end=>I<time>] diff -u -ur rrdtool-trunk/src/rrd.h rrdtool-trunk-happy/src/rrd.h --- rrdtool-trunk/src/rrd.h 2007-12-11 15:05:19.000000000 -0500 +++ rrdtool-trunk-happy/src/rrd.h 2007-12-13 10:29:45.000000000 -0500 @@ -86,6 +86,28 @@ off_t pos; /* current pos in file */ } rrd_file_t; +/* rrd info interface */ + enum info_type { RD_I_VAL = 0, + RD_I_CNT, + RD_I_STR, + RD_I_INT + }; + + typedef union infoval { + unsigned long u_cnt; + rrd_value_t u_val; + char *u_str; + int u_int; + } infoval; + + typedef struct info_t { + char *key; + enum info_type type; + union infoval value; + struct info_t *next; + } info_t; + + /* main function blocks */ int rrd_create( int, @@ -102,6 +124,16 @@ FILE *, double *, double *); + int rrd_graph_info( + int, + char **, + char ***, + int *, + int *, + FILE *, + double *, + double *, + info_t **); unsigned char *rrd_graph_in_memory( int argc, diff -u -ur rrdtool-trunk/src/rrd_graph.c rrdtool-trunk-happy/src/rrd_graph.c --- rrdtool-trunk/src/rrd_graph.c 2007-12-11 15:05:19.000000000 -0500 +++ rrdtool-trunk-happy/src/rrd_graph.c 2007-12-13 10:29:41.000000000 -0500 @@ -1247,6 +1247,11 @@ there was no data in the graph ... this is not good ... lets set these to dummy values then ... */ + if ( im->extra_flags & FORCE_SCALE ) { + minval=im->force_scale_min; + maxval=im->force_scale_max; + } + if (im->logarithmic) { if (isnan(minval)) minval = 0.2; @@ -2653,6 +2658,7 @@ int Xvertical = 0, Ytitle = 0, Xylabel = 0, Xmain = 0, Ymain = 0, Yxlabel = 0, Xspacing = 15, Yspacing = 15, Ywatermark = 4; + infoval info; if (im->extra_flags & ONLY_GRAPH) { im->xorigin = 0; @@ -2877,6 +2883,18 @@ } ytr(im, DNAN); + + /* Always display xsize and ysize */ + info.u_cnt = im->xsize; + grinfo_push (im, sprintf_alloc("xsize"), RD_I_CNT, info); + info.u_cnt = im->ysize; + grinfo_push (im, sprintf_alloc("ysize"), RD_I_CNT, info); + if(im->extra_flags & PRINT_COORDS) { + info.u_cnt = im->xorigin; + grinfo_push (im, sprintf_alloc("xorigin"), RD_I_CNT, info); + info.u_cnt = im->yorigin - Ymain; + grinfo_push (im, sprintf_alloc("yorigin"), RD_I_CNT, info); + } return 0; } @@ -2922,6 +2940,7 @@ double areazero = 0.0; graph_desc_t *lastgdes = NULL; + infoval info; PangoFontMap *font_map = pango_cairo_font_map_get_default(); @@ -2965,6 +2984,15 @@ if (!im->logarithmic) { si_unit(im); } + + if(im->extra_flags & PRINT_SCALE) { + /*printf("scale: %.2f,%.2f\n",im->minval,im->maxval);*/ + info.u_val = im->minval; + grinfo_push (im, sprintf_alloc("scale_min"), RD_I_VAL, info); + info.u_val = im->maxval; + grinfo_push (im, sprintf_alloc("scale_max"), RD_I_VAL, info); + } + /* identify si magnitude Kilo, Mega Giga ? */ if (!im->rigid && !im->logarithmic) expand_range(im); /* make sure the upper and lower limit are @@ -3455,13 +3483,28 @@ return inp; } +/* Now just a wrapper around rrd_graph_info */ +int rrd_graph( + int argc, + char **argv, + char ***prdata, + int *xsize, + int *ysize, + FILE * stream, + double *ymin, + double *ymax) +{ + return (int) (rrd_graph_info + (argc, argv, prdata, xsize, ysize, stream, ymin, ymax, NULL)); +} + /* Some surgery done on this function, it became ridiculously big. ** Things moved: ** - initializing now in rrd_graph_init() ** - options parsing now in rrd_graph_options() ** - script parsing now in rrd_graph_script() */ -int rrd_graph( +int rrd_graph_info( int argc, char **argv, char ***prdata, @@ -3469,9 +3512,11 @@ int *ysize, FILE * stream, double *ymin, - double *ymax) + double *ymax, + info_t **grinfo) { image_desc_t im; + im.grinfo = (info_t *) NULL; rrd_graph_init(&im); @@ -3520,6 +3565,7 @@ *xsize = im.ximg; *ysize = im.yimg; + *ymin = im.minval; *ymax = im.maxval; if (im.imginfo) { @@ -3549,6 +3595,9 @@ sprintf((*prdata)[0], im.imginfo, filename, (long) (im.zoom * im.ximg), (long) (im.zoom * im.yimg)); } + if ( *grinfo == (info_t *) 1 ) { + *grinfo = im.grinfo; + } im_free(&im); return 0; } @@ -3666,6 +3715,8 @@ im->zoom = 1; im->font_options = cairo_font_options_create(); im->graph_antialias = CAIRO_ANTIALIAS_GRAY; + im->force_scale_min = 0.0; + im->force_scale_max = 0.0; cairo_font_options_set_hint_style(im->font_options, CAIRO_HINT_STYLE_FULL); @@ -3720,9 +3771,9 @@ char *argv[], image_desc_t *im) { - int stroff; + int stroff, scan_matches; char *parsetime_error = NULL; - char scan_gtm[12], scan_mtm[12], scan_ltm[12], col_nam[12]; + char scan_gtm[12], scan_mtm[12], scan_ltm[12], col_nam[12], scan_info[12]; time_t start_tmp = 0, end_tmp = 0; long long_tmp; struct rrd_time_value start_tv, end_tv; @@ -3774,6 +3825,8 @@ {"font-smoothing-threshold", required_argument, 0, 'B'}, {"watermark", required_argument, 0, 'W'}, {"alt-y-mrtg", no_argument, 0, 1000}, /* this has no effect it is just here to save old apps from crashing when they use it */ + {"force-scale", required_argument, 0, 'k'}, + {"print-info", required_argument, 0, 'p'}, {0, 0, 0, 0} }; @@ -3789,7 +3842,7 @@ int col_start, col_end; opt = getopt_long(argc, argv, - "s:e:x:y:v:w:h:D:iu:l:rb:oc:n:m:t:f:a:I:zgjFYAMEX:L:S:T:NR:B:W:", + "s:e:x:y:v:w:h:D:iu:l:rb:oc:n:m:t:f:a:I:zgjFYAMEX:L:S:T:NR:B:W:k:p:", long_options, &option_index); if (opt == EOF) @@ -4117,6 +4170,41 @@ im->watermark[99] = '\0'; break; + case 'k': + im->extra_flags |= FORCE_SCALE; + if(sscanf(optarg, "%lf:%lf", &im->force_scale_min,&im->force_scale_max) != 2) { + rrd_set_error("unknown scale factor: %s. (expecting min:max)",optarg); + return; + } + break; + + case 'p': + /* options must be 12 chars or less */ + while ( (scan_matches = sscanf (optarg, "%12[^:]", scan_info)) ) { + if ( scan_matches == 0 || scan_matches == EOF ) { + break; + } + optarg += sizeof (char) * strlen (scan_info); + if ( strcmp (scan_info, "all") == 0 ) { + im->extra_flags |= PRINT_SCALE; + im->extra_flags |= PRINT_COORDS; + break; + } + if ( strcmp (scan_info, "scale") == 0 ) { + im->extra_flags |= PRINT_SCALE; + } + if ( strcmp (scan_info, "coords") == 0 ) { + im->extra_flags |= PRINT_COORDS; + } + /* Either : or we're done */ + if ( *optarg == ':' ) { + optarg++; + } else { + break; + } + } + break; + case '?': if (optopt != 0) rrd_set_error("unknown option '%c'", optopt); @@ -4596,3 +4684,16 @@ else return 1; } + +void grinfo_push ( + image_desc_t *im, + char *key, + enum info_type type, + infoval value) +{ + if ( im->grinfo == NULL ) { + im->grinfo = info_push(NULL, key, type, value); + } else { + im->grinfo = info_push(im->grinfo, key, type, value); + } +} diff -u -ur rrdtool-trunk/src/rrd_graph.h rrdtool-trunk-happy/src/rrd_graph.h --- rrdtool-trunk/src/rrd_graph.h 2007-09-24 14:04:05.000000000 -0400 +++ rrdtool-trunk-happy/src/rrd_graph.h 2007-12-13 10:29:49.000000000 -0500 @@ -30,6 +30,9 @@ #define FORCE_UNITS_SI 0x100 /* force use of SI units in Y axis (no effect in linear graph, SI instead of E in log graph) */ #define FULL_SIZE_MODE 0x200 /* -width and -height indicate the total size of the image */ +#define PRINT_SCALE 0x400 /* print the scale */ +#define PRINT_COORDS 0x800 /* print graph coords */ +#define FORCE_SCALE 0x1000 /* Force scale */ enum tmt_en { TMT_SECOND = 0, TMT_MINUTE, TMT_HOUR, TMT_DAY, TMT_WEEK, TMT_MONTH, TMT_YEAR @@ -211,6 +214,8 @@ existing one is out of date */ int slopemode; /* connect the dots of the curve directly, not using a stair */ int logarithmic; /* scale the yaxis logarithmic */ + double force_scale_min; /* Force a scale--min */ + double force_scale_max; /* Force a scale--max */ /* status information */ @@ -237,6 +242,8 @@ cairo_t *cr; /* drawin context */ cairo_font_options_t *font_options; /* cairo font options */ cairo_antialias_t graph_antialias; /* antialiasing for the graph */ + + info_t *grinfo; /* extra graph info for printing */ } image_desc_t; /* Prototypes */ @@ -338,6 +345,16 @@ FILE *, double *, double *); +int rrd_graph_info( + int, + char **, + char ***, + int *, + int *, + FILE *, + double *, + double *, + info_t **); void rrd_graph_init( image_desc_t *); void rrd_graph_options( @@ -367,8 +384,7 @@ const void *); int graph_size_location( image_desc_t *, - int - ); + int); /* create a new line */ @@ -453,3 +469,9 @@ double *y); #endif + +void grinfo_push ( + image_desc_t *im, + char *key, + enum info_type type, + infoval value); diff -u -ur rrdtool-trunk/src/rrd_info.c rrdtool-trunk-happy/src/rrd_info.c --- rrdtool-trunk/src/rrd_info.c 2007-12-11 15:05:19.000000000 -0500 +++ rrdtool-trunk-happy/src/rrd_info.c 2007-12-13 09:48:57.000000000 -0500 @@ -49,30 +49,34 @@ enum info_type type, infoval value) { - info_t *next; + info_t *first; - next = malloc(sizeof(*next)); - next->next = (info_t *) 0; - if (info) - info->next = next; - next->type = type; - next->key = key; + first = malloc(sizeof(*first)); + + if ( info ) { + first->next = info; + } else { + first->next = (info_t *) 0; + } + + first->type = type; + first->key = key; switch (type) { case RD_I_VAL: - next->value.u_val = value.u_val; + first->value.u_val = value.u_val; break; case RD_I_CNT: - next->value.u_cnt = value.u_cnt; + first->value.u_cnt = value.u_cnt; break; case RD_I_INT: - next->value.u_int = value.u_int; + first->value.u_int = value.u_int; break; case RD_I_STR: - next->value.u_str = malloc(sizeof(char) * (strlen(value.u_str) + 1)); - strcpy(next->value.u_str, value.u_str); + first->value.u_str = malloc(sizeof(char) * (strlen(value.u_str) + 1)); + strcpy(first->value.u_str, value.u_str); break; } - return (next); + return (first); } @@ -99,7 +103,7 @@ { unsigned int i, ii = 0; rrd_t rrd; - info_t *data = NULL, *cd; + info_t *data = NULL; infoval info; rrd_file_t *rrd_file; enum cf_en current_cf; @@ -110,22 +114,21 @@ goto err_free; info.u_str = filename; - cd = info_push(NULL, sprintf_alloc("filename"), RD_I_STR, info); - data = cd; + data = info_push(NULL, sprintf_alloc("filename"), RD_I_STR, info); info.u_str = rrd.stat_head->version; - cd = info_push(cd, sprintf_alloc("rrd_version"), RD_I_STR, info); + data = info_push(data, sprintf_alloc("rrd_version"), RD_I_STR, info); info.u_cnt = rrd.stat_head->pdp_step; - cd = info_push(cd, sprintf_alloc("step"), RD_I_CNT, info); + data = info_push(data, sprintf_alloc("step"), RD_I_CNT, info); info.u_cnt = rrd.live_head->last_up; - cd = info_push(cd, sprintf_alloc("last_update"), RD_I_CNT, info); + data = info_push(data, sprintf_alloc("last_update"), RD_I_CNT, info); for (i = 0; i < rrd.stat_head->ds_cnt; i++) { info.u_str = rrd.ds_def[i].dst; - cd = info_push(cd, sprintf_alloc("ds[%s].type", rrd.ds_def[i].ds_nam), + data = info_push(data, sprintf_alloc("ds[%s].type", rrd.ds_def[i].ds_nam), RD_I_STR, info); current_ds = dst_conv(rrd.ds_def[i].dst); @@ -137,7 +140,7 @@ rpn_compact2str((rpn_cdefds_t *) &(rrd.ds_def[i].par[DS_cdef]), rrd.ds_def, &buffer); info.u_str = buffer; - cd = info_push(cd, + data = info_push(data, sprintf_alloc("ds[%s].cdef", rrd.ds_def[i].ds_nam), RD_I_STR, info); free(buffer); @@ -145,93 +148,93 @@ break; default: info.u_cnt = rrd.ds_def[i].par[DS_mrhb_cnt].u_cnt; - cd = info_push(cd, + data = info_push(data, sprintf_alloc("ds[%s].minimal_heartbeat", rrd.ds_def[i].ds_nam), RD_I_CNT, info); info.u_val = rrd.ds_def[i].par[DS_min_val].u_val; - cd = info_push(cd, + data = info_push(data, sprintf_alloc("ds[%s].min", rrd.ds_def[i].ds_nam), RD_I_VAL, info); info.u_val = rrd.ds_def[i].par[DS_max_val].u_val; - cd = info_push(cd, + data = info_push(data, sprintf_alloc("ds[%s].max", rrd.ds_def[i].ds_nam), RD_I_VAL, info); break; } info.u_str = rrd.pdp_prep[i].last_ds; - cd = info_push(cd, + data = info_push(data, sprintf_alloc("ds[%s].last_ds", rrd.ds_def[i].ds_nam), RD_I_STR, info); info.u_val = rrd.pdp_prep[i].scratch[PDP_val].u_val; - cd = info_push(cd, + data = info_push(data, sprintf_alloc("ds[%s].value", rrd.ds_def[i].ds_nam), RD_I_VAL, info); info.u_cnt = rrd.pdp_prep[i].scratch[PDP_unkn_sec_cnt].u_cnt; - cd = info_push(cd, + data = info_push(data, sprintf_alloc("ds[%s].unknown_sec", rrd.ds_def[i].ds_nam), RD_I_CNT, info); } for (i = 0; i < rrd.stat_head->rra_cnt; i++) { info.u_str = rrd.rra_def[i].cf_nam; - cd = info_push(cd, sprintf_alloc("rra[%d].cf", i), RD_I_STR, info); + data = info_push(data, sprintf_alloc("rra[%d].cf", i), RD_I_STR, info); current_cf = cf_conv(rrd.rra_def[i].cf_nam); info.u_cnt = rrd.rra_def[i].row_cnt; - cd = info_push(cd, sprintf_alloc("rra[%d].rows", i), RD_I_CNT, info); + data = info_push(data, sprintf_alloc("rra[%d].rows", i), RD_I_CNT, info); info.u_cnt = rrd.rra_def[i].pdp_cnt; - cd = info_push(cd, sprintf_alloc("rra[%d].pdp_per_row", i), RD_I_CNT, + data = info_push(data, sprintf_alloc("rra[%d].pdp_per_row", i), RD_I_CNT, info); switch (current_cf) { case CF_HWPREDICT: case CF_MHWPREDICT: info.u_val = rrd.rra_def[i].par[RRA_hw_alpha].u_val; - cd = info_push(cd, sprintf_alloc("rra[%d].alpha", i), RD_I_VAL, + data = info_push(data, sprintf_alloc("rra[%d].alpha", i), RD_I_VAL, info); info.u_val = rrd.rra_def[i].par[RRA_hw_beta].u_val; - cd = info_push(cd, sprintf_alloc("rra[%d].beta", i), RD_I_VAL, + data = info_push(data, sprintf_alloc("rra[%d].beta", i), RD_I_VAL, info); break; case CF_SEASONAL: case CF_DEVSEASONAL: info.u_val = rrd.rra_def[i].par[RRA_seasonal_gamma].u_val; - cd = info_push(cd, sprintf_alloc("rra[%d].gamma", i), RD_I_VAL, + data = info_push(data, sprintf_alloc("rra[%d].gamma", i), RD_I_VAL, info); if (atoi(rrd.stat_head->version) >= 4) { info.u_val = rrd.rra_def[i].par[RRA_seasonal_smoothing_window].u_val; - cd = info_push(cd, + data = info_push(data, sprintf_alloc("rra[%d].smoothing_window", i), RD_I_VAL, info); } break; case CF_FAILURES: info.u_val = rrd.rra_def[i].par[RRA_delta_pos].u_val; - cd = info_push(cd, sprintf_alloc("rra[%d].delta_pos", i), + data = info_push(data, sprintf_alloc("rra[%d].delta_pos", i), RD_I_VAL, info); info.u_val = rrd.rra_def[i].par[RRA_delta_neg].u_val; - cd = info_push(cd, sprintf_alloc("rra[%d].delta_neg", i), + data = info_push(data, sprintf_alloc("rra[%d].delta_neg", i), RD_I_VAL, info); info.u_cnt = rrd.rra_def[i].par[RRA_failure_threshold].u_cnt; - cd = info_push(cd, sprintf_alloc("rra[%d].failure_threshold", i), + data = info_push(data, sprintf_alloc("rra[%d].failure_threshold", i), RD_I_CNT, info); info.u_cnt = rrd.rra_def[i].par[RRA_window_len].u_cnt; - cd = info_push(cd, sprintf_alloc("rra[%d].window_length", i), + data = info_push(data, sprintf_alloc("rra[%d].window_length", i), RD_I_CNT, info); break; case CF_DEVPREDICT: break; default: info.u_val = rrd.rra_def[i].par[RRA_cdp_xff_val].u_val; - cd = info_push(cd, sprintf_alloc("rra[%d].xff", i), RD_I_VAL, + data = info_push(data, sprintf_alloc("rra[%d].xff", i), RD_I_VAL, info); break; } @@ -243,19 +246,19 @@ info.u_val = rrd.cdp_prep[i * rrd.stat_head->ds_cnt + ii].scratch[CDP_hw_intercept].u_val; - cd = info_push(cd, + data = info_push(data, sprintf_alloc("rra[%d].cdp_prep[%d].intercept", i, ii), RD_I_VAL, info); info.u_val = rrd.cdp_prep[i * rrd.stat_head->ds_cnt + ii].scratch[CDP_hw_slope].u_val; - cd = info_push(cd, + data = info_push(data, sprintf_alloc("rra[%d].cdp_prep[%d].slope", i, ii), RD_I_VAL, info); info.u_cnt = rrd.cdp_prep[i * rrd.stat_head->ds_cnt + ii].scratch[CDP_null_count].u_cnt; - cd = info_push(cd, + data = info_push(data, sprintf_alloc("rra[%d].cdp_prep[%d].NaN_count", i, ii), RD_I_CNT, info); break; @@ -263,7 +266,7 @@ info.u_val = rrd.cdp_prep[i * rrd.stat_head->ds_cnt + ii].scratch[CDP_hw_seasonal].u_val; - cd = info_push(cd, + data = info_push(data, sprintf_alloc("rra[%d].cdp_prep[%d].seasonal", i, ii), RD_I_VAL, info); break; @@ -271,7 +274,7 @@ info.u_val = rrd.cdp_prep[i * rrd.stat_head->ds_cnt + ii].scratch[CDP_seasonal_deviation].u_val; - cd = info_push(cd, + data = info_push(data, sprintf_alloc("rra[%d].cdp_prep[%d].deviation", i, ii), RD_I_VAL, info); break; @@ -290,7 +293,7 @@ history[j] = (violations_array[j] == 1) ? '1' : '0'; history[j] = '\0'; info.u_str = history; - cd = info_push(cd, + data = info_push(data, sprintf_alloc("rra[%d].cdp_prep[%d].history", i, ii), RD_I_STR, info); } @@ -299,13 +302,13 @@ info.u_val = rrd.cdp_prep[i * rrd.stat_head->ds_cnt + ii].scratch[CDP_val].u_val; - cd = info_push(cd, + data = info_push(data, sprintf_alloc("rra[%d].cdp_prep[%d].value", i, ii), RD_I_VAL, info); info.u_cnt = rrd.cdp_prep[i * rrd.stat_head->ds_cnt + ii].scratch[CDP_unkn_pdp_cnt].u_cnt; - cd = info_push(cd, + data = info_push(data, sprintf_alloc ("rra[%d].cdp_prep[%d].unknown_datapoints", i, ii), RD_I_CNT, info); @@ -319,3 +322,48 @@ rrd_free(&rrd); return (data); } + +void info_print (info_t *data) { + info_t *save; + + while (data) { + save = data; + printf("%s = ", data->key); + free(data->key); + + switch (data->type) { + case RD_I_VAL: + if (isnan(data->value.u_val)) + printf("NaN"); + else + printf("%0.10e", data->value.u_val); + break; + case RD_I_CNT: + printf("%lu", data->value.u_cnt); + break; + case RD_I_INT: + printf("%d", data->value.u_int); + break; + case RD_I_STR: + printf("\"%s\"", data->value.u_str); + free(data->value.u_str); + break; + } + data = data->next; + free(save); + printf("\n"); + } +} + +void info_free (info_t *data) { + info_t *save; + + while (data) { + save = data; + if ( data->key ) { + free(data->key); + } + data = data->next; + free(save); + } +} diff -u -ur rrdtool-trunk/src/rrd_tool.c rrdtool-trunk-happy/src/rrd_tool.c --- rrdtool-trunk/src/rrd_tool.c 2007-08-16 10:28:22.000000000 -0400 +++ rrdtool-trunk-happy/src/rrd_tool.c 2007-12-13 11:03:06.000000000 -0500 @@ -593,39 +593,13 @@ else if (strcmp("dump", argv[1]) == 0) rrd_dump(argc - 1, &argv[1]); else if (strcmp("info", argv[1]) == 0 || strcmp("updatev", argv[1]) == 0) { - info_t *data, *save; + info_t *data; if (strcmp("info", argv[1]) == 0) data = rrd_info(argc - 1, &argv[1]); else data = rrd_update_v(argc - 1, &argv[1]); - while (data) { - save = data; - printf("%s = ", data->key); - free(data->key); - - switch (data->type) { - case RD_I_VAL: - if (isnan(data->value.u_val)) - printf("NaN"); - else - printf("%0.10e", data->value.u_val); - break; - case RD_I_CNT: - printf("%lu", data->value.u_cnt); - break; - case RD_I_INT: - printf("%d", data->value.u_int); - break; - case RD_I_STR: - printf("\"%s\"", data->value.u_str); - free(data->value.u_str); - break; - } - data = data->next; - free(save); - printf("\n"); - } + info_print (data); free(data); } @@ -776,6 +750,7 @@ int i; int tostdout = (strcmp(argv[2], "-") == 0); int imginfo = 0; + info_t *grinfo = (info_t *) 1; /* 1 to distinguish it from the NULL that rrd_graph sends in */ for (i = 2; i < argc; i++) { if (strcmp(argv[i], "--imginfo") == 0 @@ -784,11 +759,16 @@ break; } } - if (rrd_graph + if (rrd_graph_info (argc - 1, &argv[1], &calcpr, &xsize, &ysize, NULL, &ymin, - &ymax) != -1) { - if (!tostdout && !imginfo) - printf("%dx%d\n", xsize, ysize); + &ymax, &grinfo) != -1) { + if (!tostdout && !imginfo) { + /* print graph info if any */ + if ( grinfo != NULL && grinfo != (info_t *) 1 ) { + info_print (grinfo); + /* testing free (grinfo);*/ + } + } if (calcpr) { for (i = 0; calcpr[i]; i++) { if (!tostdout) @@ -797,7 +777,11 @@ } free(calcpr); } - } + } else { + if ( grinfo != NULL && grinfo != (info_t *) 1 ) { + info_free (grinfo); + } + } } else if (strcmp("tune", argv[1]) == 0) rrd_tune(argc - 1, &argv[1]); diff -u -ur rrdtool-trunk/src/rrd_tool.h rrdtool-trunk-happy/src/rrd_tool.h --- rrdtool-trunk/src/rrd_tool.h 2007-08-16 10:28:22.000000000 -0400 +++ rrdtool-trunk-happy/src/rrd_tool.h 2007-12-13 09:48:57.000000000 -0500 @@ -63,27 +63,6 @@ #define DIM(x) (sizeof(x)/sizeof(x[0])) -/* rrd info interface */ - enum info_type { RD_I_VAL = 0, - RD_I_CNT, - RD_I_STR, - RD_I_INT - }; - - typedef union infoval { - unsigned long u_cnt; - rrd_value_t u_val; - char *u_str; - int u_int; - } infoval; - - typedef struct info_t { - char *key; - enum info_type type; - union infoval value; - struct info_t *next; - } info_t; - info_t *rrd_info( int, char **); @@ -105,6 +84,9 @@ char *, enum info_type, infoval); + void info_print ( + info_t *data); + void info_free (info_t *); /* HELPER FUNCTIONS */
_______________________________________________ rrd-developers mailing list rrd-developers@lists.oetiker.ch https://lists.oetiker.ch/cgi-bin/listinfo/rrd-developers