original comment: +Wilson03172004,marked due to this pci host does not support MWI
[linux-2.4.git] / 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  
18 #include <linux/types.h>
19 #include <linux/string.h>
20 #include <linux/ctype.h>
21
22 #ifndef __HAVE_ARCH_STRNICMP
23 /**
24  * strnicmp - Case insensitive, length-limited string comparison
25  * @s1: One string
26  * @s2: The other string
27  * @len: the maximum number of characters to compare
28  */
29 int strnicmp(const char *s1, const char *s2, size_t len)
30 {
31         /* Yes, Virginia, it had better be unsigned */
32         unsigned char c1, c2;
33
34         c1 = 0; c2 = 0;
35         if (len) {
36                 do {
37                         c1 = *s1; c2 = *s2;
38                         s1++; s2++;
39                         if (!c1)
40                                 break;
41                         if (!c2)
42                                 break;
43                         if (c1 == c2)
44                                 continue;
45                         c1 = tolower(c1);
46                         c2 = tolower(c2);
47                         if (c1 != c2)
48                                 break;
49                 } while (--len);
50         }
51         return (int)c1 - (int)c2;
52 }
53 #endif
54
55 char * ___strtok;
56
57 #ifndef __HAVE_ARCH_STRCPY
58 /**
59  * strcpy - Copy a %NUL terminated string
60  * @dest: Where to copy the string to
61  * @src: Where to copy the string from
62  */
63 char * strcpy(char * dest,const char *src)
64 {
65         char *tmp = dest;
66
67         while ((*dest++ = *src++) != '\0')
68                 /* nothing */;
69         return tmp;
70 }
71 #endif
72
73 #ifndef __HAVE_ARCH_STRNCPY
74 /**
75  * strncpy - Copy a length-limited, %NUL-terminated string
76  * @dest: Where to copy the string to
77  * @src: Where to copy the string from
78  * @count: The maximum number of bytes to copy
79  *
80  * Note that unlike userspace strncpy, this does not %NUL-pad the buffer.
81  * However, the result is not %NUL-terminated if the source exceeds
82  * @count bytes.
83  */
84 char * strncpy(char * dest,const char *src,size_t count)
85 {
86         char *tmp = dest;
87
88         while (count-- && (*dest++ = *src++) != '\0')
89                 /* nothing */;
90
91         return tmp;
92 }
93 #endif
94
95 #ifndef __HAVE_ARCH_STRCAT
96 /**
97  * strcat - Append one %NUL-terminated string to another
98  * @dest: The string to be appended to
99  * @src: The string to append to it
100  */
101 char * strcat(char * dest, const char * src)
102 {
103         char *tmp = dest;
104
105         while (*dest)
106                 dest++;
107         while ((*dest++ = *src++) != '\0')
108                 ;
109
110         return tmp;
111 }
112 #endif
113
114 #ifndef __HAVE_ARCH_STRNCAT
115 /**
116  * strncat - Append a length-limited, %NUL-terminated string to another
117  * @dest: The string to be appended to
118  * @src: The string to append to it
119  * @count: The maximum numbers of bytes to copy
120  *
121  * Note that in contrast to strncpy, strncat ensures the result is
122  * terminated.
123  */
124 char * strncat(char *dest, const char *src, size_t count)
125 {
126         char *tmp = dest;
127
128         if (count) {
129                 while (*dest)
130                         dest++;
131                 while ((*dest++ = *src++)) {
132                         if (--count == 0) {
133                                 *dest = '\0';
134                                 break;
135                         }
136                 }
137         }
138
139         return tmp;
140 }
141 #endif
142
143 #ifndef __HAVE_ARCH_STRCMP
144 /**
145  * strcmp - Compare two strings
146  * @cs: One string
147  * @ct: Another string
148  */
149 int strcmp(const char * cs,const char * ct)
150 {
151         register signed char __res;
152
153         while (1) {
154                 if ((__res = *cs - *ct++) != 0 || !*cs++)
155                         break;
156         }
157
158         return __res;
159 }
160 #endif
161
162 #ifndef __HAVE_ARCH_STRNCMP
163 /**
164  * strncmp - Compare two length-limited strings
165  * @cs: One string
166  * @ct: Another string
167  * @count: The maximum number of bytes to compare
168  */
169 int strncmp(const char * cs,const char * ct,size_t count)
170 {
171         register signed char __res = 0;
172
173         while (count) {
174                 if ((__res = *cs - *ct++) != 0 || !*cs++)
175                         break;
176                 count--;
177         }
178
179         return __res;
180 }
181 #endif
182
183 #ifndef __HAVE_ARCH_STRCHR
184 /**
185  * strchr - Find the first occurrence of a character in a string
186  * @s: The string to be searched
187  * @c: The character to search for
188  */
189 char * strchr(const char * s, int c)
190 {
191         for(; *s != (char) c; ++s)
192                 if (*s == '\0')
193                         return NULL;
194         return (char *) s;
195 }
196 #endif
197
198 #ifndef __HAVE_ARCH_STRRCHR
199 /**
200  * strrchr - Find the last occurrence of a character in a string
201  * @s: The string to be searched
202  * @c: The character to search for
203  */
204 char * strrchr(const char * s, int c)
205 {
206        const char *p = s + strlen(s);
207        do {
208            if (*p == (char)c)
209                return (char *)p;
210        } while (--p >= s);
211        return NULL;
212 }
213 #endif
214
215 #ifndef __HAVE_ARCH_STRLEN
216 /**
217  * strlen - Find the length of a string
218  * @s: The string to be sized
219  */
220 size_t strlen(const char * s)
221 {
222         const char *sc;
223
224         for (sc = s; *sc != '\0'; ++sc)
225                 /* nothing */;
226         return sc - s;
227 }
228 #endif
229
230 #ifndef __HAVE_ARCH_STRNLEN
231 /**
232  * strnlen - Find the length of a length-limited string
233  * @s: The string to be sized
234  * @count: The maximum number of bytes to search
235  */
236 size_t strnlen(const char * s, size_t count)
237 {
238         const char *sc;
239
240         for (sc = s; count-- && *sc != '\0'; ++sc)
241                 /* nothing */;
242         return sc - s;
243 }
244 #endif
245
246 #ifndef __HAVE_ARCH_STRSPN
247 /**
248  * strspn - Calculate the length of the initial substring of @s which only
249  *      contain letters in @accept
250  * @s: The string to be searched
251  * @accept: The string to search for
252  */
253 size_t strspn(const char *s, const char *accept)
254 {
255         const char *p;
256         const char *a;
257         size_t count = 0;
258
259         for (p = s; *p != '\0'; ++p) {
260                 for (a = accept; *a != '\0'; ++a) {
261                         if (*p == *a)
262                                 break;
263                 }
264                 if (*a == '\0')
265                         return count;
266                 ++count;
267         }
268
269         return count;
270 }
271 #endif
272
273 #ifndef __HAVE_ARCH_STRPBRK
274 /**
275  * strpbrk - Find the first occurrence of a set of characters
276  * @cs: The string to be searched
277  * @ct: The characters to search for
278  */
279 char * strpbrk(const char * cs,const char * ct)
280 {
281         const char *sc1,*sc2;
282
283         for( sc1 = cs; *sc1 != '\0'; ++sc1) {
284                 for( sc2 = ct; *sc2 != '\0'; ++sc2) {
285                         if (*sc1 == *sc2)
286                                 return (char *) sc1;
287                 }
288         }
289         return NULL;
290 }
291 #endif
292
293 #ifndef __HAVE_ARCH_STRTOK
294 /**
295  * strtok - Split a string into tokens
296  * @s: The string to be searched
297  * @ct: The characters to search for
298  *
299  * WARNING: strtok is deprecated, use strsep instead.
300  */
301 char * strtok(char * s,const char * ct)
302 {
303         char *sbegin, *send;
304
305         sbegin  = s ? s : ___strtok;
306         if (!sbegin) {
307                 return NULL;
308         }
309         sbegin += strspn(sbegin,ct);
310         if (*sbegin == '\0') {
311                 ___strtok = NULL;
312                 return( NULL );
313         }
314         send = strpbrk( sbegin, ct);
315         if (send && *send != '\0')
316                 *send++ = '\0';
317         ___strtok = send;
318         return (sbegin);
319 }
320 #endif
321
322 #ifndef __HAVE_ARCH_STRSEP
323 /**
324  * strsep - Split a string into tokens
325  * @s: The string to be searched
326  * @ct: The characters to search for
327  *
328  * strsep() updates @s to point after the token, ready for the next call.
329  *
330  * It returns empty tokens, too, behaving exactly like the libc function
331  * of that name. In fact, it was stolen from glibc2 and de-fancy-fied.
332  * Same semantics, slimmer shape. ;)
333  */
334 char * strsep(char **s, const char *ct)
335 {
336         char *sbegin = *s, *end;
337
338         if (sbegin == NULL)
339                 return NULL;
340
341         end = strpbrk(sbegin, ct);
342         if (end)
343                 *end++ = '\0';
344         *s = end;
345
346         return sbegin;
347 }
348 #endif
349
350 #ifndef __HAVE_ARCH_MEMSET
351 /**
352  * memset - Fill a region of memory with the given value
353  * @s: Pointer to the start of the area.
354  * @c: The byte to fill the area with
355  * @count: The size of the area.
356  *
357  * Do not use memset() to access IO space, use memset_io() instead.
358  */
359 void * memset(void * s,int c,size_t count)
360 {
361         char *xs = (char *) s;
362
363         while (count--)
364                 *xs++ = c;
365
366         return s;
367 }
368 #endif
369
370 #ifndef __HAVE_ARCH_BCOPY
371 /**
372  * bcopy - Copy one area of memory to another
373  * @src: Where to copy from
374  * @dest: Where to copy to
375  * @count: The size of the area.
376  *
377  * Note that this is the same as memcpy(), with the arguments reversed.
378  * memcpy() is the standard, bcopy() is a legacy BSD function.
379  *
380  * You should not use this function to access IO space, use memcpy_toio()
381  * or memcpy_fromio() instead.
382  */
383 void bcopy(const void * srcp, void * destp, size_t count)
384 {
385         const char *src = srcp;
386         char *dest = destp;
387
388         while (count--)
389                 *dest++ = *src++;
390 }
391 #endif
392
393 #ifndef __HAVE_ARCH_MEMCPY
394 /**
395  * memcpy - Copy one area of memory to another
396  * @dest: Where to copy to
397  * @src: Where to copy from
398  * @count: The size of the area.
399  *
400  * You should not use this function to access IO space, use memcpy_toio()
401  * or memcpy_fromio() instead.
402  */
403 void * memcpy(void * dest,const void *src,size_t count)
404 {
405         char *tmp = (char *) dest, *s = (char *) src;
406
407         while (count--)
408                 *tmp++ = *s++;
409
410         return dest;
411 }
412 #endif
413
414 #ifndef __HAVE_ARCH_MEMMOVE
415 /**
416  * memmove - Copy one area of memory to another
417  * @dest: Where to copy to
418  * @src: Where to copy from
419  * @count: The size of the area.
420  *
421  * Unlike memcpy(), memmove() copes with overlapping areas.
422  */
423 void * memmove(void * dest,const void *src,size_t count)
424 {
425         char *tmp, *s;
426
427         if (dest <= src) {
428                 tmp = (char *) dest;
429                 s = (char *) src;
430                 while (count--)
431                         *tmp++ = *s++;
432                 }
433         else {
434                 tmp = (char *) dest + count;
435                 s = (char *) src + count;
436                 while (count--)
437                         *--tmp = *--s;
438                 }
439
440         return dest;
441 }
442 #endif
443
444 #ifndef __HAVE_ARCH_MEMCMP
445 /**
446  * memcmp - Compare two areas of memory
447  * @cs: One area of memory
448  * @ct: Another area of memory
449  * @count: The size of the area.
450  */
451 int memcmp(const void * cs,const void * ct,size_t count)
452 {
453         const unsigned char *su1, *su2;
454         int res = 0;
455
456         for( su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--)
457                 if ((res = *su1 - *su2) != 0)
458                         break;
459         return res;
460 }
461 #endif
462
463 #ifndef __HAVE_ARCH_MEMSCAN
464 /**
465  * memscan - Find a character in an area of memory.
466  * @addr: The memory area
467  * @c: The byte to search for
468  * @size: The size of the area.
469  *
470  * returns the address of the first occurrence of @c, or 1 byte past
471  * the area if @c is not found
472  */
473 void * memscan(void * addr, int c, size_t size)
474 {
475         unsigned char * p = (unsigned char *) addr;
476
477         while (size) {
478                 if (*p == c)
479                         return (void *) p;
480                 p++;
481                 size--;
482         }
483         return (void *) p;
484 }
485 #endif
486
487 #ifndef __HAVE_ARCH_STRSTR
488 /**
489  * strstr - Find the first substring in a %NUL terminated string
490  * @s1: The string to be searched
491  * @s2: The string to search for
492  */
493 char * strstr(const char * s1,const char * s2)
494 {
495         int l1, l2;
496
497         l2 = strlen(s2);
498         if (!l2)
499                 return (char *) s1;
500         l1 = strlen(s1);
501         while (l1 >= l2) {
502                 l1--;
503                 if (!memcmp(s1,s2,l2))
504                         return (char *) s1;
505                 s1++;
506         }
507         return NULL;
508 }
509 #endif
510
511 #ifndef __HAVE_ARCH_MEMCHR
512 /**
513  * memchr - Find a character in an area of memory.
514  * @s: The memory area
515  * @c: The byte to search for
516  * @n: The size of the area.
517  *
518  * returns the address of the first occurrence of @c, or %NULL
519  * if @c is not found
520  */
521 void *memchr(const void *s, int c, size_t n)
522 {
523         const unsigned char *p = s;
524         while (n-- != 0) {
525                 if ((unsigned char)c == *p++) {
526                         return (void *)(p-1);
527                 }
528         }
529         return NULL;
530 }
531
532 #endif