diff options
author | roberto <roberto@FreeBSD.org> | 1999-12-09 13:01:21 +0000 |
---|---|---|
committer | roberto <roberto@FreeBSD.org> | 1999-12-09 13:01:21 +0000 |
commit | ef64b99e8412f2273dd2e8b3291c2f78ffc4667f (patch) | |
tree | fc0cfa1aab0ff6b228f511b410733ef4f35d1ead /contrib/ntp/libntp/atolfp.c | |
download | FreeBSD-src-ef64b99e8412f2273dd2e8b3291c2f78ffc4667f.zip FreeBSD-src-ef64b99e8412f2273dd2e8b3291c2f78ffc4667f.tar.gz |
Virgin import of ntpd 4.0.98f
Diffstat (limited to 'contrib/ntp/libntp/atolfp.c')
-rw-r--r-- | contrib/ntp/libntp/atolfp.c | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/contrib/ntp/libntp/atolfp.c b/contrib/ntp/libntp/atolfp.c new file mode 100644 index 0000000..ff50947 --- /dev/null +++ b/contrib/ntp/libntp/atolfp.c @@ -0,0 +1,118 @@ +/* + * atolfp - convert an ascii string to an l_fp number + */ +#include <stdio.h> +#include <ctype.h> + +#include "ntp_fp.h" +#include "ntp_string.h" + +/* + * Powers of 10 + */ +static u_long ten_to_the_n[10] = { + 0, + 10, + 100, + 1000, + 10000, + 100000, + 1000000, + 10000000, + 100000000, + 1000000000, +}; + + +int +atolfp( + const char *str, + l_fp *lfp + ) +{ + register const char *cp; + register u_long dec_i; + register u_long dec_f; + char *ind; + int ndec; + int isneg; + static const char *digits = "0123456789"; + + isneg = 0; + dec_i = dec_f = 0; + ndec = 0; + cp = str; + + /* + * We understand numbers of the form: + * + * [spaces][-|+][digits][.][digits][spaces|\n|\0] + */ + while (isspace((int)*cp)) + cp++; + + if (*cp == '-') { + cp++; + isneg = 1; + } + + if (*cp == '+') + cp++; + + if (*cp != '.' && !isdigit((int)*cp)) + return 0; + + while (*cp != '\0' && (ind = strchr(digits, *cp)) != NULL) { + dec_i = (dec_i << 3) + (dec_i << 1); /* multiply by 10 */ + dec_i += (ind - digits); + cp++; + } + + if (*cp != '\0' && !isspace((int)*cp)) { + if (*cp++ != '.') + return 0; + + while (ndec < 9 && *cp != '\0' + && (ind = strchr(digits, *cp)) != NULL) { + ndec++; + dec_f = (dec_f << 3) + (dec_f << 1); /* *10 */ + dec_f += (ind - digits); + cp++; + } + + while (isdigit((int)*cp)) + cp++; + + if (*cp != '\0' && !isspace((int)*cp)) + return 0; + } + + if (ndec > 0) { + register u_long tmp; + register u_long bit; + register u_long ten_fact; + + ten_fact = ten_to_the_n[ndec]; + + tmp = 0; + bit = 0x80000000; + while (bit != 0) { + dec_f <<= 1; + if (dec_f >= ten_fact) { + tmp |= bit; + dec_f -= ten_fact; + } + bit >>= 1; + } + if ((dec_f << 1) > ten_fact) + tmp++; + dec_f = tmp; + } + + if (isneg) + M_NEG(dec_i, dec_f); + + lfp->l_ui = dec_i; + lfp->l_uf = dec_f; + return 1; +} |