diff --git a/src/kernel/memory/string.c b/src/kernel/memory/string.c index be9faf9..9024010 100644 --- a/src/kernel/memory/string.c +++ b/src/kernel/memory/string.c @@ -29,16 +29,26 @@ void *memset(void *s, int c, size_t n) } #ifdef TTEST -void *my_memmove(void *dest, const void *src, size_t n) +void *my_memmove(void *dst, const void *src, size_t n) #else -void *memmove(void *dest, const void *src, size_t n) +void *memmove(void *dst, const void *src, size_t n) #endif { - // We'll need some form of malloc to implement a good memmove. - // For now, we'll just use defer to memcpy - WHICH IS UNSAFE! - // TODO: Write a good implementation of memmove - memcpy(dest, src, n); - return dest; + if(src == dst) + return dst; + + const void *src_end = (const void *)((uintptr_t)src + n); + if(src < dst && dst < src_end) + { + char *dp = dst; + const char *sp = src; + while(n--) + dp[n] = sp[n]; + return dst; + } + + memcpy(dst, src, n); + return dst; } #ifdef TTEST diff --git a/src/kernel/memory/string.tt b/src/kernel/memory/string.tt index 217cc9e..f30511b 100644 --- a/src/kernel/memory/string.tt +++ b/src/kernel/memory/string.tt @@ -30,27 +30,36 @@ TEST(memset_sets_data) ASSERT_EQ_STR(dst, "aaaaa", 100); } -// Those test won't pass right now since our memmove implementation is -// incomplete (see string.c) - -/*TEST(memmove_moves_data) +TEST(memmove_moves_data) { memcpy(&dst[10], "12345", 5); my_memmove(dst, &dst[10], 5); ASSERT_EQ_STR(dst, "12345", 5); -}*/ -/*TEST(memmove_handles_overlap) +} +TEST(memmove_handles_overlap) { memcpy(&dst[5], "1234567890", 10); my_memmove(dst, &dst[5], 10); ASSERT_EQ_STR(dst, "1234567890", 10); -}*/ -/*TEST(memmove_handles_overlap_the_other_way) +} +TEST(memmove_handles_overlap_the_other_way) { memcpy(dst, "1234567890", 10); my_memmove(&dst[5], dst, 10); ASSERT_EQ_STR(&dst[5], "1234567890", 10); -}*/ +} +TEST(memmove_moves_correct_number_of_chars) +{ + memcpy(&dst[5], "1234567890", 10); + my_memmove(dst, &dst[5], 9); + ASSERT_EQ_STR(dst, "123456789567890", 15); +} +TEST(memmove_moves_correct_number_of_chars_the_other_way) +{ + memcpy(dst, "1234567890", 10); + my_memmove(&dst[5], dst, 3); + ASSERT_EQ_STR(dst, "1234512390", 10); +} TEST(memcmp_returns_zero_for_equal_strings) {