Usermode/libc - Changes to get NASM/irssi/bash ... compiling
[tpg/acess2.git] / Usermode / Libraries / libc.so_src / string.c
1 /*
2  * AcessOS Basic C Library
3  * string.c
4  */
5 #include <acess/sys.h>
6 #include <stdlib.h>
7 #include <stdio.h>
8 #include <ctype.h>
9 #include "lib.h"
10
11 /**
12  * \fn EXPORT int strcmp(const char *s1, const char *s2)
13  * \brief Compare two strings
14  */
15 EXPORT int strcmp(const char *s1, const char *s2)
16 {
17         while(*s1 == *s2 && *s1 != '\0' && *s2 != '\0') {
18                 s1++; s2++;
19         }
20         return (int)*s1 - (int)*s2;
21 }
22
23 /**
24  * \fn EXPORT int strncmp(const char *s1, const char *s2)
25  * \brief Compare two strings
26  */
27 EXPORT int strncmp(const char *s1, const char *s2, size_t n)
28 {
29         if( n == 0 )    return 0;
30         while(n -- && *s1 == *s2 && *s1 != '\0' && *s2 != '\0') {
31                 s1++; s2++;
32         }
33         return (int)*s1 - (int)*s2;
34 }
35
36 EXPORT int strcasecmp(const char *s1, const char *s2)
37 {
38          int    rv;
39         while( (rv = toupper(*s1) - toupper(*s2)) == 0 && *s1 != '\0' && *s2 != '\0' ) {
40                 s1++; s2++;
41         }
42         return rv;
43 }
44
45 EXPORT int strncasecmp(const char *s1, const char *s2, size_t n)
46 {
47          int    rv = 0;
48         if( n == 0 )    return 0;
49         while(n -- && (rv = toupper(*s1) - toupper(*s2)) == 0 && *s1 != '\0' && *s2 != '\0') {
50                 s1++; s2++;
51         }
52         return rv;
53 }
54
55 /**
56  * \fn EXPORT char *strcpy(char *dst, const char *src)
57  * \brief Copy a string to another
58  */
59 EXPORT char *strcpy(char *dst, const char *src)
60 {
61         char *_dst = dst;
62         while(*src) {
63                 *dst = *src;
64                 src++; dst++;
65         }
66         *dst = '\0';
67         return _dst;
68 }
69
70 /**
71  * \fn EXPORT char *strncpy(char *dst, const char *src)
72  * \brief Copy at most \a num characters from \a src to \a dst
73  * \return \a dst
74  */
75 EXPORT char *strncpy(char *dst, const char *src, size_t num)
76 {
77         char *to = dst;
78         while(*src && num--)    *to++ = *src++;
79         *to = '\0';
80         return dst;
81 }
82
83 /**
84  * \fn EXPORT char *strcat(char *dst, const char *src)
85  * \brief Append a string onto another
86  */
87 EXPORT char *strcat(char *dst, const char *src)
88 {
89         char    *to = dst;
90         // Find the end
91         while(*to)      to++;
92         // Copy
93         while(*src)     *to++ = *src++;
94         // End string
95         *to = '\0';
96         return dst;
97 }
98
99 /**
100  * \brief Get the length of a string
101  */
102 EXPORT size_t strlen(const char *str)
103 {
104         size_t  retval;
105         for(retval = 0; *str != '\0'; str++, retval++);
106         return retval;
107 }
108
109 /**
110  * \brief Get the length of a string, with a maximum of \a maxlen
111  * 
112  * Gets the length of a string (excluding the terminating \0 byte)
113  */
114 EXPORT size_t strnlen(const char *str, size_t maxlen)
115 {
116         size_t  len;
117         for( len = 0; maxlen -- && *str; str ++, len ++ );
118         return len;
119 }
120
121 /**
122  * \fn EXPORT char *strdup(const char *str)
123  * \brief Duplicate a string using heap memory
124  * \note Defined in POSIX Spec, not C spec
125  */
126 EXPORT char *strdup(const char *str)
127 {
128         size_t  len = strlen(str);
129         char    *ret = malloc(len+1);
130         if(ret == NULL) return NULL;
131         strcpy(ret, str);
132         return ret;
133 }
134
135 /**
136  * \fn EXPORT char *strndup(const char *str, size_t maxlen)
137  * \brief Duplicate a string into the heap with a maximum length
138  * \param str   Input string buffer
139  * \param maxlen        Maximum valid size of the \a str buffer
140  * \return Heap string with the same value of \a str
141  */
142 EXPORT char *strndup(const char *str, size_t maxlen)
143 {
144         size_t  len;
145         char    *ret;
146         for( len = 0; len < maxlen && str[len]; len ++) ;
147         ret = malloc( len + 1);
148         memcpy( ret, str, len );
149         ret[len] = '\0';
150         return ret;
151 }
152
153 /**
154  * \fn EXPORT char *strchr(char *str, int character)
155  * \brief Locate a character in a string
156  */
157 EXPORT char *strchr(const char *str, int character)
158 {
159         for(;*str;str++)
160         {
161                 if(*str == character)
162                         return (char*)str;
163         }
164         return NULL;
165 }
166
167 /**
168  * \fn EXPORT char *strrchr(char *str, int character)
169  * \brief Locate the last occurance of a character in a string
170  */
171 EXPORT char *strrchr(const char *str, int character)
172 {
173          int    i;
174         i = strlen(str)-1;
175         while(i--)
176         {
177                 if(str[i] == character)
178                         return (void*)&str[i];
179         }
180         return NULL;
181 }
182
183 /**
184  * \fn EXPORT char *strstr(char *str1, const char *str2)
185  * \brief Search a \a str1 for the first occurance of \a str2
186  */
187 EXPORT char *strstr(char *str1, const char *str2)
188 {
189         const char      *test = str2;
190         
191         for(;*str1;str1++)
192         {
193                 if(*test == '\0')       return str1;
194                 if(*str1 == *test)      test++;
195                 else    test = str2;
196         }
197         return NULL;
198 }
199
200 // --- Memory ---
201 /**
202  * \fn EXPORT void *memset(void *dest, int val, size_t num)
203  * \brief Clear memory with the specified value
204  */
205 EXPORT void *memset(void *dest, int val, size_t num)
206 {
207         unsigned char *p = dest;
208         while(num--)    *p++ = val;
209         return dest;
210 }
211
212 /**
213  * \fn EXPORT void *memcpy(void *dest, const void *src, size_t count)
214  * \brief Copy one memory area to another
215  */
216 EXPORT void *memcpy(void *dest, const void *src, size_t count)
217 {
218     char *sp = (char *)src;
219     char *dp = (char *)dest;
220     for(;count--;) *dp++ = *sp++;
221     return dest;
222 }
223
224 /**
225  * \fn EXPORT void *memmove(void *dest, const void *src, size_t count)
226  * \brief Copy data in memory, avoiding overlap problems
227  */
228 EXPORT void *memmove(void *dest, const void *src, size_t count)
229 {
230     char *sp = (char *)src;
231     char *dp = (char *)dest;
232         // Check if corruption will happen
233         if( (intptr_t)dest > (intptr_t)src && (intptr_t)dest < (intptr_t)src+count )
234                 for(;count--;) dp[count] = sp[count];
235         else
236         for(;count--;) *dp++ = *sp++;
237     return dest;
238 }
239
240 /**
241  * \fn EXPORT int memcmp(const void *mem1, const void *mem2, size_t count)
242  * \brief Compare two regions of memory
243  * \param mem1  Region 1
244  * \param mem2  Region 2
245  * \param count Number of bytes to check
246  */
247 EXPORT int memcmp(const void *mem1, const void *mem2, size_t count)
248 {
249         while(count--)
250         {
251                 if( *(unsigned char*)mem1 != *(unsigned char*)mem2 )
252                         return *(unsigned char*)mem1 - *(unsigned char*)mem2;
253                 mem1 ++;
254                 mem2 ++;
255         }
256         return 0;
257 }
258
259 /**
260  * \fn EXPORT void *memchr(void *ptr, int value, size_t num)
261  * \brief Locates the first occurence of \a value starting at \a ptr
262  * \param ptr   Starting memory location
263  * \param value Value to find
264  * \param num   Size of memory area to check
265  */
266 EXPORT void *memchr(const void *ptr, int value, size_t num)
267 {
268         while(num--)
269         {
270                 if( *(const unsigned char*)ptr == (unsigned char)value )
271                         return (void*)ptr;
272                 ptr ++;
273         }
274         return NULL;
275 }
276
277 EXPORT size_t strcspn(const char *haystack, const char *reject)
278 {
279         size_t  ret = 0;
280          int    i;
281         while( *haystack )
282         {
283                 for( i = 0; reject[i] && reject[i] == *haystack; i ++ );
284
285                 if( reject[i] ) return ret;
286                 ret ++;
287         }
288         return ret;
289 }
290
291 EXPORT size_t strspn(const char *haystack, const char *accept)
292 {
293         size_t  ret = 0;
294          int    i;
295         while( *haystack )
296         {
297                 for( i = 0; accept[i] && accept[i] == *haystack; i ++ );
298
299                 if( !accept[i] )        return ret;
300                 ret ++;
301         }
302         return ret;
303 }

UCC git Repository :: git.ucc.asn.au