/****************************************************************************
- * RRDtool 1.2.2 Copyright by Tobi Oetiker, 1997-2005
+ * RRDtool 1.2.15 Copyright by Tobi Oetiker, 1997-2006
****************************************************************************
* rrd_rpncalc.c RPN calculator functions
****************************************************************************/
if (rpnc[i].op == OP_NUMBER) {
/* convert a short into a string */
-#if defined(WIN32) && !defined(__CYGWIN__) && !defined(__CYGWIN32__)
+#if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__CYGWIN32__)
_itoa(rpnc[i].val,buffer,10);
#else
sprintf(buffer,"%d",rpnc[i].val);
add_op(OP_NOW,NOW)
add_op(OP_LTIME,LTIME)
add_op(OP_TIME,TIME)
+ add_op(OP_ATAN2,ATAN2)
add_op(OP_ATAN,ATAN)
add_op(OP_SQRT,SQRT)
add_op(OP_SORT,SORT)
add_op(OP_REV,REV)
add_op(OP_TREND,TREND)
+ add_op(OP_RAD2DEG,RAD2DEG)
+ add_op(OP_DEG2RAD,DEG2RAD)
+ add_op(OP_AVG,AVG)
#undef add_op
}
(*str)[offset] = '\0';
rpnp = rpn_parse((void*) rrd, def, &lookup_DS);
if (rpnp == NULL) {
- rrd_set_error("failed to parse computed data source %s", def);
+ rrd_set_error("failed to parse computed data source");
return;
}
/* Check for OP nodes not permitted in COMPUTE DS.
* lookup(): a function that retrieves a numeric key given a variable name
*/
rpnp_t *
-rpn_parse(void *key_hash,char *expr,long (*lookup)(void *,char*)){
+rpn_parse(void *key_hash,const char *const expr_const,long (*lookup)(void *,char*)){
int pos=0;
+ char *expr;
long steps=-1;
rpnp_t *rpnp;
- char vname[30];
+ char vname[MAX_VNAME_LEN+10];
rpnp=NULL;
+ expr=(char *)expr_const;
while(*expr){
if ((rpnp = (rpnp_t *) rrd_realloc(rpnp, (++steps + 2)*
}
#define match_op(VV,VVV) \
- else if (strncmp(expr, #VVV, strlen(#VVV))==0){ \
- rpnp[steps].op = VV; \
- expr+=strlen(#VVV); \
+ else if (strncmp(expr, #VVV, strlen(#VVV))==0 && ( expr[strlen(#VVV)] == ',' || expr[strlen(#VVV)] == '\0' )){ \
+ rpnp[steps].op = VV; \
+ expr+=strlen(#VVV); \
}
match_op(OP_ISINF,ISINF)
match_op(OP_NOW,NOW)
match_op(OP_TIME,TIME)
+ match_op(OP_ATAN2,ATAN2)
match_op(OP_ATAN,ATAN)
match_op(OP_SQRT,SQRT)
match_op(OP_SORT,SORT)
match_op(OP_REV,REV)
match_op(OP_TREND,TREND)
+ match_op(OP_RAD2DEG,RAD2DEG)
+ match_op(OP_DEG2RAD,DEG2RAD)
+ match_op(OP_AVG,AVG)
#undef match_op
stackunderflow(0);
rpnstack -> s[stptr] = atan(rpnstack -> s[stptr]);
break;
+ case OP_RAD2DEG:
+ stackunderflow(0);
+ rpnstack -> s[stptr] = 57.29577951 * rpnstack -> s[stptr];
+ break;
+ case OP_DEG2RAD:
+ stackunderflow(0);
+ rpnstack -> s[stptr] = 0.0174532952 * rpnstack -> s[stptr];
+ break;
+ case OP_ATAN2:
+ stackunderflow(1);
+ rpnstack -> s[stptr-1]= atan2(
+ rpnstack -> s[stptr-1],
+ rpnstack -> s[stptr]);
+ stptr--;
+ break;
case OP_COS:
stackunderflow(0);
rpnstack -> s[stptr] = cos(rpnstack -> s[stptr]);
rpnstack -> s[--stptr] = DNAN;
}
break;
+ case OP_AVG:
+ stackunderflow(0);
+ {
+ int i=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 bavk on stack
+ if (count>0) {
+ rpnstack -> s[++stptr]=sum/count;
+ } else {
+ rpnstack -> s[++stptr]=DNAN;
+ }
+ }
+ break;
case OP_END:
break;
}