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

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