Contents of /tags/mkinitrd-6_1_10/busybox/libbb/bb_strtod.c
Parent Directory | Revision Log
Revision 922 -
(show annotations)
(download)
Wed Oct 28 09:51:31 2009 UTC (14 years, 11 months ago) by niro
File MIME type: text/plain
File size: 1986 byte(s)
Wed Oct 28 09:51:31 2009 UTC (14 years, 11 months ago) by niro
File MIME type: text/plain
File size: 1986 byte(s)
tagged 'mkinitrd-6_1_10'
1 | /* vi: set sw=4 ts=4: */ |
2 | /* |
3 | * Utility routines. |
4 | * |
5 | * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org> |
6 | * |
7 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. |
8 | */ |
9 | |
10 | #include "libbb.h" |
11 | #include <math.h> /* just for HUGE_VAL */ |
12 | |
13 | #define NOT_DIGIT(a) (((unsigned char)(a-'0')) > 9) |
14 | |
15 | double FAST_FUNC bb_strtod(const char *arg, char **endp) |
16 | { |
17 | double v; |
18 | char *endptr; |
19 | |
20 | /* Allow .NN form. People want to use "sleep .15" etc */ |
21 | if (arg[0] != '-' && arg[0] != '.' && NOT_DIGIT(arg[0])) |
22 | goto err; |
23 | errno = 0; |
24 | v = strtod(arg, &endptr); |
25 | if (endp) |
26 | *endp = endptr; |
27 | if (endptr[0]) { |
28 | /* "1234abcg" or out-of-range? */ |
29 | if (isalnum(endptr[0]) || errno) { |
30 | err: |
31 | errno = ERANGE; |
32 | return HUGE_VAL; |
33 | } |
34 | /* good number, just suspicious terminator */ |
35 | errno = EINVAL; |
36 | } |
37 | return v; |
38 | } |
39 | |
40 | #if 0 |
41 | /* String to timespec: "NNNN[.NNNNN]" -> struct timespec. |
42 | * Can be used for other fixed-point needs. |
43 | * Returns pointer past last converted char, |
44 | * and returns errno similar to bb_strtoXX functions. |
45 | */ |
46 | char* FAST_FUNC bb_str_to_ts(struct timespec *ts, const char *arg) |
47 | { |
48 | if (sizeof(ts->tv_sec) <= sizeof(int)) |
49 | ts->tv_sec = bb_strtou(arg, &arg, 10); |
50 | else if (sizeof(ts->tv_sec) <= sizeof(long)) |
51 | ts->tv_sec = bb_strtoul(arg, &arg, 10); |
52 | else |
53 | ts->tv_sec = bb_strtoull(arg, &arg, 10); |
54 | ts->tv_nsec = 0; |
55 | |
56 | if (*arg != '.') |
57 | return arg; |
58 | |
59 | /* !EINVAL: number is not ok (alphanumeric ending, overflow etc) */ |
60 | if (errno != EINVAL) |
61 | return arg; |
62 | |
63 | if (!*++arg) /* "NNN." */ |
64 | return arg; |
65 | |
66 | { /* "NNN.xxx" - parse xxx */ |
67 | int ndigits; |
68 | char *p; |
69 | char buf[10]; /* we never use more than 9 digits */ |
70 | |
71 | /* Need to make a copy to avoid false overflow */ |
72 | safe_strncpy(buf, arg, 10); |
73 | ts->tv_nsec = bb_strtou(buf, &p, 10); |
74 | ndigits = p - buf; |
75 | arg += ndigits; |
76 | /* normalize to nsec */ |
77 | while (ndigits < 9) { |
78 | ndigits++; |
79 | ts->tv_nsec *= 10; |
80 | } |
81 | while (isdigit(*arg)) /* skip possible 10th plus digits */ |
82 | arg++; |
83 | } |
84 | return arg; |
85 | } |
86 | #endif |