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