X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Frrd_rpncalc.c;h=818ef562e32c5820ba119e46474e3a2a1207ec91;hb=360c1c42f2af4862da85b82e509952c59592a941;hp=cf3fb07597a51cd6689bef4cee8ab1cdcfa1cf02;hpb=7fdde890bb630b566d35d004579294b10947599a;p=rrdtool.git diff --git a/src/rrd_rpncalc.c b/src/rrd_rpncalc.c index cf3fb07..818ef56 100644 --- a/src/rrd_rpncalc.c +++ b/src/rrd_rpncalc.c @@ -1,5 +1,5 @@ /**************************************************************************** - * RRDtool 1.0.28 Copyright Tobias Oetiker, 1997 - 2000 + * RRDtool 1.0.28 Copyright Tobias Oetiker, 1997 - 2002 **************************************************************************** * rrd_rpncalc.c RPN calculator functions ****************************************************************************/ @@ -76,8 +76,8 @@ rpnp_t * rpn_expand(rpn_cdefds_t *rpnc) * into a CDEF string. This function is used by rrd_dump. * arguments: * rpnc: an array of compact RPN operator nodes - * rrd: a pointer an rrd header (only the ds_cnt and ds_def elements need - * to be valid) for lookup of data source names by index + * ds_def: a pointer to the data source definition section of an RRD header + * for lookup of data source names by index * str: out string, memory is allocated by the function, must be freed by the * the caller */ void rpn_compact2str(rpn_cdefds_t *rpnc,ds_def_t *ds_def,char **str) @@ -137,8 +137,10 @@ void rpn_compact2str(rpn_cdefds_t *rpnc,ds_def_t *ds_def,char **str) add_op(OP_UNKN,UNKN) add_op(OP_UN,UN) add_op(OP_NEGINF,NEGINF) + add_op(OP_NE,NE) add_op(OP_PREV,PREV) add_op(OP_INF,INF) + add_op(OP_ISINF,ISINF) add_op(OP_NOW,NOW) add_op(OP_LTIME,LTIME) add_op(OP_TIME,TIME) @@ -286,8 +288,10 @@ rpn_parse(void *key_hash,char *expr,long (*lookup)(void *,char*)){ match_op(OP_UNKN,UNKN) match_op(OP_UN,UN) match_op(OP_NEGINF,NEGINF) + match_op(OP_NE,NE) match_op(OP_PREV,PREV) match_op(OP_INF,INF) + match_op(OP_ISINF,ISINF) match_op(OP_NOW,NOW) match_op(OP_LTIME,LTIME) match_op(OP_TIME,TIME) @@ -354,43 +358,51 @@ short rpn_calc(rpnp_t *rpnp, rpnstack_t *rpnstack, long data_idx, rrd_value_t *output, int output_idx) { - int rpi; - long stptr = -1; + int rpi; + long stptr = -1; - /* process each op from the rpn in turn */ - for (rpi=0; rpnp[rpi].op != OP_END; rpi++){ - /* allocate or grow the stack */ - if (stptr + 5 > rpnstack -> dc_stacksize){ - /* could move this to a separate function */ - rpnstack -> dc_stacksize += rpnstack -> dc_stackblock; - rpnstack -> s = rrd_realloc(rpnstack -> s, - (rpnstack -> dc_stacksize)*sizeof(*(rpnstack -> s))); - if (rpnstack -> s == NULL){ - rrd_set_error("RPN stack overflow"); - return -1; - } - } - switch (rpnp[rpi].op){ - case OP_NUMBER: - rpnstack -> s[++stptr] = rpnp[rpi].val; - break; - case OP_VARIABLE: - /* make sure we pull the correct value from the *.data array - * adjust the pointer into the array acordingly. - * Advance the ptr one row in the rra (skip over - * non-relevant data sources) */ - if (data_idx % rpnp[rpi].step == 0){ - rpnp[rpi].data += rpnp[rpi].ds_cnt; - } - rpnstack -> s[++stptr] = *(rpnp[rpi].data); - break; - case OP_PREV: - if ((output_idx-1) <= 0) { - rpnstack -> s[++stptr] = DNAN; - } else { - rpnstack -> s[++stptr] = output[output_idx-1]; - } - break; + /* process each op from the rpn in turn */ + for (rpi=0; rpnp[rpi].op != OP_END; rpi++){ + /* allocate or grow the stack */ + if (stptr + 5 > rpnstack -> dc_stacksize){ + /* could move this to a separate function */ + rpnstack -> dc_stacksize += rpnstack -> dc_stackblock; + rpnstack -> s = rrd_realloc(rpnstack -> s, + (rpnstack -> dc_stacksize)*sizeof(*(rpnstack -> s))); + if (rpnstack -> s == NULL){ + rrd_set_error("RPN stack overflow"); + return -1; + } + } + switch (rpnp[rpi].op){ + case OP_NUMBER: + rpnstack -> s[++stptr] = rpnp[rpi].val; + break; + case OP_VARIABLE: + /* Sanity check: VDEFs shouldn't make it here */ + if (rpnp[rpi].ds_cnt == 0) { + rrd_set_error("VDEF made it into rpn_calc... aborting"); + return -1; + } else { + /* make sure we pull the correct value from + * the *.data array. Adjust the pointer into + * the array acordingly. Advance the ptr one + * row in the rra (skip over non-relevant + * data sources) + */ + if (data_idx % rpnp[rpi].step == 0){ + rpnp[rpi].data += rpnp[rpi].ds_cnt; + } + rpnstack -> s[++stptr] = *(rpnp[rpi].data); + } + break; + case OP_PREV: + if ((output_idx-1) <= 0) { + rpnstack -> s[++stptr] = DNAN; + } else { + rpnstack -> s[++stptr] = output[output_idx-1]; + } + break; case OP_UNKN: rpnstack -> s[++stptr] = DNAN; break; @@ -572,6 +584,19 @@ rpn_calc(rpnp_t *rpnp, rpnstack_t *rpnstack, long data_idx, rpnstack -> s[stptr-1] = rpnstack -> s[stptr-1] >= rpnstack -> s[stptr] ? 1.0 : 0.0; stptr--; break; + case OP_NE: + if(stptr<1){ + rrd_set_error("RPN stack underflow"); + return -1; + } + if (isnan(rpnstack -> s[stptr-1])) + ; + else if (isnan(rpnstack -> s[stptr])) + rpnstack -> s[stptr-1] = rpnstack -> s[stptr]; + else + rpnstack -> s[stptr-1] = rpnstack -> s[stptr-1] == rpnstack -> s[stptr] ? 0.0 : 1.0; + stptr--; + break; case OP_EQ: if(stptr<1){ rrd_set_error("RPN stack underflow"); @@ -645,8 +670,15 @@ rpn_calc(rpnp_t *rpnp, rpnstack_t *rpnstack, long data_idx, } rpnstack->s[stptr] = isnan(rpnstack->s[stptr]) ? 1.0 : 0.0; break; + case OP_ISINF: + if(stptr<0){ + rrd_set_error("RPN stack underflow"); + return -1; + } + rpnstack->s[stptr] = isinf(rpnstack->s[stptr]) ? 1.0 : 0.0; + break; case OP_END: - break; + break; } } if(stptr!=0){