fiss

Friedel's Initialization and Service Supervision
Log | Files | Refs | LICENSE

charstod.c (1357B)


      1 /* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
      2 #include "fmt.h"
      3 #include "fmtdef.h"
      4 #include "plan9.h"
      5 
      6 #include <stdarg.h>
      7 #include <string.h>
      8 
      9 /*
     10  * Reads a floating-point number by interpreting successive characters
     11  * returned by (*f)(vp).  The last call it makes to f terminates the
     12  * scan, so is not a character in the number.  It may therefore be
     13  * necessary to back up the input stream up one byte after calling charstod.
     14  */
     15 
     16 double
     17 fmtcharstod(int (*f)(void*), void* vp) {
     18 	double num, dem;
     19 	int    neg, eneg, dig, exp, c;
     20 
     21 	num  = 0;
     22 	neg  = 0;
     23 	dig  = 0;
     24 	exp  = 0;
     25 	eneg = 0;
     26 
     27 	c = (*f)(vp);
     28 	while (c == ' ' || c == '\t')
     29 		c = (*f)(vp);
     30 	if (c == '-' || c == '+') {
     31 		if (c == '-')
     32 			neg = 1;
     33 		c = (*f)(vp);
     34 	}
     35 	while (c >= '0' && c <= '9') {
     36 		num = num * 10 + c - '0';
     37 		c   = (*f)(vp);
     38 	}
     39 	if (c == '.')
     40 		c = (*f)(vp);
     41 	while (c >= '0' && c <= '9') {
     42 		num = num * 10 + c - '0';
     43 		dig++;
     44 		c = (*f)(vp);
     45 	}
     46 	if (c == 'e' || c == 'E') {
     47 		c = (*f)(vp);
     48 		if (c == '-' || c == '+') {
     49 			if (c == '-') {
     50 				dig  = -dig;
     51 				eneg = 1;
     52 			}
     53 			c = (*f)(vp);
     54 		}
     55 		while (c >= '0' && c <= '9') {
     56 			exp = exp * 10 + c - '0';
     57 			c   = (*f)(vp);
     58 		}
     59 	}
     60 	exp -= dig;
     61 	if (exp < 0) {
     62 		exp  = -exp;
     63 		eneg = !eneg;
     64 	}
     65 	dem = __fmtpow10(exp);
     66 	if (eneg)
     67 		num /= dem;
     68 	else
     69 		num *= dem;
     70 	if (neg)
     71 		return -num;
     72 	return num;
     73 }