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