.
[gnulib.git] / lib / xstrtod.c
1 #ifdef HAVE_CONFIG_H
2 #include <config.h>
3 #endif
4
5 #ifdef STDC_HEADERS
6 #include <stdlib.h>
7 #else
8 double strtod ();
9 #endif
10
11 #include <errno.h>
12 #include <stdio.h>
13 #include <limits.h>
14 #include <ctype.h>
15 #include "xstrtod.h"
16
17 /* An interface to strtod that encapsulates all the error checking
18    one should usually perform.  Like strtod, but return zero upon
19    successful conversion and put the result in *RESULT.  Return
20    non-zero upon any failure.  */
21
22 int
23 xstrtod (str, ptr, result)
24      const char *str;
25      const char **ptr;
26      double *result;
27 {
28   double val;
29   char *terminator;
30   int fail;
31
32   fail = 0;
33   errno = 0;
34   val = strtod (str, &terminator);
35
36   /* Having a non-zero terminator is an error only when PTR is NULL. */
37   if (terminator == str || (ptr == NULL && *terminator != '\0'))
38     fail = 1;
39   else
40     {
41       /* Allow underflow (in which case strtod returns zero),
42          but flag overflow as an error. */
43       if (val != 0.0 && errno == ERANGE)
44         fail = 1;
45     }
46
47   if (ptr != NULL)
48     *ptr = terminator;
49
50   *result = val;
51   return fail;
52 }
53