154359Sroberto/* 254359Sroberto * mstolfp - convert an ascii string in milliseconds to an l_fp number 354359Sroberto */ 4285612Sdelphij#include <config.h> 554359Sroberto#include <stdio.h> 654359Sroberto#include <ctype.h> 754359Sroberto 854359Sroberto#include "ntp_fp.h" 954359Sroberto#include "ntp_stdlib.h" 1054359Sroberto 1154359Srobertoint 1254359Srobertomstolfp( 1354359Sroberto const char *str, 1454359Sroberto l_fp *lfp 1554359Sroberto ) 1654359Sroberto{ 1754359Sroberto register const char *cp; 1854359Sroberto register char *bp; 1954359Sroberto register const char *cpdec; 2054359Sroberto char buf[100]; 2154359Sroberto 2254359Sroberto /* 2354359Sroberto * We understand numbers of the form: 2454359Sroberto * 2554359Sroberto * [spaces][-][digits][.][digits][spaces|\n|\0] 2654359Sroberto * 2754359Sroberto * This is one enormous hack. Since I didn't feel like 2854359Sroberto * rewriting the decoding routine for milliseconds, what 2954359Sroberto * is essentially done here is to make a copy of the string 3054359Sroberto * with the decimal moved over three places so the seconds 3154359Sroberto * decoding routine can be used. 3254359Sroberto */ 3354359Sroberto bp = buf; 3454359Sroberto cp = str; 35285612Sdelphij while (isspace((unsigned char)*cp)) 3654359Sroberto cp++; 3754359Sroberto 3854359Sroberto if (*cp == '-') { 3954359Sroberto *bp++ = '-'; 4054359Sroberto cp++; 4154359Sroberto } 4254359Sroberto 43285612Sdelphij if (*cp != '.' && !isdigit((unsigned char)*cp)) 4454359Sroberto return 0; 4554359Sroberto 4654359Sroberto 4754359Sroberto /* 4854359Sroberto * Search forward for the decimal point or the end of the string. 4954359Sroberto */ 5054359Sroberto cpdec = cp; 51285612Sdelphij while (isdigit((unsigned char)*cpdec)) 5254359Sroberto cpdec++; 5354359Sroberto 5454359Sroberto /* 5554359Sroberto * Found something. If we have more than three digits copy the 5654359Sroberto * excess over, else insert a leading 0. 5754359Sroberto */ 5854359Sroberto if ((cpdec - cp) > 3) { 5954359Sroberto do { 6054359Sroberto *bp++ = (char)*cp++; 6154359Sroberto } while ((cpdec - cp) > 3); 6254359Sroberto } else { 6354359Sroberto *bp++ = '0'; 6454359Sroberto } 6554359Sroberto 6654359Sroberto /* 6754359Sroberto * Stick the decimal in. If we've got less than three digits in 6854359Sroberto * front of the millisecond decimal we insert the appropriate number 6954359Sroberto * of zeros. 7054359Sroberto */ 7154359Sroberto *bp++ = '.'; 7254359Sroberto if ((cpdec - cp) < 3) { 73293650Sglebius size_t i = 3 - (cpdec - cp); 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++; 88285612Sdelphij while (isdigit((unsigned char)*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 */ 97285612Sdelphij if (*cp != '\0' && !isspace((unsigned char)*cp)) 9854359Sroberto return 0; 9954359Sroberto return atolfp(buf, lfp); 10054359Sroberto} 101