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

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