154359Sroberto/* 254359Sroberto * mstolfp - convert an ascii string in milliseconds to an l_fp number 354359Sroberto */ 454359Sroberto#include <stdio.h> 554359Sroberto#include <ctype.h> 654359Sroberto 754359Sroberto#include "ntp_fp.h" 854359Sroberto#include "ntp_stdlib.h" 954359Sroberto 1054359Srobertoint 1154359Srobertomstolfp( 1254359Sroberto const char *str, 1354359Sroberto l_fp *lfp 1454359Sroberto ) 1554359Sroberto{ 1654359Sroberto register const char *cp; 1754359Sroberto register char *bp; 1854359Sroberto register const char *cpdec; 1954359Sroberto char buf[100]; 2054359Sroberto 2154359Sroberto /* 2254359Sroberto * We understand numbers of the form: 2354359Sroberto * 2454359Sroberto * [spaces][-][digits][.][digits][spaces|\n|\0] 2554359Sroberto * 2654359Sroberto * This is one enormous hack. Since I didn't feel like 2754359Sroberto * rewriting the decoding routine for milliseconds, what 2854359Sroberto * is essentially done here is to make a copy of the string 2954359Sroberto * with the decimal moved over three places so the seconds 3054359Sroberto * decoding routine can be used. 3154359Sroberto */ 3254359Sroberto bp = buf; 3354359Sroberto cp = str; 3454359Sroberto while (isspace((int)*cp)) 3554359Sroberto cp++; 3654359Sroberto 3754359Sroberto if (*cp == '-') { 3854359Sroberto *bp++ = '-'; 3954359Sroberto cp++; 4054359Sroberto } 4154359Sroberto 4254359Sroberto if (*cp != '.' && !isdigit((int)*cp)) 4354359Sroberto return 0; 4454359Sroberto 4554359Sroberto 4654359Sroberto /* 4754359Sroberto * Search forward for the decimal point or the end of the string. 4854359Sroberto */ 4954359Sroberto cpdec = cp; 5054359Sroberto while (isdigit((int)*cpdec)) 5154359Sroberto cpdec++; 5254359Sroberto 5354359Sroberto /* 5454359Sroberto * Found something. If we have more than three digits copy the 5554359Sroberto * excess over, else insert a leading 0. 5654359Sroberto */ 5754359Sroberto if ((cpdec - cp) > 3) { 5854359Sroberto do { 5954359Sroberto *bp++ = (char)*cp++; 6054359Sroberto } while ((cpdec - cp) > 3); 6154359Sroberto } else { 6254359Sroberto *bp++ = '0'; 6354359Sroberto } 6454359Sroberto 6554359Sroberto /* 6654359Sroberto * Stick the decimal in. If we've got less than three digits in 6754359Sroberto * front of the millisecond decimal we insert the appropriate number 6854359Sroberto * of zeros. 6954359Sroberto */ 7054359Sroberto *bp++ = '.'; 7154359Sroberto if ((cpdec - cp) < 3) { 7254359Sroberto register int i = 3 - (cpdec - cp); 7354359Sroberto 7454359Sroberto do { 7554359Sroberto *bp++ = '0'; 7654359Sroberto } while (--i > 0); 7754359Sroberto } 7854359Sroberto 7954359Sroberto /* 8054359Sroberto * Copy the remainder up to the millisecond decimal. If cpdec 8154359Sroberto * is pointing at a decimal point, copy in the trailing number too. 8254359Sroberto */ 8354359Sroberto while (cp < cpdec) 8454359Sroberto *bp++ = (char)*cp++; 8554359Sroberto 8654359Sroberto if (*cp == '.') { 8754359Sroberto cp++; 8854359Sroberto while (isdigit((int)*cp)) 8954359Sroberto *bp++ = (char)*cp++; 9054359Sroberto } 9154359Sroberto *bp = '\0'; 9254359Sroberto 9354359Sroberto /* 9454359Sroberto * Check to make sure the string is properly terminated. If 9554359Sroberto * so, give the buffer to the decoding routine. 9654359Sroberto */ 9754359Sroberto if (*cp != '\0' && !isspace((int)*cp)) 9854359Sroberto return 0; 9954359Sroberto return atolfp(buf, lfp); 10054359Sroberto} 101