blob: ca12b9047f4f7baafbd84ba92bf7f1fff90296e6 [file] [log] [blame]
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -07001/* string.c - common string routines */
2
3/*
4 * Copyright (c) 2014 Wind River Systems, Inc.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
8 *
9 * 1) Redistributions of source code must retain the above copyright notice,
10 * this list of conditions and the following disclaimer.
11 *
12 * 2) Redistributions in binary form must reproduce the above copyright notice,
13 * this list of conditions and the following disclaimer in the documentation
14 * and/or other materials provided with the distribution.
15 *
16 * 3) Neither the name of Wind River Systems nor the names of its contributors
17 * may be used to endorse or promote products derived from this software without
18 * specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
24 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#include <string.h>
34
35/*******************************************************************************
36*
37* strcpy - copy a string
38*
39* RETURNS: pointer to destination buffer <d>
40*/
41
42char *strcpy(char *restrict d, const char *restrict s)
43{
44 char *dest = d;
45
46 while (*s != '\0') {
47 *d = *s;
48 d++;
49 s++;
50 }
51
52 *d = '\0';
53
54 return dest;
55}
56
57/*******************************************************************************
58*
59* strncpy - copy part of a string
60*
61* RETURNS: pointer to destination buffer <d>
62*/
63
64char *strncpy(char *restrict d, const char *restrict s, size_t n)
65{
66 char *dest = d;
67
68 while ((n > 0) && *s != '\0') {
69 *d = *s;
70 s++;
71 d++;
72 n--;
73 }
74
75 while (n > 0) {
76 *d = '\0';
Peter Mitsis7637d812015-04-28 10:10:42 -040077 d++;
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -070078 n--;
79 }
80
81 return dest;
82}
83
84/*******************************************************************************
85*
86* strchr - string scanning operation
87*
88* RETURNS: pointer to 1st instance of found byte, or NULL if not found
89*/
90
91char *strchr(const char *s, int c)
92{
93 char tmp = (char) c;
94
95 while ((*s != tmp) && (*s != '\0'))
96 s++;
97
98 return (*s == tmp) ? (char *) s : NULL;
99}
100
101/*******************************************************************************
102*
103* strlen - get string length
104*
105* RETURNS: number of bytes in string <s>
106*/
107
108size_t strlen(const char *s)
109{
110 size_t n = 0;
111
112 while (*s != '\0') {
113 s++;
114 n++;
115 }
116
117 return n;
118}
119
120/*******************************************************************************
121*
122* strcmp - compare two strings
123*
124* RETURNS: negative # if <s1> < <s2>, 0 if <s1> == <s2>, else positive #
125*/
126
127int strcmp(const char *s1, const char *s2)
128{
129 while ((*s1 == *s2) && (*s1 != '\0')) {
130 s1++;
131 s2++;
132 }
133
134 return *s1 - *s2;
135}
136
137/*******************************************************************************
138*
139* strncmp - compare part of two strings
140*
141* RETURNS: negative # if <s1> < <s2>, 0 if <s1> == <s2>, else positive #
142*/
143
144int strncmp(const char *s1, const char *s2, size_t n)
145{
146 while ((n > 0) && (*s1 == *s2) && (*s1 != '\0')) {
147 s1++;
148 s2++;
149 n--;
150 }
151
152 return (n == 0) ? 0 : (*s1 - *s2);
153}
154
155/*******************************************************************************
156*
Johan Hedberg7fc1c372015-05-19 11:36:53 +0300157* memcmp - compare two memory areas
158*
159* RETURNS: negative # if <m1> < <m2>, 0 if <m1> == <m2>, else positive #
160*/
161
162int memcmp(const void *m1, const void *m2, size_t n)
163{
164 const char *c1 = m1;
165 const char *c2 = m2;
166
Johan Hedbergafffab12015-05-19 20:43:30 +0300167 if (!n)
168 return 0;
169
170 while ((--n > 0) && (*c1 == *c2)) {
Johan Hedberg7fc1c372015-05-19 11:36:53 +0300171 c1++;
172 c2++;
Johan Hedberg7fc1c372015-05-19 11:36:53 +0300173 }
174
175 return *c1 - *c2;
176}
177
178/*******************************************************************************
179*
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700180* memmove - copy bytes in memory with overlapping areas
181*
182* RETURNS: pointer to destination buffer <d>
183*/
184
185void *memmove(void *d, const void *s, size_t n)
186{
187 char *dest = d;
188 const char *src = s;
189
190 if ((size_t) (d - s) < n) {
191 /*
192 * The <src> buffer overlaps with the start of the <dest> buffer.
193 * Copy backwards to prevent the premature corruption of <src>.
194 */
195
196 while (n > 0) {
197 n--;
198 dest[n] = src[n];
199 }
200 } else {
201 /* It is safe to perform a forward-copy */
202 while (n > 0) {
203 *dest = *src;
204 dest++;
205 src++;
206 n--;
207 }
208 }
209
210 return d;
211}
212
213/*******************************************************************************
214*
215* memcpy - copy bytes in memory
216*
Allan Stephensb52a09f2015-05-25 13:50:16 -0400217* RETURNS: pointer to start of destination buffer
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700218*/
219
220void *memcpy(void *restrict d, const void *restrict s, size_t n)
221{
Allan Stephensb52a09f2015-05-25 13:50:16 -0400222 /* attempt word-sized copying only if buffers have identical alignment */
223
224 unsigned char *d_byte = (unsigned char *)d;
225 const unsigned char *s_byte = (const unsigned char *)s;
226
227 if ((((unsigned int)d ^ (unsigned int)s_byte) & 0x3) == 0) {
228
229 /* do byte-sized copying until word-aligned or finished */
230
231 while (((unsigned int)d_byte) & 0x3) {
232 if (n == 0) {
233 return d;
234 }
235 *(d_byte++) = *(s_byte++);
236 n--;
237 };
238
239 /* do word-sized copying as long as possible */
240
241 unsigned int *d_word = (unsigned int *)d_byte;
242 const unsigned int *s_word = (const unsigned int *)s_byte;
243
244 while (n >= sizeof(unsigned int)) {
245 *(d_word++) = *(s_word++);
246 n -= sizeof(unsigned int);
247 }
248
249 d_byte = (unsigned char *)d_word;
250 s_byte = (unsigned char *)s_word;
251 }
252
253 /* do byte-sized copying until finished */
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700254
255 while (n > 0) {
Allan Stephensb52a09f2015-05-25 13:50:16 -0400256 *(d_byte++) = *(s_byte++);
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700257 n--;
258 }
259
260 return d;
261}
262
263/*******************************************************************************
264*
265* memset - set bytes in memory
266*
Allan Stephensb52a09f2015-05-25 13:50:16 -0400267* RETURNS: pointer to start of buffer
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700268*/
269
Allan Stephensb52a09f2015-05-25 13:50:16 -0400270void *memset(void *buf, int c, size_t n)
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700271{
Allan Stephensb52a09f2015-05-25 13:50:16 -0400272 /* do byte-sized initialization until word-aligned or finished */
273
274 unsigned char *d_byte = (unsigned char *)buf;
275 unsigned char c_byte = (unsigned char)c;
276
277 while (((unsigned int)d_byte) & 0x3) {
278 if (n == 0) {
279 return buf;
280 }
281 *(d_byte++) = c_byte;
282 n--;
283 };
284
285 /* do word-sized initialization as long as possible */
286
287 unsigned int *d_word = (unsigned int *)d_byte;
288 unsigned int c_word = (unsigned int)(unsigned char)c;
289
290 c_word |= c_word << 8;
291 c_word |= c_word << 16;
292
293 while (n >= sizeof(unsigned int)) {
294 *(d_word++) = c_word;
295 n -= sizeof(unsigned int);
296 }
297
298 /* do byte-sized initialization until finished */
299
300 d_byte = (unsigned char *)d_word;
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700301
302 while (n > 0) {
Allan Stephensb52a09f2015-05-25 13:50:16 -0400303 *(d_byte++) = c_byte;
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700304 n--;
305 }
306
Allan Stephensb52a09f2015-05-25 13:50:16 -0400307 return buf;
Inaky Perez-Gonzalez8ddf82c2015-04-10 16:44:37 -0700308}