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