Home | History | Annotate | Download | only in core
      1 /*
      2  *  Copyright (C) 1991, 1992  Linus Torvalds
      3  *  Copyright (C) 2004 Tobias Lorenz
      4  *
      5  *  string handling functions
      6  *  based on linux/lib/string.c
      7  *
      8  * This program is free software; you can redistribute it and/or modify
      9  * it under the terms of the GNU General Public License version 2 as
     10  * published by the Free Software Foundation.
     11  */
     12 
     13 /*
     14  * stupid library routines.. The optimized versions should generally be found
     15  * as inline code in <asm-xx/string.h>
     16  *
     17  * These are buggy as well..
     18  *
     19  * * Fri Jun 25 1999, Ingo Oeser <ioe (at) informatik.tu-chemnitz.de>
     20  * -  Added strsep() which will replace strtok() soon (because strsep() is
     21  *    reentrant and should be faster). Use only strsep() in new code, please.
     22  */
     23 
     24 /*
     25  * these are the standard string functions that are currently not used by
     26  * any code in etherboot. put into a separate file to avoid linking them in
     27  * with the rest of string.o
     28  * if anything ever does want to use a function of these, consider moving
     29  * the function in question back into string.c
     30  */
     31 
     32 #include <stdint.h>
     33 #include <stdlib.h>
     34 #include <string.h>
     35 #include <ctype.h>
     36 
     37 /* *** FROM string.c *** */
     38 
     39 #ifndef __HAVE_ARCH_STRNICMP
     40 /**
     41  * strnicmp - Case insensitive, length-limited string comparison
     42  * @s1: One string
     43  * @s2: The other string
     44  * @len: the maximum number of characters to compare
     45  */
     46 int strnicmp(const char *s1, const char *s2, size_t len)
     47 {
     48 	/* Yes, Virginia, it had better be unsigned */
     49 	unsigned char c1, c2;
     50 
     51 	c1 = 0;	c2 = 0;
     52 	if (len) {
     53 		do {
     54 			c1 = *s1; c2 = *s2;
     55 			s1++; s2++;
     56 			if (!c1)
     57 				break;
     58 			if (!c2)
     59 				break;
     60 			if (c1 == c2)
     61 				continue;
     62 			c1 = tolower(c1);
     63 			c2 = tolower(c2);
     64 			if (c1 != c2)
     65 				break;
     66 		} while (--len);
     67 	}
     68 	return (int)c1 - (int)c2;
     69 }
     70 #endif
     71 
     72 char * ___strtok;
     73 
     74 #ifndef __HAVE_ARCH_STRNCAT
     75 /**
     76  * strncat - Append a length-limited, %NUL-terminated string to another
     77  * @dest: The string to be appended to
     78  * @src: The string to append to it
     79  * @count: The maximum numbers of bytes to copy
     80  *
     81  * Note that in contrast to strncpy, strncat ensures the result is
     82  * terminated.
     83  */
     84 char * strncat(char *dest, const char *src, size_t count)
     85 {
     86 	char *tmp = dest;
     87 
     88 	if (count) {
     89 		while (*dest)
     90 			dest++;
     91 		while ((*dest++ = *src++)) {
     92 			if (--count == 0) {
     93 				*dest = '\0';
     94 				break;
     95 			}
     96 		}
     97 	}
     98 
     99 	return tmp;
    100 }
    101 #endif
    102 
    103 #ifndef __HAVE_ARCH_STRSPN
    104 /**
    105  * strspn - Calculate the length of the initial substring of @s which only
    106  * 	contain letters in @accept
    107  * @s: The string to be searched
    108  * @accept: The string to search for
    109  */
    110 size_t strspn(const char *s, const char *accept)
    111 {
    112 	const char *p;
    113 	const char *a;
    114 	size_t count = 0;
    115 
    116 	for (p = s; *p != '\0'; ++p) {
    117 		for (a = accept; *a != '\0'; ++a) {
    118 			if (*p == *a)
    119 				break;
    120 		}
    121 		if (*a == '\0')
    122 			return count;
    123 		++count;
    124 	}
    125 
    126 	return count;
    127 }
    128 #endif
    129 
    130 #ifndef __HAVE_ARCH_STRCSPN
    131 /**
    132  * strcspn - Calculate the length of the initial substring of @s which only
    133  * 	contain letters not in @reject
    134  * @s: The string to be searched
    135  * @accept: The string to search for
    136  */
    137 size_t strcspn(const char *s, const char *reject)
    138 {
    139 	const char *p;
    140 	const char *r;
    141 	size_t count = 0;
    142 
    143 	for (p = s; *p != '\0'; ++p) {
    144 		for (r = reject; *r != '\0'; ++r) {
    145 			if (*p == *r)
    146 				return count;
    147 		}
    148 		++count;
    149 	}
    150 
    151 	return count;
    152 }
    153 #endif
    154 
    155 #ifndef __HAVE_ARCH_STRPBRK
    156 /**
    157  * strpbrk - Find the first occurrence of a set of characters
    158  * @cs: The string to be searched
    159  * @ct: The characters to search for
    160  */
    161 char * strpbrk(const char * cs,const char * ct)
    162 {
    163 	const char *sc1,*sc2;
    164 
    165 	for( sc1 = cs; *sc1 != '\0'; ++sc1) {
    166 		for( sc2 = ct; *sc2 != '\0'; ++sc2) {
    167 			if (*sc1 == *sc2)
    168 				return (char *) sc1;
    169 		}
    170 	}
    171 	return NULL;
    172 }
    173 #endif
    174 
    175 #ifndef __HAVE_ARCH_STRTOK
    176 /**
    177  * strtok - Split a string into tokens
    178  * @s: The string to be searched
    179  * @ct: The characters to search for
    180  *
    181  * WARNING: strtok is deprecated, use strsep instead.
    182  */
    183 char * strtok(char * s,const char * ct)
    184 {
    185 	char *sbegin, *send;
    186 
    187 	sbegin  = s ? s : ___strtok;
    188 	if (!sbegin) {
    189 		return NULL;
    190 	}
    191 	sbegin += strspn(sbegin,ct);
    192 	if (*sbegin == '\0') {
    193 		___strtok = NULL;
    194 		return( NULL );
    195 	}
    196 	send = strpbrk( sbegin, ct);
    197 	if (send && *send != '\0')
    198 		*send++ = '\0';
    199 	___strtok = send;
    200 	return (sbegin);
    201 }
    202 #endif
    203 
    204 #ifndef __HAVE_ARCH_STRSEP
    205 /**
    206  * strsep - Split a string into tokens
    207  * @s: The string to be searched
    208  * @ct: The characters to search for
    209  *
    210  * strsep() updates @s to point after the token, ready for the next call.
    211  *
    212  * It returns empty tokens, too, behaving exactly like the libc function
    213  * of that name. In fact, it was stolen from glibc2 and de-fancy-fied.
    214  * Same semantics, slimmer shape. ;)
    215  */
    216 char * strsep(char **s, const char *ct)
    217 {
    218 	char *sbegin = *s, *end;
    219 
    220 	if (sbegin == NULL)
    221 		return NULL;
    222 
    223 	end = strpbrk(sbegin, ct);
    224 	if (end)
    225 		*end++ = '\0';
    226 	*s = end;
    227 
    228 	return sbegin;
    229 }
    230 #endif
    231 
    232 #ifndef __HAVE_ARCH_BCOPY
    233 /**
    234  * bcopy - Copy one area of memory to another
    235  * @src: Where to copy from
    236  * @dest: Where to copy to
    237  * @count: The size of the area.
    238  *
    239  * Note that this is the same as memcpy(), with the arguments reversed.
    240  * memcpy() is the standard, bcopy() is a legacy BSD function.
    241  *
    242  * You should not use this function to access IO space, use memcpy_toio()
    243  * or memcpy_fromio() instead.
    244  */
    245 char * bcopy(const char * src, char * dest, int count)
    246 {
    247 	return memmove(dest,src,count);
    248 }
    249 #endif
    250 
    251 #ifndef __HAVE_ARCH_MEMSCAN
    252 /**
    253  * memscan - Find a character in an area of memory.
    254  * @addr: The memory area
    255  * @c: The byte to search for
    256  * @size: The size of the area.
    257  *
    258  * returns the address of the first occurrence of @c, or 1 byte past
    259  * the area if @c is not found
    260  */
    261 void * memscan(const void * addr, int c, size_t size)
    262 {
    263 	unsigned char * p = (unsigned char *) addr;
    264 
    265 	while (size) {
    266 		if (*p == c)
    267 			return (void *) p;
    268 		p++;
    269 		size--;
    270 	}
    271   	return (void *) p;
    272 }
    273 #endif
    274