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