1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
|
#include "string.h"
#include "memory.h"
#include "utils/log.h"
#include "utils/type.h"
size_t strLength(const char *str) {
size_t i = 0;
for (; str[i] != '\0'; ++i)
;
return i;
}
bool strEquals(const char *left, const char *right) {
size_t i = 0;
for (; left[i] != '\0' && right[i] != '\0'; ++i) {
if (left[i] != right[i]) {
return false;
}
}
return left[i] == right[i];
}
bool strnEquals(const char *left, const char *right, size_t len) {
for (size_t i = 0; i < len; ++i) {
if (left[i] != right[i]) {
return false;
}
}
return true;
}
bool strnEqualsCaseInsensitive(const char *left, const char *right,
size_t len) {
for (size_t i = 0; i < len; ++i) {
if (!charEqualsCaseInsensitive(left[i], right[i])) {
return false;
}
}
return true;
}
size_t searchInStringArray(const char *array[], size_t array_size,
const char *str, size_t str_size) {
for (size_t i = 0; i < array_size; ++i) {
const size_t el_size = strLength(array[i]);
if (el_size == str_size && strnEquals(array[i], str, str_size)) {
return i;
}
}
return array_size;
}
u64 decimalToU64(char const *str_begin, char const *str_end, bool *success) {
u64 result = 0;
while (str_begin < str_end) {
if (*str_begin < '0' || *str_begin > '9') {
*success = false;
return 0;
}
result *= 10;
result += *str_begin - '0';
str_begin += 1;
}
*success = true;
return result;
}
u64 hexToU64(char const *str_begin, char const *str_end, bool *success) {
u64 result = 0;
if (str_end - str_begin > 16) {
*success = false;
return 0;
}
while (str_begin < str_end) {
result *= 16;
if ('0' <= *str_begin && *str_begin <= '9') {
result += *str_begin - '0';
} else if ('A' <= *str_begin && *str_begin <= 'F') {
result += *str_begin - 'A' + 10;
} else if ('a' <= *str_begin && *str_begin <= 'f') {
result += *str_begin - 'a' + 10;
} else {
*success = false;
return 0;
}
str_begin += 1;
}
*success = true;
return result;
}
f128 numberToFloat(char const *str_begin, char const *str_end, bool *success) {
f128 left = 0;
f128 right = 0;
bool isPastPoint = false;
while (str_begin < str_end) {
char c;
if (isPastPoint) {
c = *--str_end;
} else {
c = *str_begin++;
}
if (c >= '0' && c <= '9') {
if (isPastPoint) {
right += c - '0';
right /= 10;
} else {
left *= 10;
left += c - '0';
}
} else if (c == '.' && !isPastPoint) {
isPastPoint = true;
} else {
*success = false;
return 0;
}
}
*success = true;
return left + right;
}
char *u64ToString(u64 value) {
char *str = a404m_malloc(21 * sizeof(*str));
size_t i = 0;
do {
str[i] = (value % 10) + '0';
value /= 10;
++i;
} while (value != 0);
for (size_t j = 0; j < i / 2; ++j) {
char tmp = str[j];
str[j] = str[i - j - 1];
str[i - j - 1] = tmp;
}
str[i] = '\0';
return a404m_realloc(str, (i + 1) * sizeof(*str));
}
char *strClone(const char *str) {
const size_t str_length = strLength(str) + 1;
char *result = a404m_malloc(str_length * sizeof(*result));
for (size_t i = 0; i < str_length; ++i) {
result[i] = str[i];
}
return result;
}
bool charEqualsCaseInsensitive(char left, char right) {
return left == right ||
('A' <= right && right <= 'Z' && left == right + ('a' - 'A')) ||
('A' <= left && left <= 'Z' && right == left + ('a' - 'A'));
}
|