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