mstolfp.c revision 290001
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 == '-') {
39		*bp++ = '-';
40		cp++;
41	}
42
43	if (*cp != '.' && !isdigit((unsigned char)*cp))
44	    return 0;
45
46
47	/*
48	 * Search forward for the decimal point or the end of the string.
49	 */
50	cpdec = cp;
51	while (isdigit((unsigned char)*cpdec))
52	    cpdec++;
53
54	/*
55	 * Found something.  If we have more than three digits copy the
56	 * excess over, else insert a leading 0.
57	 */
58	if ((cpdec - cp) > 3) {
59		do {
60			*bp++ = (char)*cp++;
61		} while ((cpdec - cp) > 3);
62	} else {
63		*bp++ = '0';
64	}
65
66	/*
67	 * Stick the decimal in.  If we've got less than three digits in
68	 * front of the millisecond decimal we insert the appropriate number
69	 * of zeros.
70	 */
71	*bp++ = '.';
72	if ((cpdec - cp) < 3) {
73		register int i = 3 - (cpdec - cp);
74
75		do {
76			*bp++ = '0';
77		} while (--i > 0);
78	}
79
80	/*
81	 * Copy the remainder up to the millisecond decimal.  If cpdec
82	 * is pointing at a decimal point, copy in the trailing number too.
83	 */
84	while (cp < cpdec)
85	    *bp++ = (char)*cp++;
86
87	if (*cp == '.') {
88		cp++;
89		while (isdigit((unsigned char)*cp))
90		    *bp++ = (char)*cp++;
91	}
92	*bp = '\0';
93
94	/*
95	 * Check to make sure the string is properly terminated.  If
96	 * so, give the buffer to the decoding routine.
97	 */
98	if (*cp != '\0' && !isspace((unsigned char)*cp))
99	    return 0;
100	return atolfp(buf, lfp);
101}
102