]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/ntp/libntp/mstolfp.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / contrib / ntp / libntp / mstolfp.c
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
10 int
11 mstolfp(
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 }