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