Backport auf gcc 4.6
[hackover2013-badge-firmware.git] / core / libc / string.c
1 /*
2 * Software License Agreement (BSD License)
3 *
4 * Based on original stdio.c released by Atmel
5 * Copyright (c) 2008, Atmel Corporation
6 * All rights reserved.
7 *
8 * Modified by Roel Verdult, Copyright (c) 2010
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the copyright holders nor the
18 * names of its contributors may be used to endorse or promote products
19 * derived from this software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY
22 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
25 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
27 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
28 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 *
32 */
33
34 //------------------------------------------------------------------------------
35 // Headers
36 //------------------------------------------------------------------------------
37
38 #include <string.h>
39
40 //------------------------------------------------------------------------------
41 // Global Functions
42 //------------------------------------------------------------------------------
43
44 //------------------------------------------------------------------------------
45 /// Copies data from a source buffer into a destination buffer. The two buffers
46 /// must NOT overlap. Returns the destination buffer.
47 /// \param pDestination Destination buffer.
48 /// \param pSource Source buffer.
49 /// \param num Number of bytes to copy.
50 //------------------------------------------------------------------------------
51 void * memcpy(void *pDestination, const void *pSource, size_t num)
52 {
53 unsigned char *pByteDestination;
54 unsigned char *pByteSource;
55 unsigned int *pAlignedSource = (unsigned int *) pSource;
56 unsigned int *pAlignedDestination = (unsigned int *) pDestination;
57
58 // If num is more than 4 bytes, and both dest. and source are aligned,
59 // then copy dwords
60 if ((((unsigned int) pAlignedDestination & 0x3) == 0)
61 && (((unsigned int) pAlignedSource & 0x3) == 0)
62 && (num >= 4)) {
63
64 while (num >= 4) {
65
66 *pAlignedDestination++ = *pAlignedSource++;
67 num -= 4;
68 }
69 }
70
71 // Copy remaining bytes
72 pByteDestination = (unsigned char *) pAlignedDestination;
73 pByteSource = (unsigned char *) pAlignedSource;
74 while (num--) {
75
76 *pByteDestination++ = *pByteSource++;
77 }
78
79 return pDestination;
80 }
81
82 //------------------------------------------------------------------------------
83 /// Fills a memory region with the given value. Returns a pointer to the
84 /// memory region.
85 /// \param pBuffer Pointer to the start of the memory region to fill
86 /// \param value Value to fill the region with
87 /// \param num Size to fill in bytes
88 //------------------------------------------------------------------------------
89 void * memset(void *pBuffer, int value, size_t num)
90 {
91 unsigned char *pByteDestination;
92 unsigned int *pAlignedDestination = (unsigned int *) pBuffer;
93 unsigned int alignedValue = (value << 24) | (value << 16) | (value << 8) | value;
94
95 // Set words if possible
96 if ((((unsigned int) pAlignedDestination & 0x3) == 0) && (num >= 4)) {
97 while (num >= 4) {
98 *pAlignedDestination++ = alignedValue;
99 num -= 4;
100 }
101 }
102 // Set remaining bytes
103 pByteDestination = (unsigned char *) pAlignedDestination;
104 while (num--) {
105 *pByteDestination++ = value;
106 }
107 return pBuffer;
108 }
109
110 void* memmove(void *s1, const void *s2, size_t n)
111 {
112 char *s=(char*)s2, *d=(char*)s1;
113
114 if(d > s){
115 s+=n-1;
116 d+=n-1;
117 while(n){
118 *d--=*s--;
119 n--;
120 }
121 }else if(d < s)
122 while(n){
123 *d++=*s++;
124 n--;
125 }
126 return s1;
127 }
128
129 int memcmp(const void *av, const void *bv, size_t len)
130 {
131 const unsigned char *a = av;
132 const unsigned char *b = bv;
133 size_t i;
134
135 for (i=0; i<len; i++)
136 {
137 if (a[i] != b[i])
138 {
139 return (int)(a[i] - b[i]);
140 }
141 }
142 return 0;
143 }
144
145
146
147 //-----------------------------------------------------------------------------
148 /// Search a character in the given string.
149 /// Returns a pointer to the character location.
150 /// \param pString Pointer to the start of the string to search.
151 /// \param character The character to find.
152 //-----------------------------------------------------------------------------
153 char * strchr(const char *pString, int character)
154 {
155 char * p = (char *)pString;
156 char c = character & 0xFF;
157
158 while(*p != c) {
159 if (*p == 0) {
160 return 0;
161 }
162 p++;
163 }
164 return p;
165 }
166
167 //-----------------------------------------------------------------------------
168 /// Return the length of a given string
169 /// \param pString Pointer to the start of the string.
170 //-----------------------------------------------------------------------------
171 size_t strlen(const char *pString)
172 {
173 unsigned int length = 0;
174
175 while(*pString++ != 0) {
176 length++;
177 }
178 return length;
179 }
180
181
182 //-----------------------------------------------------------------------------
183 /// Search a character backword from the end of given string.
184 /// Returns a pointer to the character location.
185 /// \param pString Pointer to the start of the string to search.
186 /// \param character The character to find.
187 //-----------------------------------------------------------------------------
188 char * strrchr(const char *pString, int character)
189 {
190 char *p = 0;
191
192 while(*pString != 0) {
193 if (*pString++ == character) {
194 p = (char*)pString;
195 }
196 }
197 return p;
198 }
199
200 //-----------------------------------------------------------------------------
201 /// Copy from source string to destination string
202 /// Return a pointer to the destination string
203 /// \param pDestination Pointer to the destination string.
204 /// \param pSource Pointer to the source string.
205 //-----------------------------------------------------------------------------
206 char * strcpy(char *pDestination, const char *pSource)
207 {
208 char *pSaveDest = pDestination;
209
210 for(; (*pDestination = *pSource) != 0; ++pSource, ++pDestination);
211 return pSaveDest;
212 }
213
214 //-----------------------------------------------------------------------------
215 /// Compare the first specified bytes of 2 given strings
216 /// Return 0 if equals
217 /// Return >0 if 1st string > 2nd string
218 /// Return <0 if 1st string < 2nd string
219 /// \param pString1 Pointer to the start of the 1st string.
220 /// \param pString2 Pointer to the start of the 2nd string.
221 /// \param count Number of bytes that should be compared.
222 //-----------------------------------------------------------------------------
223 int strncmp(const char *pString1, const char *pString2, size_t count)
224 {
225 int r;
226
227 while(count) {
228 r = *pString1 - *pString2;
229 if (r == 0) {
230 if (*pString1 == 0) {
231 break;
232 }
233 pString1++;
234 pString2++;
235 count--;
236 continue;
237 }
238 return r;
239 }
240 return 0;
241 }
242
243 //-----------------------------------------------------------------------------
244 /// Copy the first number of bytes from source string to destination string
245 /// Return the pointer to the destination string.
246 /// \param pDestination Pointer to the start of destination string.
247 /// \param pSource Pointer to the start of the source string.
248 /// \param count Number of bytes that should be copied.
249 //-----------------------------------------------------------------------------
250 char * strncpy(char *pDestination, const char *pSource, size_t count)
251 {
252 char *pSaveDest = pDestination;
253
254 while (count) {
255 *pDestination = *pSource;
256 if (*pSource == 0) {
257 break;
258 }
259 pDestination++;
260 pSource++;
261 count--;
262 }
263 return pSaveDest;
264 }
265
266 // Following code is based on the BSD licensed code released by UoC
267 // Copyright (c) 1988 Regents of the University of California
268
269 int strcmp(const char *s1, const char *s2)
270 {
271 while (*s1 == *s2++)
272 if (*s1++ == 0)
273 return (0);
274 return (*(unsigned char *)s1 - *(unsigned char *)--s2);
275 }
276
277 char *strtok_r(char *s, const char *delim, char **last);
278
279 char *strtok(char *s, const char *delim)
280 {
281 static char *last;
282 return strtok_r(s, delim, &last);
283 }
284
285 char *strtok_r(char *s, const char *delim, char **last)
286 {
287 char *spanp;
288 int c, sc;
289 char *tok;
290
291
292 if (s == NULL && (s = *last) == NULL)
293 return (NULL);
294
295 /*
296 * Skip (span) leading delimiters (s += strspn(s, delim), sort of).
297 */
298 cont:
299 c = *s++;
300 for (spanp = (char *)delim; (sc = *spanp++) != 0;) {
301 if (c == sc)
302 goto cont;
303 }
304
305 if (c == 0) { /* no non-delimiter characters */
306 *last = NULL;
307 return (NULL);
308 }
309 tok = s - 1;
310
311 /*
312 * Scan token (scan for delimiters: s += strcspn(s, delim), sort of).
313 * Note that delim must have one NUL; we stop if we see that, too.
314 */
315 for (;;) {
316 c = *s++;
317 spanp = (char *)delim;
318 do {
319 if ((sc = *spanp++) == c) {
320 if (c == 0)
321 s = NULL;
322 else
323 s[-1] = 0;
324 *last = s;
325 return (tok);
326 }
327 } while (sc != 0);
328 }
329 /* NOTREACHED */
330 }
This page took 0.073336 seconds and 5 git commands to generate.