1/*
2 * mstolfp - convert an ascii string in milliseconds 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_stdlib.h"
10
11int
12mstolfp(
13	const char *str,
14	l_fp *lfp
15	)
16{
17	register const char *cp;
18	register char *bp;
19	register const char *cpdec;
20	char buf[100];
21
22	/*
23	 * We understand numbers of the form:
24	 *
25	 * [spaces][-|+][digits][.][digits][spaces|\n|\0]
26	 *
27	 * This is one enormous hack.  Since I didn't feel like
28	 * rewriting the decoding routine for milliseconds, what
29	 * is essentially done here is to make a copy of the string
30	 * with the decimal moved over three places so the seconds
31	 * decoding routine can be used.
32	 */
33	bp = buf;
34	cp = str;
35	while (isspace((unsigned char)*cp))
36	    cp++;
37
38	if (*cp == '-' || *cp == '+') {
39		*bp++ = *cp++;
40	}
41
42	if (*cp != '.' && !isdigit((unsigned char)*cp))
43	    return 0;
44
45
46	/*
47	 * Search forward for the decimal point or the end of the string.
48	 */
49	cpdec = cp;
50	while (isdigit((unsigned char)*cpdec))
51	    cpdec++;
52
53	/*
54	 * Found something.  If we have more than three digits copy the
55	 * excess over, else insert a leading 0.
56	 */
57	if ((cpdec - cp) > 3) {
58		do {
59			*bp++ = (char)*cp++;
60		} while ((cpdec - cp) > 3);
61	} else {
62		*bp++ = '0';
63	}
64
65	/*
66	 * Stick the decimal in.  If we've got less than three digits in
67	 * front of the millisecond decimal we insert the appropriate number
68	 * of zeros.
69	 */
70	*bp++ = '.';
71	if ((cpdec - cp) < 3) {
72		size_t i = 3 - (cpdec - cp);
73		do {
74			*bp++ = '0';
75		} while (--i > 0);
76	}
77
78	/*
79	 * Copy the remainder up to the millisecond decimal.  If cpdec
80	 * is pointing at a decimal point, copy in the trailing number too.
81	 */
82	while (cp < cpdec)
83	    *bp++ = (char)*cp++;
84
85	if (*cp == '.') {
86		cp++;
87		while (isdigit((unsigned char)*cp))
88		    *bp++ = (char)*cp++;
89	}
90	*bp = '\0';
91
92	/*
93	 * Check to make sure the string is properly terminated.  If
94	 * so, give the buffer to the decoding routine.
95	 */
96	if (*cp != '\0' && !isspace((unsigned char)*cp))
97	    return 0;
98	return atolfp(buf, lfp);
99}
100