+ 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_TREND:
+ stackunderflow(1);
+ if ((rpi < 2) || (rpnp[rpi-2].op != OP_VARIABLE)) {
+ rrd_set_error("malformed trend arguments");
+ return -1;
+ } else {
+ time_t dur = (time_t)rpnstack -> s[stptr];
+ time_t step = (time_t)rpnp[rpi-2].step;
+
+ if (output_idx > (int)ceil((float)dur / (float)step)) {
+ double accum = 0.0;
+ int i = 0;
+
+ do {
+ accum += rpnp[rpi-2].data[rpnp[rpi-2].ds_cnt * i--];
+ dur -= step;
+ } while (dur > 0);
+
+ rpnstack -> s[--stptr] = (accum / -i);
+ } else
+ rpnstack -> s[--stptr] = DNAN;
+ }
+ break;
+ case OP_AVG:
+ stackunderflow(0);
+ {
+ int i=(int)rpnstack -> s[stptr--];
+ double sum=0;
+ int count=0;
+ stackunderflow(i-1);
+ while(i>0) {
+ double val=rpnstack -> s[stptr--];
+ i--;
+ if (isnan(val)) { continue; }
+ count++;
+ sum+=val;
+ }
+ /* now push the result back on stack */
+ if (count>0) {
+ rpnstack -> s[++stptr]=sum/count;
+ } else {
+ rpnstack -> s[++stptr]=DNAN;
+ }
+ }
+ break;
+ case OP_ABS:
+ stackunderflow(0);
+ rpnstack -> s[stptr] = fabs(rpnstack -> s[stptr]);
+ break;