2006-01-17 16:22:03 +03:00
|
|
|
#include <u.h>
|
|
|
|
#include <libc.h>
|
2006-01-17 15:37:52 +03:00
|
|
|
#include "fmtdef.h"
|
2005-08-08 16:50:13 +04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Reads a floating-point number by interpreting successive characters
|
|
|
|
* returned by (*f)(vp). The last call it makes to f terminates the
|
|
|
|
* scan, so is not a character in the number. It may therefore be
|
|
|
|
* necessary to back up the input stream up one byte after calling charstod.
|
|
|
|
*/
|
|
|
|
|
|
|
|
double
|
2006-01-17 15:37:52 +03:00
|
|
|
fmtcharstod(int(*f)(void*), void *vp)
|
2005-08-08 16:50:13 +04:00
|
|
|
{
|
2006-01-17 15:37:52 +03:00
|
|
|
double num, dem;
|
|
|
|
int neg, eneg, dig, exp, c;
|
|
|
|
|
|
|
|
num = 0;
|
|
|
|
neg = 0;
|
|
|
|
dig = 0;
|
|
|
|
exp = 0;
|
|
|
|
eneg = 0;
|
2005-08-08 16:50:13 +04:00
|
|
|
|
|
|
|
c = (*f)(vp);
|
|
|
|
while(c == ' ' || c == '\t')
|
|
|
|
c = (*f)(vp);
|
|
|
|
if(c == '-' || c == '+'){
|
2006-01-17 15:37:52 +03:00
|
|
|
if(c == '-')
|
|
|
|
neg = 1;
|
|
|
|
c = (*f)(vp);
|
2005-08-08 16:50:13 +04:00
|
|
|
}
|
|
|
|
while(c >= '0' && c <= '9'){
|
2006-01-17 15:37:52 +03:00
|
|
|
num = num*10 + c-'0';
|
|
|
|
c = (*f)(vp);
|
2005-08-08 16:50:13 +04:00
|
|
|
}
|
2006-01-17 15:37:52 +03:00
|
|
|
if(c == '.')
|
|
|
|
c = (*f)(vp);
|
|
|
|
while(c >= '0' && c <= '9'){
|
|
|
|
num = num*10 + c-'0';
|
|
|
|
dig++;
|
|
|
|
c = (*f)(vp);
|
2005-08-08 16:50:13 +04:00
|
|
|
}
|
2006-01-17 15:37:52 +03:00
|
|
|
if(c == 'e' || c == 'E'){
|
|
|
|
c = (*f)(vp);
|
2005-08-08 16:50:13 +04:00
|
|
|
if(c == '-' || c == '+'){
|
2006-01-17 15:37:52 +03:00
|
|
|
if(c == '-'){
|
|
|
|
dig = -dig;
|
|
|
|
eneg = 1;
|
|
|
|
}
|
|
|
|
c = (*f)(vp);
|
2005-08-08 16:50:13 +04:00
|
|
|
}
|
|
|
|
while(c >= '0' && c <= '9'){
|
2006-01-17 15:37:52 +03:00
|
|
|
exp = exp*10 + c-'0';
|
|
|
|
c = (*f)(vp);
|
2005-08-08 16:50:13 +04:00
|
|
|
}
|
|
|
|
}
|
2006-01-17 15:37:52 +03:00
|
|
|
exp -= dig;
|
|
|
|
if(exp < 0){
|
|
|
|
exp = -exp;
|
|
|
|
eneg = !eneg;
|
|
|
|
}
|
|
|
|
dem = __fmtpow10(exp);
|
|
|
|
if(eneg)
|
|
|
|
num /= dem;
|
|
|
|
else
|
|
|
|
num *= dem;
|
|
|
|
if(neg)
|
|
|
|
return -num;
|
|
|
|
return num;
|
2005-08-08 16:50:13 +04:00
|
|
|
}
|