1/*
2 *  linux/lib/string.c
3 *
4 *  Copyright (C) 1991, 1992  Linus Torvalds
5 */
6
7/*
8 * stupid library routines.. The optimized versions should generally be found
9 * as inline code in <asm-xx/string.h>
10 *
11 * These are buggy as well..
12 *
13 * * Fri Jun 25 1999, Ingo Oeser <ioe@informatik.tu-chemnitz.de>
14 * -  Added strsep() which will replace strtok() soon (because strsep() is
15 *    reentrant and should be faster). Use only strsep() in new code, please.
16 *
17 * * Sat Feb 09 2002, Jason Thomas <jason@topic.com.au>,
18 *                    Matthew Hawkins <matt@mh.dropbear.id.au>
19 * -  Kissed strtok() goodbye
20 */
21
22#include <linux/types.h>
23#include <linux/string.h>
24#include <linux/ctype.h>
25#include <linux/module.h>
26
27#include <typedefs.h>
28#include <bcmdefs.h>
29
30#ifndef __HAVE_ARCH_STRNICMP
31/**
32 * strnicmp - Case insensitive, length-limited string comparison
33 * @s1: One string
34 * @s2: The other string
35 * @len: the maximum number of characters to compare
36 */
37int strnicmp(const char *s1, const char *s2, size_t len)
38{
39	/* Yes, Virginia, it had better be unsigned */
40	unsigned char c1, c2;
41
42	c1 = c2 = 0;
43	if (len) {
44		do {
45			c1 = *s1;
46			c2 = *s2;
47			s1++;
48			s2++;
49			if (!c1)
50				break;
51			if (!c2)
52				break;
53			if (c1 == c2)
54				continue;
55			c1 = tolower(c1);
56			c2 = tolower(c2);
57			if (c1 != c2)
58				break;
59		} while (--len);
60	}
61	return (int)c1 - (int)c2;
62}
63EXPORT_SYMBOL(strnicmp);
64#endif
65
66#ifndef __HAVE_ARCH_STRCASECMP
67int strcasecmp(const char *s1, const char *s2)
68{
69	int c1, c2;
70
71	do {
72		c1 = tolower(*s1++);
73		c2 = tolower(*s2++);
74	} while (c1 == c2 && c1 != 0);
75	return c1 - c2;
76}
77EXPORT_SYMBOL(strcasecmp);
78#endif
79
80#ifndef __HAVE_ARCH_STRNCASECMP
81int strncasecmp(const char *s1, const char *s2, size_t n)
82{
83	int c1, c2;
84
85	do {
86		c1 = tolower(*s1++);
87		c2 = tolower(*s2++);
88	} while ((--n > 0) && c1 == c2 && c1 != 0);
89	return c1 - c2;
90}
91EXPORT_SYMBOL(strncasecmp);
92#endif
93
94#ifndef __HAVE_ARCH_STRCPY
95/**
96 * strcpy - Copy a %NUL terminated string
97 * @dest: Where to copy the string to
98 * @src: Where to copy the string from
99 */
100#undef strcpy
101char *strcpy(char *dest, const char *src)
102{
103	char *tmp = dest;
104
105	while ((*dest++ = *src++) != '\0')
106		/* nothing */;
107	return tmp;
108}
109EXPORT_SYMBOL(strcpy);
110#endif
111
112#ifndef __HAVE_ARCH_STRNCPY
113/**
114 * strncpy - Copy a length-limited, %NUL-terminated string
115 * @dest: Where to copy the string to
116 * @src: Where to copy the string from
117 * @count: The maximum number of bytes to copy
118 *
119 * The result is not %NUL-terminated if the source exceeds
120 * @count bytes.
121 *
122 * In the case where the length of @src is less than  that  of
123 * count, the remainder of @dest will be padded with %NUL.
124 *
125 */
126char *strncpy(char *dest, const char *src, size_t count)
127{
128	char *tmp = dest;
129
130	while (count) {
131		if ((*tmp = *src) != 0)
132			src++;
133		tmp++;
134		count--;
135	}
136	return dest;
137}
138EXPORT_SYMBOL(strncpy);
139#endif
140
141#ifndef __HAVE_ARCH_STRLCPY
142/**
143 * strlcpy - Copy a %NUL terminated string into a sized buffer
144 * @dest: Where to copy the string to
145 * @src: Where to copy the string from
146 * @size: size of destination buffer
147 *
148 * Compatible with *BSD: the result is always a valid
149 * NUL-terminated string that fits in the buffer (unless,
150 * of course, the buffer size is zero). It does not pad
151 * out the result like strncpy() does.
152 */
153size_t strlcpy(char *dest, const char *src, size_t size)
154{
155	size_t ret = strlen(src);
156
157	if (size) {
158		size_t len = (ret >= size) ? size - 1 : ret;
159		memcpy(dest, src, len);
160		dest[len] = '\0';
161	}
162	return ret;
163}
164EXPORT_SYMBOL(strlcpy);
165#endif
166
167#ifndef __HAVE_ARCH_STRCAT
168/**
169 * strcat - Append one %NUL-terminated string to another
170 * @dest: The string to be appended to
171 * @src: The string to append to it
172 */
173#undef strcat
174char *strcat(char *dest, const char *src)
175{
176	char *tmp = dest;
177
178	while (*dest)
179		dest++;
180	while ((*dest++ = *src++) != '\0')
181		;
182	return tmp;
183}
184EXPORT_SYMBOL(strcat);
185#endif
186
187#ifndef __HAVE_ARCH_STRNCAT
188/**
189 * strncat - Append a length-limited, %NUL-terminated string to another
190 * @dest: The string to be appended to
191 * @src: The string to append to it
192 * @count: The maximum numbers of bytes to copy
193 *
194 * Note that in contrast to strncpy(), strncat() ensures the result is
195 * terminated.
196 */
197char *strncat(char *dest, const char *src, size_t count)
198{
199	char *tmp = dest;
200
201	if (count) {
202		while (*dest)
203			dest++;
204		while ((*dest++ = *src++) != 0) {
205			if (--count == 0) {
206				*dest = '\0';
207				break;
208			}
209		}
210	}
211	return tmp;
212}
213EXPORT_SYMBOL(strncat);
214#endif
215
216#ifndef __HAVE_ARCH_STRLCAT
217/**
218 * strlcat - Append a length-limited, %NUL-terminated string to another
219 * @dest: The string to be appended to
220 * @src: The string to append to it
221 * @count: The size of the destination buffer.
222 */
223size_t strlcat(char *dest, const char *src, size_t count)
224{
225	size_t dsize = strlen(dest);
226	size_t len = strlen(src);
227	size_t res = dsize + len;
228
229	/* This would be a bug */
230	BUG_ON(dsize >= count);
231
232	dest += dsize;
233	count -= dsize;
234	if (len >= count)
235		len = count-1;
236	memcpy(dest, src, len);
237	dest[len] = 0;
238	return res;
239}
240EXPORT_SYMBOL(strlcat);
241#endif
242
243#ifndef __HAVE_ARCH_STRCMP
244/**
245 * strcmp - Compare two strings
246 * @cs: One string
247 * @ct: Another string
248 */
249#undef strcmp
250int strcmp(const char *cs, const char *ct)
251{
252	signed char __res;
253
254	while (1) {
255		if ((__res = *cs - *ct++) != 0 || !*cs++)
256			break;
257	}
258	return __res;
259}
260EXPORT_SYMBOL(strcmp);
261#endif
262
263#ifndef __HAVE_ARCH_STRNCMP
264/**
265 * strncmp - Compare two length-limited strings
266 * @cs: One string
267 * @ct: Another string
268 * @count: The maximum number of bytes to compare
269 */
270int strncmp(const char *cs, const char *ct, size_t count)
271{
272	signed char __res = 0;
273
274	while (count) {
275		if ((__res = *cs - *ct++) != 0 || !*cs++)
276			break;
277		count--;
278	}
279	return __res;
280}
281EXPORT_SYMBOL(strncmp);
282#endif
283
284#ifndef __HAVE_ARCH_STRCHR
285/**
286 * strchr - Find the first occurrence of a character in a string
287 * @s: The string to be searched
288 * @c: The character to search for
289 */
290char *strchr(const char *s, int c)
291{
292	for (; *s != (char)c; ++s)
293		if (*s == '\0')
294			return NULL;
295	return (char *)s;
296}
297EXPORT_SYMBOL(strchr);
298#endif
299
300#ifndef __HAVE_ARCH_STRRCHR
301/**
302 * strrchr - Find the last occurrence of a character in a string
303 * @s: The string to be searched
304 * @c: The character to search for
305 */
306char *strrchr(const char *s, int c)
307{
308       const char *p = s + strlen(s);
309       do {
310           if (*p == (char)c)
311               return (char *)p;
312       } while (--p >= s);
313       return NULL;
314}
315EXPORT_SYMBOL(strrchr);
316#endif
317
318#ifndef __HAVE_ARCH_STRNCHR
319/**
320 * strnchr - Find a character in a length limited string
321 * @s: The string to be searched
322 * @count: The number of characters to be searched
323 * @c: The character to search for
324 */
325char *strnchr(const char *s, size_t count, int c)
326{
327	for (; count-- && *s != '\0'; ++s)
328		if (*s == (char)c)
329			return (char *)s;
330	return NULL;
331}
332EXPORT_SYMBOL(strnchr);
333#endif
334
335/**
336 * strstrip - Removes leading and trailing whitespace from @s.
337 * @s: The string to be stripped.
338 *
339 * Note that the first trailing whitespace is replaced with a %NUL-terminator
340 * in the given string @s. Returns a pointer to the first non-whitespace
341 * character in @s.
342 */
343char *strstrip(char *s)
344{
345	size_t size;
346	char *end;
347
348	size = strlen(s);
349
350	if (!size)
351		return s;
352
353	end = s + size - 1;
354	while (end >= s && isspace(*end))
355		end--;
356	*(end + 1) = '\0';
357
358	while (*s && isspace(*s))
359		s++;
360
361	return s;
362}
363EXPORT_SYMBOL(strstrip);
364
365#ifndef __HAVE_ARCH_STRLEN
366/**
367 * strlen - Find the length of a string
368 * @s: The string to be sized
369 */
370size_t strlen(const char *s)
371{
372	const char *sc;
373
374	for (sc = s; *sc != '\0'; ++sc)
375		/* nothing */;
376	return sc - s;
377}
378EXPORT_SYMBOL(strlen);
379#endif
380
381#ifndef __HAVE_ARCH_STRNLEN
382/**
383 * strnlen - Find the length of a length-limited string
384 * @s: The string to be sized
385 * @count: The maximum number of bytes to search
386 */
387size_t strnlen(const char *s, size_t count)
388{
389	const char *sc;
390
391	for (sc = s; count-- && *sc != '\0'; ++sc)
392		/* nothing */;
393	return sc - s;
394}
395EXPORT_SYMBOL(strnlen);
396#endif
397
398#ifndef __HAVE_ARCH_STRSPN
399/**
400 * strspn - Calculate the length of the initial substring of @s which only contain letters in @accept
401 * @s: The string to be searched
402 * @accept: The string to search for
403 */
404size_t strspn(const char *s, const char *accept)
405{
406	const char *p;
407	const char *a;
408	size_t count = 0;
409
410	for (p = s; *p != '\0'; ++p) {
411		for (a = accept; *a != '\0'; ++a) {
412			if (*p == *a)
413				break;
414		}
415		if (*a == '\0')
416			return count;
417		++count;
418	}
419	return count;
420}
421
422EXPORT_SYMBOL(strspn);
423#endif
424
425#ifndef __HAVE_ARCH_STRCSPN
426/**
427 * strcspn - Calculate the length of the initial substring of @s which does not contain letters in @reject
428 * @s: The string to be searched
429 * @reject: The string to avoid
430 */
431size_t strcspn(const char *s, const char *reject)
432{
433	const char *p;
434	const char *r;
435	size_t count = 0;
436
437	for (p = s; *p != '\0'; ++p) {
438		for (r = reject; *r != '\0'; ++r) {
439			if (*p == *r)
440				return count;
441		}
442		++count;
443	}
444	return count;
445}
446EXPORT_SYMBOL(strcspn);
447#endif
448
449#ifndef __HAVE_ARCH_STRPBRK
450/**
451 * strpbrk - Find the first occurrence of a set of characters
452 * @cs: The string to be searched
453 * @ct: The characters to search for
454 */
455char *strpbrk(const char *cs, const char *ct)
456{
457	const char *sc1, *sc2;
458
459	for (sc1 = cs; *sc1 != '\0'; ++sc1) {
460		for (sc2 = ct; *sc2 != '\0'; ++sc2) {
461			if (*sc1 == *sc2)
462				return (char *)sc1;
463		}
464	}
465	return NULL;
466}
467EXPORT_SYMBOL(strpbrk);
468#endif
469
470#ifndef __HAVE_ARCH_STRSEP
471/**
472 * strsep - Split a string into tokens
473 * @s: The string to be searched
474 * @ct: The characters to search for
475 *
476 * strsep() updates @s to point after the token, ready for the next call.
477 *
478 * It returns empty tokens, too, behaving exactly like the libc function
479 * of that name. In fact, it was stolen from glibc2 and de-fancy-fied.
480 * Same semantics, slimmer shape. ;)
481 */
482char *strsep(char **s, const char *ct)
483{
484	char *sbegin = *s;
485	char *end;
486
487	if (sbegin == NULL)
488		return NULL;
489
490	end = strpbrk(sbegin, ct);
491	if (end)
492		*end++ = '\0';
493	*s = end;
494	return sbegin;
495}
496EXPORT_SYMBOL(strsep);
497#endif
498
499#ifndef __HAVE_ARCH_MEMSET
500/**
501 * memset - Fill a region of memory with the given value
502 * @s: Pointer to the start of the area.
503 * @c: The byte to fill the area with
504 * @count: The size of the area.
505 *
506 * Do not use memset() to access IO space, use memset_io() instead.
507 */
508void *memset(void *s, int c, size_t count)
509{
510	char *xs = s;
511
512	while (count--)
513		*xs++ = c;
514	return s;
515}
516EXPORT_SYMBOL(memset);
517#endif
518
519#ifndef __HAVE_ARCH_MEMCPY
520/**
521 * memcpy - Copy one area of memory to another
522 * @dest: Where to copy to
523 * @src: Where to copy from
524 * @count: The size of the area.
525 *
526 * You should not use this function to access IO space, use memcpy_toio()
527 * or memcpy_fromio() instead.
528 */
529void *memcpy(void *dest, const void *src, size_t count)
530{
531	char *tmp = dest;
532	const char *s = src;
533
534	while (count--)
535		*tmp++ = *s++;
536	return dest;
537}
538EXPORT_SYMBOL(memcpy);
539#endif
540
541#ifndef __HAVE_ARCH_MEMMOVE
542/**
543 * memmove - Copy one area of memory to another
544 * @dest: Where to copy to
545 * @src: Where to copy from
546 * @count: The size of the area.
547 *
548 * Unlike memcpy(), memmove() copes with overlapping areas.
549 */
550void *memmove(void *dest, const void *src, size_t count)
551{
552	char *tmp;
553	const char *s;
554
555	if (dest <= src) {
556		tmp = dest;
557		s = src;
558		while (count--)
559			*tmp++ = *s++;
560	} else {
561		tmp = dest;
562		tmp += count;
563		s = src;
564		s += count;
565		while (count--)
566			*--tmp = *--s;
567	}
568	return dest;
569}
570EXPORT_SYMBOL(memmove);
571#endif
572
573#ifndef __HAVE_ARCH_MEMCMP
574/**
575 * memcmp - Compare two areas of memory
576 * @cs: One area of memory
577 * @ct: Another area of memory
578 * @count: The size of the area.
579 */
580#undef memcmp
581int BCMFASTPATH memcmp(const void *cs, const void *ct, size_t count)
582{
583	const unsigned char *su1, *su2;
584	int res = 0;
585
586	for (su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--)
587		if ((res = *su1 - *su2) != 0)
588			break;
589	return res;
590}
591EXPORT_SYMBOL(memcmp);
592#endif
593
594#ifndef __HAVE_ARCH_MEMSCAN
595/**
596 * memscan - Find a character in an area of memory.
597 * @addr: The memory area
598 * @c: The byte to search for
599 * @size: The size of the area.
600 *
601 * returns the address of the first occurrence of @c, or 1 byte past
602 * the area if @c is not found
603 */
604void *memscan(void *addr, int c, size_t size)
605{
606	unsigned char *p = addr;
607
608	while (size) {
609		if (*p == c)
610			return (void *)p;
611		p++;
612		size--;
613	}
614  	return (void *)p;
615}
616EXPORT_SYMBOL(memscan);
617#endif
618
619#ifndef __HAVE_ARCH_STRSTR
620/**
621 * strstr - Find the first substring in a %NUL terminated string
622 * @s1: The string to be searched
623 * @s2: The string to search for
624 */
625char *strstr(const char *s1, const char *s2)
626{
627	int l1, l2;
628
629	l2 = strlen(s2);
630	if (!l2)
631		return (char *)s1;
632	l1 = strlen(s1);
633	while (l1 >= l2) {
634		l1--;
635		if (!memcmp(s1, s2, l2))
636			return (char *)s1;
637		s1++;
638	}
639	return NULL;
640}
641EXPORT_SYMBOL(strstr);
642#endif
643
644#ifndef __HAVE_ARCH_MEMCHR
645/**
646 * memchr - Find a character in an area of memory.
647 * @s: The memory area
648 * @c: The byte to search for
649 * @n: The size of the area.
650 *
651 * returns the address of the first occurrence of @c, or %NULL
652 * if @c is not found
653 */
654void *memchr(const void *s, int c, size_t n)
655{
656	const unsigned char *p = s;
657	while (n-- != 0) {
658        	if ((unsigned char)c == *p++) {
659			return (void *)(p - 1);
660		}
661	}
662	return NULL;
663}
664EXPORT_SYMBOL(memchr);
665#endif
666