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