diff --git a/src/rrd_rpncalc.c b/src/rrd_rpncalc.c
index 7953320f084820349345a38e55b0fba2d8cfdb8d..e4b224de0a7b4fd342a7f107bf77a7dc65acc969 100644 (file)
--- a/src/rrd_rpncalc.c
+++ b/src/rrd_rpncalc.c
/****************************************************************************
- * RRDtool 1.2.23 Copyright by Tobi Oetiker, 1997-2007
+ * RRDtool 1.3.9 Copyright by Tobi Oetiker, 1997-2009
****************************************************************************
* rrd_rpncalc.c RPN calculator functions
****************************************************************************/
#include "rrd_tool.h"
#include "rrd_rpncalc.h"
-#include "rrd_graph.h"
+// #include "rrd_graph.h"
#include <limits.h>
+#include <locale.h>
+
+#ifdef WIN32
+#include <stdlib.h>
+#endif
short addop2str(
enum op_en op,
/* DS_CDEF_MAX_RPN_NODES is small, so at the expense of some wasted
* memory we avoid any reallocs */
rpnp = (rpnp_t *) calloc(DS_CDEF_MAX_RPN_NODES, sizeof(rpnp_t));
- if (rpnp == NULL)
+ if (rpnp == NULL) {
+ rrd_set_error("failed allocating rpnp array");
return NULL;
+ }
for (i = 0; rpnc[i].op != OP_END; ++i) {
- rpnp[i].op = (long) rpnc[i].op;
+ rpnp[i].op = (enum op_en) rpnc[i].op;
if (rpnp[i].op == OP_NUMBER) {
rpnp[i].val = (double) rpnc[i].val;
} else if (rpnp[i].op == OP_VARIABLE || rpnp[i].op == OP_PREV_OTHER) {
(*str)[offset++] = ',';
#define add_op(VV,VVV) \
- if (addop2str(rpnc[i].op, VV, VVV, str, &offset) == 1) continue;
+ if (addop2str((enum op_en)(rpnc[i].op), VV, VVV, str, &offset) == 1) continue;
if (rpnc[i].op == OP_NUMBER) {
/* convert a short into a string */
#undef add_op
#define add_op(VV,VVV) \
- if (addop2str(rpnc[i].op, VV, #VVV, str, &offset) == 1) continue;
+ if (addop2str((enum op_en)rpnc[i].op, VV, #VVV, str, &offset) == 1) continue;
add_op(OP_ADD, +)
add_op(OP_SUB, -)
add_op(OP_DEG2RAD, DEG2RAD)
add_op(OP_AVG, AVG)
add_op(OP_ABS, ABS)
+ add_op(OP_ADDNAN, ADDNAN)
#undef add_op
}
(*str)[offset] = '\0';
long steps = -1;
rpnp_t *rpnp;
char vname[MAX_VNAME_LEN + 10];
+ char *old_locale;
+
+ old_locale = setlocale(LC_NUMERIC, NULL);
+ setlocale(LC_NUMERIC, "C");
rpnp = NULL;
expr = (char *) expr_const;
while (*expr) {
if ((rpnp = (rpnp_t *) rrd_realloc(rpnp, (++steps + 2) *
sizeof(rpnp_t))) == NULL) {
+ setlocale(LC_NUMERIC, old_locale);
return NULL;
}
else if (strncmp(expr, #VVV, strlen(#VVV))==0 && ( expr[strlen(#VVV)] == ',' || expr[strlen(#VVV)] == '\0' )){ \
rpnp[steps].op = VV; \
expr+=strlen(#VVV); \
- }
-
+ }
#define match_op_param(VV,VVV) \
else if (sscanf(expr, #VVV "(" DEF_NAM_FMT ")",vname) == 1) { \
match_op(OP_DEG2RAD, DEG2RAD)
match_op(OP_AVG, AVG)
match_op(OP_ABS, ABS)
+ match_op(OP_ADDNAN, ADDNAN)
#undef match_op
else if ((sscanf(expr, DEF_NAM_FMT "%n", vname, &pos) == 1)
&& ((rpnp[steps].ptr = (*lookup) (key_hash, vname)) !=
}
else {
+ setlocale(LC_NUMERIC, old_locale);
free(rpnp);
return NULL;
}
+
if (*expr == 0)
break;
if (*expr == ',')
expr++;
else {
+ setlocale(LC_NUMERIC, old_locale);
free(rpnp);
return NULL;
}
}
rpnp[steps + 1].op = OP_END;
+ setlocale(LC_NUMERIC, old_locale);
return rpnp;
}
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->s = (double*)(rrd_realloc(rpnstack->s,
(rpnstack->dc_stacksize) *
- sizeof(*(rpnstack->s)));
+ sizeof(*(rpnstack->s))));
if (rpnstack->s == NULL) {
rrd_set_error("RPN stack overflow");
return -1;
+ rpnstack->s[stptr];
stptr--;
break;
+ case OP_ADDNAN:
+ stackunderflow(1);
+ if (isnan(rpnstack->s[stptr - 1])) {
+ rpnstack->s[stptr - 1] = rpnstack->s[stptr];
+ } else if (isnan(rpnstack->s[stptr])) {
+ /* NOOP */
+ /* rpnstack->s[stptr - 1] = rpnstack->s[stptr - 1]; */
+ } else {
+ rpnstack->s[stptr - 1] = rpnstack->s[stptr - 1]
+ + rpnstack->s[stptr];
+ }
+
+ stptr--;
+ break;
case OP_SUB:
stackunderflow(1);
rpnstack->s[stptr - 1] = rpnstack->s[stptr - 1]
break;
case OP_IF:
stackunderflow(2);
- rpnstack->s[stptr - 2] = rpnstack->s[stptr - 2] != 0.0 ?
- rpnstack->s[stptr - 1] : rpnstack->s[stptr];
+ rpnstack->s[stptr - 2] = (isnan(rpnstack->s[stptr - 2])
+ || rpnstack->s[stptr - 2] ==
+ 0.0) ? rpnstack->s[stptr] : rpnstack->
+ s[stptr - 1];
stptr--;
stptr--;
break;