+/* implementations */
+int parse_axis(enum gf_en gf,parsedargs_t*pa,image_desc_t *const im){
+#if 0
+ /* define X or y axis */
+ axis_t *a=im->xaxis;
+ if (gf == GF_YAXIS) { a=im->yaxis; }
+ /* try to parse the number */
+ char* cmd=getKeyValueArgument("cmd",1,pa);
+ if (cmd[5]) {
+ int num=atoi(cmd+5);
+ if ((num<1)||(num>MAX_AXIS)) {
+ rrd_set_error("invalid axis ID %i in %s - should be in range [1:%i]",num,cmd,MAX_AXIS);
+ return 1;
+ }
+ /* and forward by that much */
+ a=a+(num-1);
+ }
+
+ /* and set type */
+ char* t=getKeyValueArgument("type",1,pa);
+ if (t) {
+ set_match(t,"TIME",a->type=AXIS_TYPE_TIME)
+ else
+ set_match(t,"LINEAR",a->type=AXIS_TYPE_LINEAR)
+ else
+ set_match(t,"LOGARITHMIC",a->type=AXIS_TYPE_LOGARITHMIC)
+ else {
+ rrd_set_error("unsupported axis type %s",t);
+ return 1;
+ }
+ }
+ /* and other stuff */
+ a->bounds.lowertxt=getKeyValueArgument("min",1,pa);
+ a->bounds.uppertxt=getKeyValueArgument("max",1,pa);
+#endif
+ /* and return */
+ return 0;
+}
+
+int parse_def(enum gf_en gf,parsedargs_t*pa,image_desc_t *const im){
+ /* get new graph that we fill */
+ graph_desc_t *gdp=newGraphDescription(im,gf,pa,
+ PARSE_VNAMERRDDSCF
+ |PARSE_START
+ |PARSE_STEP
+ |PARSE_END
+ |PARSE_REDUCE
+ );
+ if (!gdp) { return -1;}
+
+ /* debugging output */
+ dprintf("=================================\n");
+ dprintf("DEF : %s\n",pa->arg_orig);
+ dprintf("VNAME : %s\n",gdp->vname);
+ dprintf("RRD : %s\n",gdp->rrd);
+ dprintf("DS : %s\n",gdp->ds_nam);
+ dprintf("CF : %i\n",gdp->cf);
+ dprintf("START : (%lld)\n",(long long int)gdp->start);
+ dprintf("STEP : (%lld)\n",(long long int)gdp->step);
+ dprintf("END : (%lld)\n",(long long int)gdp->end);
+ dprintf("REDUCE: (%i)\n",gdp->cf_reduce);
+ dprintf("=================================\n");
+
+ /* and return fine */
+ return 0;
+}
+
+int parse_cvdef(enum gf_en gf,parsedargs_t*pa,image_desc_t *const im){
+ /* get new graph that we fill */
+ graph_desc_t *gdp=newGraphDescription(im,gf,pa,
+ PARSE_VNAMERPN
+ );
+ if (!gdp) { return -1;}
+
+ /* handle RPN parsing */
+ if (gf==GF_CDEF) {
+ /* parse rpn */
+ if ((gdp->rpnp= rpn_parse((void *) im, gdp->rpn, &find_var_wrapper)) == NULL) {
+ return -1; }
+ } else {
+ /* parse vdef, as vdef_parse is a bit "stupid" right now we have to touch things here */
+ /* so find first , */
+ char*c=strchr(gdp->rpn,',');
+ if (! c) { rrd_set_error("Comma expected in VDEF definition %s",gdp->rpn); return -1;}
+ /* found a comma, so copy the first part to ds_name (re/abusing it) */
+ *c=0;
+ strncpy(gdp->ds_nam,gdp->rpn,DS_NAM_SIZE);
+ *c=',';
+ /* trying to find the vidx for that name */
+ gdp->vidx = find_var(im, gdp->ds_nam);
+ if (gdp->vidx<0) { *c=',';
+ rrd_set_error("Not a valid vname: %s in line %s", gdp->ds_nam, gdp->rpn);
+ return -1;}
+ if (im->gdes[gdp->vidx].gf != GF_DEF && im->gdes[gdp->vidx].gf != GF_CDEF) {
+ rrd_set_error("variable '%s' not DEF nor "
+ "CDEF in VDEF '%s'", gdp->ds_nam, gdp->rpn);
+ return 1;
+ }
+ /* and parsing the rpn */
+ int r=vdef_parse(gdp, c+1);
+ /* original code does not check here for some reason */
+ if (r) { return -1; }
+ }
+
+ /* debugging output */
+ dprintf("=================================\n");
+ if (gf==GF_CDEF) {
+ dprintf("CDEF : %s\n",pa->arg_orig);
+ } else {
+ dprintf("VDEF : %s\n",pa->arg_orig);
+ }
+ dprintf("VNAME : %s\n",gdp->vname);
+ dprintf("RPN : %s\n",gdp->rpn);
+ dprintf("=================================\n");
+
+ /* and return fine */
+ return 0;
+}
+
+
+int parse_line(enum gf_en gf,parsedargs_t*pa,image_desc_t *const im){
+ /* get new graph that we fill */
+ graph_desc_t *gdp=newGraphDescription(im,gf,pa,
+ PARSE_VNAMECOLORLEGEND
+ |PARSE_STACK
+ |PARSE_LINEWIDTH
+ |PARSE_DASHES
+ |PARSE_XAXIS
+ |PARSE_YAXIS
+ );
+ if (!gdp) { return -1;}
+
+ /* debug output */
+ dprintf("=================================\n");
+ dprintf("LINE : %s\n",pa->arg_orig);
+ if (gdp->vidx<0) {
+ dprintf("VAL : %g\n",gdp->yrule);
+ } else {
+ dprintf("VNAME : %s (%li)\n",gdp->vname,gdp->vidx);
+ }
+ dprintf("COLOR : r=%g g=%g b=%g a=%g\n",
+ gdp->col.red,gdp->col.green,gdp->col.blue,gdp->col.alpha);
+ dprintf("COLOR2: r=%g g=%g b=%g a=%g\n",
+ gdp->col2.red,gdp->col2.green,gdp->col2.blue,gdp->col2.alpha);
+ dprintf("LEGEND: %s\n",gdp->legend);
+ dprintf("STACK : %i\n",gdp->stack);
+ dprintf("WIDTH : %g\n",gdp->linewidth);
+ dprintf("XAXIS : %i\n",gdp->xaxisidx);
+ dprintf("YAXIS : %i\n",gdp->yaxisidx);
+ if (gdp->ndash) {
+ dprintf("DASHES: %i - %g",gdp->ndash,gdp->p_dashes[0]);
+ for(int i=1;i<gdp->ndash;i++){dprintf(", %g",gdp->p_dashes[i]);}
+ dprintf("\n");
+ }
+ dprintf("=================================\n");
+
+ /* and return fine */
+ return 0;
+}
+
+int parse_area(enum gf_en gf,parsedargs_t*pa,image_desc_t *const im){
+ /* get new graph that we fill */
+ graph_desc_t *gdp=newGraphDescription(im,gf,pa,
+ PARSE_VNAMECOLORLEGEND
+ |PARSE_STACK
+ |PARSE_XAXIS
+ |PARSE_YAXIS
+ |PARSE_HEIGHT
+ );
+ if (!gdp) { return -1;}
+
+ /* debug output */
+ dprintf("=================================\n");
+ dprintf("AREA : %s\n",pa->arg_orig);
+ if (gdp->vidx<0) {
+ dprintf("VAL : %g\n",gdp->yrule);
+ } else {
+ dprintf("VNAME : %s (%li)\n",gdp->vname,gdp->vidx);
+ }
+ dprintf("COLOR : r=%g g=%g b=%g a=%g\n",
+ gdp->col.red,gdp->col.green,gdp->col.blue,gdp->col.alpha);
+ dprintf("COLOR2: r=%g g=%g b=%g a=%g\n",
+ gdp->col2.red,gdp->col2.green,gdp->col2.blue,gdp->col2.alpha);
+ dprintf("LEGEND: %s\n",gdp->legend);
+ dprintf("STACK : %i\n",gdp->stack);
+ dprintf("XAXIS : %i\n",gdp->xaxisidx);
+ dprintf("YAXIS : %i\n",gdp->yaxisidx);
+ dprintf("=================================\n");
+
+ /* and return fine */
+ return 0;
+}
+
+int parse_stack(enum gf_en gf,parsedargs_t*pa,image_desc_t *const im){
+ /* get new graph that we fill */
+ graph_desc_t *gdp=newGraphDescription(im,gf,pa,
+ PARSE_VNAMECOLORLEGEND
+ |PARSE_XAXIS
+ |PARSE_YAXIS
+ );
+ if (!gdp) { return -1;}
+ gdp->stack=1;
+ /* and try to get the one index before ourselves */
+ long i;
+ for (i=im->gdes_c;(gdp->gf==gf)&&(i>=0);i--) {
+ dprintfparsed("trying to process entry %li with type %u\n",i,im->gdes[i].gf);
+ switch (im->gdes[i].gf) {
+ case GF_LINE:
+ case GF_AREA:
+ gdp->gf=im->gdes[i].gf;
+ gdp->linewidth=im->gdes[i].linewidth;
+ dprintfparsed("found matching LINE/AREA at %li with type %u\n",i,im->gdes[i].gf);
+ break;
+ default: break;
+ }
+ }
+ /* error the unhandled */
+ if (gdp->gf==gf) {
+ rrd_set_error("No previous LINE or AREA found for %s",pa->arg_orig); return -1;}
+
+ /* debug output */
+ dprintf("=================================\n");
+ dprintf("STACK : %s\n",pa->arg_orig);
+ if (gdp->vidx<0) {
+ dprintf("VAL : %g\n",gdp->yrule);
+ } else {
+ dprintf("VNAME : %s (%li)\n",gdp->vname,gdp->vidx);
+ }
+ dprintf("COLOR : r=%g g=%g b=%g a=%g\n",
+ gdp->col.red,gdp->col.green,gdp->col.blue,gdp->col.alpha);
+ dprintf("COLOR2: r=%g g=%g b=%g a=%g\n",
+ gdp->col2.red,gdp->col2.green,gdp->col2.blue,gdp->col2.alpha);
+ dprintf("LEGEND: %s\n",gdp->legend);
+ dprintf("STACK : %i\n",gdp->stack);
+ dprintf("WIDTH : %g\n",gdp->linewidth);
+ dprintf("XAXIS : %i\n",gdp->xaxisidx);
+ dprintf("YAXIS : %i\n",gdp->yaxisidx);
+ dprintf("DASHES: TODI\n");
+ dprintf("=================================\n");
+
+ /* and return fine */
+ return 0;
+}
+
+int parse_hvrule(enum gf_en gf,parsedargs_t*pa,image_desc_t *const im){
+ /* get new graph that we fill */
+ graph_desc_t *gdp=newGraphDescription(im,gf,pa,
+ PARSE_VNAMECOLORLEGEND
+ |PARSE_VNAMEREFNUMNOPARSE
+ |PARSE_XAXIS
+ |PARSE_YAXIS
+ |PARSE_DASHES
+ );
+ if (!gdp) { return -1;}
+
+ /* check that vidx is of type VDEF */
+ if (im->gdes[gdp->vidx].gf != GF_VDEF) {
+ rrd_set_error("Using vname %s of wrong type in line %s\n",
+ gdp->vname,pa->arg_orig);
+ return -1;
+ }
+
+ /* and here we place number parsing - depends on axis in the long-run*/
+ if (gdp->vidx<0) {
+ rrd_set_error("TODO: NOT SUPPORTED: Need to add number handler here for %s\n",
+ gdp->vname); return -1;
+ /* depending on axis type this is either number or time
+ essentially becoming generic when we get axis support
+ */
+ }
+
+ /* debug output */
+ dprintf("=================================\n");
+ if (gf==GF_VRULE) {
+ dprintf("VRULE : %s\n",pa->arg_orig);
+ } else {
+ dprintf("HRULE : %s\n",pa->arg_orig);
+ }
+ if (gdp->vidx<0) {
+ if (gf==GF_VRULE) {
+ dprintf("VAL : %g\n",gdp->yrule);
+ } else {
+ dprintf("VAL : %g\n",gdp->yrule);
+ }
+ } else {
+ dprintf("VNAME : %s (%li)\n",gdp->vname,gdp->vidx);
+ }
+ dprintf("COLOR : r=%g g=%g b=%g a=%g\n",
+ gdp->col.red,gdp->col.green,gdp->col.blue,gdp->col.alpha);
+ dprintf("COLOR2: r=%g g=%g b=%g a=%g\n",
+ gdp->col2.red,gdp->col2.green,gdp->col2.blue,gdp->col2.alpha);
+ dprintf("LEGEND: %s\n",gdp->legend);
+ dprintf("DASHES: TODO\n");
+ dprintf("XAXIS : %i\n",gdp->xaxisidx);
+ dprintf("YAXIS : %i\n",gdp->yaxisidx);
+ dprintf("=================================\n");
+
+ /* and return fine */
+ return 0;
+}
+
+int parse_gprint(enum gf_en gf,parsedargs_t*pa,image_desc_t *const im) {
+ /* get new graph that we fill */
+ graph_desc_t *gdp=newGraphDescription(im,gf,pa,
+ PARSE_VNAMEREF
+ |PARSE_CF
+ |PARSE_FORMAT
+ |PARSE_STRFTIME
+ );
+ if (!gdp) { return -1;}
+ /* here we parse pos arguments locally */
+ /* vname */
+ if (gdp->vname[0]==0) {
+ dprintfparsed("Processing postitional vname\n");
+ keyvalue_t* first=getFirstUnusedArgument(1,pa);
+ if (first) {
+ strncpy(gdp->vname,first->value,MAX_VNAME_LEN + 1);
+ /* get type of reference */
+ gdp->vidx=find_var(im, gdp->vname);
+ if (gdp->vidx<0) {
+ rrd_set_error("undefined vname %s",gdp->vname); return -1; }
+ } else { rrd_set_error("No positional VNAME"); return -1; }
+ }
+ /* check type of ref in general */
+ enum gf_en vnamegf=im->gdes[gdp->vidx].gf;
+ dprintfparsed("Processing referenced type %i\n",vnamegf);
+ switch (vnamegf) {
+ /* depreciated */
+ case GF_DEF:
+ case GF_CDEF:
+ dprintfparsed("Processing postitional CF\n");
+ /* look for CF if not given */
+ if (((int)gdp->cf)==-1) {
+ keyvalue_t* first=getFirstUnusedArgument(1,pa);
+ if (first) {
+ gdp->cf=cf_conv(first->value);
+ if (((int)gdp->cf)==-1) {
+ rrd_set_error("bad CF: %s",first->value); return -1; }
+ } else { rrd_set_error("No positional CDEF"); return -1; }
+ }
+ break;
+ case GF_VDEF:
+ break;
+ default:
+ rrd_set_error("Encountered unknown type variable '%s'",
+ im->gdes[gdp->vidx].vname);
+ return -1;
+ }
+ /* and get positional format */
+ if (gdp->format[0]==0) {
+ dprintfparsed("Processing postitional format\n");
+ keyvalue_t* first=getFirstUnusedArgument(1,pa);
+ if (first) {
+ strncpy(gdp->format,first->value,FMT_LEG_LEN);
+ dprintfparsed("got positional format: %s\n",gdp->format);
+ } else { rrd_set_error("No positional CF/FORMAT"); return -1; }
+ }
+ /* debug output */
+ dprintf("=================================\n");
+ if (gf==GF_GPRINT) {
+ dprintf("GPRINT : %s\n",pa->arg_orig);
+ } else {
+ dprintf("PRINT : %s\n",pa->arg_orig);
+ }
+ dprintf("VNAME : %s (%li)\n",gdp->vname,gdp->vidx);
+ if ((int)gdp->cf>-1) {
+ dprintf("CF : (%u)\n",gdp->cf);
+ }
+ dprintf("FORMAT: %s\n",gdp->legend);
+ dprintf("=================================\n");
+
+ /* and return */
+ return 0;
+}
+
+int parse_comment(enum gf_en gf,parsedargs_t*pa,image_desc_t *const im){
+ /* get new graph that we fill */
+ graph_desc_t *gdp=newGraphDescription(im,gf,pa,
+ PARSE_LEGEND
+ );
+ if (!gdp) { return -1;}
+
+ /* and if we have no legend, then use the first positional one */
+ if (gdp->legend[0]==0) {
+ keyvalue_t* first=getFirstUnusedArgument(1,pa);
+ if (first) {
+ strncpy(gdp->legend,first->value,FMT_LEG_LEN);
+ } else { rrd_set_error("No positional CF/FORMAT"); return -1; }
+ }
+ /* debug output */
+ dprintf("=================================\n");
+ dprintf("COMMENT : %s\n",pa->arg_orig);
+ dprintf("LEGEND : %s\n",gdp->legend);
+ /* and return */
+ return 0;
+}
+
+int parse_tick(enum gf_en gf,parsedargs_t* pa,image_desc_t *const im) {
+ /* get new graph that we fill */
+ graph_desc_t *gdp=newGraphDescription(im,gf,pa,
+ PARSE_VNAMECOLORFRACTIONLEGEND
+ );
+ if (!gdp) { return -1;}
+ /* debug output */
+ dprintf("=================================\n");
+ dprintf("TICK : %s\n",pa->arg_orig);
+ dprintf("VNAME : %s (%li)\n",gdp->vname,gdp->vidx);
+ dprintf("COLOR : r=%g g=%g b=%g a=%g\n",
+ gdp->col.red,gdp->col.green,gdp->col.blue,gdp->col.alpha);
+ if (gdp->cf==CF_LAST) {
+ dprintf("FRAC : %s\n",gdp->vname);
+ } else {
+ dprintf("FRAC : %g\n",gdp->yrule);
+ }
+ dprintf("LEGEND: %s\n",gdp->legend);
+ dprintf("XAXIS : %i\n",gdp->xaxisidx);
+ dprintf("YAXIS : %i\n",gdp->yaxisidx);
+ dprintf("=================================\n");
+ /* and return */
+ return 0;
+}
+
+int parse_textalign(enum gf_en gf,parsedargs_t* pa,image_desc_t *const im) {
+ /* get new graph that we fill */
+ graph_desc_t *gdp=newGraphDescription(im,gf,pa,0);
+ if (!gdp) { return -1;}
+
+ /* get align */
+ char* align=getKeyValueArgument("align",1,pa);
+ if (!align) align=getFirstUnusedArgument(1,pa)->value;
+ if (!align) { rrd_set_error("No alignment given"); return -1; }
+
+ /* parse align */
+ if (strcmp(align, "left") == 0) {
+ gdp->txtalign = TXA_LEFT;
+ } else if (strcmp(align, "right") == 0) {
+ gdp->txtalign = TXA_RIGHT;
+ } else if (strcmp(align, "justified") == 0) {
+ gdp->txtalign = TXA_JUSTIFIED;
+ } else if (strcmp(align, "center") == 0) {
+ gdp->txtalign = TXA_CENTER;
+ } else {
+ rrd_set_error("Unknown alignement type '%s'", align);
+ return 1;
+ }
+
+ /* debug output */
+ dprintf("=================================\n");
+ dprintf("TEXTALIGN : %s\n",pa->arg_orig);
+ dprintf("ALIGNMENT : %s (%u)\n",align,gdp->txtalign);
+ dprintf("=================================\n");
+ /* and return */
+ return 0;
+}
+
+int parse_shift(enum gf_en gf,parsedargs_t* pa,image_desc_t *const im) {
+ /* get new graph that we fill */
+ graph_desc_t *gdp=newGraphDescription(im,gf,pa,PARSE_VNAMEREFPOS);
+ if (!gdp) { return -1;}
+ /* and check that it is a CDEF */
+ switch (im->gdes[gdp->vidx].gf) {
+ case GF_DEF:
+ case GF_CDEF:
+ dprintf("- vname is of type DEF or CDEF, OK\n");
+ break;
+ case GF_VDEF:
+ rrd_set_error("Cannot shift a VDEF: '%s' in line '%s'\n",
+ im->gdes[gdp->vidx].vname, pa->arg_orig);
+ return 1;
+ default:
+ rrd_set_error("Encountered unknown type variable '%s' in line '%s'",
+ im->gdes[gdp->vidx].vname, pa->arg_orig);
+ return 1;
+ }
+
+ /* now parse the "shift" */
+ char* shift=getKeyValueArgument("shift",1,pa);
+ if (!shift) {shift=getFirstUnusedArgument(1,pa)->value;}
+ if (!shift) { rrd_set_error("No shift given"); return -1; }
+ /* identify shift */
+ gdp->shidx=find_var(im, shift);
+ if (gdp->shidx>=0) {
+ /* it is a def, so let us check its type*/
+ switch (im->gdes[gdp->shidx].gf) {
+ case GF_DEF:
+ case GF_CDEF:
+ rrd_set_error("Offset cannot be a (C)DEF: '%s' in line '%s'\n",
+ im->gdes[gdp->shidx].vname, pa->arg_orig);
+ return 1;
+ case GF_VDEF:
+ dprintf("- vname is of type VDEF, OK\n");
+ break;
+ default:
+ rrd_set_error
+ ("Encountered unknown type variable '%s' in line '%s'",
+ im->gdes[gdp->vidx].vname, pa->arg_orig);
+ return 1;
+ }
+ } else {
+ /* it is no def, so parse as number */
+ long val;
+ char *x;
+ int f=getLong(shift,&val,&x,10);
+ if (f) { rrd_set_error("error parsing number %s",shift); return -1; }
+ gdp->shval = val;
+ gdp->shidx = -1;
+ }
+
+ /* debug output */
+ dprintf("=================================\n");
+ dprintf("SHIFT : %s\n",pa->arg_orig);
+ dprintf("VNAME : %s (%li)\n",im->gdes[gdp->vidx].vname,gdp->vidx);
+ if (gdp->shidx>=0) {
+ dprintf("SHIFTBY : %s (%i)\n",im->gdes[gdp->shidx].vname,gdp->shidx);
+ } else {
+ dprintf("SHIFTBY : %li\n",gdp->shval);
+ }
+ dprintf("=================================\n");
+ /* and return */
+ return 0;
+}
+int parse_xport(enum gf_en gf,parsedargs_t* pa,image_desc_t *const im) {
+ /* get new graph that we fill */
+ graph_desc_t *gdp=newGraphDescription(im,gf,pa,PARSE_VNAMECOLORLEGEND);
+ if (!gdp) { return -1;}
+ /* check for cdef */
+ /* and check that it is a CDEF */
+ switch (im->gdes[gdp->vidx].gf) {
+ case GF_DEF:
+ case GF_CDEF:
+ dprintf("- vname is of type DEF or CDEF, OK\n");
+ break;
+ case GF_VDEF:
+ rrd_set_error("Cannot shift a VDEF: '%s' in line '%s'\n",
+ im->gdes[gdp->vidx].vname, pa->arg_orig);
+ return 1;
+ default:
+ rrd_set_error("Encountered unknown type variable '%s' in line '%s'",
+ im->gdes[gdp->vidx].vname, pa->arg_orig);
+ return 1;
+ }
+
+ /* debug output */
+ dprintf("=================================\n");
+ dprintf("LINE : %s\n",pa->arg_orig);
+ dprintf("VNAME : %s (%li)\n",gdp->vname,gdp->vidx);
+ dprintf("LEGEND: %s\n",gdp->legend);
+ dprintf("=================================\n");
+
+ return 0;
+}
+
+void rrd_graph_script(
+ int argc,
+ char *argv[],
+ image_desc_t *const im,
+ int optno)
+{
+ int i;
+
+ /* and now handle the things*/
+ parsedargs_t pa;
+ initParsedArguments(&pa);
+
+ /* loop arguments */
+ for (i = optind + optno; i < argc; i++) {
+ /* release parsed args - avoiding late cleanups*/
+ freeParsedArguments(&pa);
+ /* processed parsed args */
+ if (parseArguments(argv[i],&pa)) {
+ return; }
+
+ /* now let us handle the field based on the first command or cmd=...*/
+ char*cmd=NULL;
+ /* and try to get via cmd */
+ char* t=getKeyValueArgument("cmd",1,&pa);
+ if (t) {
+ cmd=t;
+ } else if ((t=getKeyValueArgument("pos0",1,&pa))) {
+ cmd=t;
+ } else {
+ rrd_set_error("no command set in argument %s",pa.arg_orig);
+ freeParsedArguments(&pa);
+ return;
+ }
+
+ /* convert to enum but handling LINE special*/
+ enum gf_en gf=-1;
+ gf=gf_conv(cmd);
+ if ((int)gf == -1) {
+ if (strncmp("LINE",cmd,4)==0) {
+ gf=GF_LINE;
+ addToArguments(&pa,"linewidth",cmd+4,0);
+ } else {
+ rrd_set_error("'%s' is not a valid function name in %s", cmd,pa.arg_orig );
+ return;
+ }
+ }
+ /* now we can handle the commands */
+ int r=0;
+ switch (gf) {
+ case GF_XAXIS: r=parse_axis(gf,&pa,im); break;
+ case GF_YAXIS: r=parse_axis(gf,&pa,im); break;
+ case GF_DEF: r=parse_def(gf,&pa,im); break;
+ case GF_CDEF: r=parse_cvdef(gf,&pa,im); break;
+ case GF_VDEF: r=parse_cvdef(gf,&pa,im); break;
+ case GF_LINE: r=parse_line(gf,&pa,im); break;
+ case GF_AREA: r=parse_area(gf,&pa,im); break;
+ case GF_PRINT: r=parse_gprint(gf,&pa,im); break;
+ case GF_GPRINT: r=parse_gprint(gf,&pa,im); break;
+ case GF_COMMENT: r=parse_comment(gf,&pa,im); break;
+ case GF_HRULE: r=parse_hvrule(gf,&pa,im); break;
+ case GF_VRULE: r=parse_hvrule(gf,&pa,im); break;
+ case GF_STACK: r=parse_stack(gf,&pa,im); break;
+ case GF_TICK: r=parse_tick(gf,&pa,im); break;
+ case GF_TEXTALIGN: r=parse_textalign(gf,&pa,im); break;
+ case GF_SHIFT: r=parse_shift(gf,&pa,im); break;
+ case GF_XPORT: r=parse_xport(gf,&pa,im); break;
+ /* unsupported types right now */
+ case GF_GRAD:
+ rrd_set_error("GRAD unsupported - use AREA instead");
+ break;
+ }
+ /* handle the return error case */
+ if (r) { freeParsedArguments(&pa); return;}
+ /* check for unprocessed keyvalue args */
+ char *s;
+ if ((s=checkUnusedValues(&pa))) {
+ rrd_set_error("Unused Arguments in %s: %s",pa.arg_orig,s);
+ freeParsedArguments(&pa);
+ free(s);
+ return;
+ }
+ }
+ /* finally free arguments */
+ freeParsedArguments(&pa);
+}