source: mainline/uspace/lib/compat/string.c@ 3daba9de

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 3daba9de was f5c8046, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 14 years ago

add basics of libcompat

  • Property mode set to 100644
File size: 5.5 KB
Line 
1/*
2 * Copyright (c) 2011 Jiri Zarevucky
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29
30#include "string.h"
31#include "assert.h"
32#include <str_error.h>
33
34/**
35 * Defined for convenience. Returns pointer to the terminating nul character.
36 */
37static char *strzero(const char *s) {
38 for (; *s != '\0'; ++ s) ;;
39 return (char*) s;
40}
41
42char *strcpy(char *dest, const char *src) {
43 assert (dest != NULL);
44 assert (src != NULL);
45
46 return (char *) memcpy(dest, src, strlen(src) + 1);
47}
48
49char *strncpy(char *dest, const char *src, size_t n) {
50 assert (dest != NULL);
51 assert (src != NULL);
52
53 size_t len = strlen(src) + 1;
54 memcpy(dest, src, (n < len ? n : len));
55 if (n > len) {
56 /* the standard requires that nul characters
57 are appended to the length of n */
58 memset(dest + len, '\0', n - len);
59 }
60 return dest;
61}
62
63char *strcat(char *dest, const char *src) {
64 assert (dest != NULL);
65 assert (src != NULL);
66
67 strcpy(strzero(dest), src);
68 return dest;
69}
70
71char *strncat(char *dest, const char *src, size_t n) {
72 assert (dest != NULL);
73 assert (src != NULL);
74
75 char *zeroptr = strncpy(strzero(dest), src, n);
76 /* strncpy doesn't append the nul terminator */
77 zeroptr[n] = '\0';
78 return dest;
79}
80
81int memcmp(const void *mem1, const void *mem2, size_t n) {
82 assert (mem1 != NULL);
83 assert (mem2 != NULL);
84
85 const unsigned char *s1 = mem1;
86 const unsigned char *s2 = mem2;
87
88 while (n != 0 && *s1 == *s2) {
89 n --;
90 s1 ++;
91 s2 ++;
92 }
93
94 return (n == 0) ? 0 : (*s2 - *s1);
95}
96
97int strcmp(const char *s1, const char *s2) {
98 assert (s1 != NULL);
99 assert (s2 != NULL);
100
101 return strncmp(s1, s2, STR_NO_LIMIT);
102}
103
104int strncmp(const char *s1, const char *s2, size_t n) {
105 assert (s1 != NULL);
106 assert (s2 != NULL);
107
108 while (n != 0 && *s1 == *s2 && *s1 != '\0') {
109 n --;
110 s1 ++;
111 s2 ++;
112 }
113
114 return (n == 0) ? 0 : (*s2 - *s1);
115}
116
117/* currently ignores locale and just calls strcmp */
118int strcoll(const char *s1, const char *s2) {
119 assert (s1 != NULL);
120 assert (s2 != NULL);
121
122 return strcmp(s1, s2);
123}
124
125/* strcoll is stub, so this just makes a copy */
126size_t strxfrm(char *s1, const char *s2, size_t n) {
127 assert (s1 != NULL || n == 0);
128 assert (s2 != NULL);
129
130 size_t len = strlen(s2);
131
132 if (n > len)
133 strcpy(s1, s2);
134
135 return len;
136}
137
138void *memchr(const void *mem, int c, size_t n) {
139 assert (mem != NULL);
140
141 const unsigned char *s = mem;
142
143 for (; n != 0; -- n) {
144 if (*s == (unsigned char) c) {
145 return (void *) s;
146 }
147 s ++;
148 }
149 return NULL;
150}
151
152
153char *strchr(const char *s, int c) {
154 assert (s != NULL);
155
156 if (c == '\0')
157 return strzero(s);
158
159 while (*s != (char) c) {
160 if (*s == '\0')
161 return NULL;
162
163 s ++;
164 }
165 return (char *) s;
166}
167
168char *strrchr(const char *s, int c) {
169 assert (s != NULL);
170
171 const char *ptr;
172
173 for (ptr = strzero(s); ptr >= s; -- ptr) {
174 if (*ptr == (char) c)
175 return (char *) ptr;
176 }
177 return NULL;
178}
179
180/* the same as strpbrk, except it returns pointer to the nul terminator
181 if no occurence is found */
182static char *strpbrk_null(const char *s1, const char *s2) {
183 while (!strchr(s2, *s1))
184 ++ s1;
185 return (char *) s1;
186}
187
188size_t strcspn(const char *s1, const char *s2) {
189 assert (s1 != NULL);
190 assert (s2 != NULL);
191
192 char *ptr = strpbrk_null(s1, s2);
193 return (size_t) (ptr - s1);
194}
195
196char *strpbrk(const char *s1, const char *s2) {
197 assert (s1 != NULL);
198 assert (s2 != NULL);
199
200 char *ptr = strpbrk_null(s1, s2);
201 return (*ptr == '\0') ? NULL : ptr;
202}
203
204size_t strspn(const char *s1, const char *s2) {
205 assert (s1 != NULL);
206 assert (s2 != NULL);
207
208 const char *ptr;
209 for (ptr = s1; *ptr != '\0'; ++ ptr) {
210 if (!strchr(s2, *ptr))
211 break;
212 }
213 return ptr - s1;
214}
215
216/* returns true if s2 is a prefix of s1 */
217static bool begins_with(const char *s1, const char *s2) {
218 for (; *s1 == *s2 && *s2 != '\0'; ++ s1, ++ s2) ;;
219 return *s2 == '\0';
220}
221
222char *strstr(const char *s1, const char *s2) {
223 assert (s1 != NULL);
224 assert (s2 != NULL);
225
226 if (*s2 == '\0')
227 return (char *) s1;
228
229 while (*s1 != '\0') {
230 s1 = strchr(s1, *s2);
231
232 if (s1 == NULL)
233 return NULL;
234
235 if (begins_with(s1, s2))
236 return (char *) s1;
237
238 s1 ++;
239 }
240
241 return NULL;
242}
243
244char *strerror(int errnum) {
245 return (char *) str_error (-errnum);
246}
247
248size_t strlen(const char *s) {
249 assert (s != NULL);
250 return (size_t) (strzero(s) - s);
251}
252
Note: See TracBrowser for help on using the repository browser.