Browse Source

new: string.h

fslongjin 2 years ago
parent
commit
d9ee6ea859

+ 16 - 0
docs/kernel/core_api/kernel_api.md

@@ -170,6 +170,22 @@
 
   要拷贝的源字符串的长度
 
+#### `char *strcpy(char *dst, const char *src)`
+
+##### 描述
+
+  拷贝源字符串,返回dst字符串
+
+##### 参数
+
+**src**
+
+  源字符串
+
+**dst**
+
+  目标字符串
+
 #### `long strncpy_from_user(char *dst, const char *src, unsigned long size)`
 
 ##### 描述

+ 5 - 2
kernel/common/Makefile

@@ -10,7 +10,7 @@ $(kernel_common_subdirs): ECHO
 
 	$(MAKE) -C $@ all CFLAGS="$(CFLAGS)" ASFLAGS="$(ASFLAGS)" PIC="$(PIC)"
 
-all: glib.o printk.o cpu.o bitree.o kfifo.o wait_queue.o mutex.o wait.o unistd.o $(kernel_common_subdirs)
+all: glib.o printk.o cpu.o bitree.o kfifo.o wait_queue.o mutex.o wait.o unistd.o string.o $(kernel_common_subdirs)
 
 
 glib.o: glib.c
@@ -38,4 +38,7 @@ wait.o: sys/wait.c
 	gcc $(CFLAGS) -c sys/wait.c -o sys/wait.o
 
 unistd.o: unistd.c
-	gcc $(CFLAGS) -c unistd.c -o unistd.o
+	gcc $(CFLAGS) -c unistd.c -o unistd.o
+
+string.o: string.c
+	gcc $(CFLAGS) -c string.c -o string.o

+ 2 - 1
kernel/common/bitree.c

@@ -2,6 +2,7 @@
 #include <mm/slab.h>
 #include <common/errno.h>
 #include <common/kfifo.h>
+#include <common/string.h>
 #include <debug/bug.h>
 
 #define smaller(root, a, b) (root->cmp((a)->value, (b)->value) == -1)
@@ -19,7 +20,7 @@
 struct bt_root_t *bt_create_tree(struct bt_node_t *node, int (*cmp)(void *a, void *b), int (*release)(void *value))
 {
     if (node == NULL || cmp == NULL)
-        return -EINVAL;
+        return (void*)-EINVAL;
 
     struct bt_root_t *root = (struct bt_root_t *)kmalloc(sizeof(struct bt_root_t), 0);
     memset((void *)root, 0, sizeof(struct bt_root_t));

+ 1 - 29
kernel/common/glib.c

@@ -1,31 +1,3 @@
 #include "glib.h"
+#include "string.h"
 
-/**
- * @brief 测量来自用户空间的字符串的长度,会检验地址空间是否属于用户空间
- * @param src
- * @param maxlen
- * @return long
- */
-long strnlen_user(const char *src, unsigned long maxlen)
-{
-
-    unsigned long size = strlen(src);
-    // 地址不合法
-    if (!verify_area((uint64_t)src, size))
-        return 0;
-
-    return size <= maxlen ? size : maxlen;
-}
-
-long strnlen(const char *src, unsigned long maxlen)
-{
-
-    if (src == NULL)
-        return 0;
-    register int __res = 0;
-    while (src[__res] != '\0' && __res < maxlen)
-    {
-        ++__res;
-    }
-    return __res;
-}

+ 0 - 88
kernel/common/glib.h

@@ -179,28 +179,6 @@ static inline struct List *list_next(struct List *entry)
         return NULL;
 }
 
-//计算字符串的长度(经过测试,该版本比采用repne/scasb汇编的运行速度快16.8%左右)
-static inline int strlen(const char *s)
-{
-    if (s == NULL)
-        return 0;
-    register int __res = 0;
-    while (s[__res] != '\0')
-    {
-        ++__res;
-    }
-    return __res;
-}
-
-/**
- * @brief 测量字符串的长度
- *
- * @param src 字符串
- * @param maxlen 最大长度
- * @return long
- */
-long strnlen(const char *src, unsigned long maxlen);
-
 void *memset(void *dst, unsigned char C, ul size)
 {
 
@@ -265,36 +243,6 @@ static void *memcpy(void *dst, const void *src, long Num)
     return dst;
 }
 
