-/* Parsing of PART, VRULE, HRULE, LINE, AREA, STACK and TICK
-** is done in one function.
-**
-** Stacking PART, 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.
-** While this is arguable, so is entering fixed numbers
-** with more than MAX_VNAME_LEN significant digits.
-*/
-int
-rrd_parse_PVHLAST(const char *const line, unsigned int *const eaten, graph_desc_t *const gdp, image_desc_t *const im) {
- int i,j,k;
- int colorfound=0;
- char tmpstr[MAX_VNAME_LEN + 10]; /* vname#RRGGBBAA\0 */
- static int spacecnt = 0;
-
- if (spacecnt == 0) {
- float one_space = gfx_get_text_width(im->canvas, 0,
- im->text_prop[TEXT_PROP_LEGEND].font,
- im->text_prop[TEXT_PROP_LEGEND].size,
- im->tabwidth," ", 0) / 4.0;
- float target_space = gfx_get_text_width(im->canvas, 0,
- im->text_prop[TEXT_PROP_LEGEND].font,
- im->text_prop[TEXT_PROP_LEGEND].size,
- im->tabwidth,"oo", 0);
- spacecnt = target_space / one_space;
- dprintf("- spacecnt: %i onespace: %f targspace: %f\n",spacecnt,one_space,target_space);
- }
-
-
- dprintf("- parsing '%s'\n",&line[*eaten]);
-
- /* have simpler code in the drawing section */
- if ( gdp->gf == GF_STACK ){
- gdp->stack=1;
- }
-
- i=scan_for_col(&line[*eaten],MAX_VNAME_LEN+9,tmpstr);
- if (line[*eaten+i]!='\0' && line[*eaten+i]!=':') {
- rrd_set_error("Cannot parse line '%s'",line);
- return 1;
+/* this would allow for 240 different values */
+#define PARSE_FIELD1 (1L<<60)
+#define PARSE_FIELD2 (1L<<61)
+#define PARSE_FIELD3 (1L<<62)
+#define PARSE_FIELD4 (1L<<63)
+#define PARSE_POSITIONAL (1L<<59)
+#define PARSE_ONYAXIS (1L<<58)
+#define PARSE_VNAME (PARSE_FIELD1|(1L<< 0))
+#define PARSE_RRD (PARSE_FIELD1|(1L<< 1))
+#define PARSE_DS (PARSE_FIELD1|(1L<< 2))
+#define PARSE_CF (PARSE_FIELD1|(1L<< 3))
+#define PARSE_COLOR (PARSE_FIELD1|(1L<< 4))
+#define PARSE_COLOR2 (PARSE_FIELD1|(1L<< 5))
+#define PARSE_LEGEND (PARSE_FIELD1|(1L<< 6))
+#define PARSE_RPN (PARSE_FIELD1|(1L<< 7))
+#define PARSE_START (PARSE_FIELD1|(1L<< 8))
+#define PARSE_STEP (PARSE_FIELD1|(1L<< 9))
+#define PARSE_END (PARSE_FIELD1|(1L<<10))
+#define PARSE_STACK (PARSE_FIELD1|(1L<<11))
+#define PARSE_LINEWIDTH (PARSE_FIELD1|(1L<<12))
+#define PARSE_XAXIS (PARSE_FIELD1|(1L<<13))
+#define PARSE_YAXIS (PARSE_FIELD1|(1L<<14))
+#define PARSE_REDUCE (PARSE_FIELD1|(1L<<15))
+#define PARSE_DASHES (PARSE_FIELD1|(1L<<20))
+#define PARSE_HEIGHT (PARSE_FIELD1|(1L<<21))
+#define PARSE_FORMAT (PARSE_FIELD1|(1L<<22))
+#define PARSE_STRFTIME (PARSE_FIELD1|(1L<<23))
+#define PARSE_FRACTION (PARSE_FIELD1|(1L<<24))
+/* VNAME Special cases for generic parsing */
+#define PARSE_VNAMEDEF (PARSE_VNAME|(1L<<57))
+#define PARSE_VNAMEREF (PARSE_VNAME|(1L<<56))
+#define PARSE_VNAMEREFNUM (PARSE_VNAMEREF|(1L<<55))
+#define PARSE_VNAMEREFNUMNOPARSE (PARSE_FIELD1|(1L<<54))
+/* special positional cases */
+#define PARSE_VNAMERRDDSCF (PARSE_POSITIONAL|PARSE_VNAMEDEF|PARSE_RRD|PARSE_DS|PARSE_CF)
+#define PARSE_VNAMECOLORLEGEND (PARSE_POSITIONAL|PARSE_VNAMEREFNUM|PARSE_COLOR|PARSE_COLOR2|PARSE_LEGEND)
+#define PARSE_VNAMECOLORFRACTIONLEGEND (PARSE_VNAMECOLORLEGEND|PARSE_FRACTION)
+#define PARSE_VNAMERPN (PARSE_POSITIONAL|PARSE_VNAMEDEF|PARSE_RPN)
+#define PARSE_VNAMEREFPOS (PARSE_POSITIONAL|PARSE_VNAMEREF)
+
+graph_desc_t* newGraphDescription(image_desc_t *const,enum gf_en,parsedargs_t*,unsigned long);
+graph_desc_t* newGraphDescription(image_desc_t *const im,enum gf_en gf,parsedargs_t* pa,unsigned long bits) {
+ /* check that none of the othe bitfield marker is set */
+ if ((bits&PARSE_FIELD1)&&((bits&(PARSE_FIELD2|PARSE_FIELD3|PARSE_FIELD4)))) {
+ rrd_set_error("newGraphDescription: bad bitfield1 value %08x",bits);return NULL; }
+ /* the normal handler that adds to img */
+ if (gdes_alloc(im)) { return NULL; }
+ /* set gdp */
+ graph_desc_t *gdp= &im->gdes[im->gdes_c - 1];
+
+ /* set some generic things */
+ gdp->gf=gf;
+ if (1) {
+ char *t,*x;
+ long debug=0;
+ if ((t=getKeyValueArgument("debug",1,pa)) && ((getLong(t,&debug,&x,10)))) {
+ rrd_set_error("Bad debug value: %s",t); return NULL; }
+ gdp->debug=debug;
+ }
+
+ /* and the "flagged" parser implementation
+ *
+ * first the fields with legacy positional args
+ */
+#define bitscmp(v) ((bits&v)==v)
+ char* vname=NULL;
+ if (bitscmp(PARSE_VNAME)) { vname=getKeyValueArgument("vname",1,pa);
+ dprintfparsed("got vname: %s\n",vname);}
+ char *rrd=NULL;
+ if (bitscmp(PARSE_RRD)) { rrd=getKeyValueArgument("rrd",1,pa);
+ dprintfparsed("got rrd: %s\n",rrd);}
+ char *ds=NULL;
+ if (bitscmp(PARSE_DS)) { ds=getKeyValueArgument("ds",1,pa);
+ dprintfparsed("got ds: %s\n",ds);}
+ char *cf=NULL;
+ if (bitscmp(PARSE_CF)) { cf=getKeyValueArgument("cf",1,pa);
+ dprintfparsed("got cf: %s\n",cf);}
+ char *color=NULL;
+ if (bitscmp(PARSE_COLOR)) { color=getKeyValueArgument("color",1,pa);
+ dprintfparsed("got color: %s\n",color);}
+ char *color2=NULL;
+ if (bitscmp(PARSE_COLOR2)) { color2=getKeyValueArgument("color2",1,pa);
+ dprintfparsed("got color2: %s\n",color2);}
+ char *rpn=NULL;
+ if (bitscmp(PARSE_RPN)) { rpn=getKeyValueArgument("rpn",1,pa);
+ dprintfparsed("got rpn: %s\n",rpn);}
+ char *legend=NULL;
+ if (bitscmp(PARSE_LEGEND)) { legend=getKeyValueArgument("legend",1,pa);
+ dprintfparsed("got legend: %s\n",legend);}
+ char *fraction=NULL;
+ if (bitscmp(PARSE_FRACTION)) { fraction=getKeyValueArgument("fraction",1,pa);
+ dprintfparsed("got fraction: %s\n",fraction);}
+ /*
+ * here the ones without delayed assigns (which are for positional parsers)
+ */
+ if (bitscmp(PARSE_FORMAT)) {
+ char *format=getKeyValueArgument("format",1,pa);
+ if(format) {
+ strncpy(gdp->format,format,FMT_LEG_LEN);
+ dprintfparsed("got format: %s\n",format);