1 /*
2 * atolfp - convert an ascii string to an l_fp number
3 */
4 #include <config.h>
5 #include <stdio.h>
6 #include <ctype.h>
7
8 #include "ntp_fp.h"
9 #include "ntp_string.h"
10 #include "ntp_assert.h"
11
12 /*
13 * Powers of 10
14 */
15 static u_long ten_to_the_n[10] = {
16 0,
17 10,
18 100,
19 1000,
20 10000,
21 100000,
22 1000000,
23 10000000,
24 100000000,
25 1000000000,
26 };
27
28
29 int
atolfp(const char * str,l_fp * lfp)30 atolfp(
31 const char *str,
32 l_fp *lfp
33 )
34 {
35 register const char *cp;
36 register u_long dec_i;
37 register u_long dec_f;
38 char *ind;
39 int ndec;
40 int isneg;
41 static const char *digits = "0123456789";
42
43 REQUIRE(str != NULL);
44
45 isneg = 0;
46 dec_i = dec_f = 0;
47 ndec = 0;
48 cp = str;
49
50 /*
51 * We understand numbers of the form:
52 *
53 * [spaces][-|+][digits][.][digits][spaces|\n|\0]
54 */
55 while (isspace((unsigned char)*cp))
56 cp++;
57
58 if (*cp == '-') {
59 cp++;
60 isneg = 1;
61 }
62
63 if (*cp == '+')
64 cp++;
65
66 if (*cp != '.' && !isdigit((unsigned char)*cp))
67 return 0;
68
69 while (*cp != '\0' && (ind = strchr(digits, *cp)) != NULL) {
70 dec_i = (dec_i << 3) + (dec_i << 1); /* multiply by 10 */
71 dec_i += (u_long)(ind - digits);
72 cp++;
73 }
74
75 if (*cp != '\0' && !isspace((unsigned char)*cp)) {
76 if (*cp++ != '.')
77 return 0;
78
79 while (ndec < 9 && *cp != '\0'
80 && (ind = strchr(digits, *cp)) != NULL) {
81 ndec++;
82 dec_f = (dec_f << 3) + (dec_f << 1); /* *10 */
83 dec_f += (u_long)(ind - digits);
84 cp++;
85 }
86
87 while (isdigit((unsigned char)*cp))
88 cp++;
89
90 if (*cp != '\0' && !isspace((unsigned char)*cp))
91 return 0;
92 }
93
94 if (ndec > 0) {
95 register u_long tmp;
96 register u_long bit;
97 register u_long ten_fact;
98
99 ten_fact = ten_to_the_n[ndec];
100
101 tmp = 0;
102 bit = 0x80000000;
103 while (bit != 0) {
104 dec_f <<= 1;
105 if (dec_f >= ten_fact) {
106 tmp |= bit;
107 dec_f -= ten_fact;
108 }
109 bit >>= 1;
110 }
111 if ((dec_f << 1) > ten_fact)
112 tmp++;
113 dec_f = tmp;
114 }
115
116 if (isneg)
117 M_NEG(dec_i, dec_f);
118
119 lfp->l_ui = dec_i;
120 lfp->l_uf = dec_f;
121 return 1;
122 }
123