charstod.c - 9base - revived minimalist port of Plan 9 userland to Unix
 (HTM) git clone git://git.suckless.org/9base
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
       charstod.c (1309B)
       ---
            1 /* Copyright (c) 2002-2006 Lucent Technologies; see LICENSE */
            2 #include <stdarg.h>
            3 #include <string.h>
            4 #include "plan9.h"
            5 #include "fmt.h"
            6 #include "fmtdef.h"
            7 
            8 /*
            9  * Reads a floating-point number by interpreting successive characters
           10  * returned by (*f)(vp).  The last call it makes to f terminates the
           11  * scan, so is not a character in the number.  It may therefore be
           12  * necessary to back up the input stream up one byte after calling charstod.
           13  */
           14 
           15 double
           16 fmtcharstod(int(*f)(void*), void *vp)
           17 {
           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 }