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
|
// ============================================================================
// lib/string.cpp - Freestanding memory and string operations
//
// These are required because we compile with -nostdlib.
// The compiler may generate implicit calls to memcpy/memset/memmove
// (e.g., for struct copies, array init), so these must exist with
// standard C linkage and standard names.
// ============================================================================
#include <stdint.h>
#include <stddef.h>
extern "C" {
void* memcpy(void* dest, const void* src, size_t n) {
auto* d = static_cast<uint8_t*>(dest);
auto* s = static_cast<const uint8_t*>(src);
for (size_t i = 0; i < n; i++) d[i] = s[i];
return dest;
}
void* memmove(void* dest, const void* src, size_t n) {
auto* d = static_cast<uint8_t*>(dest);
auto* s = static_cast<const uint8_t*>(src);
if (d < s) {
for (size_t i = 0; i < n; i++) d[i] = s[i];
} else {
for (size_t i = n; i > 0; i--) d[i - 1] = s[i - 1];
}
return dest;
}
void* memset(void* dest, int val, size_t n) {
auto* d = static_cast<uint8_t*>(dest);
for (size_t i = 0; i < n; i++) d[i] = static_cast<uint8_t>(val);
return dest;
}
int memcmp(const void* s1, const void* s2, size_t n) {
auto* a = static_cast<const uint8_t*>(s1);
auto* b = static_cast<const uint8_t*>(s2);
for (size_t i = 0; i < n; i++) {
// Cast to int before subtracting: uint8_t → int is safe, range [0, 255]
if (a[i] != b[i]) return static_cast<int>(a[i]) - static_cast<int>(b[i]);
}
return 0;
}
size_t strlen(const char* s) {
size_t len = 0;
while (s[len]) len++;
return len;
}
int strcmp(const char* s1, const char* s2) {
// Cast to unsigned before comparison — char may be signed,
// and unsigned subtraction gives the correct lexicographic ordering.
const auto* u1 = reinterpret_cast<const uint8_t*>(s1);
const auto* u2 = reinterpret_cast<const uint8_t*>(s2);
while (*u1 && *u1 == *u2) { ++u1; ++u2; }
return static_cast<int>(*u1) - static_cast<int>(*u2);
}
char* strcpy(char* dest, const char* src) {
char* ret = dest;
while (*src) *dest++ = *src++;
*dest = '\0';
return ret;
}
char* strncpy(char* dest, const char* src, size_t n) {
size_t i = 0;
for (; i < n && src[i]; i++) dest[i] = src[i];
for (; i < n; i++) dest[i] = '\0';
return dest;
}
void* memchr(const void* s, int c, size_t n) {
auto* p = static_cast<const uint8_t*>(s);
auto uc = static_cast<uint8_t>(c);
for (size_t i = 0; i < n; i++)
if (p[i] == uc) return const_cast<void*>(static_cast<const void*>(p + i));
return nullptr;
}
int strncmp(const char* s1, const char* s2, size_t n) {
const auto* u1 = reinterpret_cast<const uint8_t*>(s1);
const auto* u2 = reinterpret_cast<const uint8_t*>(s2);
for (size_t i = 0; i < n; i++) {
if (u1[i] != u2[i]) return static_cast<int>(u1[i]) - static_cast<int>(u2[i]);
if (u1[i] == 0) break;
}
return 0;
}
} // extern "C"
|