1 /* $NetBSD: atolfp.c,v 1.6 2015/07/10 14:20:32 christos Exp $ */ 2 3 /* 4 * atolfp - convert an ascii string 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_string.h" 12 #include "ntp_assert.h" 13 14 /* 15 * Powers of 10 16 */ 17 static u_long ten_to_the_n[10] = { 18 0, 19 10, 20 100, 21 1000, 22 10000, 23 100000, 24 1000000, 25 10000000, 26 100000000, 27 1000000000, 28 }; 29 30 31 int 32 atolfp( 33 const char *str, 34 l_fp *lfp 35 ) 36 { 37 register const char *cp; 38 register u_long dec_i; 39 register u_long dec_f; 40 char *ind; 41 int ndec; 42 int isneg; 43 static const char *digits = "0123456789"; 44 45 NTP_REQUIRE(str != NULL); 46 47 isneg = 0; 48 dec_i = dec_f = 0; 49 ndec = 0; 50 cp = str; 51 52 /* 53 * We understand numbers of the form: 54 * 55 * [spaces][-|+][digits][.][digits][spaces|\n|\0] 56 */ 57 while (isspace((unsigned char)*cp)) 58 cp++; 59 60 if (*cp == '-') { 61 cp++; 62 isneg = 1; 63 } 64 65 if (*cp == '+') 66 cp++; 67 68 if (*cp != '.' && !isdigit((unsigned char)*cp)) 69 return 0; 70 71 while (*cp != '\0' && (ind = strchr(digits, *cp)) != NULL) { 72 dec_i = (dec_i << 3) + (dec_i << 1); /* multiply by 10 */ 73 dec_i += (ind - digits); 74 cp++; 75 } 76 77 if (*cp != '\0' && !isspace((unsigned char)*cp)) { 78 if (*cp++ != '.') 79 return 0; 80 81 while (ndec < 9 && *cp != '\0' 82 && (ind = strchr(digits, *cp)) != NULL) { 83 ndec++; 84 dec_f = (dec_f << 3) + (dec_f << 1); /* *10 */ 85 dec_f += (ind - digits); 86 cp++; 87 } 88 89 while (isdigit((unsigned char)*cp)) 90 cp++; 91 92 if (*cp != '\0' && !isspace((unsigned char)*cp)) 93 return 0; 94 } 95 96 if (ndec > 0) { 97 register u_long tmp; 98 register u_long bit; 99 register u_long ten_fact; 100 101 ten_fact = ten_to_the_n[ndec]; 102 103 tmp = 0; 104 bit = 0x80000000; 105 while (bit != 0) { 106 dec_f <<= 1; 107 if (dec_f >= ten_fact) { 108 tmp |= bit; 109 dec_f -= ten_fact; 110 } 111 bit >>= 1; 112 } 113 if ((dec_f << 1) > ten_fact) 114 tmp++; 115 dec_f = tmp; 116 } 117 118 if (isneg) 119 M_NEG(dec_i, dec_f); 120 121 lfp->l_ui = dec_i; 122 lfp->l_uf = dec_f; 123 return 1; 124 } 125