Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


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