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