SimpleKernel
1.17.0
Loading...
Searching...
No Matches
sk_stdlib.c
Go to the documentation of this file.
1
5
#include "
sk_stdlib.h
"
6
7
#include <limits.h>
8
#include <stdbool.h>
9
#include <stddef.h>
10
#include <stdint.h>
11
12
#include "
sk_ctype.h
"
13
14
#ifdef __cplusplus
15
extern
"C"
{
16
#endif
17
19
uint64_t
__stack_chk_guard
= 0x595E9FBD94FDA766;
20
22
[[noreturn]]
void
__stack_chk_fail
() {
while
(
true
); }
23
24
// Internal helper for string to number conversion
25
// Parses magnitude into unsigned long long.
26
// handles base detection, whitespace, signs.
27
static
unsigned
long
long
strtox_main
(
const
char
* nptr,
char
** endptr,
int
base,
28
int
* sign_out,
int
* overflow) {
29
const
char
* s = nptr;
30
unsigned
long
long
acc = 0;
31
int
c;
32
unsigned
long
long
cutoff;
33
int
cutlim;
34
int
any = 0;
35
int
negative = 0;
36
37
*overflow = 0;
38
39
// Skip whitespace
40
while
(
isspace
(*s)) s++;
41
42
// Check sign
43
if
(*s ==
'-'
) {
44
negative = 1;
45
s++;
46
}
else
if
(*s ==
'+'
) {
47
s++;
48
}
49
if
(sign_out) *sign_out = negative;
50
51
// Detect base
52
if
((base == 0 || base == 16) && *s ==
'0'
&& (s[1] ==
'x'
|| s[1] ==
'X'
)) {
53
// Hex prefix
54
// We speculatively consume it.
55
if
(
isxdigit
(s[2])) {
56
s += 2;
57
base = 16;
58
}
else
{
59
// '0x' followed by non-hex.
60
// if base==0, it's octal 0.
61
if
(base == 0) base = 8;
62
}
63
}
64
if
(base == 0) {
65
base = *s ==
'0'
? 8 : 10;
66
}
67
68
if
(base < 2 || base > 36) {
69
if
(endptr) *endptr = (
char
*)nptr;
// Invalid base
70
return
0;
71
}
72
73
cutoff = ULLONG_MAX / (
unsigned
long
long)base;
74
cutlim = ULLONG_MAX % (
unsigned
long
long)base;
75
76
for
(;; s++) {
77
c = *s;
78
if
(
isdigit
(c))
79
c -=
'0'
;
80
else
if
(
isalpha
(c))
81
c =
toupper
(c) -
'A'
+ 10;
82
else
83
break
;
84
85
if
(c >= base)
break
;
86
87
if
(any < 0 || acc > cutoff || (acc == cutoff && c > cutlim)) {
88
any = -1;
// overflow
89
}
else
{
90
any = 1;
91
acc = acc * base + c;
92
}
93
}
94
95
if
(any < 0) {
96
*overflow = 1;
97
acc = ULLONG_MAX;
98
}
99
100
// Set endptr
101
if
(endptr) {
102
*endptr = (
char
*)(any ? s : nptr);
103
}
104
return
acc;
105
}
106
107
unsigned
long
long
int
strtoull
(
const
char
* nptr,
char
** endptr,
int
base) {
108
int
negative;
109
int
overflow;
110
unsigned
long
long
acc =
111
strtox_main
(nptr, endptr, base, &negative, &overflow);
112
113
if
(overflow)
return
ULLONG_MAX;
114
return
negative ? -acc : acc;
115
}
116
117
long
long
int
strtoll
(
const
char
* nptr,
char
** endptr,
int
base) {
118
int
negative;
119
int
overflow;
120
unsigned
long
long
acc =
121
strtox_main
(nptr, endptr, base, &negative, &overflow);
122
123
if
(overflow) {
124
return
negative ? LLONG_MIN : LLONG_MAX;
125
}
126
127
if
(negative) {
128
if
(acc > (
unsigned
long
long
)LLONG_MAX + 1)
return
LLONG_MIN;
129
return
-(
long
long)acc;
130
}
else
{
131
if
(acc > LLONG_MAX)
return
LLONG_MAX;
132
return
(
long
long
)acc;
133
}
134
}
135
136
long
int
strtol
(
const
char
* nptr,
char
** endptr,
int
base) {
137
long
long
int
val =
strtoll
(nptr, endptr, base);
138
#if LONG_MAX != LLONG_MAX
139
if
(val > LONG_MAX)
return
LONG_MAX;
140
if
(val < LONG_MIN)
return
LONG_MIN;
141
#endif
142
return
(
long
int
)val;
143
}
144
145
unsigned
long
int
strtoul
(
const
char
* nptr,
char
** endptr,
int
base) {
146
unsigned
long
long
int
val =
strtoull
(nptr, endptr, base);
147
#if ULONG_MAX != ULLONG_MAX
148
if
(val > ULONG_MAX)
return
ULONG_MAX;
149
#endif
150
return
(
unsigned
long
int
)val;
151
}
152
153
int
atoi
(
const
char
* nptr) {
return
(
int
)
strtol
(nptr, NULL, 10); }
154
155
long
int
atol
(
const
char
* nptr) {
return
strtol
(nptr, NULL, 10); }
156
157
long
long
int
atoll
(
const
char
* nptr) {
return
strtoll
(nptr, NULL, 10); }
158
159
#if (defined(__x86_64__) && defined(__SSE__)) || \
160
(defined(__aarch64__) && defined(__ARM_FP)) || defined(__riscv)
161
double
strtod
(
const
char
* nptr,
char
** endptr) {
162
const
char
* s = nptr;
163
double
acc = 0.0;
164
int
sign = 1;
165
166
while
(
isspace
(*s)) s++;
167
168
if
(*s ==
'-'
) {
169
sign = -1;
170
s++;
171
}
else
if
(*s ==
'+'
) {
172
s++;
173
}
174
175
int
any = 0;
176
while
(
isdigit
(*s)) {
177
any = 1;
178
acc = acc * 10.0 + (*s -
'0'
);
179
s++;
180
}
181
182
if
(*s ==
'.'
) {
183
s++;
184
double
k = 0.1;
185
while
(
isdigit
(*s)) {
186
any = 1;
187
acc += (*s -
'0'
) * k;
188
k *= 0.1;
189
s++;
190
}
191
}
192
193
if
(any && (*s ==
'e'
|| *s ==
'E'
)) {
194
int
esign = 1;
195
int
exp = 0;
196
const
char
* eptr = s + 1;
197
198
if
(*eptr ==
'-'
) {
199
esign = -1;
200
eptr++;
201
}
else
if
(*eptr ==
'+'
) {
202
eptr++;
203
}
204
205
if
(
isdigit
(*eptr)) {
206
while
(
isdigit
(*eptr)) {
207
exp = exp * 10 + (*eptr -
'0'
);
208
eptr++;
209
}
210
s = eptr;
211
double
p = 1.0;
212
double
b = 10.0;
213
while
(exp) {
214
if
(exp & 1) p *= b;
215
b *= b;
216
exp >>= 1;
217
}
218
if
(esign > 0)
219
acc *= p;
220
else
221
acc /= p;
222
}
223
}
224
225
if
(endptr) *endptr = (
char
*)(any ? s : nptr);
226
return
sign * acc;
227
}
228
229
float
strtof
(
const
char
* nptr,
char
** endptr) {
230
return
(
float
)
strtod
(nptr, endptr);
231
}
232
233
double
atof
(
const
char
* nptr) {
return
strtod
(nptr, NULL); }
234
#endif
235
236
#ifdef __cplusplus
237
}
238
#endif
sk_ctype.h
isxdigit
#define isxdigit
Definition
sk_ctype_test.cpp:19
isdigit
#define isdigit
Definition
sk_ctype_test.cpp:12
isspace
#define isspace
Definition
sk_ctype_test.cpp:17
toupper
#define toupper
Definition
sk_ctype_test.cpp:21
isalpha
#define isalpha
Definition
sk_ctype_test.cpp:9
atof
#define atof
Definition
sk_libc_test.cpp:8
strtod
#define strtod
Definition
sk_libc_test.cpp:12
strtoul
#define strtoul
Definition
sk_libc_test.cpp:17
strtoll
#define strtoll
Definition
sk_libc_test.cpp:16
strtof
#define strtof
Definition
sk_libc_test.cpp:13
atol
#define atol
Definition
sk_libc_test.cpp:10
atoi
#define atoi
Definition
sk_libc_test.cpp:9
strtoull
#define strtoull
Definition
sk_libc_test.cpp:18
atoll
#define atoll
Definition
sk_libc_test.cpp:11
strtol
#define strtol
Definition
sk_libc_test.cpp:15
strtox_main
static unsigned long long strtox_main(const char *nptr, char **endptr, int base, int *sign_out, int *overflow)
Definition
sk_stdlib.c:27
__stack_chk_guard
uint64_t __stack_chk_guard
栈保护
Definition
sk_stdlib.c:19
__stack_chk_fail
void __stack_chk_fail()
栈保护检查失败后进入死循环
Definition
sk_stdlib.c:22
sk_stdlib.h
src
libc
sk_stdlib.c
Generated by
1.9.8