Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include <u.h>
2
#include <libc.h>
3
 
4
/*
5
 * Reads a floating-point number by interpreting successive characters
6
 * returned by (*f)(vp).  The last call it makes to f terminates the
7
 * scan, so is not a character in the number.  It may therefore be
8
 * necessary to back up the input stream up one byte after calling charstod.
9
 */
10
 
11
#define ADVANCE *s++ = c; if(s>=e) return NaN(); c = (*f)(vp)
12
 
13
double
14
charstod(int(*f)(void*), void *vp)
15
{
16
	char str[400], *s, *e, *start;
17
	int c;
18
 
19
	s = str;
20
	e = str + sizeof str - 1;
21
	c = (*f)(vp);
22
	while(c == ' ' || c == '\t')
23
		c = (*f)(vp);
24
	if(c == '-' || c == '+'){
25
		ADVANCE;
26
	}
27
	start = s;
28
	while(c >= '0' && c <= '9'){
29
		ADVANCE;
30
	}
31
	if(c == '.'){
32
		ADVANCE;
33
		while(c >= '0' && c <= '9'){
34
			ADVANCE;
35
		}
36
	}
37
	if(s > start && (c == 'e' || c == 'E')){
38
		ADVANCE;
39
		if(c == '-' || c == '+'){
40
			ADVANCE;
41
		}
42
		while(c >= '0' && c <= '9'){
43
			ADVANCE;
44
		}
45
	}else if(s == start && (c == 'i' || c == 'I')){
46
		ADVANCE;
47
		if(c != 'n' && c != 'N')
48
			return NaN();
49
		ADVANCE;
50
		if(c != 'f' && c != 'F')
51
			return NaN();
52
		ADVANCE;
53
		if(c != 'i' && c != 'I')
54
			return NaN();
55
		ADVANCE;
56
		if(c != 'n' && c != 'N')
57
			return NaN();
58
		ADVANCE;
59
		if(c != 'i' && c != 'I')
60
			return NaN();
61
		ADVANCE;
62
		if(c != 't' && c != 'T')
63
			return NaN();
64
		ADVANCE;
65
		if(c != 'y' && c != 'Y')
66
			return NaN();
67
		ADVANCE;  /* so caller can back up uniformly */
68
		USED(c);
69
	}else if(s == str && (c == 'n' || c == 'N')){
70
		ADVANCE;
71
		if(c != 'a' && c != 'A')
72
			return NaN();
73
		ADVANCE;
74
		if(c != 'n' && c != 'N')
75
			return NaN();
76
		ADVANCE;  /* so caller can back up uniformly */
77
		USED(c);
78
	}
79
	*s = 0;
80
	return strtod(str, &s);
81
}