1 /*
2 * linux/lib/string.c
3 *
4 * Copyright (C) 1991, 1992 Linus Torvalds
5 */
6
7 #include <xen/types.h>
8 #include <xen/string.h>
9 #include <xen/ctype.h>
10
11 #ifndef __HAVE_ARCH_STRNICMP
12 /**
13 * strnicmp - Case insensitive, length-limited string comparison
14 * @s1: One string
15 * @s2: The other string
16 * @len: the maximum number of characters to compare
17 */
strnicmp(const char * s1,const char * s2,size_t len)18 int strnicmp(const char *s1, const char *s2, size_t len)
19 {
20 /* Yes, Virginia, it had better be unsigned */
21 unsigned char c1, c2;
22
23 c1 = 0; c2 = 0;
24 if (len) {
25 do {
26 c1 = *s1; c2 = *s2;
27 s1++; s2++;
28 if (!c1)
29 break;
30 if (!c2)
31 break;
32 if (c1 == c2)
33 continue;
34 c1 = tolower(c1);
35 c2 = tolower(c2);
36 if (c1 != c2)
37 break;
38 } while (--len);
39 }
40 return (int)c1 - (int)c2;
41 }
42 #endif
43
44 #ifndef __HAVE_ARCH_STRCASECMP
45 int (strcasecmp)(const char *s1, const char *s2)
46 {
47 int c1, c2;
48
49 do
50 {
51 c1 = tolower(*s1++);
52 c2 = tolower(*s2++);
53 } while ( c1 == c2 && c1 != 0 );
54
55 return c1 - c2;
56 }
57 #endif
58
59 #ifndef __HAVE_ARCH_STRLCPY
60 /**
61 * strlcpy - Copy a %NUL terminated string into a sized buffer
62 * @dest: Where to copy the string to
63 * @src: Where to copy the string from
64 * @size: size of destination buffer
65 *
66 * Compatible with *BSD: the result is always a valid
67 * NUL-terminated string that fits in the buffer (unless,
68 * of course, the buffer size is zero). It does not pad
69 * out the result like strncpy() does.
70 */
strlcpy(char * dest,const char * src,size_t size)71 size_t strlcpy(char *dest, const char *src, size_t size)
72 {
73 size_t ret = strlen(src);
74
75 if (size) {
76 size_t len = (ret >= size) ? size-1 : ret;
77 memcpy(dest, src, len);
78 dest[len] = '\0';
79 }
80 return ret;
81 }
82 EXPORT_SYMBOL(strlcpy);
83 #endif
84
85 #ifndef __HAVE_ARCH_STRLCAT
86 /**
87 * strlcat - Append a %NUL terminated string into a sized buffer
88 * @dest: Where to copy the string to
89 * @src: Where to copy the string from
90 * @size: size of destination buffer
91 *
92 * Compatible with *BSD: the result is always a valid
93 * NUL-terminated string that fits in the buffer (unless,
94 * of course, the buffer size is zero).
95 */
strlcat(char * dest,const char * src,size_t size)96 size_t strlcat(char *dest, const char *src, size_t size)
97 {
98 size_t slen = strlen(src);
99 size_t dlen = strnlen(dest, size);
100 char *p = dest + dlen;
101
102 while ((p - dest) < size)
103 if ((*p++ = *src++) == '\0')
104 break;
105
106 if (dlen < size)
107 *(p-1) = '\0';
108
109 return slen + dlen;
110 }
111 EXPORT_SYMBOL(strlcat);
112 #endif
113
114 #ifndef __HAVE_ARCH_STRCMP
115 /**
116 * strcmp - Compare two strings
117 * @cs: One string
118 * @ct: Another string
119 */
120 int (strcmp)(const char *cs, const char *ct)
121 {
122 register signed char __res;
123
124 while (1) {
125 if ((__res = *cs - *ct++) != 0 || !*cs++)
126 break;
127 }
128
129 return __res;
130 }
131 #endif
132
133 #ifndef __HAVE_ARCH_STRNCMP
134 /**
135 * strncmp - Compare two length-limited strings
136 * @cs: One string
137 * @ct: Another string
138 * @count: The maximum number of bytes to compare
139 */
140 int (strncmp)(const char *cs, const char *ct, size_t count)
141 {
142 register signed char __res = 0;
143
144 while (count) {
145 if ((__res = *cs - *ct++) != 0 || !*cs++)
146 break;
147 count--;
148 }
149
150 return __res;
151 }
152 #endif
153
154 #ifndef __HAVE_ARCH_STRCHR
155 /**
156 * strchr - Find the first occurrence of a character in a string
157 * @s: The string to be searched
158 * @c: The character to search for
159 */
160 char *(strchr)(const char *s, int c)
161 {
162 for(; *s != (char) c; ++s)
163 if (*s == '\0')
164 return NULL;
165 return (char *) s;
166 }
167 #endif
168
169 #ifndef __HAVE_ARCH_STRRCHR
170 /**
171 * strrchr - Find the last occurrence of a character in a string
172 * @s: The string to be searched
173 * @c: The character to search for
174 */
175 char *(strrchr)(const char *s, int c)
176 {
177 const char *p = s + strlen(s);
178
179 for (; *p != (char)c; --p)
180 if (p == s)
181 return NULL;
182
183 return (char *)p;
184 }
185 #endif
186
187 #ifndef __HAVE_ARCH_STRLEN
188 /**
189 * strlen - Find the length of a string
190 * @s: The string to be sized
191 */
size_t(strlen)192 size_t (strlen)(const char * s)
193 {
194 const char *sc;
195
196 for (sc = s; *sc != '\0'; ++sc)
197 /* nothing */;
198 return sc - s;
199 }
200 #endif
201
202 #ifndef __HAVE_ARCH_STRNLEN
203 /**
204 * strnlen - Find the length of a length-limited string
205 * @s: The string to be sized
206 * @count: The maximum number of bytes to search
207 */
strnlen(const char * s,size_t count)208 size_t strnlen(const char * s, size_t count)
209 {
210 const char *sc;
211
212 for (sc = s; count-- && *sc != '\0'; ++sc)
213 /* nothing */;
214 return sc - s;
215 }
216 #endif
217
218 #ifndef __HAVE_ARCH_STRSPN
219 /**
220 * strspn - Calculate the length of the initial substring of @s which only
221 * contain letters in @accept
222 * @s: The string to be searched
223 * @accept: The string to search for
224 */
strspn(const char * s,const char * accept)225 size_t strspn(const char *s, const char *accept)
226 {
227 const char *p;
228 const char *a;
229 size_t count = 0;
230
231 for (p = s; *p != '\0'; ++p) {
232 for (a = accept; *a != '\0'; ++a) {
233 if (*p == *a)
234 break;
235 }
236 if (*a == '\0')
237 return count;
238 ++count;
239 }
240
241 return count;
242 }
243 #endif
244
245 #ifndef __HAVE_ARCH_STRPBRK
246 /**
247 * strpbrk - Find the first occurrence of a set of characters
248 * @cs: The string to be searched
249 * @ct: The characters to search for
250 */
strpbrk(const char * cs,const char * ct)251 char * strpbrk(const char * cs,const char * ct)
252 {
253 const char *sc1,*sc2;
254
255 for( sc1 = cs; *sc1 != '\0'; ++sc1) {
256 for( sc2 = ct; *sc2 != '\0'; ++sc2) {
257 if (*sc1 == *sc2)
258 return (char *) sc1;
259 }
260 }
261 return NULL;
262 }
263 #endif
264
265 #ifndef __HAVE_ARCH_STRSEP
266 /**
267 * strsep - Split a string into tokens
268 * @s: The string to be searched
269 * @ct: The characters to search for
270 *
271 * strsep() updates @s to point after the token, ready for the next call.
272 *
273 * It returns empty tokens, too, behaving exactly like the libc function
274 * of that name. In fact, it was stolen from glibc2 and de-fancy-fied.
275 * Same semantics, slimmer shape. ;)
276 */
strsep(char ** s,const char * ct)277 char * strsep(char **s, const char *ct)
278 {
279 char *sbegin = *s, *end;
280
281 if (sbegin == NULL)
282 return NULL;
283
284 end = strpbrk(sbegin, ct);
285 if (end)
286 *end++ = '\0';
287 *s = end;
288
289 return sbegin;
290 }
291 #endif
292
293 #ifndef __HAVE_ARCH_STRSTR
294 /**
295 * strstr - Find the first substring in a %NUL terminated string
296 * @s1: The string to be searched
297 * @s2: The string to search for
298 */
299 char *(strstr)(const char *s1, const char *s2)
300 {
301 size_t l1, l2 = strlen(s2);
302
303 if (!l2)
304 return (char *)s1;
305
306 for (l1 = strlen(s1); l1 >= l2; --l1, ++s1)
307 if (!memcmp(s1, s2, l2))
308 return (char *)s1;
309
310 return NULL;
311 }
312 #endif
313
314 #ifndef __HAVE_ARCH_MEMSET
315 /**
316 * memset - Fill a region of memory with the given value
317 * @s: Pointer to the start of the area.
318 * @c: The byte to fill the area with
319 * @count: The size of the area.
320 *
321 * Do not use memset() to access IO space, use memset_io() instead.
322 */
323 void *(memset)(void *s, int c, size_t count)
324 {
325 char *xs = (char *) s;
326
327 while (count--)
328 *xs++ = c;
329
330 return s;
331 }
332 #endif
333
334 #ifndef __HAVE_ARCH_MEMCPY
335 /**
336 * memcpy - Copy one area of memory to another
337 * @dest: Where to copy to
338 * @src: Where to copy from
339 * @count: The size of the area.
340 *
341 * You should not use this function to access IO space, use memcpy_toio()
342 * or memcpy_fromio() instead.
343 */
344 void *(memcpy)(void *dest, const void *src, size_t count)
345 {
346 char *tmp = (char *) dest, *s = (char *) src;
347
348 while (count--)
349 *tmp++ = *s++;
350
351 return dest;
352 }
353 #endif
354
355 #ifndef __HAVE_ARCH_MEMMOVE
356 /**
357 * memmove - Copy one area of memory to another
358 * @dest: Where to copy to
359 * @src: Where to copy from
360 * @count: The size of the area.
361 *
362 * Unlike memcpy(), memmove() copes with overlapping areas.
363 */
364 void *(memmove)(void *dest, const void *src, size_t count)
365 {
366 char *tmp, *s;
367
368 if (dest <= src) {
369 tmp = (char *) dest;
370 s = (char *) src;
371 while (count--)
372 *tmp++ = *s++;
373 }
374 else {
375 tmp = (char *) dest + count;
376 s = (char *) src + count;
377 while (count--)
378 *--tmp = *--s;
379 }
380
381 return dest;
382 }
383 #endif
384
385 #ifndef __HAVE_ARCH_MEMCMP
386 /**
387 * memcmp - Compare two areas of memory
388 * @cs: One area of memory
389 * @ct: Another area of memory
390 * @count: The size of the area.
391 */
392 int (memcmp)(const void *cs, const void *ct, size_t count)
393 {
394 const unsigned char *su1, *su2;
395 int res = 0;
396
397 for( su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--)
398 if ((res = *su1 - *su2) != 0)
399 break;
400 return res;
401 }
402 #endif
403
404 #ifndef __HAVE_ARCH_MEMCHR
405 /**
406 * memchr - Find a character in an area of memory.
407 * @s: The memory area
408 * @c: The byte to search for
409 * @n: The size of the area.
410 *
411 * returns the address of the first occurrence of @c, or %NULL
412 * if @c is not found
413 */
414 void *(memchr)(const void *s, int c, size_t n)
415 {
416 const unsigned char *p = s;
417
418 while (n--)
419 if ((unsigned char)c == *p++)
420 return (void *)(p - 1);
421
422 return NULL;
423 }
424 #endif
425
426 /**
427 * memchr_inv - Find an unmatching character in an area of memory.
428 * @s: The memory area
429 * @c: The byte that is expected
430 * @n: The size of the area.
431 *
432 * returns the address of the first occurrence of a character other than @c,
433 * or %NULL if the whole buffer contains just @c.
434 */
memchr_inv(const void * s,int c,size_t n)435 void *memchr_inv(const void *s, int c, size_t n)
436 {
437 const unsigned char *p = s;
438
439 while (n--)
440 if ((unsigned char)c != *p++)
441 return (void *)(p - 1);
442
443 return NULL;
444 }
445
446 /*
447 * Local variables:
448 * mode: C
449 * c-file-style: "BSD"
450 * c-basic-offset: 8
451 * tab-width: 8
452 * indent-tabs-mode: t
453 * End:
454 */
455