/****************************************************************************
- * RRDtool 1.2.23 Copyright by Tobi Oetiker, 1997-2007
+ * RRDtool 1.4.3 Copyright by Tobi Oetiker, 1997-2010
****************************************************************************
* rrd_graph_helper.c commandline parser functions
* this code initially written by Alex van den Bogaerdt
case GF_LINE:
if (c1 == ':') {
gdp->linewidth = 1;
- dprintf("- - using default width of 1\n");
+ dprintf("- using default width of 1\n");
} else {
i = 0;
sscanf(&line[*eaten], "%lf:%n", &gdp->linewidth, &i);
&line[*eaten], line);
return 1;
} else {
- dprintf("- - scanned width %f\n", gdp->linewidth);
+ dprintf("- scanned width %f\n", gdp->linewidth);
if (isnan(gdp->linewidth)) {
rrd_set_error
("LINE width '%s' is not a number in line '%s'\n",
return 1;
}
} else {
+ long time_tmp = 0;
+
rrd_clear_error();
i = 0;
- sscanf(&line[*eaten], "%li%n", &gdp->shval, &i);
+ 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);
}
-/* Parsing of PART, VRULE, HRULE, LINE, AREA, STACK and TICK
+/* Parsing of VRULE, HRULE, LINE, AREA, STACK and TICK
** is done in one function.
**
-** Stacking PART, VRULE, HRULE or TICK is not allowed.
+** Stacking VRULE, HRULE or TICK is not allowed.
**
** If a number (which is valid to enter) is more than a
** certain amount of characters, it is caught as an error.
graph_desc_t *const gdp,
image_desc_t *const im)
{
- int i, j, k;
+ int i, j, k, j2;
int colorfound = 0;
char tmpstr[MAX_VNAME_LEN + 10]; /* vname#RRGGBBAA\0 */
static int spacecnt = 0;
float one_space = gfx_get_text_width(im, 0,
im->
text_prop[TEXT_PROP_LEGEND].
- font,
- im->
- text_prop[TEXT_PROP_LEGEND].
- size,
+ font_desc,
im->tabwidth, " ") / 4.0;
float target_space = gfx_get_text_width(im, 0,
im->
text_prop
- [TEXT_PROP_LEGEND].font,
- im->
- text_prop
- [TEXT_PROP_LEGEND].size,
+ [TEXT_PROP_LEGEND].font_desc,
im->tabwidth, "oo");
spacecnt = target_space / one_space;
rrd_set_error("Cannot parse line '%s'", line);
return 1;
}
-
- j = i;
+
+ j = i;
while (j > 0 && tmpstr[j] != '#')
j--;
+ //see if there is a second color
+ j2 = j-1;
+ while (j2 > 0 && tmpstr[j2] != '#')
+ j2--;
+ if (j && j2) { //yes, swap j and j2, so that j is first color, j2 is second
+ int tmp = j;
+ j = j2;
+ j2 = tmp;
+ tmpstr[j2] = '\0';
+ } else {
+ j2 = 0;
+ }
if (j) {
tmpstr[j] = '\0';
/* We now have:
* tmpstr[0] containing vname
* tmpstr[j] if j!=0 then containing color
- * i size of vname + color
+ * tmpstr[j2] if j2!=0 then containing second color
+ * i size of vname
* j if j!=0 then size of vname
+ * j2 if j2!=0 then size of vname + first color
*/
/* Number or vname ?
if ((gdp->vidx = find_var(im, tmpstr)) >= 0) {
dprintf("- found vname: '%s' vidx %li\n", tmpstr, gdp->vidx);
switch (gdp->gf) {
-#ifdef WITH_PIECHART
- case GF_PART:
-#endif
case GF_VRULE:
case GF_HRULE:
if (im->gdes[gdp->vidx].gf != GF_VDEF) {
default:;
}
} else {
+ long time_tmp = 0;
+
dprintf("- it is not an existing vname\n");
switch (gdp->gf) {
case GF_VRULE:
k = 0;
- sscanf(tmpstr, "%li%n", &gdp->xrule, &k);
+ 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 {
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);
dprintf("- parsed color %0.0f,%0.0f,%0.0f,%0.0f\n", gdp->col.red,
gdp->col.green, gdp->col.blue, gdp->col.alpha);
colorfound = 1;
+ if (j2) { //second color?
+ j2++;
+ dprintf("- examining second color '%s'\n", &tmpstr[j2]);
+ //TODO: maybe rrd_parse_color should take a pointer to gdp->col instead of gdp
+ struct gfx_color_t firstcol = gdp->col;
+ if (rrd_parse_color(&tmpstr[j2], gdp)) {
+ rrd_set_error("Could not parse color in '%s'", &tmpstr[j2]);
+ return 1;
+ }
+ dprintf("- parsed color %0.0f,%0.0f,%0.0f,%0.0f\n", gdp->col.red,
+ gdp->col.green, gdp->col.blue, gdp->col.alpha);
+ gdp->col2 = gdp->col;
+ gdp->col = firstcol;
+ //we now have a mandatory grid height
+ (*eaten) += i;
+ if (line[*eaten] != '\0') {
+ (*eaten)++;
+ }
+ dprintf("- examining gradient height\n");
+ i = scan_for_col(&line[*eaten], MAX_VNAME_LEN + 9, tmpstr);
+ sscanf(tmpstr, "%lf%n", &gdp->gradheight, &j);
+ if (i != j) {
+ rrd_set_error("Could not parse gradient height in '%s'", tmpstr);
+ return 1;
+ }
+ dprintf("- parsed gradientheight %0.0f\n", gdp->gradheight);
+ }
} else {
dprintf("- no color present in '%s'\n", tmpstr);
}
}
(*eaten)++; /* after colon */
- /* PART, HRULE, VRULE and TICK cannot be stacked. */
- if ((gdp->gf == GF_HRULE)
- || (gdp->gf == GF_VRULE)
- || (gdp->gf == GF_TICK)
- )
- return 0;
+ /* HRULE, VRULE and TICK cannot be stacked. */
+ if ((gdp->gf != GF_HRULE)
+ && (gdp->gf != GF_VRULE)
+ && (gdp->gf != GF_TICK)) {
- dprintf("- parsing '%s'\n", &line[*eaten]);
- if (line[*eaten] != '\0') {
- dprintf("- still more, should be STACK\n");
+ dprintf("- parsing '%s', looking for STACK\n", &line[*eaten]);
j = scan_for_col(&line[*eaten], 5, tmpstr);
- if (line[*eaten + j] != '\0' && line[*eaten + j] != ':') {
- /* not 5 chars */
- rrd_set_error("STACK expected and not found");
- return 1;
- }
if (!strcmp("STACK", tmpstr)) {
dprintf("- found STACK\n");
gdp->stack = 1;
(*eaten) += j;
- } else {
- rrd_set_error("STACK expected and not found");
- return 1;
+ if (line[*eaten] == ':') {
+ (*eaten) += 1;
+ } else if (line[*eaten] == '\0') {
+ dprintf("- done parsing line\n");
+ return 0;
+ } else {
+ dprintf("- found %s instead of just STACK\n", &line[*eaten]);
+ rrd_set_error("STACK expected but %s found", &line[*eaten]);
+ return 1;
+ }
+ } else
+ dprintf("- not STACKing\n");
+ }
+
+ dprintf("- still more, should be dashes[=...]\n");
+ dprintf("- parsing '%s'\n", &line[*eaten]);
+ if (line[*eaten] != '\0') {
+ /* parse dash arguments here. Possible options:
+ - dashes
+ - dashes=n_on[,n_off[,n_on,n_off]]
+ - dashes[=n_on[,n_off[,n_on,n_off]]]:dash-offset=offset
+ allowing 64 characters for definition of dash style */
+ j = scan_for_col(&line[*eaten], 64, tmpstr);
+ /* start with dashes */
+ if (strcmp(tmpstr, "dashes") == 0) {
+ /* if line was "dashes" or "dashes:dash-offset=xdashes="
+ tmpstr will be "dashes" */
+ dprintf("- found %s\n", tmpstr);
+ /* initialise all required variables we need for dashed lines
+ using default dash length of 5 pixels */
+ gdp->dash = 1;
+ gdp->p_dashes = (double *) malloc(sizeof(double));
+ gdp->p_dashes[0] = 5;
+ gdp->ndash = 1;
+ gdp->offset = 0;
+ (*eaten) += j;
+ } else if (sscanf(tmpstr, "dashes=%s", tmpstr)) {
+ /* dashes=n_on[,n_off[,n_on,n_off]] */
+ char csv[64];
+ char *pch;
+ float dsh;
+ int count = 0;
+ char *saveptr;
+
+ strcpy(csv, tmpstr);
+
+ pch = strtok_r(tmpstr, ",", &saveptr);
+ while (pch != NULL) {
+ pch = strtok_r(NULL, ",", &saveptr);
+ count++;
+ }
+ dprintf("- %d dash value(s) found: ", count);
+ if (count > 0) {
+ gdp->dash = 1;
+ gdp->ndash = count;
+ gdp->p_dashes = (double *) malloc(sizeof(double) * count);
+ pch = strtok_r(csv, ",", &saveptr);
+ count = 0;
+ while (pch != NULL) {
+ if (sscanf(pch, "%f", &dsh)) {
+ gdp->p_dashes[count] = (double) dsh;
+ dprintf("%.1f ", gdp->p_dashes[count]);
+ count++;
+ }
+ pch = strtok_r(NULL, ",", &saveptr);
+ }
+ dprintf("\n");
+ } else
+ dprintf("- syntax error. No dash lengths found!\n");
+ (*eaten) += j;
+ } else
+ dprintf("- error: expected dashes[=...], found %s\n", tmpstr);
+ if (line[*eaten] == ':') {
+ (*eaten) += 1;
+ } else if (line[*eaten] == '\0') {
+ dprintf("- done parsing line\n");
+ return 0;
+ }
+ /* dashes[=n_on[,n_off[,n_on,n_off]]]:dash-offset=offset
+ allowing 16 characters for dash-offset=....
+ => 4 characters for the offset value */
+ j = scan_for_col(&line[*eaten], 16, tmpstr);
+ if (sscanf(tmpstr, "dash-offset=%lf", &gdp->offset)) {
+ dprintf("- found dash-offset=%.1f\n", gdp->offset);
+ gdp->dash = 1;
+ (*eaten) += j;
+ if (line[*eaten] == ':')
+ (*eaten) += 1;
+ }
+ if (line[*eaten] == '\0') {
+ dprintf("- done parsing line\n");
+ return 0;
}
}
if (line[*eaten] == '\0') {
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) {
int i = 0;
char command[7]; /* step, start, end, reduce */
char tmpstr[256];
- struct rrd_time_value start_tv, end_tv;
+ rrd_time_value_t start_tv, end_tv;
time_t start_tmp = 0, end_tmp = 0;
char *parsetime_error = NULL;
} else if (!strcmp("start", command)) {
i = scan_for_col(&line[*eaten], 255, tmpstr);
(*eaten) += i;
- if ((parsetime_error = parsetime(tmpstr, &start_tv))) {
+ if ((parsetime_error = rrd_parsetime(tmpstr, &start_tv))) {
rrd_set_error("start time: %s", parsetime_error);
return 1;
}
} else if (!strcmp("end", command)) {
i = scan_for_col(&line[*eaten], 255, tmpstr);
(*eaten) += i;
- if ((parsetime_error = parsetime(tmpstr, &end_tv))) {
+ if ((parsetime_error = rrd_parsetime(tmpstr, &end_tv))) {
rrd_set_error("end time: %s", parsetime_error);
return 1;
}
dprintf("- done parsing: '%s'\n", &line[*eaten]);
+ } else if (!strcmp("daemon", command)) {
+ i = scan_for_col(&line[*eaten],
+ sizeof (gdp->daemon), gdp->daemon);
+ (*eaten) += i;
+ dprintf("- using daemon '%s'\n", gdp->daemon);
} else {
rrd_set_error("Parse error in '%s'", line);
return 1;
}
(*eaten)++;
}
- if (proc_start_end(&start_tv, &end_tv, &start_tmp, &end_tmp) == -1) {
- /* error string is set in parsetime.c */
+ if (rrd_proc_start_end(&start_tv, &end_tv, &start_tmp, &end_tmp) == -1) {
+ /* error string is set in rrd_parsetime.c */
return 1;
}
if (start_tmp < 3600 * 24 * 365 * 10) {
case GF_HRULE: /* value#color[:legend] */
case GF_LINE: /* vname-or-value[#color[:legend]][:STACK] */
case GF_AREA: /* vname-or-value[#color[:legend]][:STACK] */
+ case GF_GRAD: /* vname-or-value[#color[:legend][#color[:gradientheight]]][:STACK] */
case GF_TICK: /* vname#color[:num[:legend]] */
if (rrd_parse_PVHLAST(argv[i], &eaten, gdp, im))
return;
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) {
+ if (last_gf == GF_LINE || last_gf == GF_AREA || last_gf == GF_GRAD) {
gdp->gf = last_gf;
gdp->linewidth = last_linewidth;
} else {