github.com/razvanm/vanadium-go-1.3@v0.0.0-20160721203343-4a65068e5915/src/lib9/fmt/charstod.c (about) 1 /* 2 * The authors of this software are Rob Pike and Ken Thompson, 3 * with contributions from Mike Burrows and Sean Dorward. 4 * 5 * Copyright (c) 2002-2006 by Lucent Technologies. 6 * Portions Copyright (c) 2004 Google Inc. 7 * 8 * Permission to use, copy, modify, and distribute this software for any 9 * purpose without fee is hereby granted, provided that this entire notice 10 * is included in all copies of any software which is or includes a copy 11 * or modification of this software and in all copies of the supporting 12 * documentation for such software. 13 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED 14 * WARRANTY. IN PARTICULAR, NEITHER THE AUTHORS NOR LUCENT TECHNOLOGIES 15 * NOR GOOGLE INC MAKE ANY REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING 16 * THE MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. 17 */ 18 19 #include <u.h> 20 #include <libc.h> 21 #include "fmtdef.h" 22 23 /* 24 * Reads a floating-point number by interpreting successive characters 25 * returned by (*f)(vp). The last call it makes to f terminates the 26 * scan, so is not a character in the number. It may therefore be 27 * necessary to back up the input stream up one byte after calling charstod. 28 */ 29 30 double 31 fmtcharstod(int(*f)(void*), void *vp) 32 { 33 double num, dem; 34 int neg, eneg, dig, exp, c; 35 36 num = 0; 37 neg = 0; 38 dig = 0; 39 exp = 0; 40 eneg = 0; 41 42 c = (*f)(vp); 43 while(c == ' ' || c == '\t') 44 c = (*f)(vp); 45 if(c == '-' || c == '+'){ 46 if(c == '-') 47 neg = 1; 48 c = (*f)(vp); 49 } 50 while(c >= '0' && c <= '9'){ 51 num = num*10 + c-'0'; 52 c = (*f)(vp); 53 } 54 if(c == '.') 55 c = (*f)(vp); 56 while(c >= '0' && c <= '9'){ 57 num = num*10 + c-'0'; 58 dig++; 59 c = (*f)(vp); 60 } 61 if(c == 'e' || c == 'E'){ 62 c = (*f)(vp); 63 if(c == '-' || c == '+'){ 64 if(c == '-'){ 65 dig = -dig; 66 eneg = 1; 67 } 68 c = (*f)(vp); 69 } 70 while(c >= '0' && c <= '9'){ 71 exp = exp*10 + c-'0'; 72 c = (*f)(vp); 73 } 74 } 75 exp -= dig; 76 if(exp < 0){ 77 exp = -exp; 78 eneg = !eneg; 79 } 80 dem = __fmtpow10(exp); 81 if(eneg) 82 num /= dem; 83 else 84 num *= dem; 85 if(neg) 86 return -num; 87 return num; 88 }