X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;f=src%2Frrd_rpncalc.c;h=75c24cfa49799873f7f08dc5198ef061d488e95e;hb=0209ff81818995fcd2e2b7080c0ca504fa14d949;hp=65748cc491cf1933ee48934aa2b7ebb9dc3463dc;hpb=801ce418130e78b4b6818f2c8af85c3ddae400ff;p=rrdtool.git diff --git a/src/rrd_rpncalc.c b/src/rrd_rpncalc.c index 65748cc..75c24cf 100644 --- a/src/rrd_rpncalc.c +++ b/src/rrd_rpncalc.c @@ -153,6 +153,10 @@ void rpn_compact2str(rpn_cdefds_t *rpnc,ds_def_t *ds_def,char **str) add_op(OP_NOW,NOW) add_op(OP_LTIME,LTIME) add_op(OP_TIME,TIME) + add_op(OP_ATAN,ATAN) + add_op(OP_SQRT,SQRT) + add_op(OP_SORT,SORT) + add_op(OP_REV,REV) #undef add_op } @@ -299,6 +303,7 @@ rpn_parse(void *key_hash,char *expr,long (*lookup)(void *,char*)){ match_op(OP_DUP,DUP) match_op(OP_EXC,EXC) match_op(OP_POP,POP) + match_op(OP_LTIME,LTIME) match_op(OP_LT,LT) match_op(OP_LE,LE) match_op(OP_GT,GT) @@ -319,9 +324,11 @@ rpn_parse(void *key_hash,char *expr,long (*lookup)(void *,char*)){ 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) - + match_op(OP_ATAN,ATAN) + match_op(OP_SQRT,SQRT) + match_op(OP_SORT,SORT) + match_op(OP_REV,REV) #undef match_op @@ -365,6 +372,14 @@ rpnstack_free(rpnstack_t *rpnstack) rpnstack -> dc_stacksize = 0; } +static int +rpn_compare_double(const void *x, const void *y) +{ + double diff = *((const double *)x) - *((const double *)y); + + return (diff < 0) ? -1 : (diff > 0) ? 1 : 0; +} + /* rpn_calc: run the RPN calculator; also performs variable substitution; * moved and modified from data_calc() originally included in rrd_graph.c * arguments: @@ -501,6 +516,10 @@ rpn_calc(rpnp_t *rpnp, rpnstack_t *rpnstack, long data_idx, stackunderflow(0); rpnstack -> s[stptr] = sin(rpnstack -> s[stptr]); break; + case OP_ATAN: + stackunderflow(0); + rpnstack -> s[stptr] = atan(rpnstack -> s[stptr]); + break; case OP_COS: stackunderflow(0); rpnstack -> s[stptr] = cos(rpnstack -> s[stptr]); @@ -654,6 +673,38 @@ rpn_calc(rpnp_t *rpnp, rpnstack_t *rpnstack, long data_idx, stackunderflow(0); rpnstack->s[stptr] = isinf(rpnstack->s[stptr]) ? 1.0 : 0.0; break; + case OP_SQRT: + stackunderflow(0); + rpnstack -> s[stptr] = sqrt(rpnstack -> s[stptr]); + break; + case OP_SORT: + stackunderflow(0); + { + int spn = (int)rpnstack -> s[stptr--]; + + stackunderflow(spn-1); + qsort(rpnstack -> s + stptr-spn+1, spn, sizeof(double), + rpn_compare_double); + } + break; + case OP_REV: + stackunderflow(0); + { + int spn = (int)rpnstack -> s[stptr--]; + double *p, *q; + + stackunderflow(spn-1); + + p = rpnstack -> s + stptr-spn+1; + q = rpnstack -> s + stptr; + while (p < q) { + double x = *q; + + *q-- = *p; + *p++ = x; + } + } + break; case OP_END: break; }