From 19ee20b6f5c1fab9bb88ad3bc3d6077b3bd0d249 Mon Sep 17 00:00:00 2001 From: apio Date: Wed, 12 Oct 2022 11:19:14 +0200 Subject: [PATCH] libc: Document the functions in string.h --- libs/libc/include/string.h | 36 ++++++++++++++++++++-------- libs/libc/src/string.cpp | 48 +++++++++++++++++++------------------- 2 files changed, 50 insertions(+), 34 deletions(-) diff --git a/libs/libc/include/string.h b/libs/libc/include/string.h index e4379614..f7fef890 100644 --- a/libs/libc/include/string.h +++ b/libs/libc/include/string.h @@ -9,21 +9,37 @@ extern "C" { #endif - void* memcpy(void*, const void*, size_t); - void* memset(void*, int, size_t); - void* memclr(void*, size_t); + /* Copies n bytes from src to dst. */ + void* memcpy(void* dest, const void* src, size_t n); - size_t strlen(const char*); + /* Sets n bytes of buf to c, cast to a character. */ + void* memset(void* buf, int c, size_t n); - deprecated("strcpy is unsafe and should not be used; use strncpy instead") char* strcpy(char*, const char*); - char* strncpy(char*, const char*, size_t); + /* Clears n bytes of buf. */ + void* memclr(void* buf, size_t n); - char* strchr(const char*, int); + /* Returns the length of the string str. */ + size_t strlen(const char* str); - deprecated("strcat is unsafe and should not be used; use strncat instead") char* strcat(char*, const char*); - char* strncat(char*, const char*, size_t); + /* Copies the string src into dest. This function is unsafe, use strncpy instead. */ + deprecated("strcpy is unsafe and should not be used; use strncpy instead") char* strcpy(char* dest, + const char* src); - char* strerror(int); + /* Copies at most max bytes from the string src into dest. */ + char* strncpy(char* dest, const char* src, size_t max); + + /* Returns a pointer to the first occurrence of the character c in str, or NULL if it is not found. */ + char* strchr(const char* str, int c); + + /* Concatenates the string src into dest. This function is unsafe, use strncat instead. */ + deprecated("strcat is unsafe and should not be used; use strncat instead") char* strcat(char* dest, + const char* src); + + /* Concatenates at most max bytes of the string src into dest. */ + char* strncat(char* dest, const char* src, size_t max); + + /* Returns the error string associated with the error number err. */ + char* strerror(int err); #ifdef __cplusplus } diff --git a/libs/libc/src/string.cpp b/libs/libc/src/string.cpp index 8055e9a0..a4afc53f 100644 --- a/libs/libc/src/string.cpp +++ b/libs/libc/src/string.cpp @@ -10,18 +10,18 @@ extern "C" return dest; } - void* memset(void* dest, int c, size_t n) + void* memset(void* buf, int c, size_t n) { - for (size_t i = 0; i < n; ++i) { *((char*)dest + i) = (char)c; } - return dest; + for (size_t i = 0; i < n; ++i) { *((char*)buf + i) = (char)c; } + return buf; } - size_t strlen(const char* s) + size_t strlen(const char* str) { - const char* i = s; + const char* i = str; for (; *i; ++i) ; - return (i - s); + return (i - str); } char* strcpy(char* dest, const char* src) @@ -30,10 +30,10 @@ extern "C" return dest; } - char* strncpy(char* dest, const char* src, size_t n) + char* strncpy(char* dest, const char* src, size_t max) { size_t src_len = strlen(src) + 1; // NULL byte - memcpy(dest, src, src_len > n ? n : src_len); + memcpy(dest, src, src_len > max ? max : src_len); return dest; } @@ -49,40 +49,40 @@ extern "C" return dest; } - char* strncat(char* dest, const char* src, size_t n) + char* strncat(char* dest, const char* src, size_t max) { size_t dest_len = strlen(dest); size_t i; - for (i = 0; i < n && *(src + i); i++) *(char*)(dest + dest_len + i) = *(const char*)(src + i); + for (i = 0; i < max && *(src + i); i++) *(char*)(dest + dest_len + i) = *(const char*)(src + i); *(char*)(dest + dest_len + i) = '\0'; return dest; } - char* strchr(const char* str, int chr) + char* strchr(const char* str, int c) { - while (*str && *str != (char)chr) str++; + while (*str && *str != (char)c) str++; if (*str) return const_cast(str); return NULL; } - void* memclr(void* start, size_t count) + void* memclr(void* buf, size_t n) { // "i" is our counter of how many bytes we've cleared size_t i; // find out if "m_start" is aligned on a SSE_XMM_SIZE boundary - if ((size_t)start & (15)) + if ((size_t)buf & (15)) { i = 0; // we need to clear byte-by-byte until "m_start" is aligned on an SSE_XMM_SIZE boundary // ... and lets make sure we don't copy 'too' many bytes (i < m_count) - while (((size_t)start + i) & (15) && i < count) + while (((size_t)buf + i) & (15) && i < n) { - asm("stosb;" ::"D"((size_t)start + i), "a"(0)); + asm("stosb;" ::"D"((size_t)buf + i), "a"(0)); i++; } } @@ -93,31 +93,31 @@ extern "C" } // clear 64-byte chunks of memory (4 16-byte operations) - for (; i + 64 <= count; i += 64) + for (; i + 64 <= n; i += 64) { asm volatile(" pxor %%xmm0, %%xmm0; " // set XMM0 to 0 " movdqa %%xmm0, 0(%0); " // move 16 bytes from XMM0 to %0 + 0 " movdqa %%xmm0, 16(%0); " " movdqa %%xmm0, 32(%0); " - " movdqa %%xmm0, 48(%0); " ::"r"((size_t)start + i)); + " movdqa %%xmm0, 48(%0); " ::"r"((size_t)buf + i)); } // copy the remaining bytes (if any) - asm(" rep stosb; " ::"a"((size_t)(0)), "D"(((size_t)start) + i), "c"(count - i)); + asm(" rep stosb; " ::"a"((size_t)(0)), "D"(((size_t)buf) + i), "c"(n - i)); // "i" will contain the total amount of bytes that were actually transfered - i += count - i; + i += n - i; // we return "m_start" + the amount of bytes that were transfered - return (void*)(((size_t)start) + i); + return (void*)(((size_t)buf) + i); } #pragma GCC push_options #pragma GCC diagnostic ignored "-Wwrite-strings" - char* strerror(int errnum) + char* strerror(int err) { - switch (errnum) + switch (err) { case EPERM: return "Operation not permitted"; case EINVAL: return "Invalid argument"; @@ -128,7 +128,7 @@ extern "C" case EMFILE: return "Too many open files"; case EISDIR: return "Is a directory"; case 0: return "Success"; - default: return (char*)(unsigned long int)errnum; + default: return (char*)(unsigned long int)err; } }