-/*
-        比较字符串 FirstPart and SecondPart
-        FirstPart = SecondPart =>  0
-        FirstPart > SecondPart =>  1
-        FirstPart < SecondPart => -1
-*/
-
-int strcmp(char *FirstPart, char *SecondPart)
-{
-    register int __res;
-    __asm__ __volatile__("cld	\n\t"
-                         "1:	\n\t"
-                         "lodsb	\n\t"
-                         "scasb	\n\t"
-                         "jne	2f	\n\t"
-                         "testb	%%al,	%%al	\n\t"
-                         "jne	1b	\n\t"
-                         "xorl	%%eax,	%%eax	\n\t"
-                         "jmp	3f	\n\t"
-                         "2:	\n\t"
-                         "movl	$1,	%%eax	\n\t"
-                         "jl	3f	\n\t"
-                         "negl	%%eax	\n\t"
-                         "3:	\n\t"
-                         : "=a"(__res)
-                         : "D"(FirstPart), "S"(SecondPart)
-                         :);
-    return __res;
-}
-
 // 从io口读入8个bit
 unsigned char io_in8(unsigned short port)
 {
@@ -536,39 +484,3 @@ static inline uint64_t copy_to_user(void *dst, void *src, uint64_t size)
                  : "memory");
     return size;
 }
-
-/**
- * @brief 测量来自用户空间的字符串的长度,会检验地址空间是否属于用户空间
- * @param src
- * @param maxlen
- * @return long
- */
-long strnlen_user(const char *src, unsigned long maxlen);
-
-char *strncpy(char *dst, const char *src, long count)
-{
-    __asm__ __volatile__("cld	\n\t"
-                         "1:	\n\t"
-                         "decq	%2	\n\t"
-                         "js	2f	\n\t"
-                         "lodsb	\n\t"
-                         "stosb	\n\t"
-                         "testb	%%al,	%%al	\n\t"
-                         "jne	1b	\n\t"
-                         "rep	\n\t"
-                         "stosb	\n\t"
-                         "2:	\n\t"
-                         :
-                         : "S"(src), "D"(dst), "c"(count)
-                         : "ax", "memory");
-    return dst;
-}
-
-long strncpy_from_user(char *dst, const char *src, unsigned long size)
-{
-    if (!verify_area((uint64_t)src, size))
-        return 0;
-
-    strncpy(dst, src, size);
-    return size;
-}

+ 1 - 0
kernel/common/printk.c

@@ -10,6 +10,7 @@
 #include <driver/uart/uart.h>
 #include <driver/video/video.h>
 #include "math.h"
+#include <common/string.h>
 
 struct printk_screen_info pos;
 extern ul VBE_FB_phys_addr; // 由bootloader传来的帧缓存区的物理地址

+ 109 - 0
kernel/common/string.c

@@ -0,0 +1,109 @@
+#include "string.h"
+#include "glib.h"
+
+/**
+ * @brief 拷贝整个字符串
+ *
+ * @param dst 目标地址
+ * @param src 源地址
+ * @return char* 目标字符串
+ */
+char *strcpy(char *dst, const char *src)
+{
+    while (*src)
+    {
+        *(dst++) = *(src++);
+    }
+    *dst = 0;
+
+    return dst;
+}
+
+long strnlen(const char *src, unsigned long maxlen)
+{
+
+    if (src == NULL)
+        return 0;
+    register int __res = 0;
+    while (src[__res] != '\0' && __res < maxlen)
+    {
+        ++__res;
+    }
+    return __res;
+}
+
+/*
+        比较字符串 FirstPart and SecondPart
+        FirstPart = SecondPart =>  0
+        FirstPart > SecondPart =>  1
+        FirstPart < SecondPart => -1
+*/
+
+int strcmp(char *FirstPart, char *SecondPart)
+{
+    register int __res;
+    __asm__ __volatile__("cld	\n\t"
+                         "1:	\n\t"
+                         "lodsb	\n\t"
+                         "scasb	\n\t"
+                         "jne	2f	\n\t"
+                         "testb	%%al,	%%al	\n\t"
+                         "jne	1b	\n\t"
+                         "xorl	%%eax,	%%eax	\n\t"
+                         "jmp	3f	\n\t"
+                         "2:	\n\t"
+                         "movl	$1,	%%eax	\n\t"
+                         "jl	3f	\n\t"
+                         "negl	%%eax	\n\t"
+                         "3:	\n\t"
+                         : "=a"(__res)
+                         : "D"(FirstPart), "S"(SecondPart)
+                         :);
+    return __res;
+}
+
+char *strncpy(char *dst, const char *src, long count)
+{
+    __asm__ __volatile__("cld	\n\t"
+                         "1:	\n\t"
+                         "decq	%2	\n\t"
+                         "js	2f	\n\t"
+                         "lodsb	\n\t"
+                         "stosb	\n\t"
+                         "testb	%%al,	%%al	\n\t"
+                         "jne	1b	\n\t"
+                         "rep	\n\t"
+                         "stosb	\n\t"
+                         "2:	\n\t"
+                         :
+                         : "S"(src), "D"(dst), "c"(count)
+                         : "ax", "memory");
+    return dst;
+}
+
+long strncpy_from_user(char *dst, const char *src, unsigned long size)
+{
+    if (!verify_area((uint64_t)src, size))
+        return 0;
+
+    strncpy(dst, src, size);
+    return size;
+}
+
+/**
+ * @brief 测量来自用户空间的字符串的长度,会检验地址空间是否属于用户空间
+ * @param src
+ * @param maxlen
+ * @return long
+ */
+long strnlen_user(const char *src, unsigned long maxlen)
+{
+
+    unsigned long size = strlen(src);
+    // 地址不合法
+    if (!verify_area((uint64_t)src, size))
+        return 0;
+
+    return size <= maxlen ? size : maxlen;
+}
+

