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