483949f |
Jamozed |
2022-03-06 01:25:30 |
0
|
// util/strtos.c |
98e5939 |
Jamozed |
2021-11-27 17:53:46 |
1
|
// String conversion source file from libutil |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
2
|
// Copyright (C) 2021, Jakob Wakeling |
7f427d9 |
Jamozed |
2022-03-06 12:55:13 |
3
|
// MIT Licence |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
4
|
|
1aa1d3f |
Jamozed |
2022-02-04 19:57:13 |
5
|
#include "util.h" |
1aa1d3f |
Jamozed |
2022-02-04 19:57:13 |
6
|
|
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
7
|
#include <ctype.h> |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
8
|
#include <errno.h> |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
9
|
|
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
10
|
/* Convert a string to a signed 8-bit integer */ |
1aa1d3f |
Jamozed |
2022-02-04 19:57:13 |
11
|
s8 strtos8(const char *nptr, char **endptr, register int base) { |
1aa1d3f |
Jamozed |
2022-02-04 19:57:13 |
12
|
register const char *s = nptr; register u8 i = 0, c; bool neg = false; |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
13
|
|
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
14
|
for (; isspace(*s); ++s); |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
15
|
|
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
16
|
if (*s == '+') { ++s; } else if (*s == '-') { ++s; neg = true; } |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
17
|
|
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
18
|
if ((!base || base == 16) && s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) { |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
19
|
s += 2; base = 16; |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
20
|
} |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
21
|
else if (base == 0) { base = s[0] == '0' ? 8 : 10; } |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
22
|
else if (base < 2 || base > 36) { errno = EINVAL; goto end; } |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
23
|
|
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
24
|
for (;; ++s) { |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
25
|
if (*s >= '0' && *s <= '9') { c = *s - '0'; } |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
26
|
else if (*s >= 'A' && *s <= 'Z') { c = *s - ('A' - 10); } |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
27
|
else if (*s >= 'a' && *s <= 'z') { c = *s - ('a' - 10); } |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
28
|
else { break; } |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
29
|
|
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
30
|
if (c >= base) { break; } |
1aa1d3f |
Jamozed |
2022-02-04 19:57:13 |
31
|
if (i > (neg ? -(S8_MIN + 1) : S8_MAX - c) / base) { |
1aa1d3f |
Jamozed |
2022-02-04 19:57:13 |
32
|
errno = ERANGE; i = neg ? S8_MIN : S8_MAX; goto end; |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
33
|
} |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
34
|
|
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
35
|
i = i * base + c; |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
36
|
} |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
37
|
|
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
38
|
end:; |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
39
|
if (endptr) { *endptr = (char *)s; } return neg ? -i : i; |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
40
|
} |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
41
|
|
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
42
|
/* Convert a string to a signed 16-bit integer */ |
1aa1d3f |
Jamozed |
2022-02-04 19:57:13 |
43
|
s16 strtos16(const char *nptr, char **endptr, register int base) { |
1aa1d3f |
Jamozed |
2022-02-04 19:57:13 |
44
|
register const char *s = nptr; register u16 i = 0, c; bool neg = false; |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
45
|
|
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
46
|
for (; isspace(*s); ++s); |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
47
|
|
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
48
|
if (*s == '+') { ++s; } else if (*s == '-') { ++s; neg = true; } |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
49
|
|
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
50
|
if ((!base || base == 16) && s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) { |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
51
|
s += 2; base = 16; |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
52
|
} |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
53
|
else if (base == 0) { base = s[0] == '0' ? 8 : 10; } |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
54
|
else if (base < 2 || base > 36) { errno = EINVAL; goto end; } |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
55
|
|
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
56
|
for (;; ++s) { |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
57
|
if (*s >= '0' && *s <= '9') { c = *s - '0'; } |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
58
|
else if (*s >= 'A' && *s <= 'Z') { c = *s - ('A' - 10); } |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
59
|
else if (*s >= 'a' && *s <= 'z') { c = *s - ('a' - 10); } |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
60
|
else { break; } |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
61
|
|
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
62
|
if (c >= base) { break; } |
1aa1d3f |
Jamozed |
2022-02-04 19:57:13 |
63
|
if (i > (neg ? -(S16_MIN + 1) : S16_MAX - c) / base) { |
1aa1d3f |
Jamozed |
2022-02-04 19:57:13 |
64
|
errno = ERANGE; i = neg ? S16_MIN : S16_MAX; goto end; |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
65
|
} |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
66
|
|
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
67
|
i = i * base + c; |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
68
|
} |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
69
|
|
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
70
|
end:; |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
71
|
if (endptr) { *endptr = (char *)s; } return neg ? -i : i; |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
72
|
} |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
73
|
|
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
74
|
/* Convert a string to a signed 32-bit integer */ |
1aa1d3f |
Jamozed |
2022-02-04 19:57:13 |
75
|
s32 strtos32(const char *nptr, char **endptr, register int base) { |
1aa1d3f |
Jamozed |
2022-02-04 19:57:13 |
76
|
register const char *s = nptr; register u32 i = 0, c; bool neg = false; |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
77
|
|
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
78
|
for (; isspace(*s); ++s); |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
79
|
|
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
80
|
if (*s == '+') { ++s; } else if (*s == '-') { ++s; neg = true; } |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
81
|
|
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
82
|
if ((!base || base == 16) && s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) { |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
83
|
s += 2; base = 16; |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
84
|
} |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
85
|
else if (base == 0) { base = s[0] == '0' ? 8 : 10; } |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
86
|
else if (base < 2 || base > 36) { errno = EINVAL; goto end; } |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
87
|
|
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
88
|
for (;; ++s) { |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
89
|
if (*s >= '0' && *s <= '9') { c = *s - '0'; } |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
90
|
else if (*s >= 'A' && *s <= 'Z') { c = *s - ('A' - 10); } |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
91
|
else if (*s >= 'a' && *s <= 'z') { c = *s - ('a' - 10); } |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
92
|
else { break; } |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
93
|
|
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
94
|
if (c >= base) { break; } |
1aa1d3f |
Jamozed |
2022-02-04 19:57:13 |
95
|
if (i > (neg ? -(S32_MIN + 1) : S32_MAX - c) / base) { |
1aa1d3f |
Jamozed |
2022-02-04 19:57:13 |
96
|
errno = ERANGE; i = neg ? S32_MIN : S32_MAX; goto end; |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
97
|
} |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
98
|
|
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
99
|
i = i * base + c; |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
100
|
} |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
101
|
|
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
102
|
end:; |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
103
|
if (endptr) { *endptr = (char *)s; } return neg ? -i : i; |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
104
|
} |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
105
|
|
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
106
|
/* Convert a string to a signed 64-bit integer */ |
1aa1d3f |
Jamozed |
2022-02-04 19:57:13 |
107
|
s64 strtos64(const char *nptr, char **endptr, register int base) { |
1aa1d3f |
Jamozed |
2022-02-04 19:57:13 |
108
|
register const char *s = nptr; register u64 i = 0, c; bool neg = false; |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
109
|
|
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
110
|
for (; isspace(*s); ++s); |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
111
|
|
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
112
|
if (*s == '+') { ++s; } else if (*s == '-') { ++s; neg = true; } |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
113
|
|
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
114
|
if ((!base || base == 16) && s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) { |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
115
|
s += 2; base = 16; |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
116
|
} |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
117
|
else if (base == 0) { base = s[0] == '0' ? 8 : 10; } |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
118
|
else if (base < 2 || base > 36) { errno = EINVAL; goto end; } |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
119
|
|
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
120
|
for (;; ++s) { |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
121
|
if (*s >= '0' && *s <= '9') { c = *s - '0'; } |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
122
|
else if (*s >= 'A' && *s <= 'Z') { c = *s - ('A' - 10); } |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
123
|
else if (*s >= 'a' && *s <= 'z') { c = *s - ('a' - 10); } |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
124
|
else { break; } |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
125
|
|
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
126
|
if (c >= base) { break; } |
1aa1d3f |
Jamozed |
2022-02-04 19:57:13 |
127
|
if (i > (neg ? -(S64_MIN + 1) : S64_MAX - c) / base) { |
1aa1d3f |
Jamozed |
2022-02-04 19:57:13 |
128
|
errno = ERANGE; i = neg ? S64_MIN : S64_MAX; goto end; |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
129
|
} |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
130
|
|
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
131
|
i = i * base + c; |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
132
|
} |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
133
|
|
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
134
|
end:; |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
135
|
if (endptr) { *endptr = (char *)s; } return neg ? -i : i; |
9b704eb |
Jamozed |
2021-02-22 11:39:52 |
136
|
} |
|
|
|
137
|
|