diff options
Diffstat (limited to 'lib/string.c')
| -rw-r--r-- | lib/string.c | 57 | 
1 files changed, 55 insertions, 2 deletions
diff --git a/lib/string.c b/lib/string.c index 01fad9b203e1..dc4a86341f91 100644 --- a/lib/string.c +++ b/lib/string.c @@ -360,7 +360,6 @@ char *strim(char *s)  	size_t size;  	char *end; -	s = skip_spaces(s);  	size = strlen(s);  	if (!size)  		return s; @@ -370,7 +369,7 @@ char *strim(char *s)  		end--;  	*(end + 1) = '\0'; -	return s; +	return skip_spaces(s);  }  EXPORT_SYMBOL(strim); @@ -756,3 +755,57 @@ void *memchr(const void *s, int c, size_t n)  }  EXPORT_SYMBOL(memchr);  #endif + +static void *check_bytes8(const u8 *start, u8 value, unsigned int bytes) +{ +	while (bytes) { +		if (*start != value) +			return (void *)start; +		start++; +		bytes--; +	} +	return NULL; +} + +/** + * memchr_inv - Find an unmatching character in an area of memory. + * @start: The memory area + * @c: Find a character other than c + * @bytes: The size of the area. + * + * returns the address of the first character other than @c, or %NULL + * if the whole buffer contains just @c. + */ +void *memchr_inv(const void *start, int c, size_t bytes) +{ +	u8 value = c; +	u64 value64; +	unsigned int words, prefix; + +	if (bytes <= 16) +		return check_bytes8(start, value, bytes); + +	value64 = value | value << 8 | value << 16 | value << 24; +	value64 = (value64 & 0xffffffff) | value64 << 32; +	prefix = 8 - ((unsigned long)start) % 8; + +	if (prefix) { +		u8 *r = check_bytes8(start, value, prefix); +		if (r) +			return r; +		start += prefix; +		bytes -= prefix; +	} + +	words = bytes / 8; + +	while (words) { +		if (*(u64 *)start != value64) +			return check_bytes8(start, value, 8); +		start += 8; +		words--; +	} + +	return check_bytes8(start, value, bytes % 8); +} +EXPORT_SYMBOL(memchr_inv);  | 
