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