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