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        do {
179            if (*p == (char)c)
180                return (char *)p;
181        } while (--p >= s);
182        return NULL;
183 }
184 #endif
185 
186 #ifndef __HAVE_ARCH_STRLEN
187 /**
188  * strlen - Find the length of a string
189  * @s: The string to be sized
190  */
size_t(strlen)191 size_t (strlen)(const char * s)
192 {
193 	const char *sc;
194 
195 	for (sc = s; *sc != '\0'; ++sc)
196 		/* nothing */;
197 	return sc - s;
198 }
199 #endif
200 
201 #ifndef __HAVE_ARCH_STRNLEN
202 /**
203  * strnlen - Find the length of a length-limited string
204  * @s: The string to be sized
205  * @count: The maximum number of bytes to search
206  */
strnlen(const char * s,size_t count)207 size_t strnlen(const char * s, size_t count)
208 {
209 	const char *sc;
210 
211 	for (sc = s; count-- && *sc != '\0'; ++sc)
212 		/* nothing */;
213 	return sc - s;
214 }
215 #endif
216 
217 #ifndef __HAVE_ARCH_STRSPN
218 /**
219  * strspn - Calculate the length of the initial substring of @s which only
220  * 	contain letters in @accept
221  * @s: The string to be searched
222  * @accept: The string to search for
223  */
strspn(const char * s,const char * accept)224 size_t strspn(const char *s, const char *accept)
225 {
226 	const char *p;
227 	const char *a;
228 	size_t count = 0;
229 
230 	for (p = s; *p != '\0'; ++p) {
231 		for (a = accept; *a != '\0'; ++a) {
232 			if (*p == *a)
233 				break;
234 		}
235 		if (*a == '\0')
236 			return count;
237 		++count;
238 	}
239 
240 	return count;
241 }
242 #endif
243 
244 #ifndef __HAVE_ARCH_STRPBRK
245 /**
246  * strpbrk - Find the first occurrence of a set of characters
247  * @cs: The string to be searched
248  * @ct: The characters to search for
249  */
strpbrk(const char * cs,const char * ct)250 char * strpbrk(const char * cs,const char * ct)
251 {
252 	const char *sc1,*sc2;
253 
254 	for( sc1 = cs; *sc1 != '\0'; ++sc1) {
255 		for( sc2 = ct; *sc2 != '\0'; ++sc2) {
256 			if (*sc1 == *sc2)
257 				return (char *) sc1;
258 		}
259 	}
260 	return NULL;
261 }
262 #endif
263 
264 #ifndef __HAVE_ARCH_STRSEP
265 /**
266  * strsep - Split a string into tokens
267  * @s: The string to be searched
268  * @ct: The characters to search for
269  *
270  * strsep() updates @s to point after the token, ready for the next call.
271  *
272  * It returns empty tokens, too, behaving exactly like the libc function
273  * of that name. In fact, it was stolen from glibc2 and de-fancy-fied.
274  * Same semantics, slimmer shape. ;)
275  */
strsep(char ** s,const char * ct)276 char * strsep(char **s, const char *ct)
277 {
278 	char *sbegin = *s, *end;
279 
280 	if (sbegin == NULL)
281 		return NULL;
282 
283 	end = strpbrk(sbegin, ct);
284 	if (end)
285 		*end++ = '\0';
286 	*s = end;
287 
288 	return sbegin;
289 }
290 #endif
291 
292 #ifndef __HAVE_ARCH_MEMSET
293 /**
294  * memset - Fill a region of memory with the given value
295  * @s: Pointer to the start of the area.
296  * @c: The byte to fill the area with
297  * @count: The size of the area.
298  *
299  * Do not use memset() to access IO space, use memset_io() instead.
300  */
301 void *(memset)(void *s, int c, size_t count)
302 {
303 	char *xs = (char *) s;
304 
305 	while (count--)
306 		*xs++ = c;
307 
308 	return s;
309 }
310 #endif
311 
312 #ifndef __HAVE_ARCH_MEMCPY
313 /**
314  * memcpy - Copy one area of memory to another
315  * @dest: Where to copy to
316  * @src: Where to copy from
317  * @count: The size of the area.
318  *
319  * You should not use this function to access IO space, use memcpy_toio()
320  * or memcpy_fromio() instead.
321  */
322 void *(memcpy)(void *dest, const void *src, size_t count)
323 {
324 	char *tmp = (char *) dest, *s = (char *) src;
325 
326 	while (count--)
327 		*tmp++ = *s++;
328 
329 	return dest;
330 }
331 #endif
332 
333 #ifndef __HAVE_ARCH_MEMMOVE
334 /**
335  * memmove - Copy one area of memory to another
336  * @dest: Where to copy to
337  * @src: Where to copy from
338  * @count: The size of the area.
339  *
340  * Unlike memcpy(), memmove() copes with overlapping areas.
341  */
342 void *(memmove)(void *dest, const void *src, size_t count)
343 {
344 	char *tmp, *s;
345 
346 	if (dest <= src) {
347 		tmp = (char *) dest;
348 		s = (char *) src;
349 		while (count--)
350 			*tmp++ = *s++;
351 		}
352 	else {
353 		tmp = (char *) dest + count;
354 		s = (char *) src + count;
355 		while (count--)
356 			*--tmp = *--s;
357 		}
358 
359 	return dest;
360 }
361 #endif
362 
363 #ifndef __HAVE_ARCH_MEMCMP
364 /**
365  * memcmp - Compare two areas of memory
366  * @cs: One area of memory
367  * @ct: Another area of memory
368  * @count: The size of the area.
369  */
370 int (memcmp)(const void *cs, const void *ct, size_t count)
371 {
372 	const unsigned char *su1, *su2;
373 	int res = 0;
374 
375 	for( su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--)
376 		if ((res = *su1 - *su2) != 0)
377 			break;
378 	return res;
379 }
380 #endif
381 
382 #ifndef __HAVE_ARCH_MEMSCAN
383 /**
384  * memscan - Find a character in an area of memory.
385  * @addr: The memory area
386  * @c: The byte to search for
387  * @size: The size of the area.
388  *
389  * returns the address of the first occurrence of @c, or 1 byte past
390  * the area if @c is not found
391  */
memscan(void * addr,int c,size_t size)392 void * memscan(void * addr, int c, size_t size)
393 {
394 	unsigned char * p = (unsigned char *) addr;
395 
396 	while (size) {
397 		if (*p == c)
398 			return (void *) p;
399 		p++;
400 		size--;
401 	}
402   	return (void *) p;
403 }
404 #endif
405 
406 #ifndef __HAVE_ARCH_STRSTR
407 /**
408  * strstr - Find the first substring in a %NUL terminated string
409  * @s1: The string to be searched
410  * @s2: The string to search for
411  */
412 char *(strstr)(const char *s1, const char *s2)
413 {
414 	int l1, l2;
415 
416 	l2 = strlen(s2);
417 	if (!l2)
418 		return (char *) s1;
419 	l1 = strlen(s1);
420 	while (l1 >= l2) {
421 		l1--;
422 		if (!memcmp(s1,s2,l2))
423 			return (char *) s1;
424 		s1++;
425 	}
426 	return NULL;
427 }
428 #endif
429 
430 #ifndef __HAVE_ARCH_MEMCHR
431 /**
432  * memchr - Find a character in an area of memory.
433  * @s: The memory area
434  * @c: The byte to search for
435  * @n: The size of the area.
436  *
437  * returns the address of the first occurrence of @c, or %NULL
438  * if @c is not found
439  */
440 void *(memchr)(const void *s, int c, size_t n)
441 {
442 	const unsigned char *p = s;
443 	while (n-- != 0) {
444         	if ((unsigned char)c == *p++) {
445 			return (void *)(p-1);
446 		}
447 	}
448 	return NULL;
449 }
450 
451 #endif
452 
453 /*
454  * Local variables:
455  * mode: C
456  * c-file-style: "BSD"
457  * c-basic-offset: 8
458  * tab-width: 8
459  * indent-tabs-mode: t
460  * End:
461  */
462