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