From: Upasana Date: Sat, 5 Jul 2014 23:33:49 +0000 (+0530) Subject: added rrd_strtoding & replaced all rrd_strtod instances with it X-Git-Tag: v1.5.0-rc1~63^2~7 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=7a47523f2f81f82f4239f846fa254dbb6420c82c;p=thirdparty%2Frrdtool-1.x.git added rrd_strtoding & replaced all rrd_strtod instances with it --- diff --git a/src/rrd_client.c b/src/rrd_client.c index 5e744c6b..035b0eea 100644 --- a/src/rrd_client.c +++ b/src/rrd_client.c @@ -243,6 +243,7 @@ static int parse_value_array_header (char *line, /* {{{ */ char *endptr; int status; size_t i; + double tmp; if ((str_array = (char**)malloc(array_len * sizeof (char*))) == NULL) return (-1); @@ -268,12 +269,11 @@ static int parse_value_array_header (char *line, /* {{{ */ * will expect a comma as the decimal separator, i.e. "42,77". */ for (i = 0; i < array_len; i++) { - endptr = NULL; - array[i] = (rrd_value_t) rrd_strtod (str_array[i], &endptr); - if ((endptr == str_array[i]) || (errno != 0)) - { - free(str_array); - return (-1); + if( rrd_strtoding(str_array[i], 0, &tmp) == 2) { + array[i] = (rrd_value_t)tmp; + } else { + free(str_array); + return (-1); } } @@ -1586,7 +1586,7 @@ int rrdc_stats_get (rrdc_stats_t **ret_stats) /* {{{ */ || (strcmp ("TreeNodesNumber", key) == 0)) { s->type = RRDC_STATS_TYPE_GAUGE; - s->value.gauge = rrd_strtod (value, &endptr); + rrd_strtoding(value, &endptr, &(s->value.gauge)); } else if ((strcmp ("DataSetsWritten", key) == 0) || (strcmp ("FlushesReceived", key) == 0) @@ -1605,7 +1605,7 @@ int rrdc_stats_get (rrdc_stats_t **ret_stats) /* {{{ */ } /* Conversion failed */ - if (endptr == value) + if ( (endptr == value) || (endptr[0] != '\0') ) { free (s); continue; diff --git a/src/rrd_create.c b/src/rrd_create.c index 39bdb19e..50d7d2ae 100644 --- a/src/rrd_create.c +++ b/src/rrd_create.c @@ -666,12 +666,12 @@ void parseGENERIC_DS( if (minstr[0] == 'U' && minstr[1] == 0) ds_def->par[DS_min_val].u_val = DNAN; else - ds_def->par[DS_min_val].u_val = rrd_strtod(minstr, 0); + rrd_strtoding(minstr, 0, &(ds_def->par[DS_min_val].u_val) ); if (maxstr[0] == 'U' && maxstr[1] == 0) ds_def->par[DS_max_val].u_val = DNAN; else - ds_def->par[DS_max_val].u_val = rrd_strtod(maxstr, 0); + rrd_strtoding(maxstr, 0, &(ds_def->par[DS_max_val].u_val) ); if (!isnan(ds_def->par[DS_min_val].u_val) && !isnan(ds_def->par[DS_max_val].u_val) && diff --git a/src/rrd_daemon.c b/src/rrd_daemon.c index b949d900..3423f0e7 100644 --- a/src/rrd_daemon.c +++ b/src/rrd_daemon.c @@ -1512,8 +1512,7 @@ static int handle_request_update (HANDLER_PROTO) /* {{{ */ /* make sure update time is always moving forward. We use double here since update does support subsecond precision for timestamps ... */ - stamp = rrd_strtod(value, &eostamp); - if (eostamp == value || eostamp == NULL || *eostamp != ':') + if ( ( rrd_strtoding( value, &eostamp, &stamp ) != 2 ) || *eostamp != ':') { pthread_mutex_unlock(&cache_lock); return send_response(sock, RESP_ERR, diff --git a/src/rrd_fetch_libdbi.c b/src/rrd_fetch_libdbi.c index d90a3032..3c2a2a61 100644 --- a/src/rrd_fetch_libdbi.c +++ b/src/rrd_fetch_libdbi.c @@ -101,7 +101,7 @@ static double rrd_fetch_dbi_double(dbi_result *result,int idx) { switch (type) { case DBI_TYPE_STRING: ptmp=(char*)dbi_result_get_string_idx(result,idx); - value=rrd_strtod(ptmp,NULL); + rrd_strtoding(ptmp,NULL, &value); break; case DBI_TYPE_INTEGER: if (attr & DBI_INTEGER_SIZE1) { value=dbi_result_get_char_idx(result,idx); @@ -131,7 +131,7 @@ static double rrd_fetch_dbi_double(dbi_result *result,int idx) { } } /* convert to number */ - value=rrd_strtod(ptmp,NULL); + rrd_strtoding(ptmp,NULL, &value); /* free pointer */ free(ptmp); break; diff --git a/src/rrd_graph.c b/src/rrd_graph.c index 898e78f9..58ac6adb 100644 --- a/src/rrd_graph.c +++ b/src/rrd_graph.c @@ -4583,7 +4583,7 @@ void rrd_graph_options( im->forceleftspace = 1; break; case 'T': - im->tabwidth = rrd_strtod(optarg, 0); + rrd_strtoding(optarg, 0, &(im->tabwidth) ); break; case 'S': im->step = atoi(optarg); @@ -4652,7 +4652,7 @@ void rrd_graph_options( break; }; if (sscanf(optarg, "%[-0-9.e+]:%d", double_str , &im->ylabfact) == 2) { - im->ygridstep = rrd_strtod( double_str, 0 ); + rrd_strtoding( double_str, 0, &(im->ygridstep) ); if (im->ygridstep <= 0) { rrd_set_error("grid step must be > 0"); return; @@ -4673,8 +4673,8 @@ void rrd_graph_options( "%[-0-9.e+]:%[-0-9.e+]", double_str, double_str2 ) != 2) { - im->grid_dash_on = rrd_strtod( double_str, 0 ); - im->grid_dash_off = rrd_strtod( double_str2, 0 ); + rrd_strtoding( double_str, 0, &(im->grid_dash_on) ); + rrd_strtoding( double_str2, 0, &(im->grid_dash_off) ); rrd_set_error("expected grid-dash format float:float"); return; } @@ -4691,8 +4691,8 @@ void rrd_graph_options( "%[-0-9.e+]:%[-0-9.e+]", double_str, double_str2 ) == 2) { - im->second_axis_scale = rrd_strtod( double_str, 0 ); - im->second_axis_shift = rrd_strtod( double_str2, 0 ); + rrd_strtoding( double_str, 0, &(im->second_axis_scale) ); + rrd_strtoding( double_str2, 0, &(im->second_axis_shift) ); if(im->second_axis_scale==0){ rrd_set_error("the second_axis_scale must not be 0"); return; @@ -4739,10 +4739,10 @@ void rrd_graph_options( } break; case 'u': - im->maxval = rrd_strtod(optarg, 0); + rrd_strtoding(optarg, 0, &(im->maxval)); break; case 'l': - im->minval = rrd_strtod(optarg, 0); + rrd_strtoding(optarg, 0, &(im->minval)); break; case 'b': im->base = atol(optarg); @@ -4855,7 +4855,7 @@ void rrd_graph_options( int end; if (sscanf(optarg, "%10[A-Z]:%[-0-9.e+]%n", prop, double_str, &end) >= 2) { - size = rrd_strtod( double_str, 0 ); + rrd_strtoding( double_str, 0, &size ); int sindex, propidx; if ((sindex = text_prop_conv(prop)) != -1) { @@ -4890,18 +4890,18 @@ void rrd_graph_options( break; } case 'm': - im->zoom = rrd_strtod(optarg, 0); + rrd_strtoding(optarg, 0, &(im->zoom)); if (im->zoom <= 0.0) { rrd_set_error("zoom factor must be > 0"); return; } break; case 't': - im->title=strdup(optarg); - if (!im->title) { + im->title=strdup(optarg); + if (!im->title) { rrd_set_error("cannot allocate memory for title"); return; - } + } break; case 'R': if (strcmp(optarg, "normal") == 0) { @@ -5162,7 +5162,7 @@ int vdef_parse( n = 0; sscanf(str, "%[-0-9.e+],%29[A-Z]%n", double_str, func, &n); - param = rrd_strtod( double_str, 0 ); + rrd_strtoding( double_str, 0, ¶m ); if (n == (int) strlen(str)) { /* matched */ ; } else { diff --git a/src/rrd_graph_helper.c b/src/rrd_graph_helper.c index 19ec8c4a..c42de4a5 100644 --- a/src/rrd_graph_helper.c +++ b/src/rrd_graph_helper.c @@ -141,28 +141,24 @@ int getLong(const char* v,long *val,char**extra,int base) { int getDouble(const char* v, double *val,char**extra) { /* try to execute the parser */ /* NOTE that this may be a bit different from the original parser */ + unsigned int strtod_ret; *extra=NULL; - errno = 0; - *val = rrd_strtod(v,extra); - if (errno > 0) { - rrd_set_error("converting '%s' to float: %s", v, rrd_strerror(errno)); - return -1; - }; - - *val=rrd_strtod(v,extra); - /* and error handling */ - if (extra==NULL) { - return 0; - } else { - if (*extra==v) { - return -1; /* failed miserably */ - } else { - if ((*extra)[0]==0) { return 0; } - return 1; /* got extra bytes */ - } + + if( rrd_strtoding( v, extra, val ) != 2 ) { + return -1; } - /* not found, so return error */ - return -2; + + strtod_ret = rrd_strtoding( v, extra, val ); + + /* see rrd_strtoding's return values for more infromation */ + if( strtod_ret == 0 ) + return -1; + else if( strtod_ret == 1 ) + return 1; + else if( strtod_ret == 2 ) + return 0; + else + return -2; } int addToArguments(parsedargs_t* pa, char*key, char*value, int cnt) { diff --git a/src/rrd_restore.c b/src/rrd_restore.c index 6a509b97..4756febe 100644 --- a/src/rrd_restore.c +++ b/src/rrd_restore.c @@ -329,13 +329,11 @@ static int get_xml_double( xmlFree(text); return 0; } - errno = 0; - temp = rrd_strtod((char *)text,NULL); - if (errno>0){ + if ( rrd_strtoding((char *)text,NULL, &temp) != 2 ){ rrd_set_error("ling %d: get_xml_double from '%s' %s", xmlTextReaderGetParserLineNumber(reader), text,rrd_strerror(errno)); - xmlFree(text); + xmlFree(text); return -1; } xmlFree(text); diff --git a/src/rrd_rpncalc.c b/src/rrd_rpncalc.c index f0c00cba..a35a8804 100644 --- a/src/rrd_rpncalc.c +++ b/src/rrd_rpncalc.c @@ -318,7 +318,7 @@ rpnp_t *rpn_parse( else if ((sscanf(expr, "%[-0-9.e+]%n", double_str, &pos) == 1) && (expr[pos] == ',')) { - rpnp[steps].val = rrd_strtod( double_str, 0 ); + rrd_strtoding( double_str, 0, &(rpnp[steps].val) ); rpnp[steps].op = OP_NUMBER; expr += pos; } @@ -706,12 +706,16 @@ short rpn_calc( break; case OP_GT: stackunderflow(1); + printf("in OP_GT\n"); if (isnan(rpnstack->s[stptr - 1])); else if (isnan(rpnstack->s[stptr])) rpnstack->s[stptr - 1] = rpnstack->s[stptr]; else rpnstack->s[stptr - 1] = rpnstack->s[stptr - 1] > rpnstack->s[stptr] ? 1.0 : 0.0; + printf("rpnstack->s[stptr - 1] = %f\n", rpnstack->s[stptr - 1]); + printf("rpnstack->s[stptr]) = %f\n", rpnstack->s[stptr] ); + printf("rpnstack->s[stptr - 1] = %f\n", rpnstack->s[stptr - 1]); stptr--; break; case OP_GE: @@ -750,6 +754,10 @@ short rpn_calc( || rpnstack->s[stptr - 2] == 0.0) ? rpnstack->s[stptr] : rpnstack-> s[stptr - 1]; + printf("In OP_IF\n"); + printf("rpnstack->s[stptr - 2] = %f\n", rpnstack->s[stptr - 2]); + printf("rpnstack->s[stptr] = %f\n", rpnstack->s[stptr] ); + printf("rpnstack->s[stptr - 1] = %f\n", rpnstack->s[stptr - 1]); stptr--; stptr--; break; diff --git a/src/rrd_strtod.c b/src/rrd_strtod.c index 87a9e599..4ea8205e 100644 --- a/src/rrd_strtod.c +++ b/src/rrd_strtod.c @@ -32,15 +32,42 @@ // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF // SUCH DAMAGE. // - + #include #include #include #include #include - + +#include "rrd.h" #include "rrd_strtod.h" - + +/* returns 2 on success */ +/* i.e. if the whole string has been converted to a double successfully */ +unsigned int rrd_strtoding(const char * str, char ** endptr, double * dbl) { + *dbl = rrd_strtod( str, endptr ); + + if( endptr != NULL && *endptr == str ) { + /* no conversion has been done */ + /* for inputs like "abcdj", i.e. no number at all */ + rrd_set_error("Cannot convert %s to float", str); + return 0; + } else if( endptr != NULL && endptr[0] != '\0' ) { + /* conversion has been done, but whole string is not a number */ + /* for inputs like "33.343djdjk" */ + rrd_set_error("Cannot convert %s to float", str); + return 1; + } else if( endptr != NULL && endptr[0] == '\0' ) { + /* conversion successfully done */ + /* for inputs that are totally numbers "23.343" */ + return 2; + } else { + /* just to be safe */ + rrd_set_error(".."); + return 3; + } +} + double rrd_strtod(const char *str, char **endptr) { double number; int exponent; @@ -50,51 +77,51 @@ double rrd_strtod(const char *str, char **endptr) { int n; int num_digits; int num_decimals; - + // Skip leading whitespace while (isspace(*p)) p++; - + // Handle optional sign negative = 0; switch (*p) { case '-': negative = 1; // Fall through to increment position case '+': p++; } - + number = 0.; exponent = 0; num_digits = 0; num_decimals = 0; - + // Process string of digits while (isdigit(*p)) { number = number * 10. + (*p - '0'); p++; num_digits++; } - + // Process decimal part if (*p == '.') { p++; - + while (isdigit(*p)) { number = number * 10. + (*p - '0'); p++; num_digits++; num_decimals++; } - + exponent -= num_decimals; } - + if (num_digits == 0) { errno = ERANGE; return 0.0; } - + // Correct for sign if (negative) number = -number; - + // Process an exponent string if (*p == 'e' || *p == 'E') { // Handle optional sign @@ -103,26 +130,26 @@ double rrd_strtod(const char *str, char **endptr) { case '-': negative = 1; // Fall through to increment pos case '+': p++; } - + // Process string of digits n = 0; while (isdigit(*p)) { n = n * 10 + (*p - '0'); p++; } - + if (negative) { exponent -= n; } else { exponent += n; } } - + if (exponent < DBL_MIN_EXP || exponent > DBL_MAX_EXP) { errno = ERANGE; return HUGE_VAL; } - + // Scale the result p10 = 10.; n = exponent; @@ -138,9 +165,9 @@ double rrd_strtod(const char *str, char **endptr) { n >>= 1; p10 *= p10; } - + if (number == HUGE_VAL) errno = ERANGE; if (endptr) *endptr = p; - + return number; } diff --git a/src/rrd_strtod.h b/src/rrd_strtod.h index b1303e57..145c9bda 100644 --- a/src/rrd_strtod.h +++ b/src/rrd_strtod.h @@ -1 +1,2 @@ +unsigned int rrd_strtoding(const char * str, char ** endptr, double * dbl); double rrd_strtod(const char *str, char **endptr); diff --git a/src/rrd_tune.c b/src/rrd_tune.c index 41ed3b0f..f7f3c11c 100644 --- a/src/rrd_tune.c +++ b/src/rrd_tune.c @@ -211,7 +211,7 @@ int rrd_tune( rrd_set_error("invalid arguments for minimum ds value"); goto done; } - min = rrd_strtod( double_str, 0 ); + rrd_strtoding( double_str, 0, &min ); if ((ds = ds_match(&rrd, ds_nam)) == -1) { goto done; } @@ -227,7 +227,7 @@ int rrd_tune( rrd_set_error("invalid arguments for maximum ds value"); goto done; } - max = rrd_strtod( double_str, 0 ); + rrd_strtoding( double_str, 0, &max ); if ((ds = ds_match(&rrd, ds_nam)) == -1) { goto done; } @@ -420,7 +420,7 @@ int set_hwarg( signed short rra_idx = -1; /* read the value */ - param = rrd_strtod(arg, 0); + rrd_strtoding(arg, 0, ¶m); if (param <= 0.0 || param >= 1.0) { rrd_set_error("Holt-Winters parameter must be between 0 and 1"); return -1; @@ -453,7 +453,7 @@ int set_hwsmootharg( signed short rra_idx = -1; /* read the value */ - param = rrd_strtod(arg, 0); + rrd_strtoding(arg, 0, ¶m); /* in order to avoid smoothing of SEASONAL or DEVSEASONAL, we need to * the 0.0 value*/ if (param < 0.0 || param > 1.0) { @@ -486,7 +486,7 @@ int set_deltaarg( unsigned long i; signed short rra_idx = -1; - param = rrd_strtod(arg, 0); + rrd_strtoding(arg, 0, ¶m); if (param < 0.1) { rrd_set_error("Parameter specified is too small"); return -1; diff --git a/src/rrd_update.c b/src/rrd_update.c index 03fae8fd..d75c61db 100644 --- a/src/rrd_update.c +++ b/src/rrd_update.c @@ -1317,11 +1317,7 @@ static int get_time_from_reading( *current_time = tmp_time.tv_sec; *current_time_usec = tmp_time.tv_usec; } else { - errno = 0; - tmp = rrd_strtod(updvals[0], 0); - if (errno > 0) { - rrd_set_error("converting '%s' to float: %s", - updvals[0], rrd_strerror(errno)); + if ( rrd_strtoding( updvals[0], 0, &tmp) != 2) { return -1; }; if (tmp < 0.0){ @@ -1361,8 +1357,8 @@ static int update_pdp_prep( { unsigned long ds_idx; int ii; - char *endptr; /* used in the conversion */ double rate; + double tmp; enum dst_en dst_idx; for (ds_idx = 0; ds_idx < rrd->stat_head->ds_cnt; ds_idx++) { @@ -1426,34 +1422,15 @@ static int update_pdp_prep( } break; case DST_ABSOLUTE: - errno = 0; - pdp_new[ds_idx] = rrd_strtod(updvals[ds_idx + 1], &endptr); - if (errno > 0) { - rrd_set_error("converting '%s' to float: %s", - updvals[ds_idx + 1], rrd_strerror(errno)); - return -1; - }; - if (endptr[0] != '\0') { - rrd_set_error - ("conversion of '%s' to float not complete: tail '%s'", - updvals[ds_idx + 1], endptr); + if( rrd_strtoding(updvals[ds_idx + 1], 0, &pdp_new[ds_idx] ) != 2 ) { return -1; } rate = pdp_new[ds_idx] / interval; break; case DST_GAUGE: - errno = 0; - pdp_new[ds_idx] = - rrd_strtod(updvals[ds_idx + 1], &endptr) * interval; - if (errno) { - rrd_set_error("converting '%s' to float: %s", - updvals[ds_idx + 1], rrd_strerror(errno)); - return -1; - }; - if (endptr[0] != '\0') { - rrd_set_error - ("conversion of '%s' to float not complete: tail '%s'", - updvals[ds_idx + 1], endptr); + if( rrd_strtoding( updvals[ds_idx + 1], 0, &tmp ) == 2 ) { + pdp_new[ds_idx] = tmp * interval; + } else { return -1; } rate = pdp_new[ds_idx] / interval;