blob: 0d789a0ea7fb79205211905384de700ec18ecd83 [file] [log] [blame]
Harald Welted09829d2017-02-27 22:58:59 +01001/* ----------------------------------------------------------------------------
2 * ATMEL Microcontroller Software Support
3 * ----------------------------------------------------------------------------
4 * Copyright (c) 2008, Atmel Corporation
5 *
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are met:
10 *
11 * - Redistributions of source code must retain the above copyright notice,
12 * this list of conditions and the disclaimer below.
13 *
14 * Atmel's name may not be used to endorse or promote products derived from
15 * this software without specific prior written permission.
16 *
17 * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
20 * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
23 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
24 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
25 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
26 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 * ----------------------------------------------------------------------------
28 */
29
30//------------------------------------------------------------------------------
31/// \unit
32///
33/// !Purpose
34///
35/// Implementation of several methods defined in string.h, for reducing the
36/// memory footprint when using them (since the whole libc.o file gets included
37/// even when using a single method).
38///
39/// !Usage
40///
41/// Add string.c to the list of files to compile for the project. This will
42/// automatically replace standard libc methods by the custom ones.
43//------------------------------------------------------------------------------
44
45//------------------------------------------------------------------------------
46// Headers
47//------------------------------------------------------------------------------
48
49#include <string.h>
50
51//------------------------------------------------------------------------------
52// Global Functions
53//------------------------------------------------------------------------------
54
55//------------------------------------------------------------------------------
56/// Copies data from a source buffer into a destination buffer. The two buffers
57/// must NOT overlap. Returns the destination buffer.
58/// \param pDestination Destination buffer.
59/// \param pSource Source buffer.
60/// \param num Number of bytes to copy.
61//------------------------------------------------------------------------------
62void * memcpy(void *pDestination, const void *pSource, size_t num)
63{
Kévin Redon33d1eb72018-07-08 13:58:12 +020064 unsigned char *pByteDestination;
65 unsigned char *pByteSource;
66 unsigned int *pAlignedSource = (unsigned int *) pSource;
67 unsigned int *pAlignedDestination = (unsigned int *) pDestination;
Harald Welted09829d2017-02-27 22:58:59 +010068
Kévin Redon33d1eb72018-07-08 13:58:12 +020069 // If num is more than 4 bytes, and both dest. and source are aligned,
70 // then copy dwords
71 if ((((unsigned int) pAlignedDestination & 0x3) == 0)
72 && (((unsigned int) pAlignedSource & 0x3) == 0)
73 && (num >= 4)) {
Harald Welted09829d2017-02-27 22:58:59 +010074
Kévin Redon33d1eb72018-07-08 13:58:12 +020075 while (num >= 4) {
Harald Welted09829d2017-02-27 22:58:59 +010076
Kévin Redon33d1eb72018-07-08 13:58:12 +020077 *pAlignedDestination++ = *pAlignedSource++;
78 num -= 4;
79 }
80 }
Harald Welted09829d2017-02-27 22:58:59 +010081
Kévin Redon33d1eb72018-07-08 13:58:12 +020082 // Copy remaining bytes
83 pByteDestination = (unsigned char *) pAlignedDestination;
84 pByteSource = (unsigned char *) pAlignedSource;
85 while (num--) {
Harald Welted09829d2017-02-27 22:58:59 +010086
Kévin Redon33d1eb72018-07-08 13:58:12 +020087 *pByteDestination++ = *pByteSource++;
88 }
Harald Welted09829d2017-02-27 22:58:59 +010089
Kévin Redon33d1eb72018-07-08 13:58:12 +020090 return pDestination;
Harald Welted09829d2017-02-27 22:58:59 +010091}
92
93//------------------------------------------------------------------------------
94/// Fills a memory region with the given value. Returns a pointer to the
95/// memory region.
96/// \param pBuffer Pointer to the start of the memory region to fill
97/// \param value Value to fill the region with
98/// \param num Size to fill in bytes
99//------------------------------------------------------------------------------
100void * memset(void *pBuffer, int value, size_t num)
101{
Kévin Redon33d1eb72018-07-08 13:58:12 +0200102 unsigned char *pByteDestination;
103 unsigned int *pAlignedDestination = (unsigned int *) pBuffer;
104 unsigned int alignedValue = (value << 24) | (value << 16) | (value << 8) | value;
Harald Welted09829d2017-02-27 22:58:59 +0100105
Kévin Redon33d1eb72018-07-08 13:58:12 +0200106 // Set words if possible
107 if ((((unsigned int) pAlignedDestination & 0x3) == 0) && (num >= 4)) {
108 while (num >= 4) {
109 *pAlignedDestination++ = alignedValue;
110 num -= 4;
111 }
112 }
113 // Set remaining bytes
114 pByteDestination = (unsigned char *) pAlignedDestination;
115 while (num--) {
116 *pByteDestination++ = value;
117 }
118 return pBuffer;
Harald Welted09829d2017-02-27 22:58:59 +0100119}
120
121//-----------------------------------------------------------------------------
122/// Search a character in the given string.
123/// Returns a pointer to the character location.
124/// \param pString Pointer to the start of the string to search.
125/// \param character The character to find.
126//-----------------------------------------------------------------------------
127char * strchr(const char *pString, int character)
128{
Kévin Redon33d1eb72018-07-08 13:58:12 +0200129 char * p = (char *)pString;
130 char c = character & 0xFF;
Harald Welted09829d2017-02-27 22:58:59 +0100131
Kévin Redon33d1eb72018-07-08 13:58:12 +0200132 while(*p != c) {
133 if (*p == 0) {
134 return 0;
135 }
136 p++;
137 }
138 return p;
Harald Welted09829d2017-02-27 22:58:59 +0100139}
140
141//-----------------------------------------------------------------------------
142/// Return the length of a given string
143/// \param pString Pointer to the start of the string.
144//-----------------------------------------------------------------------------
145size_t strlen(const char *pString)
146{
Kévin Redon33d1eb72018-07-08 13:58:12 +0200147 unsigned int length = 0;
Harald Welted09829d2017-02-27 22:58:59 +0100148
Kévin Redon33d1eb72018-07-08 13:58:12 +0200149 while(*pString++ != 0) {
150 length++;
151 }
152 return length;
Harald Welted09829d2017-02-27 22:58:59 +0100153}
154
155
156//-----------------------------------------------------------------------------
157/// Search a character backword from the end of given string.
158/// Returns a pointer to the character location.
159/// \param pString Pointer to the start of the string to search.
160/// \param character The character to find.
161//-----------------------------------------------------------------------------
162char * strrchr(const char *pString, int character)
163{
Kévin Redon33d1eb72018-07-08 13:58:12 +0200164 char *p = 0;
Harald Welted09829d2017-02-27 22:58:59 +0100165
Kévin Redon33d1eb72018-07-08 13:58:12 +0200166 while(*pString != 0) {
167 if (*pString++ == character) {
168 p = (char*)pString;
169 }
170 }
171 return p;
Harald Welted09829d2017-02-27 22:58:59 +0100172}
173
174//-----------------------------------------------------------------------------
175/// Copy from source string to destination string
176/// Return a pointer to the destination string
177/// \param pDestination Pointer to the destination string.
178/// \param pSource Pointer to the source string.
179//-----------------------------------------------------------------------------
180char * strcpy(char *pDestination, const char *pSource)
181{
Kévin Redon33d1eb72018-07-08 13:58:12 +0200182 char *pSaveDest = pDestination;
Harald Welted09829d2017-02-27 22:58:59 +0100183
Kévin Redon33d1eb72018-07-08 13:58:12 +0200184 for(; (*pDestination = *pSource) != 0; ++pSource, ++pDestination);
185 return pSaveDest;
Harald Welted09829d2017-02-27 22:58:59 +0100186}
187
188//-----------------------------------------------------------------------------
189/// Compare the first specified bytes of 2 given strings
190/// Return 0 if equals
191/// Return >0 if 1st string > 2nd string
192/// Return <0 if 1st string < 2nd string
193/// \param pString1 Pointer to the start of the 1st string.
194/// \param pString2 Pointer to the start of the 2nd string.
195/// \param count Number of bytes that should be compared.
196//-----------------------------------------------------------------------------
197int strncmp(const char *pString1, const char *pString2, size_t count)
198{
Kévin Redon33d1eb72018-07-08 13:58:12 +0200199 int r;
Harald Welted09829d2017-02-27 22:58:59 +0100200
Kévin Redon33d1eb72018-07-08 13:58:12 +0200201 while(count) {
202 r = *pString1 - *pString2;
203 if (r == 0) {
204 if (*pString1 == 0) {
205 break;
206 }
207 pString1++;
208 pString2++;
209 count--;
210 continue;
211 }
212 return r;
213 }
214 return 0;
Harald Welted09829d2017-02-27 22:58:59 +0100215}
216
217//-----------------------------------------------------------------------------
218/// Copy the first number of bytes from source string to destination string
219/// Return the pointer to the destination string.
220/// \param pDestination Pointer to the start of destination string.
221/// \param pSource Pointer to the start of the source string.
222/// \param count Number of bytes that should be copied.
223//-----------------------------------------------------------------------------
224char * strncpy(char *pDestination, const char *pSource, size_t count)
225{
Kévin Redon33d1eb72018-07-08 13:58:12 +0200226 char *pSaveDest = pDestination;
Harald Welted09829d2017-02-27 22:58:59 +0100227
Kévin Redon33d1eb72018-07-08 13:58:12 +0200228 while (count) {
229 *pDestination = *pSource;
230 if (*pSource == 0) {
231 break;
232 }
233 pDestination++;
234 pSource++;
235 count--;
236 }
237 return pSaveDest;
Harald Welted09829d2017-02-27 22:58:59 +0100238}
239