xref: /DragonOS/kernel/src/libs/string.c (revision 4454d1a2dd1f1078750151c028a794cfd9a04a1b)
1 #include <common/string.h>
2 #include <common/glib.h>
3 
4 /**
5  * @brief 拷贝整个字符串
6  *
7  * @param dst 目标地址
8  * @param src 源地址
9  * @return char* 目标字符串
10  */
11 char *strcpy(char *dst, const char *src)
12 {
13     while (*src)
14     {
15         *(dst++) = *(src++);
16     }
17     *dst = 0;
18 
19     return dst;
20 }
21 
22 long strnlen(const char *src, unsigned long maxlen)
23 {
24 
25     if (src == NULL)
26         return 0;
27     register int __res = 0;
28     while (src[__res] != '\0' && __res < maxlen)
29     {
30         ++__res;
31     }
32     return __res;
33 }
34 
35 /*
36         比较字符串 FirstPart and SecondPart
37         FirstPart = SecondPart =>  0
38         FirstPart > SecondPart =>  1
39         FirstPart < SecondPart => -1
40 */
41 
42 int strcmp(const char *FirstPart, const char *SecondPart)
43 {
44     register int __res;
45     __asm__ __volatile__("cld	\n\t"
46                          "1:	\n\t"
47                          "lodsb	\n\t"
48                          "scasb	\n\t"
49                          "jne	2f	\n\t"
50                          "testb	%%al,	%%al	\n\t"
51                          "jne	1b	\n\t"
52                          "xorl	%%eax,	%%eax	\n\t"
53                          "jmp	3f	\n\t"
54                          "2:	\n\t"
55                          "movl	$1,	%%eax	\n\t"
56                          "jl	3f	\n\t"
57                          "negl	%%eax	\n\t"
58                          "3:	\n\t"
59                          : "=a"(__res)
60                          : "D"(FirstPart), "S"(SecondPart)
61                          :);
62     return __res;
63 }
64 
65 char *strncpy(char *dst, const char *src, long count)
66 {
67     __asm__ __volatile__("cld	\n\t"
68                          "1:	\n\t"
69                          "decq	%2	\n\t"
70                          "js	2f	\n\t"
71                          "lodsb	\n\t"
72                          "stosb	\n\t"
73                          "testb	%%al,	%%al	\n\t"
74                          "jne	1b	\n\t"
75                          "rep	\n\t"
76                          "stosb	\n\t"
77                          "2:	\n\t"
78                          :
79                          : "S"(src), "D"(dst), "c"(count)
80                          : "ax", "memory");
81     return dst;
82 }
83 
84 long strncpy_from_user(char *dst, const char *src, unsigned long size)
85 {
86     if (!verify_area((uint64_t)src, size))
87         return 0;
88 
89     strncpy(dst, src, size);
90     return size;
91 }
92 
93 /**
94  * @brief 测量来自用户空间的字符串的长度,会检验地址空间是否属于用户空间
95  * @param src
96  * @param maxlen
97  * @return long
98  */
99 long strnlen_user(const char *src, unsigned long maxlen)
100 {
101 
102     unsigned long size = strlen(src);
103     // 地址不合法
104     if (!verify_area((uint64_t)src, size))
105         return 0;
106 
107     return size <= maxlen ? size : maxlen;
108 }
109 
110 /**
111  * @brief 拼接两个字符串(将src接到dest末尾)
112  *
113  * @param dest 目标串
114  * @param src 源串
115  * @return char*
116  */
117 char *strcat(char *dest, const char *src)
118 {
119     strcpy(dest + strlen(dest), src);
120     return dest;
121 }