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 
18 #include <linux/types.h>
19 #include <linux/string.h>
20 #include <linux/ctype.h>
21 
22 #ifndef __HAVE_ARCH_STRNICMP
23 /**
24  * strnicmp - Case insensitive, length-limited string comparison
25  * @s1: One string
26  * @s2: The other string
27  * @len: the maximum number of characters to compare
28  */
strnicmp(const char * s1,const char * s2,size_t len)29 int strnicmp(const char *s1, const char *s2, size_t len)
30 {
31 	/* Yes, Virginia, it had better be unsigned */
32 	unsigned char c1, c2;
33 
34 	c1 = 0;	c2 = 0;
35 	if (len) {
36 		do {
37 			c1 = *s1; c2 = *s2;
38 			s1++; s2++;
39 			if (!c1)
40 				break;
41 			if (!c2)
42 				break;
43 			if (c1 == c2)
44 				continue;
45 			c1 = tolower(c1);
46 			c2 = tolower(c2);
47 			if (c1 != c2)
48 				break;
49 		} while (--len);
50 	}
51 	return (int)c1 - (int)c2;
52 }
53 #endif
54 
55 char * ___strtok;
56 
57 #ifndef __HAVE_ARCH_STRCPY
58 /**
59  * strcpy - Copy a %NUL terminated string
60  * @dest: Where to copy the string to
61  * @src: Where to copy the string from
62  */
strcpy(char * dest,const char * src)63 char * strcpy(char * dest,const char *src)
64 {
65 	char *tmp = dest;
66 
67 	while ((*dest++ = *src++) != '\0')
68 		/* nothing */;
69 	return tmp;
70 }
71 #endif
72 
73 #ifndef __HAVE_ARCH_STRNCPY
74 /**
75  * strncpy - Copy a length-limited, %NUL-terminated string
76  * @dest: Where to copy the string to
77  * @src: Where to copy the string from
78  * @count: The maximum number of bytes to copy
79  *
80  * Note that unlike userspace strncpy, this does not %NUL-pad the buffer.
81  * However, the result is not %NUL-terminated if the source exceeds
82  * @count bytes.
83  */
strncpy(char * dest,const char * src,size_t count)84 char * strncpy(char * dest,const char *src,size_t count)
85 {
86 	char *tmp = dest;
87 
88 	while (count-- && (*dest++ = *src++) != '\0')
89 		/* nothing */;
90 
91 	return tmp;
92 }
93 #endif
94 
95 #ifndef __HAVE_ARCH_STRCAT
96 /**
97  * strcat - Append one %NUL-terminated string to another
98  * @dest: The string to be appended to
99  * @src: The string to append to it
100  */
strcat(char * dest,const char * src)101 char * strcat(char * dest, const char * src)
102 {
103 	char *tmp = dest;
104 
105 	while (*dest)
106 		dest++;
107 	while ((*dest++ = *src++) != '\0')
108 		;
109 
110 	return tmp;
111 }
112 #endif
113 
114 #ifndef __HAVE_ARCH_STRNCAT
115 /**
116  * strncat - Append a length-limited, %NUL-terminated string to another
117  * @dest: The string to be appended to
118  * @src: The string to append to it
119  * @count: The maximum numbers of bytes to copy
120  *
121  * Note that in contrast to strncpy, strncat ensures the result is
122  * terminated.
123  */
strncat(char * dest,const char * src,size_t count)124 char * strncat(char *dest, const char *src, size_t count)
125 {
126 	char *tmp = dest;
127 
128 	if (count) {
129 		while (*dest)
130 			dest++;
131 		while ((*dest++ = *src++)) {
132 			if (--count == 0) {
133 				*dest = '\0';
134 				break;
135 			}
136 		}
137 	}
138 
139 	return tmp;
140 }
141 #endif
142 
143 #ifndef __HAVE_ARCH_STRCMP
144 /**
145  * strcmp - Compare two strings
146  * @cs: One string
147  * @ct: Another string
148  */
strcmp(const char * cs,const char * ct)149 int strcmp(const char * cs,const char * ct)
150 {
151 	register signed char __res;
152 
153 	while (1) {
154 		if ((__res = *cs - *ct++) != 0 || !*cs++)
155 			break;
156 	}
157 
158 	return __res;
159 }
160 #endif
161 
162 #ifndef __HAVE_ARCH_STRNCMP
163 /**
164  * strncmp - Compare two length-limited strings
165  * @cs: One string
166  * @ct: Another string
167  * @count: The maximum number of bytes to compare
168  */
strncmp(const char * cs,const char * ct,size_t count)169 int strncmp(const char * cs,const char * ct,size_t count)
170 {
171 	register signed char __res = 0;
172 
173 	while (count) {
174 		if ((__res = *cs - *ct++) != 0 || !*cs++)
175 			break;
176 		count--;
177 	}
178 
179 	return __res;
180 }
181 #endif
182 
183 #ifndef __HAVE_ARCH_STRCHR
184 /**
185  * strchr - Find the first occurrence of a character in a string
186  * @s: The string to be searched
187  * @c: The character to search for
188  */
strchr(const char * s,int c)189 char * strchr(const char * s, int c)
190 {
191 	for(; *s != (char) c; ++s)
192 		if (*s == '\0')
193 			return NULL;
194 	return (char *) s;
195 }
196 #endif
197 
198 #ifndef __HAVE_ARCH_STRRCHR
199 /**
200  * strrchr - Find the last occurrence of a character in a string
201  * @s: The string to be searched
202  * @c: The character to search for
203  */
strrchr(const char * s,int c)204 char * strrchr(const char * s, int c)
205 {
206        const char *p = s + strlen(s);
207        do {
208            if (*p == (char)c)
209                return (char *)p;
210        } while (--p >= s);
211        return NULL;
212 }
213 #endif
214 
215 #ifndef __HAVE_ARCH_STRLEN
216 /**
217  * strlen - Find the length of a string
218  * @s: The string to be sized
219  */
strlen(const char * s)220 size_t strlen(const char * s)
221 {
222 	const char *sc;
223 
224 	for (sc = s; *sc != '\0'; ++sc)
225 		/* nothing */;
226 	return sc - s;
227 }
228 #endif
229 
230 #ifndef __HAVE_ARCH_STRNLEN
231 /**
232  * strnlen - Find the length of a length-limited string
233  * @s: The string to be sized
234  * @count: The maximum number of bytes to search
235  */
strnlen(const char * s,size_t count)236 size_t strnlen(const char * s, size_t count)
237 {
238 	const char *sc;
239 
240 	for (sc = s; count-- && *sc != '\0'; ++sc)
241 		/* nothing */;
242 	return sc - s;
243 }
244 #endif
245 
246 #ifndef __HAVE_ARCH_STRSPN
247 /**
248  * strspn - Calculate the length of the initial substring of @s which only
249  * 	contain letters in @accept
250  * @s: The string to be searched
251  * @accept: The string to search for
252  */
strspn(const char * s,const char * accept)253 size_t strspn(const char *s, const char *accept)
254 {
255 	const char *p;
256 	const char *a;
257 	size_t count = 0;
258 
259 	for (p = s; *p != '\0'; ++p) {
260 		for (a = accept; *a != '\0'; ++a) {
261 			if (*p == *a)
262 				break;
263 		}
264 		if (*a == '\0')
265 			return count;
266 		++count;
267 	}
268 
269 	return count;
270 }
271 #endif
272 
273 #ifndef __HAVE_ARCH_STRPBRK
274 /**
275  * strpbrk - Find the first occurrence of a set of characters
276  * @cs: The string to be searched
277  * @ct: The characters to search for
278  */
strpbrk(const char * cs,const char * ct)279 char * strpbrk(const char * cs,const char * ct)
280 {
281 	const char *sc1,*sc2;
282 
283 	for( sc1 = cs; *sc1 != '\0'; ++sc1) {
284 		for( sc2 = ct; *sc2 != '\0'; ++sc2) {
285 			if (*sc1 == *sc2)
286 				return (char *) sc1;
287 		}
288 	}
289 	return NULL;
290 }
291 #endif
292 
293 #ifndef __HAVE_ARCH_STRTOK
294 /**
295  * strtok - Split a string into tokens
296  * @s: The string to be searched
297  * @ct: The characters to search for
298  *
299  * WARNING: strtok is deprecated, use strsep instead.
300  */
strtok(char * s,const char * ct)301 char * strtok(char * s,const char * ct)
302 {
303 	char *sbegin, *send;
304 
305 	sbegin  = s ? s : ___strtok;
306 	if (!sbegin) {
307 		return NULL;
308 	}
309 	sbegin += strspn(sbegin,ct);
310 	if (*sbegin == '\0') {
311 		___strtok = NULL;
312 		return( NULL );
313 	}
314 	send = strpbrk( sbegin, ct);
315 	if (send && *send != '\0')
316 		*send++ = '\0';
317 	___strtok = send;
318 	return (sbegin);
319 }
320 #endif
321 
322 #ifndef __HAVE_ARCH_STRSEP
323 /**
324  * strsep - Split a string into tokens
325  * @s: The string to be searched
326  * @ct: The characters to search for
327  *
328  * strsep() updates @s to point after the token, ready for the next call.
329  *
330  * It returns empty tokens, too, behaving exactly like the libc function
331  * of that name. In fact, it was stolen from glibc2 and de-fancy-fied.
332  * Same semantics, slimmer shape. ;)
333  */
strsep(char ** s,const char * ct)334 char * strsep(char **s, const char *ct)
335 {
336 	char *sbegin = *s, *end;
337 
338 	if (sbegin == NULL)
339 		return NULL;
340 
341 	end = strpbrk(sbegin, ct);
342 	if (end)
343 		*end++ = '\0';
344 	*s = end;
345 
346 	return sbegin;
347 }
348 #endif
349 
350 #ifndef __HAVE_ARCH_MEMSET
351 /**
352  * memset - Fill a region of memory with the given value
353  * @s: Pointer to the start of the area.
354  * @c: The byte to fill the area with
355  * @count: The size of the area.
356  *
357  * Do not use memset() to access IO space, use memset_io() instead.
358  */
memset(void * s,int c,size_t count)359 void * memset(void * s,int c,size_t count)
360 {
361 	char *xs = (char *) s;
362 
363 	while (count--)
364 		*xs++ = c;
365 
366 	return s;
367 }
368 #endif
369 
370 #ifndef __HAVE_ARCH_BCOPY
371 /**
372  * bcopy - Copy one area of memory to another
373  * @src: Where to copy from
374  * @dest: Where to copy to
375  * @count: The size of the area.
376  *
377  * Note that this is the same as memcpy(), with the arguments reversed.
378  * memcpy() is the standard, bcopy() is a legacy BSD function.
379  *
380  * You should not use this function to access IO space, use memcpy_toio()
381  * or memcpy_fromio() instead.
382  */
bcopy(const void * srcp,void * destp,size_t count)383 void bcopy(const void * srcp, void * destp, size_t count)
384 {
385 	const char *src = srcp;
386 	char *dest = destp;
387 
388 	while (count--)
389 		*dest++ = *src++;
390 }
391 #endif
392 
393 #ifndef __HAVE_ARCH_MEMCPY
394 /**
395  * memcpy - Copy one area of memory to another
396  * @dest: Where to copy to
397  * @src: Where to copy from
398  * @count: The size of the area.
399  *
400  * You should not use this function to access IO space, use memcpy_toio()
401  * or memcpy_fromio() instead.
402  */
memcpy(void * dest,const void * src,size_t count)403 void * memcpy(void * dest,const void *src,size_t count)
404 {
405 	char *tmp = (char *) dest, *s = (char *) src;
406 
407 	while (count--)
408 		*tmp++ = *s++;
409 
410 	return dest;
411 }
412 #endif
413 
414 #ifndef __HAVE_ARCH_MEMMOVE
415 /**
416  * memmove - Copy one area of memory to another
417  * @dest: Where to copy to
418  * @src: Where to copy from
419  * @count: The size of the area.
420  *
421  * Unlike memcpy(), memmove() copes with overlapping areas.
422  */
memmove(void * dest,const void * src,size_t count)423 void * memmove(void * dest,const void *src,size_t count)
424 {
425 	char *tmp, *s;
426 
427 	if (dest <= src) {
428 		tmp = (char *) dest;
429 		s = (char *) src;
430 		while (count--)
431 			*tmp++ = *s++;
432 		}
433 	else {
434 		tmp = (char *) dest + count;
435 		s = (char *) src + count;
436 		while (count--)
437 			*--tmp = *--s;
438 		}
439 
440 	return dest;
441 }
442 #endif
443 
444 #ifndef __HAVE_ARCH_MEMCMP
445 /**
446  * memcmp - Compare two areas of memory
447  * @cs: One area of memory
448  * @ct: Another area of memory
449  * @count: The size of the area.
450  */
451 #undef memcmp
memcmp(const void * cs,const void * ct,size_t count)452 int memcmp(const void * cs,const void * ct,size_t count)
453 {
454 	const unsigned char *su1, *su2;
455 	int res = 0;
456 
457 	for( su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--)
458 		if ((res = *su1 - *su2) != 0)
459 			break;
460 	return res;
461 }
462 #endif
463 
464 #ifndef __HAVE_ARCH_MEMSCAN
465 /**
466  * memscan - Find a character in an area of memory.
467  * @addr: The memory area
468  * @c: The byte to search for
469  * @size: The size of the area.
470  *
471  * returns the address of the first occurrence of @c, or 1 byte past
472  * the area if @c is not found
473  */
memscan(void * addr,int c,size_t size)474 void * memscan(void * addr, int c, size_t size)
475 {
476 	unsigned char * p = (unsigned char *) addr;
477 
478 	while (size) {
479 		if (*p == c)
480 			return (void *) p;
481 		p++;
482 		size--;
483 	}
484   	return (void *) p;
485 }
486 #endif
487 
488 #ifndef __HAVE_ARCH_STRSTR
489 /**
490  * strstr - Find the first substring in a %NUL terminated string
491  * @s1: The string to be searched
492  * @s2: The string to search for
493  */
strstr(const char * s1,const char * s2)494 char * strstr(const char * s1,const char * s2)
495 {
496 	int l1, l2;
497 
498 	l2 = strlen(s2);
499 	if (!l2)
500 		return (char *) s1;
501 	l1 = strlen(s1);
502 	while (l1 >= l2) {
503 		l1--;
504 		if (!memcmp(s1,s2,l2))
505 			return (char *) s1;
506 		s1++;
507 	}
508 	return NULL;
509 }
510 #endif
511 
512 #ifndef __HAVE_ARCH_MEMCHR
513 /**
514  * memchr - Find a character in an area of memory.
515  * @s: The memory area
516  * @c: The byte to search for
517  * @n: The size of the area.
518  *
519  * returns the address of the first occurrence of @c, or %NULL
520  * if @c is not found
521  */
memchr(const void * s,int c,size_t n)522 void *memchr(const void *s, int c, size_t n)
523 {
524 	const unsigned char *p = s;
525 	while (n-- != 0) {
526         	if ((unsigned char)c == *p++) {
527 			return (void *)(p-1);
528 		}
529 	}
530 	return NULL;
531 }
532 
533 #endif
534