index ef1e8e747bb2b6c18ef85dc656fbcdcea98ea388..55185c93594d8c0662c57daa7202caa9ccfb8deb 100644 (file)
+/****************************************************************************
+ * RRDtool 1.2.x Copyright Tobias Oetiker, 1997 - 2005
+ ****************************************************************************
+ * rrd_graph_helper.c commandline parser functions
+ * this code was probably writtenn by Alex van den Bogaerdt
+ ****************************************************************************/
+
#include "rrd_graph.h"
#define dprintf if (gdp->debug) printf
+/* Define prototypes for the parsing methods.
+ Inputs:
+ char *line - pointer to base of input source
+ unsigned int eaten - index to next input character (INPUT/OUTPUT)
+ graph_desc_t *gdp - pointer to a graph description
+ image_desc_t *im - pointer to an image description
+*/
+
+int rrd_parse_find_gf (char *, unsigned int *, graph_desc_t *);
+int rrd_parse_legend (char *, unsigned int *, graph_desc_t *);
+int rrd_parse_color (char *, graph_desc_t *);
+int rrd_parse_CF (char *, unsigned int *, graph_desc_t *, enum cf_en *);
+int rrd_parse_print (char *, unsigned int *, graph_desc_t *, image_desc_t *);
+int rrd_parse_shift (char *, unsigned int *, graph_desc_t *, image_desc_t *);
+int rrd_parse_xport (char *, unsigned int *, graph_desc_t *, image_desc_t *);
+int rrd_parse_PVHLAST (char *, unsigned int *, graph_desc_t *, image_desc_t *);
+int rrd_parse_vname (char *, unsigned int *, graph_desc_t *, image_desc_t *);
+int rrd_parse_def (char *, unsigned int *, graph_desc_t *, image_desc_t *);
+int rrd_parse_vdef (char *, unsigned int *, graph_desc_t *, image_desc_t *);
+int rrd_parse_cdef (char *, unsigned int *, graph_desc_t *, image_desc_t *);
+
+
+
int
rrd_parse_find_gf(char *line, unsigned int *eaten, graph_desc_t *gdp) {
char funcname[11],c1=0,c2=0;
}
int
-rrd_parse_CF(char *line, unsigned int *eaten, graph_desc_t *gdp) {
+rrd_parse_CF(char *line, unsigned int *eaten, graph_desc_t *gdp, enum cf_en *cf) {
char symname[CF_NAM_SIZE];
int i=0;
(*eaten)+=i;
dprintf("- using CF '%s'\n",symname);
- if ((int)(gdp->cf = cf_conv(symname))==-1) {
+ if ((int)(*cf = cf_conv(symname))==-1) {
rrd_set_error("Unknown CF '%s' in '%s'",symname,line);
return 1;
}
@@ -122,7 +152,7 @@ rrd_parse_print(char *line, unsigned int *eaten, graph_desc_t *gdp, image_desc_t
case GF_DEF:
case GF_CDEF:
dprintf("- vname is of type DEF or CDEF, looking for CF\n");
- if (rrd_parse_CF(line,eaten,gdp)) return 1;
+ if (rrd_parse_CF(line,eaten,gdp,&gdp->cf)) return 1;
break;
case GF_VDEF:
dprintf("- vname is of type VDEF\n");
@@ -133,13 +163,84 @@ rrd_parse_print(char *line, unsigned int *eaten, graph_desc_t *gdp, image_desc_t
}
if (rrd_parse_legend(line,eaten,gdp)) return 1;
-
- /* Why is there a separate structure member "format" ??? */
+ /* for *PRINT the legend itself gets renderd later. We only
+ get the format at this juncture */
strcpy(gdp->format,gdp->legend);
-
+ gdp->legend[0]='\0';
return 0;
}
+int
+rrd_parse_shift(char *line, unsigned int *eaten, graph_desc_t *gdp, image_desc_t *im) {
+ char *l = strdup(line + *eaten), *p;
+ int rc = 1;
+
+ p = strchr(l, ':');
+ if (p == NULL) {
+ rrd_set_error("Invalid SHIFT syntax");
+ goto out;
+ }
+ *p++ = '\0';
+
+ if ((gdp->vidx=find_var(im,l))<0) {
+ rrd_set_error("Not a valid vname: %s in line %s",l,line);
+ goto out;
+ }
+
+ /* constant will parse; otherwise, must be VDEF reference */
+ if (sscanf(p, "%ld", &gdp->shval) != 1) {
+ graph_desc_t *vdp;
+
+ if ((gdp->shidx=find_var(im, p))<0) {
+ rrd_set_error("invalid offset vname: %s", p);
+ goto out;
+ }
+
+ vdp = &im->gdes[gdp->shidx];
+ if (vdp->gf != GF_VDEF) {
+ rrd_set_error("offset must specify value or VDEF");
+ goto out;
+ }
+ } else {
+ gdp->shidx = -1;
+ }
+
+ *eaten = strlen(line);
+ rc = 0;
+
+ out:
+ free(l);
+ return rc;
+}
+
+int
+rrd_parse_xport(char *line, unsigned int *eaten, graph_desc_t *gdp, image_desc_t *im) {
+ char *l = strdup(line + *eaten), *p;
+ int rc = 1;
+
+ p = strchr(l, ':');
+ if (p != NULL)
+ *p++ = '\0';
+ else
+ p = "";
+
+ if ((gdp->vidx=find_var(im, l))==-1){
+ rrd_set_error("unknown variable '%s'",l);
+ goto out;
+ }
+
+ if (strlen(p) >= FMT_LEG_LEN)
+ *(p + FMT_LEG_LEN) = '\0';
+
+ strcpy(gdp->legend, p);
+ *eaten = strlen(line);
+ rc = 0;
+
+ out:
+ free(l);
+ return rc;
+}
+
/* Parsing of PART, VRULE, HRULE, LINE, AREA, STACK and TICK
** is done in one function. Stacking STACK is silently ignored
** as it is redundant. Stacking PART, VRULE, HRULE or TICK is
@@ -213,7 +314,7 @@ rrd_parse_PVHLAST(char *line, unsigned int *eaten, graph_desc_t *gdp, image_desc
if (colorfound) { /* no legend if no color */
if (gdp->gf == GF_TICK) {
dprintf("- looking for optional number\n");
- sscanf(&line[*eaten],"%lf:%n",&gdp->yrule,&j);
+ sscanf(&line[*eaten],"%lf%n",&gdp->yrule,&j);
if (j) {
dprintf("- found number %f\n",gdp->yrule);
(*eaten)+=j;
@@ -221,6 +322,8 @@ rrd_parse_PVHLAST(char *line, unsigned int *eaten, graph_desc_t *gdp, image_desc
rrd_set_error("Tick factor should be <= 1.0");
return 1;
}
+ if (line[*eaten] == ':')
+ (*eaten)++;
} else {
dprintf("- not found, defaulting to 0.1\n");
gdp->yrule=0.1;
@@ -229,13 +332,24 @@ rrd_parse_PVHLAST(char *line, unsigned int *eaten, graph_desc_t *gdp, image_desc
}
dprintf("- looking for optional legend\n");
dprintf("- in '%s'\n",&line[*eaten]);
+ /* the legend for a graph item must start with "m " the first
+ m will then be over drawn with a color box. Since there
+ is ample space I overwrite the first few characters of the line
+ with the material that I want to see in the legend */
+ if (line[*eaten] != '\0' && line[*eaten] != ':'){
+ *eaten = *eaten - 2;
+ line[*eaten] = 'm';
+ line[*eaten+1] = ' ';
+ }
if (rrd_parse_legend(line, eaten, gdp)) return 1;
}
/* PART, HRULE, VRULE and TICK cannot be stacked. We're finished */
if ( (gdp->gf == GF_HRULE)
|| (gdp->gf == GF_VRULE)
+#ifdef WITH_PIECHART
|| (gdp->gf == GF_PART)
+#endif
|| (gdp->gf == GF_TICK)
) return 0;
@@ -256,7 +370,6 @@ rrd_parse_PVHLAST(char *line, unsigned int *eaten, graph_desc_t *gdp, image_desc
return 1;
}
}
-
return 0;
}
@@ -285,7 +398,7 @@ rrd_parse_vname(char *line, unsigned int *eaten, graph_desc_t *gdp, image_desc_t
int
rrd_parse_def(char *line, unsigned int *eaten, graph_desc_t *gdp, image_desc_t *im) {
int i=0;
- char command[6]; /* step, start, end */
+ char command[7]; /* step, start, end, reduce */
char tmpstr[256];
struct rrd_time_value start_tv,end_tv;
time_t start_tmp=0,end_tmp=0;
@@ -317,21 +430,26 @@ rrd_parse_def(char *line, unsigned int *eaten, graph_desc_t *gdp, image_desc_t *
(*eaten)+=i;
dprintf("- using DS '%s'\n",gdp->ds_nam);
- if (rrd_parse_CF(line,eaten,gdp)) return 1;
-
+ if (rrd_parse_CF(line,eaten,gdp,&gdp->cf)) return 1;
+ gdp->cf_reduce = gdp->cf;
+
if (line[*eaten]=='\0') return 0;
while (1) {
dprintf("- optional parameter follows: %s\n", &line[*eaten]);
i=0;
- sscanf(&line[*eaten], "%5[a-z]=%n", command, &i);
+ sscanf(&line[*eaten], "%6[a-z]=%n", command, &i);
if (!i) {
rrd_set_error("Parse error in '%s'",line);
return 1;
}
(*eaten)+=i;
dprintf("- processing '%s'\n",command);
- if (!strcmp("step",command)) {
+ if (!strcmp("reduce",command)) {
+ if (rrd_parse_CF(line,eaten,gdp,&gdp->cf_reduce)) return 1;
+ if (line[*eaten] != '\0')
+ (*eaten)--;
+ } else if (!strcmp("step",command)) {
i=0;
sscanf(&line[*eaten],"%lu%n",&gdp->step,&i);
(*eaten)+=i;
@@ -442,10 +560,10 @@ rrd_parse_cdef(char *line, unsigned int *eaten, graph_desc_t *gdp, image_desc_t
}
void
-rrd_graph_script(int argc, char *argv[], image_desc_t *im) {
+rrd_graph_script(int argc, char *argv[], image_desc_t *im, int optno) {
int i;
- for (i=optind+1;i<argc;i++) {
+ for (i=optind+optno;i<argc;i++) {
graph_desc_t *gdp;
unsigned int eaten=0;
if (rrd_parse_find_gf(argv[i],&eaten,gdp)) return;
switch (gdp->gf) {
-#if 0
- /* future command */
- case GF_SHIFT: vname:value
-#endif
+ case GF_SHIFT: /* vname:value */
+ if (rrd_parse_shift(argv[i],&eaten,gdp,im)) return;
+ break;
case GF_XPORT:
+ if (rrd_parse_xport(argv[i],&eaten,gdp,im)) return;
break;
case GF_PRINT: /* vname:CF:format -or- vname:format */
case GF_GPRINT: /* vname:CF:format -or- vname:format */
case GF_COMMENT: /* text */
if (rrd_parse_legend(argv[i],&eaten,gdp)) return;
break;
+#ifdef WITH_PIECHART
case GF_PART: /* value[#color[:legend]] */
+#endif
case GF_VRULE: /* value#color[:legend] */
case GF_HRULE: /* value#color[:legend] */
case GF_LINE: /* vname-or-value[#color[:legend]][:STACK] */