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 11 int 12 mstolfp( 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