/** * @file string.c * @brief Minimal C string/memory functions for the freestanding kernel. * * These implementations replace the standard library versions since the * kernel is compiled with -ffreestanding and does not link against libc. */ #include #include /** * Fill a region of memory with a byte value. * * @param s Destination pointer. * @param c Byte value to fill (only low 8 bits used). * @param n Number of bytes to fill. * @return The destination pointer. */ void *memset(void *s, int c, size_t n) { unsigned char *p = (unsigned char *)s; while (n--) { *p++ = (unsigned char)c; } return s; } /** * Copy a region of memory (non-overlapping). * * @param dest Destination pointer. * @param src Source pointer. * @param n Number of bytes to copy. * @return The destination pointer. */ void *memcpy(void *dest, const void *src, size_t n) { unsigned char *d = (unsigned char *)dest; const unsigned char *s = (const unsigned char *)src; while (n--) { *d++ = *s++; } return dest; } /** * Copy a region of memory, handling overlaps correctly. * * @param dest Destination pointer. * @param src Source pointer. * @param n Number of bytes to copy. * @return The destination pointer. */ void *memmove(void *dest, const void *src, size_t n) { unsigned char *d = (unsigned char *)dest; const unsigned char *s = (const unsigned char *)src; if (d < s) { while (n--) { *d++ = *s++; } } else { d += n; s += n; while (n--) { *--d = *--s; } } return dest; } /** * Compare two regions of memory. * * @param s1 First memory region. * @param s2 Second memory region. * @param n Number of bytes to compare. * @return 0 if equal, negative if s1 < s2, positive if s1 > s2. */ int memcmp(const void *s1, const void *s2, size_t n) { const unsigned char *a = (const unsigned char *)s1; const unsigned char *b = (const unsigned char *)s2; while (n--) { if (*a != *b) { return *a - *b; } a++; b++; } return 0; } /** * Calculate the length of a null-terminated string. * * @param s The string. * @return Number of characters before the null terminator. */ size_t strlen(const char *s) { size_t len = 0; while (*s++) { len++; } return len; } /** * Compare two null-terminated strings. * * @param s1 First string. * @param s2 Second string. * @return 0 if equal, negative if s1 < s2, positive if s1 > s2. */ int strcmp(const char *s1, const char *s2) { while (*s1 && *s1 == *s2) { s1++; s2++; } return *(unsigned char *)s1 - *(unsigned char *)s2; } /** * Compare at most n characters of two strings. * * @param s1 First string. * @param s2 Second string. * @param n Maximum number of characters to compare. * @return 0 if equal, negative if s1 < s2, positive if s1 > s2. */ int strncmp(const char *s1, const char *s2, size_t n) { while (n && *s1 && *s1 == *s2) { s1++; s2++; n--; } if (n == 0) { return 0; } return *(unsigned char *)s1 - *(unsigned char *)s2; } /** * Copy a null-terminated string. * * @param dest Destination buffer (must be large enough). * @param src Source string. * @return The destination pointer. */ char *strcpy(char *dest, const char *src) { char *d = dest; while ((*d++ = *src++)) ; return dest; } /** * Copy at most n characters of a string, null-padding if shorter. * * @param dest Destination buffer. * @param src Source string. * @param n Maximum characters to copy. * @return The destination pointer. */ char *strncpy(char *dest, const char *src, size_t n) { char *d = dest; while (n && (*d++ = *src++)) { n--; } while (n--) { *d++ = '\0'; } return dest; }