|  | @@ -1,353 +1,368 @@
 | 
		
	
		
			
			| 1 | 1 |  /*
 | 
		
	
		
			
			| 2 |  | - *  Copyright (C) 1991, 1992  Linus Torvalds
 | 
		
	
		
			
			| 3 |  | - *  Copyright (C) 2004 Tobias Lorenz
 | 
		
	
		
			
			|  | 2 | + * Copyright (C) 2015 Michael Brown <mbrown@fensystems.co.uk>.
 | 
		
	
		
			
			| 4 | 3 |   *
 | 
		
	
		
			
			| 5 |  | - *  string handling functions
 | 
		
	
		
			
			| 6 |  | - *  based on linux/lib/string.c
 | 
		
	
		
			
			|  | 4 | + * This program is free software; you can redistribute it and/or
 | 
		
	
		
			
			|  | 5 | + * modify it under the terms of the GNU General Public License as
 | 
		
	
		
			
			|  | 6 | + * published by the Free Software Foundation; either version 2 of the
 | 
		
	
		
			
			|  | 7 | + * License, or (at your option) any later version.
 | 
		
	
		
			
			| 7 | 8 |   *
 | 
		
	
		
			
			| 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.
 | 
		
	
		
			
			|  | 9 | + * This program is distributed in the hope that it will be useful, but
 | 
		
	
		
			
			|  | 10 | + * WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
		
	
		
			
			|  | 11 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
		
	
		
			
			|  | 12 | + * General Public License for more details.
 | 
		
	
		
			
			|  | 13 | + *
 | 
		
	
		
			
			|  | 14 | + * You should have received a copy of the GNU General Public License
 | 
		
	
		
			
			|  | 15 | + * along with this program; if not, write to the Free Software
 | 
		
	
		
			
			|  | 16 | + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
		
	
		
			
			|  | 17 | + * 02110-1301, USA.
 | 
		
	
		
			
			| 11 | 18 |   */
 | 
		
	
		
			
			| 12 | 19 |  
 | 
		
	
		
			
			| 13 |  | -FILE_LICENCE ( GPL2_ONLY );
 | 
		
	
		
			
			|  | 20 | +FILE_LICENCE ( GPL2_OR_LATER );
 | 
		
	
		
			
			| 14 | 21 |  
 | 
		
	
		
			
			| 15 |  | -/*
 | 
		
	
		
			
			| 16 |  | - * stupid library routines.. The optimized versions should generally be found
 | 
		
	
		
			
			| 17 |  | - * as inline code in <asm-xx/string.h>
 | 
		
	
		
			
			| 18 |  | - *
 | 
		
	
		
			
			| 19 |  | - * These are buggy as well..
 | 
		
	
		
			
			| 20 |  | - *
 | 
		
	
		
			
			| 21 |  | - * * Fri Jun 25 1999, Ingo Oeser <ioe@informatik.tu-chemnitz.de>
 | 
		
	
		
			
			| 22 |  | - * -  Added strsep() which will replace strtok() soon (because strsep() is
 | 
		
	
		
			
			| 23 |  | - *    reentrant and should be faster). Use only strsep() in new code, please.
 | 
		
	
		
			
			| 24 |  | - */
 | 
		
	
		
			
			| 25 |  | - 
 | 
		
	
		
			
			|  | 22 | +#include <stddef.h>
 | 
		
	
		
			
			| 26 | 23 |  #include <stdint.h>
 | 
		
	
		
			
			| 27 | 24 |  #include <stdlib.h>
 | 
		
	
		
			
			| 28 | 25 |  #include <string.h>
 | 
		
	
		
			
			| 29 | 26 |  #include <ctype.h>
 | 
		
	
		
			
			| 30 | 27 |  
 | 
		
	
		
			
			| 31 |  | -/* *** FROM string.c *** */
 | 
		
	
		
			
			|  | 28 | +/** @file
 | 
		
	
		
			
			|  | 29 | + *
 | 
		
	
		
			
			|  | 30 | + * String functions
 | 
		
	
		
			
			|  | 31 | + *
 | 
		
	
		
			
			|  | 32 | + */
 | 
		
	
		
			
			| 32 | 33 |  
 | 
		
	
		
			
			| 33 |  | -#ifndef __HAVE_ARCH_STRCPY
 | 
		
	
		
			
			| 34 | 34 |  /**
 | 
		
	
		
			
			| 35 |  | - * strcpy - Copy a %NUL terminated string
 | 
		
	
		
			
			| 36 |  | - * @dest: Where to copy the string to
 | 
		
	
		
			
			| 37 |  | - * @src: Where to copy the string from
 | 
		
	
		
			
			|  | 35 | + * Fill memory region
 | 
		
	
		
			
			|  | 36 | + *
 | 
		
	
		
			
			|  | 37 | + * @v dest		Destination region
 | 
		
	
		
			
			|  | 38 | + * @v character		Fill character
 | 
		
	
		
			
			|  | 39 | + * @v len		Length
 | 
		
	
		
			
			|  | 40 | + * @ret dest		Destination region
 | 
		
	
		
			
			| 38 | 41 |   */
 | 
		
	
		
			
			| 39 |  | -char * strcpy(char * dest,const char *src)
 | 
		
	
		
			
			| 40 |  | -{
 | 
		
	
		
			
			| 41 |  | -	char *tmp = dest;
 | 
		
	
		
			
			|  | 42 | +void * generic_memset ( void *dest, int character, size_t len ) {
 | 
		
	
		
			
			|  | 43 | +	uint8_t *dest_bytes = dest;
 | 
		
	
		
			
			| 42 | 44 |  
 | 
		
	
		
			
			| 43 |  | -	while ((*dest++ = *src++) != '\0')
 | 
		
	
		
			
			| 44 |  | -		/* nothing */;
 | 
		
	
		
			
			| 45 |  | -	return tmp;
 | 
		
	
		
			
			|  | 45 | +	while ( len-- )
 | 
		
	
		
			
			|  | 46 | +		*(dest_bytes++) = character;
 | 
		
	
		
			
			|  | 47 | +	return dest;
 | 
		
	
		
			
			| 46 | 48 |  }
 | 
		
	
		
			
			| 47 |  | -#endif
 | 
		
	
		
			
			| 48 | 49 |  
 | 
		
	
		
			
			| 49 |  | -#ifndef __HAVE_ARCH_STRNCPY
 | 
		
	
		
			
			| 50 | 50 |  /**
 | 
		
	
		
			
			| 51 |  | - * strncpy - Copy a length-limited, %NUL-terminated string
 | 
		
	
		
			
			| 52 |  | - * @dest: Where to copy the string to
 | 
		
	
		
			
			| 53 |  | - * @src: Where to copy the string from
 | 
		
	
		
			
			| 54 |  | - * @count: The maximum number of bytes to copy
 | 
		
	
		
			
			|  | 51 | + * Copy memory region
 | 
		
	
		
			
			| 55 | 52 |   *
 | 
		
	
		
			
			| 56 |  | - * Note that unlike userspace strncpy, this does not %NUL-pad the buffer.
 | 
		
	
		
			
			| 57 |  | - * However, the result is not %NUL-terminated if the source exceeds
 | 
		
	
		
			
			| 58 |  | - * @count bytes.
 | 
		
	
		
			
			|  | 53 | + * @v dest		Destination region
 | 
		
	
		
			
			|  | 54 | + * @v src		Source region
 | 
		
	
		
			
			|  | 55 | + * @v len		Length
 | 
		
	
		
			
			|  | 56 | + * @ret dest		Destination region
 | 
		
	
		
			
			| 59 | 57 |   */
 | 
		
	
		
			
			| 60 |  | -char * strncpy(char * dest,const char *src,size_t count)
 | 
		
	
		
			
			| 61 |  | -{
 | 
		
	
		
			
			| 62 |  | -	char *tmp = dest;
 | 
		
	
		
			
			| 63 |  | -
 | 
		
	
		
			
			| 64 |  | -	while (count-- && (*dest++ = *src++) != '\0')
 | 
		
	
		
			
			| 65 |  | -		/* nothing */;
 | 
		
	
		
			
			|  | 58 | +void * generic_memcpy ( void *dest, const void *src, size_t len ) {
 | 
		
	
		
			
			|  | 59 | +	const uint8_t *src_bytes = src;
 | 
		
	
		
			
			|  | 60 | +	uint8_t *dest_bytes = dest;
 | 
		
	
		
			
			| 66 | 61 |  
 | 
		
	
		
			
			| 67 |  | -	return tmp;
 | 
		
	
		
			
			|  | 62 | +	while ( len-- )
 | 
		
	
		
			
			|  | 63 | +		*(dest_bytes++) = *(src_bytes++);
 | 
		
	
		
			
			|  | 64 | +	return dest;
 | 
		
	
		
			
			| 68 | 65 |  }
 | 
		
	
		
			
			| 69 |  | -#endif
 | 
		
	
		
			
			| 70 | 66 |  
 | 
		
	
		
			
			| 71 |  | -#ifndef __HAVE_ARCH_STRCAT
 | 
		
	
		
			
			| 72 | 67 |  /**
 | 
		
	
		
			
			| 73 |  | - * strcat - Append one %NUL-terminated string to another
 | 
		
	
		
			
			| 74 |  | - * @dest: The string to be appended to
 | 
		
	
		
			
			| 75 |  | - * @src: The string to append to it
 | 
		
	
		
			
			|  | 68 | + * Copy (possibly overlapping) memory region
 | 
		
	
		
			
			|  | 69 | + *
 | 
		
	
		
			
			|  | 70 | + * @v dest		Destination region
 | 
		
	
		
			
			|  | 71 | + * @v src		Source region
 | 
		
	
		
			
			|  | 72 | + * @v len		Length
 | 
		
	
		
			
			|  | 73 | + * @ret dest		Destination region
 | 
		
	
		
			
			| 76 | 74 |   */
 | 
		
	
		
			
			| 77 |  | -char * strcat(char * dest, const char * src)
 | 
		
	
		
			
			| 78 |  | -{
 | 
		
	
		
			
			| 79 |  | -	char *tmp = dest;
 | 
		
	
		
			
			| 80 |  | -
 | 
		
	
		
			
			| 81 |  | -	while (*dest)
 | 
		
	
		
			
			| 82 |  | -		dest++;
 | 
		
	
		
			
			| 83 |  | -	while ((*dest++ = *src++) != '\0')
 | 
		
	
		
			
			| 84 |  | -		;
 | 
		
	
		
			
			| 85 |  | -
 | 
		
	
		
			
			| 86 |  | -	return tmp;
 | 
		
	
		
			
			|  | 75 | +void * generic_memmove ( void *dest, const void *src, size_t len ) {
 | 
		
	
		
			
			|  | 76 | +	const uint8_t *src_bytes = ( src + len );
 | 
		
	
		
			
			|  | 77 | +	uint8_t *dest_bytes = ( dest + len );
 | 
		
	
		
			
			|  | 78 | +
 | 
		
	
		
			
			|  | 79 | +	if ( dest < src )
 | 
		
	
		
			
			|  | 80 | +		return memcpy ( dest, src, len );
 | 
		
	
		
			
			|  | 81 | +	while ( len-- )
 | 
		
	
		
			
			|  | 82 | +		*(--dest_bytes) = *(--src_bytes);
 | 
		
	
		
			
			|  | 83 | +	return dest;
 | 
		
	
		
			
			| 87 | 84 |  }
 | 
		
	
		
			
			| 88 |  | -#endif
 | 
		
	
		
			
			| 89 | 85 |  
 | 
		
	
		
			
			| 90 |  | -#ifndef __HAVE_ARCH_STRCMP
 | 
		
	
		
			
			| 91 | 86 |  /**
 | 
		
	
		
			
			| 92 |  | - * strcmp - Compare two strings
 | 
		
	
		
			
			| 93 |  | - * @cs: One string
 | 
		
	
		
			
			| 94 |  | - * @ct: Another string
 | 
		
	
		
			
			|  | 87 | + * Compare memory regions
 | 
		
	
		
			
			|  | 88 | + *
 | 
		
	
		
			
			|  | 89 | + * @v first		First region
 | 
		
	
		
			
			|  | 90 | + * @v second		Second region
 | 
		
	
		
			
			|  | 91 | + * @v len		Length
 | 
		
	
		
			
			|  | 92 | + * @ret diff		Difference
 | 
		
	
		
			
			| 95 | 93 |   */
 | 
		
	
		
			
			| 96 |  | -int strcmp(const char * cs,const char * ct)
 | 
		
	
		
			
			| 97 |  | -{
 | 
		
	
		
			
			| 98 |  | -	register signed char __res;
 | 
		
	
		
			
			| 99 |  | -
 | 
		
	
		
			
			| 100 |  | -	while (1) {
 | 
		
	
		
			
			| 101 |  | -		if ((__res = *cs - *ct++) != 0 || !*cs++)
 | 
		
	
		
			
			| 102 |  | -			break;
 | 
		
	
		
			
			|  | 94 | +int memcmp ( const void *first, const void *second, size_t len ) {
 | 
		
	
		
			
			|  | 95 | +	const uint8_t *first_bytes = first;
 | 
		
	
		
			
			|  | 96 | +	const uint8_t *second_bytes = second;
 | 
		
	
		
			
			|  | 97 | +	int diff;
 | 
		
	
		
			
			|  | 98 | +
 | 
		
	
		
			
			|  | 99 | +	while ( len-- ) {
 | 
		
	
		
			
			|  | 100 | +		diff = ( *(second_bytes++) - *(first_bytes++) );
 | 
		
	
		
			
			|  | 101 | +		if ( diff )
 | 
		
	
		
			
			|  | 102 | +			return diff;
 | 
		
	
		
			
			| 103 | 103 |  	}
 | 
		
	
		
			
			| 104 |  | -
 | 
		
	
		
			
			| 105 |  | -	return __res;
 | 
		
	
		
			
			|  | 104 | +	return 0;
 | 
		
	
		
			
			| 106 | 105 |  }
 | 
		
	
		
			
			| 107 |  | -#endif
 | 
		
	
		
			
			| 108 | 106 |  
 | 
		
	
		
			
			| 109 |  | -#ifndef __HAVE_ARCH_STRNCMP
 | 
		
	
		
			
			| 110 | 107 |  /**
 | 
		
	
		
			
			| 111 |  | - * strncmp - Compare two length-limited strings
 | 
		
	
		
			
			| 112 |  | - * @cs: One string
 | 
		
	
		
			
			| 113 |  | - * @ct: Another string
 | 
		
	
		
			
			| 114 |  | - * @count: The maximum number of bytes to compare
 | 
		
	
		
			
			|  | 108 | + * Find character within a memory region
 | 
		
	
		
			
			|  | 109 | + *
 | 
		
	
		
			
			|  | 110 | + * @v src		Source region
 | 
		
	
		
			
			|  | 111 | + * @v character		Character to find
 | 
		
	
		
			
			|  | 112 | + * @v len		Length
 | 
		
	
		
			
			|  | 113 | + * @ret found		Found character, or NULL if not found
 | 
		
	
		
			
			| 115 | 114 |   */
 | 
		
	
		
			
			| 116 |  | -int strncmp(const char * cs,const char * ct,size_t count)
 | 
		
	
		
			
			| 117 |  | -{
 | 
		
	
		
			
			| 118 |  | -	register signed char __res = 0;
 | 
		
	
		
			
			|  | 115 | +void * memchr ( const void *src, int character, size_t len ) {
 | 
		
	
		
			
			|  | 116 | +	const uint8_t *src_bytes = src;
 | 
		
	
		
			
			| 119 | 117 |  
 | 
		
	
		
			
			| 120 |  | -	while (count) {
 | 
		
	
		
			
			| 121 |  | -		if ((__res = *cs - *ct++) != 0 || !*cs++)
 | 
		
	
		
			
			| 122 |  | -			break;
 | 
		
	
		
			
			| 123 |  | -		count--;
 | 
		
	
		
			
			|  | 118 | +	for ( ; len-- ; src_bytes++ ) {
 | 
		
	
		
			
			|  | 119 | +		if ( *src_bytes == character )
 | 
		
	
		
			
			|  | 120 | +			return ( ( void * ) src_bytes );
 | 
		
	
		
			
			| 124 | 121 |  	}
 | 
		
	
		
			
			| 125 |  | -
 | 
		
	
		
			
			| 126 |  | -	return __res;
 | 
		
	
		
			
			|  | 122 | +	return NULL;
 | 
		
	
		
			
			| 127 | 123 |  }
 | 
		
	
		
			
			| 128 |  | -#endif
 | 
		
	
		
			
			| 129 | 124 |  
 | 
		
	
		
			
			| 130 |  | -#ifndef __HAVE_ARCH_STRCASECMP
 | 
		
	
		
			
			| 131 |  | -int strcasecmp(const char *a, const char *b)
 | 
		
	
		
			
			| 132 |  | -{
 | 
		
	
		
			
			| 133 |  | -	while (*a && *b && (*a & ~0x20) == (*b & ~0x20)) {a++; b++; }
 | 
		
	
		
			
			| 134 |  | -	return((*a & ~0x20) - (*b & ~0x20));
 | 
		
	
		
			
			|  | 125 | +/**
 | 
		
	
		
			
			|  | 126 | + * Swap memory regions
 | 
		
	
		
			
			|  | 127 | + *
 | 
		
	
		
			
			|  | 128 | + * @v first		First region
 | 
		
	
		
			
			|  | 129 | + * @v second		Second region
 | 
		
	
		
			
			|  | 130 | + * @v len		Length
 | 
		
	
		
			
			|  | 131 | + * @ret first		First region
 | 
		
	
		
			
			|  | 132 | + */
 | 
		
	
		
			
			|  | 133 | +void * memswap ( void *first, void *second, size_t len ) {
 | 
		
	
		
			
			|  | 134 | +	uint8_t *first_bytes = first;
 | 
		
	
		
			
			|  | 135 | +	uint8_t *second_bytes = second;
 | 
		
	
		
			
			|  | 136 | +	uint8_t temp;
 | 
		
	
		
			
			|  | 137 | +
 | 
		
	
		
			
			|  | 138 | +	for ( ; len-- ; first_bytes++, second_bytes++ ) {
 | 
		
	
		
			
			|  | 139 | +		temp = *first_bytes;
 | 
		
	
		
			
			|  | 140 | +		*first_bytes = *second_bytes;
 | 
		
	
		
			
			|  | 141 | +		*second_bytes = temp;
 | 
		
	
		
			
			|  | 142 | +	}
 | 
		
	
		
			
			|  | 143 | +	return first;
 | 
		
	
		
			
			| 135 | 144 |  }
 | 
		
	
		
			
			| 136 |  | -#endif
 | 
		
	
		
			
			| 137 | 145 |  
 | 
		
	
		
			
			| 138 |  | -#ifndef __HAVE_ARCH_STRCHR
 | 
		
	
		
			
			| 139 | 146 |  /**
 | 
		
	
		
			
			| 140 |  | - * strchr - Find the first occurrence of a character in a string
 | 
		
	
		
			
			| 141 |  | - * @s: The string to be searched
 | 
		
	
		
			
			| 142 |  | - * @c: The character to search for
 | 
		
	
		
			
			|  | 147 | + * Compare strings
 | 
		
	
		
			
			|  | 148 | + *
 | 
		
	
		
			
			|  | 149 | + * @v first		First string
 | 
		
	
		
			
			|  | 150 | + * @v second		Second string
 | 
		
	
		
			
			|  | 151 | + * @ret diff		Difference
 | 
		
	
		
			
			| 143 | 152 |   */
 | 
		
	
		
			
			| 144 |  | -char * strchr(const char * s, int c)
 | 
		
	
		
			
			| 145 |  | -{
 | 
		
	
		
			
			| 146 |  | -	for(; *s != (char) c; ++s)
 | 
		
	
		
			
			| 147 |  | -		if (*s == '\0')
 | 
		
	
		
			
			| 148 |  | -			return NULL;
 | 
		
	
		
			
			| 149 |  | -	return (char *) s;
 | 
		
	
		
			
			|  | 153 | +int strcmp ( const char *first, const char *second ) {
 | 
		
	
		
			
			|  | 154 | +
 | 
		
	
		
			
			|  | 155 | +	return strncmp ( first, second, ~( ( size_t ) 0 ) );
 | 
		
	
		
			
			| 150 | 156 |  }
 | 
		
	
		
			
			| 151 |  | -#endif
 | 
		
	
		
			
			| 152 | 157 |  
 | 
		
	
		
			
			| 153 |  | -#ifndef __HAVE_ARCH_STRRCHR
 | 
		
	
		
			
			| 154 | 158 |  /**
 | 
		
	
		
			
			| 155 |  | - * strrchr - Find the last occurrence of a character in a string
 | 
		
	
		
			
			| 156 |  | - * @s: The string to be searched
 | 
		
	
		
			
			| 157 |  | - * @c: The character to search for
 | 
		
	
		
			
			|  | 159 | + * Compare strings
 | 
		
	
		
			
			|  | 160 | + *
 | 
		
	
		
			
			|  | 161 | + * @v first		First string
 | 
		
	
		
			
			|  | 162 | + * @v second		Second string
 | 
		
	
		
			
			|  | 163 | + * @v max		Maximum length to compare
 | 
		
	
		
			
			|  | 164 | + * @ret diff		Difference
 | 
		
	
		
			
			| 158 | 165 |   */
 | 
		
	
		
			
			| 159 |  | -char * strrchr(const char * s, int c)
 | 
		
	
		
			
			| 160 |  | -{
 | 
		
	
		
			
			| 161 |  | -       const char *p = s + strlen(s);
 | 
		
	
		
			
			| 162 |  | -       do {
 | 
		
	
		
			
			| 163 |  | -           if (*p == (char)c)
 | 
		
	
		
			
			| 164 |  | -               return (char *)p;
 | 
		
	
		
			
			| 165 |  | -       } while (--p >= s);
 | 
		
	
		
			
			| 166 |  | -       return NULL;
 | 
		
	
		
			
			|  | 166 | +int strncmp ( const char *first, const char *second, size_t max ) {
 | 
		
	
		
			
			|  | 167 | +	const uint8_t *first_bytes = ( ( const uint8_t * ) first );
 | 
		
	
		
			
			|  | 168 | +	const uint8_t *second_bytes = ( ( const uint8_t * ) second );
 | 
		
	
		
			
			|  | 169 | +	int diff;
 | 
		
	
		
			
			|  | 170 | +
 | 
		
	
		
			
			|  | 171 | +	for ( ; max-- ; first_bytes++, second_bytes++ ) {
 | 
		
	
		
			
			|  | 172 | +		diff = ( *second_bytes - *first_bytes );
 | 
		
	
		
			
			|  | 173 | +		if ( diff )
 | 
		
	
		
			
			|  | 174 | +			return diff;
 | 
		
	
		
			
			|  | 175 | +		if ( ! *first_bytes )
 | 
		
	
		
			
			|  | 176 | +			return 0;
 | 
		
	
		
			
			|  | 177 | +	}
 | 
		
	
		
			
			|  | 178 | +	return 0;
 | 
		
	
		
			
			| 167 | 179 |  }
 | 
		
	
		
			
			| 168 |  | -#endif
 | 
		
	
		
			
			| 169 | 180 |  
 | 
		
	
		
			
			| 170 |  | -#ifndef __HAVE_ARCH_STRLEN
 | 
		
	
		
			
			| 171 | 181 |  /**
 | 
		
	
		
			
			| 172 |  | - * strlen - Find the length of a string
 | 
		
	
		
			
			| 173 |  | - * @s: The string to be sized
 | 
		
	
		
			
			|  | 182 | + * Compare case-insensitive strings
 | 
		
	
		
			
			|  | 183 | + *
 | 
		
	
		
			
			|  | 184 | + * @v first		First string
 | 
		
	
		
			
			|  | 185 | + * @v second		Second string
 | 
		
	
		
			
			|  | 186 | + * @ret diff		Difference
 | 
		
	
		
			
			| 174 | 187 |   */
 | 
		
	
		
			
			| 175 |  | -size_t strlen(const char * s)
 | 
		
	
		
			
			| 176 |  | -{
 | 
		
	
		
			
			| 177 |  | -	const char *sc;
 | 
		
	
		
			
			| 178 |  | -
 | 
		
	
		
			
			| 179 |  | -	for (sc = s; *sc != '\0'; ++sc)
 | 
		
	
		
			
			| 180 |  | -		/* nothing */;
 | 
		
	
		
			
			| 181 |  | -	return sc - s;
 | 
		
	
		
			
			|  | 188 | +int strcasecmp ( const char *first, const char *second ) {
 | 
		
	
		
			
			|  | 189 | +	const uint8_t *first_bytes = ( ( const uint8_t * ) first );
 | 
		
	
		
			
			|  | 190 | +	const uint8_t *second_bytes = ( ( const uint8_t * ) second );
 | 
		
	
		
			
			|  | 191 | +	int diff;
 | 
		
	
		
			
			|  | 192 | +
 | 
		
	
		
			
			|  | 193 | +	for ( ; ; first_bytes++, second_bytes++ ) {
 | 
		
	
		
			
			|  | 194 | +		diff = ( toupper ( *second_bytes ) -
 | 
		
	
		
			
			|  | 195 | +			 toupper ( *first_bytes ) );
 | 
		
	
		
			
			|  | 196 | +		if ( diff )
 | 
		
	
		
			
			|  | 197 | +			return diff;
 | 
		
	
		
			
			|  | 198 | +		if ( ! *first_bytes )
 | 
		
	
		
			
			|  | 199 | +			return 0;
 | 
		
	
		
			
			|  | 200 | +	}
 | 
		
	
		
			
			| 182 | 201 |  }
 | 
		
	
		
			
			| 183 |  | -#endif
 | 
		
	
		
			
			| 184 | 202 |  
 | 
		
	
		
			
			| 185 |  | -#ifndef __HAVE_ARCH_STRNLEN
 | 
		
	
		
			
			| 186 | 203 |  /**
 | 
		
	
		
			
			| 187 |  | - * strnlen - Find the length of a length-limited string
 | 
		
	
		
			
			| 188 |  | - * @s: The string to be sized
 | 
		
	
		
			
			| 189 |  | - * @count: The maximum number of bytes to search
 | 
		
	
		
			
			|  | 204 | + * Get length of string
 | 
		
	
		
			
			|  | 205 | + *
 | 
		
	
		
			
			|  | 206 | + * @v src		String
 | 
		
	
		
			
			|  | 207 | + * @ret len		Length
 | 
		
	
		
			
			| 190 | 208 |   */
 | 
		
	
		
			
			| 191 |  | -size_t strnlen(const char * s, size_t count)
 | 
		
	
		
			
			| 192 |  | -{
 | 
		
	
		
			
			| 193 |  | -	const char *sc;
 | 
		
	
		
			
			|  | 209 | +size_t strlen ( const char *src ) {
 | 
		
	
		
			
			| 194 | 210 |  
 | 
		
	
		
			
			| 195 |  | -	for (sc = s; count-- && *sc != '\0'; ++sc)
 | 
		
	
		
			
			| 196 |  | -		/* nothing */;
 | 
		
	
		
			
			| 197 |  | -	return sc - s;
 | 
		
	
		
			
			|  | 211 | +	return strnlen ( src, ~( ( size_t ) 0 ) );
 | 
		
	
		
			
			| 198 | 212 |  }
 | 
		
	
		
			
			| 199 |  | -#endif
 | 
		
	
		
			
			| 200 | 213 |  
 | 
		
	
		
			
			| 201 |  | -#ifndef __HAVE_ARCH_MEMSET
 | 
		
	
		
			
			| 202 | 214 |  /**
 | 
		
	
		
			
			| 203 |  | - * memset - Fill a region of memory with the given value
 | 
		
	
		
			
			| 204 |  | - * @s: Pointer to the start of the area.
 | 
		
	
		
			
			| 205 |  | - * @c: The byte to fill the area with
 | 
		
	
		
			
			| 206 |  | - * @count: The size of the area.
 | 
		
	
		
			
			|  | 215 | + * Get length of string
 | 
		
	
		
			
			| 207 | 216 |   *
 | 
		
	
		
			
			| 208 |  | - * Do not use memset() to access IO space, use memset_io() instead.
 | 
		
	
		
			
			|  | 217 | + * @v src		String
 | 
		
	
		
			
			|  | 218 | + * @v max		Maximum length
 | 
		
	
		
			
			|  | 219 | + * @ret len		Length
 | 
		
	
		
			
			| 209 | 220 |   */
 | 
		
	
		
			
			| 210 |  | -void * memset(void * s,int c,size_t count)
 | 
		
	
		
			
			| 211 |  | -{
 | 
		
	
		
			
			| 212 |  | -	char *xs = (char *) s;
 | 
		
	
		
			
			| 213 |  | -
 | 
		
	
		
			
			| 214 |  | -	while (count--)
 | 
		
	
		
			
			| 215 |  | -		*xs++ = c;
 | 
		
	
		
			
			|  | 221 | +size_t strnlen ( const char *src, size_t max ) {
 | 
		
	
		
			
			|  | 222 | +	const uint8_t *src_bytes = ( ( const uint8_t * ) src );
 | 
		
	
		
			
			|  | 223 | +	size_t len = 0;
 | 
		
	
		
			
			| 216 | 224 |  
 | 
		
	
		
			
			| 217 |  | -	return s;
 | 
		
	
		
			
			|  | 225 | +	while ( max-- && *(src_bytes++) )
 | 
		
	
		
			
			|  | 226 | +		len++;
 | 
		
	
		
			
			|  | 227 | +	return len;
 | 
		
	
		
			
			| 218 | 228 |  }
 | 
		
	
		
			
			| 219 |  | -#endif
 | 
		
	
		
			
			| 220 | 229 |  
 | 
		
	
		
			
			| 221 |  | -#ifndef __HAVE_ARCH_MEMCPY
 | 
		
	
		
			
			| 222 | 230 |  /**
 | 
		
	
		
			
			| 223 |  | - * memcpy - Copy one area of memory to another
 | 
		
	
		
			
			| 224 |  | - * @dest: Where to copy to
 | 
		
	
		
			
			| 225 |  | - * @src: Where to copy from
 | 
		
	
		
			
			| 226 |  | - * @count: The size of the area.
 | 
		
	
		
			
			|  | 231 | + * Find character within a string
 | 
		
	
		
			
			| 227 | 232 |   *
 | 
		
	
		
			
			| 228 |  | - * You should not use this function to access IO space, use memcpy_toio()
 | 
		
	
		
			
			| 229 |  | - * or memcpy_fromio() instead.
 | 
		
	
		
			
			|  | 233 | + * @v src		String
 | 
		
	
		
			
			|  | 234 | + * @v character		Character to find
 | 
		
	
		
			
			|  | 235 | + * @ret found		Found character, or NULL if not found
 | 
		
	
		
			
			| 230 | 236 |   */
 | 
		
	
		
			
			| 231 |  | -void * memcpy(void * dest,const void *src,size_t count)
 | 
		
	
		
			
			| 232 |  | -{
 | 
		
	
		
			
			| 233 |  | -	char *tmp = (char *) dest, *s = (char *) src;
 | 
		
	
		
			
			| 234 |  | -
 | 
		
	
		
			
			| 235 |  | -	while (count--)
 | 
		
	
		
			
			| 236 |  | -		*tmp++ = *s++;
 | 
		
	
		
			
			|  | 237 | +char * strchr ( const char *src, int character ) {
 | 
		
	
		
			
			|  | 238 | +	const uint8_t *src_bytes = ( ( const uint8_t * ) src );
 | 
		
	
		
			
			| 237 | 239 |  
 | 
		
	
		
			
			| 238 |  | -	return dest;
 | 
		
	
		
			
			|  | 240 | +	for ( ; ; src_bytes++ ) {
 | 
		
	
		
			
			|  | 241 | +		if ( *src_bytes == character )
 | 
		
	
		
			
			|  | 242 | +			return ( ( char * ) src_bytes );
 | 
		
	
		
			
			|  | 243 | +		if ( ! *src_bytes )
 | 
		
	
		
			
			|  | 244 | +			return NULL;
 | 
		
	
		
			
			|  | 245 | +	}
 | 
		
	
		
			
			| 239 | 246 |  }
 | 
		
	
		
			
			| 240 |  | -#endif
 | 
		
	
		
			
			| 241 | 247 |  
 | 
		
	
		
			
			| 242 |  | -#ifndef __HAVE_ARCH_MEMMOVE
 | 
		
	
		
			
			| 243 | 248 |  /**
 | 
		
	
		
			
			| 244 |  | - * memmove - Copy one area of memory to another
 | 
		
	
		
			
			| 245 |  | - * @dest: Where to copy to
 | 
		
	
		
			
			| 246 |  | - * @src: Where to copy from
 | 
		
	
		
			
			| 247 |  | - * @count: The size of the area.
 | 
		
	
		
			
			|  | 249 | + * Find rightmost character within a string
 | 
		
	
		
			
			| 248 | 250 |   *
 | 
		
	
		
			
			| 249 |  | - * Unlike memcpy(), memmove() copes with overlapping areas.
 | 
		
	
		
			
			|  | 251 | + * @v src		String
 | 
		
	
		
			
			|  | 252 | + * @v character		Character to find
 | 
		
	
		
			
			|  | 253 | + * @ret found		Found character, or NULL if not found
 | 
		
	
		
			
			| 250 | 254 |   */
 | 
		
	
		
			
			| 251 |  | -void * memmove(void * dest,const void *src,size_t count)
 | 
		
	
		
			
			| 252 |  | -{
 | 
		
	
		
			
			| 253 |  | -	char *tmp, *s;
 | 
		
	
		
			
			| 254 |  | -
 | 
		
	
		
			
			| 255 |  | -	if (dest <= src) {
 | 
		
	
		
			
			| 256 |  | -		tmp = (char *) dest;
 | 
		
	
		
			
			| 257 |  | -		s = (char *) src;
 | 
		
	
		
			
			| 258 |  | -		while (count--)
 | 
		
	
		
			
			| 259 |  | -			*tmp++ = *s++;
 | 
		
	
		
			
			| 260 |  | -		}
 | 
		
	
		
			
			| 261 |  | -	else {
 | 
		
	
		
			
			| 262 |  | -		tmp = (char *) dest + count;
 | 
		
	
		
			
			| 263 |  | -		s = (char *) src + count;
 | 
		
	
		
			
			| 264 |  | -		while (count--)
 | 
		
	
		
			
			| 265 |  | -			*--tmp = *--s;
 | 
		
	
		
			
			| 266 |  | -		}
 | 
		
	
		
			
			| 267 |  | -
 | 
		
	
		
			
			| 268 |  | -	return dest;
 | 
		
	
		
			
			|  | 255 | +char * strrchr ( const char *src, int character ) {
 | 
		
	
		
			
			|  | 256 | +	const uint8_t *src_bytes = ( ( const uint8_t * ) src );
 | 
		
	
		
			
			|  | 257 | +	const uint8_t *start = src_bytes;
 | 
		
	
		
			
			|  | 258 | +
 | 
		
	
		
			
			|  | 259 | +	while ( *src_bytes )
 | 
		
	
		
			
			|  | 260 | +		src_bytes++;
 | 
		
	
		
			
			|  | 261 | +	for ( src_bytes-- ; src_bytes >= start ; src_bytes-- ) {
 | 
		
	
		
			
			|  | 262 | +		if ( *src_bytes == character )
 | 
		
	
		
			
			|  | 263 | +			return ( ( char * ) src_bytes );
 | 
		
	
		
			
			|  | 264 | +	}
 | 
		
	
		
			
			|  | 265 | +	return NULL;
 | 
		
	
		
			
			| 269 | 266 |  }
 | 
		
	
		
			
			| 270 |  | -#endif
 | 
		
	
		
			
			| 271 | 267 |  
 | 
		
	
		
			
			| 272 |  | -#ifndef __HAVE_ARCH_MEMCMP
 | 
		
	
		
			
			| 273 | 268 |  /**
 | 
		
	
		
			
			| 274 |  | - * memcmp - Compare two areas of memory
 | 
		
	
		
			
			| 275 |  | - * @cs: One area of memory
 | 
		
	
		
			
			| 276 |  | - * @ct: Another area of memory
 | 
		
	
		
			
			| 277 |  | - * @count: The size of the area.
 | 
		
	
		
			
			|  | 269 | + * Find substring
 | 
		
	
		
			
			|  | 270 | + *
 | 
		
	
		
			
			|  | 271 | + * @v haystack		String
 | 
		
	
		
			
			|  | 272 | + * @v needle		Substring
 | 
		
	
		
			
			|  | 273 | + * @ret found		Found substring, or NULL if not found
 | 
		
	
		
			
			| 278 | 274 |   */
 | 
		
	
		
			
			| 279 |  | -int memcmp(const void * cs,const void * ct,size_t count)
 | 
		
	
		
			
			| 280 |  | -{
 | 
		
	
		
			
			| 281 |  | -	const unsigned char *su1, *su2;
 | 
		
	
		
			
			| 282 |  | -	int res = 0;
 | 
		
	
		
			
			|  | 275 | +char * strstr ( const char *haystack, const char *needle ) {
 | 
		
	
		
			
			|  | 276 | +	size_t len = strlen ( needle );
 | 
		
	
		
			
			| 283 | 277 |  
 | 
		
	
		
			
			| 284 |  | -	for( su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--)
 | 
		
	
		
			
			| 285 |  | -		if ((res = *su1 - *su2) != 0)
 | 
		
	
		
			
			| 286 |  | -			break;
 | 
		
	
		
			
			| 287 |  | -	return res;
 | 
		
	
		
			
			|  | 278 | +	for ( ; *haystack ; haystack++ ) {
 | 
		
	
		
			
			|  | 279 | +		if ( memcmp ( haystack, needle, len ) == 0 )
 | 
		
	
		
			
			|  | 280 | +			return ( ( char * ) haystack );
 | 
		
	
		
			
			|  | 281 | +	}
 | 
		
	
		
			
			|  | 282 | +	return NULL;
 | 
		
	
		
			
			| 288 | 283 |  }
 | 
		
	
		
			
			| 289 |  | -#endif
 | 
		
	
		
			
			| 290 | 284 |  
 | 
		
	
		
			
			| 291 |  | -#ifndef __HAVE_ARCH_STRSTR
 | 
		
	
		
			
			| 292 | 285 |  /**
 | 
		
	
		
			
			| 293 |  | - * strstr - Find the first substring in a %NUL terminated string
 | 
		
	
		
			
			| 294 |  | - * @s1: The string to be searched
 | 
		
	
		
			
			| 295 |  | - * @s2: The string to search for
 | 
		
	
		
			
			|  | 286 | + * Copy string
 | 
		
	
		
			
			|  | 287 | + *
 | 
		
	
		
			
			|  | 288 | + * @v dest		Destination string
 | 
		
	
		
			
			|  | 289 | + * @v src		Source string
 | 
		
	
		
			
			|  | 290 | + * @ret dest		Destination string
 | 
		
	
		
			
			| 296 | 291 |   */
 | 
		
	
		
			
			| 297 |  | -char * strstr(const char * s1,const char * s2)
 | 
		
	
		
			
			| 298 |  | -{
 | 
		
	
		
			
			| 299 |  | -	int l1, l2;
 | 
		
	
		
			
			| 300 |  | -
 | 
		
	
		
			
			| 301 |  | -	l2 = strlen(s2);
 | 
		
	
		
			
			| 302 |  | -	if (!l2)
 | 
		
	
		
			
			| 303 |  | -		return (char *) s1;
 | 
		
	
		
			
			| 304 |  | -	l1 = strlen(s1);
 | 
		
	
		
			
			| 305 |  | -	while (l1 >= l2) {
 | 
		
	
		
			
			| 306 |  | -		l1--;
 | 
		
	
		
			
			| 307 |  | -		if (!memcmp(s1,s2,l2))
 | 
		
	
		
			
			| 308 |  | -			return (char *) s1;
 | 
		
	
		
			
			| 309 |  | -		s1++;
 | 
		
	
		
			
			|  | 292 | +char * strcpy ( char *dest, const char *src ) {
 | 
		
	
		
			
			|  | 293 | +	const uint8_t *src_bytes = ( ( const uint8_t * ) src );
 | 
		
	
		
			
			|  | 294 | +	uint8_t *dest_bytes = ( ( uint8_t * ) dest );
 | 
		
	
		
			
			|  | 295 | +
 | 
		
	
		
			
			|  | 296 | +	/* We cannot use strncpy(), since that would pad the destination */
 | 
		
	
		
			
			|  | 297 | +	for ( ; ; src_bytes++, dest_bytes++ ) {
 | 
		
	
		
			
			|  | 298 | +		*dest_bytes = *src_bytes;
 | 
		
	
		
			
			|  | 299 | +		if ( ! *dest_bytes )
 | 
		
	
		
			
			|  | 300 | +			break;
 | 
		
	
		
			
			| 310 | 301 |  	}
 | 
		
	
		
			
			| 311 |  | -	return NULL;
 | 
		
	
		
			
			|  | 302 | +	return dest;
 | 
		
	
		
			
			| 312 | 303 |  }
 | 
		
	
		
			
			| 313 |  | -#endif
 | 
		
	
		
			
			| 314 | 304 |  
 | 
		
	
		
			
			| 315 |  | -#ifndef __HAVE_ARCH_MEMCHR
 | 
		
	
		
			
			| 316 | 305 |  /**
 | 
		
	
		
			
			| 317 |  | - * memchr - Find a character in an area of memory.
 | 
		
	
		
			
			| 318 |  | - * @s: The memory area
 | 
		
	
		
			
			| 319 |  | - * @c: The byte to search for
 | 
		
	
		
			
			| 320 |  | - * @n: The size of the area.
 | 
		
	
		
			
			|  | 306 | + * Copy string
 | 
		
	
		
			
			| 321 | 307 |   *
 | 
		
	
		
			
			| 322 |  | - * returns the address of the first occurrence of @c, or %NULL
 | 
		
	
		
			
			| 323 |  | - * if @c is not found
 | 
		
	
		
			
			|  | 308 | + * @v dest		Destination string
 | 
		
	
		
			
			|  | 309 | + * @v src		Source string
 | 
		
	
		
			
			|  | 310 | + * @v max		Maximum length
 | 
		
	
		
			
			|  | 311 | + * @ret dest		Destination string
 | 
		
	
		
			
			| 324 | 312 |   */
 | 
		
	
		
			
			| 325 |  | -void * memchr(const void *s, int c, size_t n)
 | 
		
	
		
			
			| 326 |  | -{
 | 
		
	
		
			
			| 327 |  | -	const unsigned char *p = s;
 | 
		
	
		
			
			| 328 |  | -	while (n-- != 0) {
 | 
		
	
		
			
			| 329 |  | -        	if ((unsigned char)c == *p++) {
 | 
		
	
		
			
			| 330 |  | -			return (void *)(p-1);
 | 
		
	
		
			
			| 331 |  | -		}
 | 
		
	
		
			
			|  | 313 | +char * strncpy ( char *dest, const char *src, size_t max ) {
 | 
		
	
		
			
			|  | 314 | +	const uint8_t *src_bytes = ( ( const uint8_t * ) src );
 | 
		
	
		
			
			|  | 315 | +	uint8_t *dest_bytes = ( ( uint8_t * ) dest );
 | 
		
	
		
			
			|  | 316 | +
 | 
		
	
		
			
			|  | 317 | +	for ( ; max ; max--, src_bytes++, dest_bytes++ ) {
 | 
		
	
		
			
			|  | 318 | +		*dest_bytes = *src_bytes;
 | 
		
	
		
			
			|  | 319 | +		if ( ! *dest_bytes )
 | 
		
	
		
			
			|  | 320 | +			break;
 | 
		
	
		
			
			| 332 | 321 |  	}
 | 
		
	
		
			
			| 333 |  | -	return NULL;
 | 
		
	
		
			
			|  | 322 | +	while ( max-- )
 | 
		
	
		
			
			|  | 323 | +		*(dest_bytes++) = '\0';
 | 
		
	
		
			
			|  | 324 | +	return dest;
 | 
		
	
		
			
			| 334 | 325 |  }
 | 
		
	
		
			
			| 335 | 326 |  
 | 
		
	
		
			
			| 336 |  | -#endif
 | 
		
	
		
			
			|  | 327 | +/**
 | 
		
	
		
			
			|  | 328 | + * Concatenate string
 | 
		
	
		
			
			|  | 329 | + *
 | 
		
	
		
			
			|  | 330 | + * @v dest		Destination string
 | 
		
	
		
			
			|  | 331 | + * @v src		Source string
 | 
		
	
		
			
			|  | 332 | + * @ret dest		Destination string
 | 
		
	
		
			
			|  | 333 | + */
 | 
		
	
		
			
			|  | 334 | +char * strcat ( char *dest, const char *src ) {
 | 
		
	
		
			
			|  | 335 | +
 | 
		
	
		
			
			|  | 336 | +	strcpy ( ( dest + strlen ( dest ) ), src );
 | 
		
	
		
			
			|  | 337 | +	return dest;
 | 
		
	
		
			
			|  | 338 | +}
 | 
		
	
		
			
			| 337 | 339 |  
 | 
		
	
		
			
			| 338 |  | -char * strndup(const char *s, size_t n)
 | 
		
	
		
			
			| 339 |  | -{
 | 
		
	
		
			
			| 340 |  | -        size_t len = strnlen(s,n);
 | 
		
	
		
			
			| 341 |  | -        char *new;
 | 
		
	
		
			
			|  | 340 | +/**
 | 
		
	
		
			
			|  | 341 | + * Duplicate string
 | 
		
	
		
			
			|  | 342 | + *
 | 
		
	
		
			
			|  | 343 | + * @v src		Source string
 | 
		
	
		
			
			|  | 344 | + * @ret dup		Duplicated string, or NULL if allocation failed
 | 
		
	
		
			
			|  | 345 | + */
 | 
		
	
		
			
			|  | 346 | +char * strdup ( const char *src ) {
 | 
		
	
		
			
			| 342 | 347 |  
 | 
		
	
		
			
			| 343 |  | -        new = malloc(len+1);
 | 
		
	
		
			
			| 344 |  | -        if (new) {
 | 
		
	
		
			
			| 345 |  | -                new[len] = '\0';
 | 
		
	
		
			
			| 346 |  | -                memcpy(new,s,len);
 | 
		
	
		
			
			| 347 |  | -        }
 | 
		
	
		
			
			| 348 |  | -        return new;
 | 
		
	
		
			
			|  | 348 | +	return strndup ( src, ~( ( size_t ) 0 ) );
 | 
		
	
		
			
			| 349 | 349 |  }
 | 
		
	
		
			
			| 350 | 350 |  
 | 
		
	
		
			
			| 351 |  | -char * strdup(const char *s) {
 | 
		
	
		
			
			| 352 |  | -	return strndup(s, ~((size_t)0));
 | 
		
	
		
			
			|  | 351 | +/**
 | 
		
	
		
			
			|  | 352 | + * Duplicate string
 | 
		
	
		
			
			|  | 353 | + *
 | 
		
	
		
			
			|  | 354 | + * @v src		Source string
 | 
		
	
		
			
			|  | 355 | + * @v max		Maximum length
 | 
		
	
		
			
			|  | 356 | + * @ret dup		Duplicated string, or NULL if allocation failed
 | 
		
	
		
			
			|  | 357 | + */
 | 
		
	
		
			
			|  | 358 | +char * strndup ( const char *src, size_t max ) {
 | 
		
	
		
			
			|  | 359 | +	size_t len = strnlen ( src, max );
 | 
		
	
		
			
			|  | 360 | +        char *dup;
 | 
		
	
		
			
			|  | 361 | +
 | 
		
	
		
			
			|  | 362 | +        dup = malloc ( len + 1 /* NUL */ );
 | 
		
	
		
			
			|  | 363 | +        if ( dup ) {
 | 
		
	
		
			
			|  | 364 | +		memcpy ( dup, src, len );
 | 
		
	
		
			
			|  | 365 | +		dup[len] = '\0';
 | 
		
	
		
			
			|  | 366 | +        }
 | 
		
	
		
			
			|  | 367 | +        return dup;
 | 
		
	
		
			
			| 353 | 368 |  }
 |