From: Julien Thomas Date: Fri, 7 Feb 2014 13:21:53 +0000 (+0100) Subject: merged changes X-Git-Tag: v1.5.0-rc1~137 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=22074e444101a7b59a650aeae23dd71fa83daf3e;p=thirdparty%2Frrdtool-1.x.git merged changes --- diff --git a/doc/rrdgraph_rpn.pod b/doc/rrdgraph_rpn.pod index 87fc8e66..733cfaa4 100644 --- a/doc/rrdgraph_rpn.pod +++ b/doc/rrdgraph_rpn.pod @@ -79,6 +79,12 @@ respectively. Note that I is larger than anything else. If one of the input numbers is I then the result of the operation will be I too. +B + +NAN-safe version of MIN and MAX. If one of the input numbers is I +then the result of the operation will be the other one. If both are +I, then the result of the operation is I. + B Pops two elements from the stack and uses them to define a range. diff --git a/src/rrd_rpncalc.c b/src/rrd_rpncalc.c index 2587e444..3ac63872 100644 --- a/src/rrd_rpncalc.c +++ b/src/rrd_rpncalc.c @@ -185,6 +185,8 @@ void rpn_compact2str( add_op(OP_AVG, AVG) add_op(OP_ABS, ABS) add_op(OP_ADDNAN, ADDNAN) + add_op(OP_MINNAN, MINNAN) + add_op(OP_MAXNAN, MAXNAN) #undef add_op } (*str)[offset] = '\0'; @@ -388,7 +390,10 @@ rpnp_t *rpn_parse( match_op(OP_AVG, AVG) match_op(OP_ABS, ABS) match_op(OP_ADDNAN, ADDNAN) + match_op(OP_MINNAN, MINNAN) + match_op(OP_MAXNAN, MAXNAN) match_op(OP_MEDIAN, MEDIAN) + #undef match_op else if ((sscanf(expr, DEF_NAM_FMT "%n", vname, &pos) == 1) && ((rpnp[steps].ptr = (*lookup) (key_hash, vname)) != @@ -736,6 +741,15 @@ short rpn_calc( rpnstack->s[stptr - 1] = rpnstack->s[stptr]; stptr--; break; + case OP_MINNAN: + stackunderflow(1); + if (isnan(rpnstack->s[stptr - 1])) + rpnstack->s[stptr - 1] = rpnstack->s[stptr]; + else if (isnan(rpnstack->s[stptr])); + else if (rpnstack->s[stptr - 1] > rpnstack->s[stptr]) + rpnstack->s[stptr - 1] = rpnstack->s[stptr]; + stptr--; + break; case OP_MAX: stackunderflow(1); if (isnan(rpnstack->s[stptr - 1])); @@ -745,6 +759,15 @@ short rpn_calc( rpnstack->s[stptr - 1] = rpnstack->s[stptr]; stptr--; break; + case OP_MAXNAN: + stackunderflow(1); + if (isnan(rpnstack->s[stptr - 1])) + rpnstack->s[stptr - 1] = rpnstack->s[stptr]; + else if (isnan(rpnstack->s[stptr])); + else if (rpnstack->s[stptr - 1] < rpnstack->s[stptr]) + rpnstack->s[stptr - 1] = rpnstack->s[stptr]; + stptr--; + break; case OP_LIMIT: stackunderflow(2); if (isnan(rpnstack->s[stptr - 2])); diff --git a/src/rrd_rpncalc.h b/src/rrd_rpncalc.h index 9661e6a0..dd9f109e 100644 --- a/src/rrd_rpncalc.h +++ b/src/rrd_rpncalc.h @@ -19,8 +19,10 @@ enum op_en { OP_NUMBER = 0, OP_VARIABLE, OP_INF, OP_PREV, OP_NEGINF, OP_ATAN, OP_SQRT, OP_SORT, OP_REV, OP_TREND, OP_TRENDNAN, OP_ATAN2, OP_RAD2DEG, OP_DEG2RAD, OP_PREDICT,OP_PREDICTSIGMA, - OP_AVG, OP_ABS, OP_ADDNAN, OP_MEDIAN -}; + OP_AVG, OP_ABS, OP_ADDNAN, + OP_MINNAN, OP_MAXNAN, + OP_MEDIAN + }; typedef struct rpnp_t { enum op_en op;