Usermode/libc - Fix strchr and strrchr behavior
[tpg/acess2.git] / Usermode / Libraries / libc.so_src / strtof.c
1 /*
2  * Acess2 C Library
3  * - By John Hodge (thePowersGang)
4  *
5  * strtof.c
6  * - strto[df]/atof implimentation
7  */
8 #include <ctype.h>
9 #include <errno.h>
10 #include <limits.h>
11 #include <stddef.h>
12 #include <stdlib.h>     // strtoll
13
14 double strtod(const char *ptr, char **end)
15 {
16          int    negative = 0;
17          int    is_hex = 0;
18         double  rv = 0;
19         char    *tmp;
20         
21         while( isspace(*ptr) )
22                 ptr ++;
23         
24         if( *ptr == '+' || *ptr == '-' )
25         {
26                 negative = (*ptr == '-');
27                 ptr ++;
28         }
29                 
30         #if 0
31         // NAN.*
32         if( strncasecmp(ptr, "NAN", 3) == 0)
33         {
34                 ptr += 3;
35                 while( isalnum(*ptr) || *ptr == '_' )
36                         ptr ++;
37                 
38                 rv = negative ? -NAN : NAN;
39                 if(end) *end = ptr;
40                 return rv;
41         }
42
43         // INF/INFINITY
44         if( strncasecmp(ptr, "INF", 3) == 0 )
45         {
46                 if( strncasecmp(ptr, "INFINITY", 8) == 0 )
47                         ptr += 8;
48                 else
49                         ptr += 3;
50                 rv = negative ? -INFINITY : INFINITY;
51                 if(end) *end = ptr;
52                 return rv;
53         }
54         #endif
55
56         if( *ptr == '0' && (ptr[1] == 'X' || ptr[1] == 'x') )
57         {
58                 is_hex = 1;
59                 ptr += 2;
60         }
61         
62         rv = strtoll(ptr, &tmp, (is_hex ? 16 : 10));
63         
64         // TODO: errors?
65         
66         ptr = tmp;
67         if( *ptr == '.' )
68         {
69                 ptr ++;
70                 if( isspace(*ptr) || *ptr == '-' || *ptr == '+' ) {
71                         goto _err;
72                 }
73                 double frac = strtoll(ptr, &tmp, (is_hex ? 16 : 10));
74                 // TODO: Error check
75                 while( ptr != tmp )
76                 {
77                         frac /= 10;
78                         ptr ++;
79                 }
80                 rv += frac;
81         }
82         
83          int    exp = 0;
84         if( is_hex )
85         {
86                 if( *ptr == 'P' || *ptr == 'p' )
87                 {
88                         ptr ++;
89                         exp = strtoll(ptr, &tmp, 16);
90                         ptr = tmp;
91                 }
92         }
93         else
94         {
95                 if( *ptr == 'E' || *ptr == 'e' )
96                 {
97                         ptr ++;
98                         exp = strtoll(ptr, &tmp, 10);
99                         ptr = tmp;
100                 }
101         }
102
103         if( exp == 0 )
104                 ;
105         else if( exp < 0 )
106                 while( exp ++ )
107                         rv /= 10;
108         else
109                 while( exp -- )
110                         rv *= 10;
111
112         if( negative )
113                 rv = -rv;
114         
115         if( end )
116                 *end = (char*)ptr;
117         
118         return rv;
119 _err:
120         if( end )
121                 *end = (char*)ptr;
122         
123         return 0.0f;
124 }
125
126 float strtof(const char *ptr, char **end)
127 {
128         double rv = strtod(ptr, end);
129         // TODO: ERANGE
130         return rv;
131 }
132
133 float atof(const char *ptr)
134 {
135         return strtof(ptr, NULL);
136 }

UCC git Repository :: git.ucc.asn.au