/root/src/xen/xen/common/string.c
Line | Count | Source (jump to first uncovered line) |
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 | | */ |
18 | | int strnicmp(const char *s1, const char *s2, size_t len) |
19 | 6 | { |
20 | 6 | /* Yes, Virginia, it had better be unsigned */ |
21 | 6 | unsigned char c1, c2; |
22 | 6 | |
23 | 6 | c1 = 0; c2 = 0; |
24 | 6 | if (len) { |
25 | 7 | do { |
26 | 7 | c1 = *s1; c2 = *s2; |
27 | 7 | s1++; s2++; |
28 | 7 | if (!c1) |
29 | 0 | break; |
30 | 7 | if (!c2) |
31 | 0 | break; |
32 | 7 | if (c1 == c2) |
33 | 1 | continue; |
34 | 6 | c1 = tolower(c1); |
35 | 6 | c2 = tolower(c2); |
36 | 6 | if (c1 != c2) |
37 | 6 | break; |
38 | 1 | } while (--len); |
39 | 6 | } |
40 | 6 | return (int)c1 - (int)c2; |
41 | 6 | } |
42 | | #endif |
43 | | |
44 | | #ifndef __HAVE_ARCH_STRCASECMP |
45 | | int (strcasecmp)(const char *s1, const char *s2) |
46 | 0 | { |
47 | 0 | int c1, c2; |
48 | 0 |
|
49 | 0 | do |
50 | 0 | { |
51 | 0 | c1 = tolower(*s1++); |
52 | 0 | c2 = tolower(*s2++); |
53 | 0 | } while ( c1 == c2 && c1 != 0 ); |
54 | 0 |
|
55 | 0 | return c1 - c2; |
56 | 0 | } |
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 | | */ |
71 | | size_t strlcpy(char *dest, const char *src, size_t size) |
72 | 31 | { |
73 | 31 | size_t ret = strlen(src); |
74 | 31 | |
75 | 31 | if (size) { |
76 | 31 | size_t len = (ret >= size) ? size-1 : ret; |
77 | 31 | memcpy(dest, src, len); |
78 | 31 | dest[len] = '\0'; |
79 | 31 | } |
80 | 31 | return ret; |
81 | 31 | } |
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 | | */ |
96 | | size_t strlcat(char *dest, const char *src, size_t size) |
97 | 0 | { |
98 | 0 | size_t slen = strlen(src); |
99 | 0 | size_t dlen = strnlen(dest, size); |
100 | 0 | char *p = dest + dlen; |
101 | 0 |
|
102 | 0 | while ((p - dest) < size) |
103 | 0 | if ((*p++ = *src++) == '\0') |
104 | 0 | break; |
105 | 0 |
|
106 | 0 | if (dlen < size) |
107 | 0 | *(p-1) = '\0'; |
108 | 0 |
|
109 | 0 | return slen + dlen; |
110 | 0 | } |
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 | 1.23k | { |
122 | 1.23k | register signed char __res; |
123 | 1.23k | |
124 | 1.71k | while (1) { |
125 | 1.71k | if ((__res = *cs - *ct++) != 0 || !*cs++) |
126 | 1.23k | break; |
127 | 1.71k | } |
128 | 1.23k | |
129 | 1.23k | return __res; |
130 | 1.23k | } |
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 | 13.1k | { |
142 | 13.1k | register signed char __res = 0; |
143 | 13.1k | |
144 | 13.3k | while (count) { |
145 | 13.3k | if ((__res = *cs - *ct++) != 0 || !*cs++) |
146 | 13.1k | break; |
147 | 225 | count--; |
148 | 225 | } |
149 | 13.1k | |
150 | 13.1k | return __res; |
151 | 13.1k | } |
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 | 728 | { |
162 | 14.6k | for(; *s != (char) c; ++s) |
163 | 14.3k | if (*s == '\0') |
164 | 408 | return NULL; |
165 | 320 | return (char *) s; |
166 | 728 | } |
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 | 0 | { |
177 | 0 | const char *p = s + strlen(s); |
178 | 0 | do { |
179 | 0 | if (*p == (char)c) |
180 | 0 | return (char *)p; |
181 | 0 | } while (--p >= s); |
182 | 0 | return NULL; |
183 | 0 | } |
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 | | */ |
191 | | size_t (strlen)(const char * s) |
192 | 428 | { |
193 | 428 | const char *sc; |
194 | 428 | |
195 | 5.70k | for (sc = s; *sc != '\0'; ++sc) |
196 | 5.27k | /* nothing */; |
197 | 428 | return sc - s; |
198 | 428 | } |
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 | | */ |
207 | | size_t strnlen(const char * s, size_t count) |
208 | 66 | { |
209 | 66 | const char *sc; |
210 | 66 | |
211 | 385 | for (sc = s; count-- && *sc != '\0'; ++sc) |
212 | 319 | /* nothing */; |
213 | 66 | return sc - s; |
214 | 66 | } |
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 | | */ |
224 | | size_t strspn(const char *s, const char *accept) |
225 | 0 | { |
226 | 0 | const char *p; |
227 | 0 | const char *a; |
228 | 0 | size_t count = 0; |
229 | 0 |
|
230 | 0 | for (p = s; *p != '\0'; ++p) { |
231 | 0 | for (a = accept; *a != '\0'; ++a) { |
232 | 0 | if (*p == *a) |
233 | 0 | break; |
234 | 0 | } |
235 | 0 | if (*a == '\0') |
236 | 0 | return count; |
237 | 0 | ++count; |
238 | 0 | } |
239 | 0 |
|
240 | 0 | return count; |
241 | 0 | } |
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 | | */ |
250 | | char * strpbrk(const char * cs,const char * ct) |
251 | 6 | { |
252 | 6 | const char *sc1,*sc2; |
253 | 6 | |
254 | 44 | for( sc1 = cs; *sc1 != '\0'; ++sc1) { |
255 | 190 | for( sc2 = ct; *sc2 != '\0'; ++sc2) { |
256 | 152 | if (*sc1 == *sc2) |
257 | 0 | return (char *) sc1; |
258 | 152 | } |
259 | 38 | } |
260 | 6 | return NULL; |
261 | 6 | } |
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 | | */ |
276 | | char * strsep(char **s, const char *ct) |
277 | 0 | { |
278 | 0 | char *sbegin = *s, *end; |
279 | 0 |
|
280 | 0 | if (sbegin == NULL) |
281 | 0 | return NULL; |
282 | 0 |
|
283 | 0 | end = strpbrk(sbegin, ct); |
284 | 0 | if (end) |
285 | 0 | *end++ = '\0'; |
286 | 0 | *s = end; |
287 | 0 |
|
288 | 0 | return sbegin; |
289 | 0 | } |
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 | 108k | { |
372 | 108k | const unsigned char *su1, *su2; |
373 | 108k | int res = 0; |
374 | 108k | |
375 | 3.26M | for( su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--) |
376 | 3.16M | if ((res = *su1 - *su2) != 0) |
377 | 10.1k | break; |
378 | 108k | return res; |
379 | 108k | } |
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 | | */ |
392 | | void * memscan(void * addr, int c, size_t size) |
393 | 0 | { |
394 | 0 | unsigned char * p = (unsigned char *) addr; |
395 | 0 |
|
396 | 0 | while (size) { |
397 | 0 | if (*p == c) |
398 | 0 | return (void *) p; |
399 | 0 | p++; |
400 | 0 | size--; |
401 | 0 | } |
402 | 0 | return (void *) p; |
403 | 0 | } |
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 | 94 | { |
414 | 94 | int l1, l2; |
415 | 94 | |
416 | 94 | l2 = strlen(s2); |
417 | 94 | if (!l2) |
418 | 0 | return (char *) s1; |
419 | 94 | l1 = strlen(s1); |
420 | 433 | while (l1 >= l2) { |
421 | 364 | l1--; |
422 | 364 | if (!memcmp(s1,s2,l2)) |
423 | 25 | return (char *) s1; |
424 | 339 | s1++; |
425 | 339 | } |
426 | 69 | return NULL; |
427 | 94 | } |
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 | 0 | { |
442 | 0 | const unsigned char *p = s; |
443 | 0 | while (n-- != 0) { |
444 | 0 | if ((unsigned char)c == *p++) { |
445 | 0 | return (void *)(p-1); |
446 | 0 | } |
447 | 0 | } |
448 | 0 | return NULL; |
449 | 0 | } |
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 | | */ |