+ 53 - 0
kernel/common/string.h

@@ -0,0 +1,53 @@
+#pragma once
+#include "glib.h"
+/**
+ * @brief 拷贝整个字符串
+ *
+ * @param dst 目标地址
+ * @param src 源地址
+ * @return char* 目标字符串
+ */
+char *strcpy(char *dst, const char *src);
+
+//计算字符串的长度(经过测试,该版本比采用repne/scasb汇编的运行速度快16.8%左右)
+static inline int strlen(const char *s)
+{
+    if (s == NULL)
+        return 0;
+    register int __res = 0;
+    while (s[__res] != '\0')
+    {
+        ++__res;
+    }
+    return __res;
+}
+
+/**
+ * @brief 测量字符串的长度
+ *
+ * @param src 字符串
+ * @param maxlen 最大长度
+ * @return long
+ */
+long strnlen(const char *src, unsigned long maxlen);
+
+/*
+        比较字符串 FirstPart and SecondPart
+        FirstPart = SecondPart =>  0
+        FirstPart > SecondPart =>  1
+        FirstPart < SecondPart => -1
+*/
+
+int strcmp(char *FirstPart, char *SecondPart);
+
+char *strncpy(char *dst, const char *src, long count);
+
+long strncpy_from_user(char *dst, const char *src, unsigned long size);
+
+/**
+ * @brief 测量来自用户空间的字符串的长度,会检验地址空间是否属于用户空间
+ * @param src
+ * @param maxlen
+ * @return long
+ */
+long strnlen_user(const char *src, unsigned long maxlen);

+ 1 - 0
kernel/exception/irq.c

@@ -11,6 +11,7 @@
 
 #include <common/asm.h>
 #include <common/printk.h>
+#include <common/string.h>
 #include "gate.h"
 #include <mm/slab.h>
 

+ 1 - 0
kernel/filesystem/VFS/VFS.c

@@ -1,6 +1,7 @@
 #include "VFS.h"
 #include <common/kprint.h>
 #include <common/dirent.h>
+#include <common/string.h>
 #include <common/errno.h>
 #include <mm/mm.h>
 #include <mm/slab.h>

+ 1 - 0
kernel/process/process.c

@@ -3,6 +3,7 @@
 #include <common/printk.h>
 #include <common/kprint.h>
 #include <common/stdio.h>
+#include <common/string.h>
 #include <common/compiler.h>
 #include <common/libELF/elf.h>
 #include <common/time.h>

+ 1 - 0
kernel/syscall/syscall.c

@@ -6,6 +6,7 @@
 #include <mm/slab.h>
 #include <common/errno.h>
 #include <common/fcntl.h>
+#include <common/string.h>
 #include <filesystem/fat32/fat32.h>
 #include <filesystem/VFS/VFS.h>
 #include <driver/keyboard/ps2_keyboard.h>