1/*
2 * mstolfp - convert an ascii string in milliseconds to an l_fp number
3 */
4#include <stdio.h>
5#include <ctype.h>
6
7#include "ntp_fp.h"
8#include "ntp_stdlib.h"
9
10int
11mstolfp(
12	const char *str,
13	l_fp *lfp
14	)
15{
16	register const char *cp;
17	register char *bp;
18	register const char *cpdec;
19	char buf[100];
20
21	/*
22	 * We understand numbers of the form:
23	 *
24	 * [spaces][-][digits][.][digits][spaces|\n|\0]
25	 *
26	 * This is one enormous hack.  Since I didn't feel like
27	 * rewriting the decoding routine for milliseconds, what
28	 * is essentially done here is to make a copy of the string
29	 * with the decimal moved over three places so the seconds
30	 * decoding routine can be used.
31	 */
32	bp = buf;
33	cp = str;
34	while (isspace((int)*cp))
35	    cp++;
36
37	if (*cp == '-') {
38		*bp++ = '-';
39		cp++;
40	}
41
42	if (*cp != '.' && !isdigit((int)*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((int)*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		register int i = 3 - (cpdec - cp);
73
74		do {
75			*bp++ = '0';
76		} while (--i > 0);
77	}
78
79	/*
80	 * Copy the remainder up to the millisecond decimal.  If cpdec
81	 * is pointing at a decimal point, copy in the trailing number too.
82	 */
83	while (cp < cpdec)
84	    *bp++ = (char)*cp++;
85
86	if (*cp == '.') {
87		cp++;
88		while (isdigit((int)*cp))
89		    *bp++ = (char)*cp++;
90	}
91	*bp = '\0';
92
93	/*
94	 * Check to make sure the string is properly terminated.  If
95	 * so, give the buffer to the decoding routine.
96	 */
97	if (*cp != '\0' && !isspace((int)*cp))
98	    return 0;
99	return atolfp(buf, lfp);
100}
101