1/* error-checking interface to strtod-like functions 2 3 Copyright (C) 1996, 1999-2000, 2003-2006, 2009-2010 Free Software 4 Foundation, Inc. 5 6 This program is free software: you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 3 of the License, or 9 (at your option) any later version. 10 11 This program is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 18 19/* Written by Jim Meyering. */ 20 21#include <config.h> 22 23#include "xstrtod.h" 24 25#include <errno.h> 26#include <limits.h> 27#include <stdio.h> 28 29#if LONG 30# define XSTRTOD xstrtold 31# define DOUBLE long double 32#else 33# define XSTRTOD xstrtod 34# define DOUBLE double 35#endif 36 37/* An interface to a string-to-floating-point conversion function that 38 encapsulates all the error checking one should usually perform. 39 Like strtod/strtold, but upon successful 40 conversion put the result in *RESULT and return true. Return 41 false and don't modify *RESULT upon any failure. CONVERT 42 specifies the conversion function, e.g., strtod itself. */ 43 44bool 45XSTRTOD (char const *str, char const **ptr, DOUBLE *result, 46 DOUBLE (*convert) (char const *, char **)) 47{ 48 DOUBLE val; 49 char *terminator; 50 bool ok = true; 51 52 errno = 0; 53 val = convert (str, &terminator); 54 55 /* Having a non-zero terminator is an error only when PTR is NULL. */ 56 if (terminator == str || (ptr == NULL && *terminator != '\0')) 57 ok = false; 58 else 59 { 60 /* Allow underflow (in which case CONVERT returns zero), 61 but flag overflow as an error. */ 62 if (val != 0 && errno == ERANGE) 63 ok = false; 64 } 65 66 if (ptr != NULL) 67 *ptr = terminator; 68 69 *result = val; 70 return ok; 71} 72