foo
[mdlife] / src / libc / string.c
1 #include <string.h>
2 #include <ctype.h>
3 #include <stdint.h>
4 #include <stddef.h>
5
6 void *memcpy(void *dest, const void *src, size_t n)
7 {
8         size_t i;
9         char *dptr = dest;
10         const char *sptr = src;
11         for(i=0; i<n; i++) {
12                 dptr[i] = sptr[i];
13         }
14
15         return dest;
16 }
17
18 void *memmove(void *dest, const void *src, size_t n)
19 {
20         int i;
21         char *dptr;
22         const char *sptr;
23
24         if(dest <= src) {
25                 /* forward copy */
26                 dptr = dest;
27                 sptr = src;
28                 for(i=0; i<n; i++) {
29                         *dptr++ = *sptr++;
30                 }
31         } else {
32                 /* backwards copy */
33                 dptr = (char*)dest + n - 1;
34                 sptr = (const char*)src + n - 1;
35                 for(i=0; i<n; i++) {
36                         *dptr-- = *sptr--;
37                 }
38         }
39
40         return dest;
41 }
42
43 int memcmp(void *aptr, void *bptr, size_t n)
44 {
45         int i, startoffs, diff;
46         uint32_t *a32, *b32;
47         unsigned char *a = aptr;
48         unsigned char *b = bptr;
49
50         a32 = (uint32_t*)((intptr_t)(a + 3) & 0xfffffffc);
51         b32 = (uint32_t*)((intptr_t)(b + 3) & 0xfffffffc);
52
53         /* if both are aligned the same way... */
54         if((startoffs = (unsigned char*)a32 - a) == (unsigned char*)b32 - b) {
55                 /* catch-up to the 32bit alignment */
56                 for(i=0; i<startoffs; i++) {
57                         if((diff = *a++ - *b++) != 0 || --n <= 0) {
58                                 return diff;
59                         }
60                 }
61
62                 /* compare 32bit at once */
63                 while(n >= 4) {
64                         if(*a32 != *b32) break;
65                         a32++;
66                         b32++;
67                         n -= 4;
68                 }
69
70                 /* update byte pointers to contine with the tail */
71                 a = (unsigned char*)a32;
72                 b = (unsigned char*)b32;
73         }
74
75         /* we're here both for the tail-end of same-alignment buffers, or for the
76          * whole length of mis-aligned buffers.
77          */
78         while(n-- > 0) {
79                 if((diff = *a++ - *b++) != 0) {
80                         return diff;
81                 }
82         }
83         return 0;
84 }
85
86 size_t strlen(const char *s)
87 {
88         size_t len = 0;
89         while(*s++) len++;
90         return len;
91 }
92
93 char *strchr(const char *s, int c)
94 {
95         while(*s) {
96                 if(*s == c) {
97                         return (char*)s;
98                 }
99                 s++;
100         }
101         return 0;
102 }
103
104 char *strrchr(const char *s, int c)
105 {
106         const char *ptr = s;
107
108         /* find the end */
109         while(*ptr) ptr++;
110
111         /* go back checking for c */
112         while(--ptr >= s) {
113                 if(*ptr == c) {
114                         return (char*)ptr;
115                 }
116         }
117         return 0;
118 }
119
120 char *strstr(const char *str, const char *substr)
121 {
122         while(*str) {
123                 const char *s1 = str;
124                 const char *s2 = substr;
125
126                 while(*s1 && *s1 == *s2) {
127                         s1++;
128                         s2++;
129                 }
130                 if(!*s2) {
131                         return (char*)str;
132                 }
133                 str++;
134         }
135         return 0;
136 }
137
138 char *strcasestr(const char *str, const char *substr)
139 {
140         while(*str) {
141                 const char *s1 = str;
142                 const char *s2 = substr;
143
144                 while(*s1 && tolower(*s1) == tolower(*s2)) {
145                         s1++;
146                         s2++;
147                 }
148                 if(!*s2) {
149                         return (char*)str;
150                 }
151                 str++;
152         }
153         return 0;
154 }
155
156 int strcmp(const char *s1, const char *s2)
157 {
158         while(*s1 && *s1 == *s2) {
159                 s1++;
160                 s2++;
161         }
162         return *s1 - *s2;
163 }
164
165 int strcasecmp(const char *s1, const char *s2)
166 {
167         while(*s1 && tolower(*s1) == tolower(*s2)) {
168                 s1++;
169                 s2++;
170         }
171         return tolower(*s1) - tolower(*s2);
172 }
173
174 int strncmp(const char *s1, const char *s2, int n)
175 {
176         if(n <= 0) return 0;
177
178         while(n-- > 0 && *s1 && *s2 && *s1 == *s2) {
179                 s1++;
180                 s2++;
181         }
182
183         if(n <= 0) return 0;
184         return *s1 - *s2;
185 }
186
187 int strncasecmp(const char *s1, const char *s2, int n)
188 {
189         if(n <= 0) return 0;
190
191         while(n-- > 0 && *s1 && *s2 && tolower(*s1) == tolower(*s2)) {
192                 s1++;
193                 s2++;
194         }
195
196         if(n <= 0) return 0;
197         return tolower(*s1) - tolower(*s2);
198 }
199
200 char *strcpy(char *dest, const char *src)
201 {
202         char *dptr = dest;
203         while((*dptr++ = *src++));
204         return dest;
205 }
206
207 char *strcat(char *dest, const char *src)
208 {
209         strcpy(dest + strlen(dest), src);
210         return dest;
211 }
212
213 char *strncpy(char *dest, const char *src, int n)
214 {
215         char *dptr = dest;
216         while(n-- > 0 && (*dptr++ = *src++));
217         return dest;
218 }