summaryrefslogtreecommitdiff
path: root/kernel/libc/string
diff options
context:
space:
mode:
authorAnton Kling <anton@kling.gg>2023-10-30 22:12:14 +0100
committerAnton Kling <anton@kling.gg>2023-10-31 00:18:38 +0100
commit8a9208612eec8ddae4c418485d848ecfa0613699 (patch)
tree2f4b29200c2f0c19ae52f45bdb9b38a41b356e30 /kernel/libc/string
parentca76600acc8bf7a02346efa5bd8f17072210ec01 (diff)
Meta: Move kernel and userland to their own folders.
This is to allow both the kernel and the userland to share certain header files and to make the folder structure a bit more clear.
Diffstat (limited to 'kernel/libc/string')
-rw-r--r--kernel/libc/string/copy.c26
-rw-r--r--kernel/libc/string/isequal.c15
-rw-r--r--kernel/libc/string/memcmp.c12
-rw-r--r--kernel/libc/string/memcpy.c20
-rw-r--r--kernel/libc/string/memset.c9
-rw-r--r--kernel/libc/string/strcat.c6
-rw-r--r--kernel/libc/string/strcmp.c8
-rw-r--r--kernel/libc/string/strcpy.c8
-rw-r--r--kernel/libc/string/strlcpy.c21
-rw-r--r--kernel/libc/string/strlen.c8
-rw-r--r--kernel/libc/string/strncpy.c11
11 files changed, 144 insertions, 0 deletions
diff --git a/kernel/libc/string/copy.c b/kernel/libc/string/copy.c
new file mode 100644
index 0000000..277c808
--- /dev/null
+++ b/kernel/libc/string/copy.c
@@ -0,0 +1,26 @@
+#include <assert.h>
+#include <kmalloc.h>
+#include <stddef.h>
+#include <string.h>
+
+char *copy_and_allocate_string(const char *s) {
+ size_t l = strlen(s);
+ char *r = kmalloc(l + 1);
+ if (!r)
+ return NULL;
+ return strncpy(r, s, l);
+}
+
+char *copy_and_allocate_user_string(const char *s) {
+ size_t len;
+ if (!is_valid_user_c_string(s, &len))
+ return NULL;
+ size_t real_len = strlen(s);
+ assert(real_len == len);
+ len = real_len;
+ char *r = kmalloc(len + 1);
+ if (!r)
+ return NULL;
+ strlcpy(r, s, len);
+ return r;
+}
diff --git a/kernel/libc/string/isequal.c b/kernel/libc/string/isequal.c
new file mode 100644
index 0000000..cdbd3cc
--- /dev/null
+++ b/kernel/libc/string/isequal.c
@@ -0,0 +1,15 @@
+#include "../include/string.h"
+
+int isequal(const char *s1, const char *s2) {
+ for(;*s1;s1++,s2++)
+ if(*s1 != *s2)
+ return 0;
+ return 1;
+}
+
+int isequal_n(const char *s1, const char *s2, uint32_t n) {
+ for(;*s1 && n;s1++,s2++,n--)
+ if(*s1 != *s2)
+ return 0;
+ return 1;
+}
diff --git a/kernel/libc/string/memcmp.c b/kernel/libc/string/memcmp.c
new file mode 100644
index 0000000..72c680a
--- /dev/null
+++ b/kernel/libc/string/memcmp.c
@@ -0,0 +1,12 @@
+#include "../include/string.h"
+
+int memcmp(const void *s1, const void *s2, uint32_t n)
+{
+ int return_value = 0;
+
+ for(uint32_t i = 0;i < n;i++)
+ if(((unsigned char *)(s1))[i] != ((unsigned char *)(s2))[i])
+ return_value++;
+
+ return return_value;
+}
diff --git a/kernel/libc/string/memcpy.c b/kernel/libc/string/memcpy.c
new file mode 100644
index 0000000..5c04407
--- /dev/null
+++ b/kernel/libc/string/memcpy.c
@@ -0,0 +1,20 @@
+#include "../include/string.h"
+
+void *
+memcpy(void *dest, const void *src, uint32_t n) {
+ unsigned char *d = dest;
+ const unsigned char *s = src;
+
+ for (; n >= 8; n -= 8, d += 8, s += 8)
+ *(uint64_t *)d = *(uint64_t *)s;
+
+ for (; n >= 4; n -= 4, d += 4, s += 4)
+ *(uint32_t *)d = *(uint32_t *)s;
+
+ for (; n >= 2; n -= 2, d += 2, s += 2)
+ *(uint16_t *)d = *(uint16_t *)s;
+
+ for (; n; n--)
+ *d++ = *s++;
+ return dest;
+}
diff --git a/kernel/libc/string/memset.c b/kernel/libc/string/memset.c
new file mode 100644
index 0000000..a446eb4
--- /dev/null
+++ b/kernel/libc/string/memset.c
@@ -0,0 +1,9 @@
+#include <string.h>
+
+void *memset(void *dst, const unsigned char c, uint32_t n) {
+ uintptr_t d = (uintptr_t)dst;
+ for (uint32_t i = 0; i < n; i++, d++)
+ *(unsigned char *)d = c;
+
+ return (void *)d;
+}
diff --git a/kernel/libc/string/strcat.c b/kernel/libc/string/strcat.c
new file mode 100644
index 0000000..78a9ec6
--- /dev/null
+++ b/kernel/libc/string/strcat.c
@@ -0,0 +1,6 @@
+#include <string.h>
+
+char *strcat(char *s1, const char *s2) {
+ strcpy(s1 + strlen(s1), s2);
+ return s1;
+}
diff --git a/kernel/libc/string/strcmp.c b/kernel/libc/string/strcmp.c
new file mode 100644
index 0000000..d7039e2
--- /dev/null
+++ b/kernel/libc/string/strcmp.c
@@ -0,0 +1,8 @@
+#include "../include/string.h"
+
+int strcmp(const char *s1, const char *s2)
+{
+ for(;*s1 == *s2 && *s1; s1++, s2++)
+ ;
+ return *s1 - *s2;
+}
diff --git a/kernel/libc/string/strcpy.c b/kernel/libc/string/strcpy.c
new file mode 100644
index 0000000..fa1e336
--- /dev/null
+++ b/kernel/libc/string/strcpy.c
@@ -0,0 +1,8 @@
+#include <string.h>
+
+char *strcpy(char *d, const char *s) {
+ char *s1 = d;
+ for (; (*d++ = *s++);)
+ ;
+ return s1;
+}
diff --git a/kernel/libc/string/strlcpy.c b/kernel/libc/string/strlcpy.c
new file mode 100644
index 0000000..43d0e58
--- /dev/null
+++ b/kernel/libc/string/strlcpy.c
@@ -0,0 +1,21 @@
+#include <stddef.h>
+#include <string.h>
+
+// Copy string src to buffer dst of size dsize. At most dsize-1
+// chars will be copied. Always NUL terminates (unless dsize == 0).
+// Returns strlen(src); if retval >= dsize, truncation occurred.
+size_t strlcpy(char *dst, const char *src, size_t dsize) {
+ size_t n = dsize;
+ const char *osrc = src;
+ for (; n; n--) {
+ if ((*dst++ = *src++) == '\0')
+ break;
+ }
+ if (n == 0) {
+ if (dsize != 0)
+ *dst = '\0'; /* NUL-terminate dst */
+ while (*src++)
+ ;
+ }
+ return src - osrc - 1;
+}
diff --git a/kernel/libc/string/strlen.c b/kernel/libc/string/strlen.c
new file mode 100644
index 0000000..4346383
--- /dev/null
+++ b/kernel/libc/string/strlen.c
@@ -0,0 +1,8 @@
+#include "../include/string.h"
+
+unsigned long strlen(const char *s)
+{
+ const char * tmp = s;
+ for(;*tmp++;);
+ return (tmp - s)-1;
+}
diff --git a/kernel/libc/string/strncpy.c b/kernel/libc/string/strncpy.c
new file mode 100644
index 0000000..a886895
--- /dev/null
+++ b/kernel/libc/string/strncpy.c
@@ -0,0 +1,11 @@
+#include <stddef.h>
+#include <string.h>
+
+// FIXME: Something is weird with this function
+char *strncpy(char *dest, const char *src, size_t n) {
+ char *r = dest;
+ for (; n && (*dest = *src); n--, src++, dest++)
+ ;
+ *dest = '\0';
+ return r;
+}