diff options
author | Michael Brown | 2015-02-16 18:59:11 +0100 |
---|---|---|
committer | Michael Brown | 2015-02-17 00:16:20 +0100 |
commit | 8ee39f7432e63c2382ab3e7d24e234310f4532c9 (patch) | |
tree | 9261fe919a505f8f5d98e288f68ac99a6fd62c3c | |
parent | [libc] Remove unused string functions (diff) | |
download | ipxe-8ee39f7432e63c2382ab3e7d24e234310f4532c9.tar.gz ipxe-8ee39f7432e63c2382ab3e7d24e234310f4532c9.tar.xz ipxe-8ee39f7432e63c2382ab3e7d24e234310f4532c9.zip |
[libc] Rewrite string functions
Some of the C library string functions have an unknown provenance.
Reimplement all such functions to avoid potential licensing
uncertainty.
Remove the inline-assembler versions of strlen(), memswap(), and
strncmp(); these save a minimal amount of space (around 40 bytes in
total) and are not performance-critical.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
-rw-r--r-- | src/arch/x86/core/x86_string.c | 84 | ||||
-rw-r--r-- | src/arch/x86/include/bits/string.h | 18 | ||||
-rw-r--r-- | src/core/string.c | 531 | ||||
-rw-r--r-- | src/hci/strerror.c | 2 | ||||
-rw-r--r-- | src/include/string.h | 77 | ||||
-rw-r--r-- | src/include/strings.h | 62 |
6 files changed, 371 insertions, 403 deletions
diff --git a/src/arch/x86/core/x86_string.c b/src/arch/x86/core/x86_string.c index d48347c9..59e0eaae 100644 --- a/src/arch/x86/core/x86_string.c +++ b/src/arch/x86/core/x86_string.c @@ -104,87 +104,3 @@ void * __memmove ( void *dest, const void *src, size_t len ) { return __memcpy_reverse ( dest, src, len ); } } - -/** - * Swap memory areas - * - * @v dest Destination address - * @v src Source address - * @v len Length - * @ret dest Destination address - */ -void * memswap ( void *dest, void *src, size_t len ) { - size_t discard_c; - int discard; - - __asm__ __volatile__ ( "\n1:\n\t" - "dec %2\n\t" - "js 2f\n\t" - "movb (%0,%2), %b3\n\t" - "xchgb (%1,%2), %b3\n\t" - "movb %b3, (%0,%2)\n\t" - "jmp 1b\n\t" - "2:\n\t" - : "=r" ( src ), "=r" ( dest ), - "=&c" ( discard_c ), "=&q" ( discard ) - : "0" ( src ), "1" ( dest ), "2" ( len ) - : "memory" ); - - return dest; -} - -/** - * Calculate length of string - * - * @v string String - * @ret len Length (excluding NUL) - */ -size_t strlen ( const char *string ) { - const char *discard_D; - size_t len_plus_one; - - __asm__ __volatile__ ( "repne scasb\n\t" - "not %1\n\t" - : "=&D" ( discard_D ), "=&c" ( len_plus_one ) - : "0" ( string ), "1" ( -1UL ), "a" ( 0 ) ); - - return ( len_plus_one - 1 ); -} - -/** - * Compare strings (up to a specified length) - * - * @v str1 First string - * @v str2 Second string - * @v len Maximum length - * @ret diff Difference - */ -int strncmp ( const char *str1, const char *str2, size_t len ) { - const void *discard_S; - const void *discard_D; - size_t discard_c; - int diff; - - __asm__ __volatile__ ( "\n1:\n\t" - "dec %2\n\t" - "js 2f\n\t" - "lodsb\n\t" - "scasb\n\t" - "jne 3f\n\t" - "testb %b3, %b3\n\t" - "jnz 1b\n\t" - /* Equal */ - "\n2:\n\t" - "xor %3, %3\n\t" - "jmp 4f\n\t" - /* Not equal; CF indicates difference */ - "\n3:\n\t" - "sbb %3, %3\n\t" - "orb $1, %b3\n\t" - "\n4:\n\t" - : "=&S" ( discard_S ), "=&D" ( discard_D ), - "=&c" ( discard_c ), "=&a" ( diff ) - : "0" ( str1 ), "1" ( str2 ), "2" ( len ) ); - - return diff; -} diff --git a/src/arch/x86/include/bits/string.h b/src/arch/x86/include/bits/string.h index dce99498..5c4f4b8a 100644 --- a/src/arch/x86/include/bits/string.h +++ b/src/arch/x86/include/bits/string.h @@ -28,8 +28,6 @@ FILE_LICENCE ( GPL2_OR_LATER ); * */ -#define __HAVE_ARCH_MEMCPY - extern void * __memcpy ( void *dest, const void *src, size_t len ); extern void * __memcpy_reverse ( void *dest, const void *src, size_t len ); @@ -169,8 +167,6 @@ memcpy ( void *dest, const void *src, size_t len ) { } } -#define __HAVE_ARCH_MEMMOVE - extern void * __memmove ( void *dest, const void *src, size_t len ); /** @@ -196,8 +192,6 @@ memmove ( void *dest, const void *src, size_t len ) { } } -#define __HAVE_ARCH_MEMSET - /** * Fill memory region * @@ -217,16 +211,4 @@ static inline void * memset ( void *dest, int fill, size_t len ) { return dest; } -#define __HAVE_ARCH_MEMSWAP - -extern void * memswap ( void *dest, void *src, size_t len ); - -#define __HAVE_ARCH_STRNCMP - -extern int strncmp ( const char *str1, const char *str2, size_t len ); - -#define __HAVE_ARCH_STRLEN - -extern size_t strlen ( const char *string ); - #endif /* X86_BITS_STRING_H */ diff --git a/src/core/string.c b/src/core/string.c index e53c283c..db80d612 100644 --- a/src/core/string.c +++ b/src/core/string.c @@ -1,353 +1,368 @@ /* - * Copyright (C) 1991, 1992 Linus Torvalds - * Copyright (C) 2004 Tobias Lorenz + * Copyright (C) 2015 Michael Brown <mbrown@fensystems.co.uk>. * - * string handling functions - * based on linux/lib/string.c + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. */ -FILE_LICENCE ( GPL2_ONLY ); +FILE_LICENCE ( GPL2_OR_LATER ); -/* - * stupid library routines.. The optimized versions should generally be found - * as inline code in <asm-xx/string.h> - * - * These are buggy as well.. - * - * * Fri Jun 25 1999, Ingo Oeser <ioe@informatik.tu-chemnitz.de> - * - Added strsep() which will replace strtok() soon (because strsep() is - * reentrant and should be faster). Use only strsep() in new code, please. - */ - +#include <stddef.h> #include <stdint.h> #include <stdlib.h> #include <string.h> #include <ctype.h> -/* *** FROM string.c *** */ +/** @file + * + * String functions + * + */ -#ifndef __HAVE_ARCH_STRCPY /** - * strcpy - Copy a %NUL terminated string - * @dest: Where to copy the string to - * @src: Where to copy the string from + * Fill memory region + * + * @v dest Destination region + * @v character Fill character + * @v len Length + * @ret dest Destination region */ -char * strcpy(char * dest,const char *src) -{ - char *tmp = dest; +void * generic_memset ( void *dest, int character, size_t len ) { + uint8_t *dest_bytes = dest; - while ((*dest++ = *src++) != '\0') - /* nothing */; - return tmp; + while ( len-- ) + *(dest_bytes++) = character; + return dest; } -#endif -#ifndef __HAVE_ARCH_STRNCPY /** - * strncpy - Copy a length-limited, %NUL-terminated string - * @dest: Where to copy the string to - * @src: Where to copy the string from - * @count: The maximum number of bytes to copy + * Copy memory region * - * Note that unlike userspace strncpy, this does not %NUL-pad the buffer. - * However, the result is not %NUL-terminated if the source exceeds - * @count bytes. + * @v dest Destination region + * @v src Source region + * @v len Length + * @ret dest Destination region */ -char * strncpy(char * dest,const char *src,size_t count) -{ - char *tmp = dest; - - while (count-- && (*dest++ = *src++) != '\0') - /* nothing */; +void * generic_memcpy ( void *dest, const void *src, size_t len ) { + const uint8_t *src_bytes = src; + uint8_t *dest_bytes = dest; - return tmp; + while ( len-- ) + *(dest_bytes++) = *(src_bytes++); + return dest; } -#endif -#ifndef __HAVE_ARCH_STRCAT /** - * strcat - Append one %NUL-terminated string to another - * @dest: The string to be appended to - * @src: The string to append to it + * Copy (possibly overlapping) memory region + * + * @v dest Destination region + * @v src Source region + * @v len Length + * @ret dest Destination region */ -char * strcat(char * dest, const char * src) -{ - char *tmp = dest; - - while (*dest) - dest++; - while ((*dest++ = *src++) != '\0') - ; - - return tmp; +void * generic_memmove ( void *dest, const void *src, size_t len ) { + const uint8_t *src_bytes = ( src + len ); + uint8_t *dest_bytes = ( dest + len ); + + if ( dest < src ) + return memcpy ( dest, src, len ); + while ( len-- ) + *(--dest_bytes) = *(--src_bytes); + return dest; } -#endif -#ifndef __HAVE_ARCH_STRCMP /** - * strcmp - Compare two strings - * @cs: One string - * @ct: Another string + * Compare memory regions + * + * @v first First region + * @v second Second region + * @v len Length + * @ret diff Difference */ -int strcmp(const char * cs,const char * ct) -{ - register signed char __res; - - while (1) { - if ((__res = *cs - *ct++) != 0 || !*cs++) - break; +int memcmp ( const void *first, const void *second, size_t len ) { + const uint8_t *first_bytes = first; + const uint8_t *second_bytes = second; + int diff; + + while ( len-- ) { + diff = ( *(second_bytes++) - *(first_bytes++) ); + if ( diff ) + return diff; } - - return __res; + return 0; } -#endif -#ifndef __HAVE_ARCH_STRNCMP /** - * strncmp - Compare two length-limited strings - * @cs: One string - * @ct: Another string - * @count: The maximum number of bytes to compare + * Find character within a memory region + * + * @v src Source region + * @v character Character to find + * @v len Length + * @ret found Found character, or NULL if not found */ -int strncmp(const char * cs,const char * ct,size_t count) -{ - register signed char __res = 0; +void * memchr ( const void *src, int character, size_t len ) { + const uint8_t *src_bytes = src; - while (count) { - if ((__res = *cs - *ct++) != 0 || !*cs++) - break; - count--; + for ( ; len-- ; src_bytes++ ) { + if ( *src_bytes == character ) + return ( ( void * ) src_bytes ); } - - return __res; + return NULL; } -#endif -#ifndef __HAVE_ARCH_STRCASECMP -int strcasecmp(const char *a, const char *b) -{ - while (*a && *b && (*a & ~0x20) == (*b & ~0x20)) {a++; b++; } - return((*a & ~0x20) - (*b & ~0x20)); +/** + * Swap memory regions + * + * @v first First region + * @v second Second region + * @v len Length + * @ret first First region + */ +void * memswap ( void *first, void *second, size_t len ) { + uint8_t *first_bytes = first; + uint8_t *second_bytes = second; + uint8_t temp; + + for ( ; len-- ; first_bytes++, second_bytes++ ) { + temp = *first_bytes; + *first_bytes = *second_bytes; + *second_bytes = temp; + } + return first; } -#endif -#ifndef __HAVE_ARCH_STRCHR /** - * strchr - Find the first occurrence of a character in a string - * @s: The string to be searched - * @c: The character to search for + * Compare strings + * + * @v first First string + * @v second Second string + * @ret diff Difference */ -char * strchr(const char * s, int c) -{ - for(; *s != (char) c; ++s) - if (*s == '\0') - return NULL; - return (char *) s; +int strcmp ( const char *first, const char *second ) { + + return strncmp ( first, second, ~( ( size_t ) 0 ) ); } -#endif -#ifndef __HAVE_ARCH_STRRCHR /** - * strrchr - Find the last occurrence of a character in a string - * @s: The string to be searched - * @c: The character to search for + * Compare strings + * + * @v first First string + * @v second Second string + * @v max Maximum length to compare + * @ret diff Difference */ -char * strrchr(const char * s, int c) -{ - const char *p = s + strlen(s); - do { - if (*p == (char)c) - return (char *)p; - } while (--p >= s); - return NULL; +int strncmp ( const char *first, const char *second, size_t max ) { + const uint8_t *first_bytes = ( ( const uint8_t * ) first ); + const uint8_t *second_bytes = ( ( const uint8_t * ) second ); + int diff; + + for ( ; max-- ; first_bytes++, second_bytes++ ) { + diff = ( *second_bytes - *first_bytes ); + if ( diff ) + return diff; + if ( ! *first_bytes ) + return 0; + } + return 0; } -#endif -#ifndef __HAVE_ARCH_STRLEN /** - * strlen - Find the length of a string - * @s: The string to be sized + * Compare case-insensitive strings + * + * @v first First string + * @v second Second string + * @ret diff Difference */ -size_t strlen(const char * s) -{ - const char *sc; - - for (sc = s; *sc != '\0'; ++sc) - /* nothing */; - return sc - s; +int strcasecmp ( const char *first, const char *second ) { + const uint8_t *first_bytes = ( ( const uint8_t * ) first ); + const uint8_t *second_bytes = ( ( const uint8_t * ) second ); + int diff; + + for ( ; ; first_bytes++, second_bytes++ ) { + diff = ( toupper ( *second_bytes ) - + toupper ( *first_bytes ) ); + if ( diff ) + return diff; + if ( ! *first_bytes ) + return 0; + } } -#endif -#ifndef __HAVE_ARCH_STRNLEN /** - * strnlen - Find the length of a length-limited string - * @s: The string to be sized - * @count: The maximum number of bytes to search + * Get length of string + * + * @v src String + * @ret len Length */ -size_t strnlen(const char * s, size_t count) -{ - const char *sc; +size_t strlen ( const char *src ) { - for (sc = s; count-- && *sc != '\0'; ++sc) - /* nothing */; - return sc - s; + return strnlen ( src, ~( ( size_t ) 0 ) ); } -#endif -#ifndef __HAVE_ARCH_MEMSET /** - * memset - Fill a region of memory with the given value - * @s: Pointer to the start of the area. - * @c: The byte to fill the area with - * @count: The size of the area. + * Get length of string * - * Do not use memset() to access IO space, use memset_io() instead. + * @v src String + * @v max Maximum length + * @ret len Length */ -void * memset(void * s,int c,size_t count) -{ - char *xs = (char *) s; - - while (count--) - *xs++ = c; +size_t strnlen ( const char *src, size_t max ) { + const uint8_t *src_bytes = ( ( const uint8_t * ) src ); + size_t len = 0; - return s; + while ( max-- && *(src_bytes++) ) + len++; + return len; } -#endif -#ifndef __HAVE_ARCH_MEMCPY /** - * memcpy - Copy one area of memory to another - * @dest: Where to copy to - * @src: Where to copy from - * @count: The size of the area. + * Find character within a string * - * You should not use this function to access IO space, use memcpy_toio() - * or memcpy_fromio() instead. + * @v src String + * @v character Character to find + * @ret found Found character, or NULL if not found */ -void * memcpy(void * dest,const void *src,size_t count) -{ - char *tmp = (char *) dest, *s = (char *) src; - - while (count--) - *tmp++ = *s++; +char * strchr ( const char *src, int character ) { + const uint8_t *src_bytes = ( ( const uint8_t * ) src ); - return dest; + for ( ; ; src_bytes++ ) { + if ( *src_bytes == character ) + return ( ( char * ) src_bytes ); + if ( ! *src_bytes ) + return NULL; + } } -#endif -#ifndef __HAVE_ARCH_MEMMOVE /** - * memmove - Copy one area of memory to another - * @dest: Where to copy to - * @src: Where to copy from - * @count: The size of the area. + * Find rightmost character within a string * - * Unlike memcpy(), memmove() copes with overlapping areas. + * @v src String + * @v character Character to find + * @ret found Found character, or NULL if not found */ -void * memmove(void * dest,const void *src,size_t count) -{ - char *tmp, *s; - - if (dest <= src) { - tmp = (char *) dest; - s = (char *) src; - while (count--) - *tmp++ = *s++; - } - else { - tmp = (char *) dest + count; - s = (char *) src + count; - while (count--) - *--tmp = *--s; - } - - return dest; +char * strrchr ( const char *src, int character ) { + const uint8_t *src_bytes = ( ( const uint8_t * ) src ); + const uint8_t *start = src_bytes; + + while ( *src_bytes ) + src_bytes++; + for ( src_bytes-- ; src_bytes >= start ; src_bytes-- ) { + if ( *src_bytes == character ) + return ( ( char * ) src_bytes ); + } + return NULL; } -#endif -#ifndef __HAVE_ARCH_MEMCMP /** - * memcmp - Compare two areas of memory - * @cs: One area of memory - * @ct: Another area of memory - * @count: The size of the area. + * Find substring + * + * @v haystack String + * @v needle Substring + * @ret found Found substring, or NULL if not found */ -int memcmp(const void * cs,const void * ct,size_t count) -{ - const unsigned char *su1, *su2; - int res = 0; +char * strstr ( const char *haystack, const char *needle ) { + size_t len = strlen ( needle ); - for( su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--) - if ((res = *su1 - *su2) != 0) - break; - return res; + for ( ; *haystack ; haystack++ ) { + if ( memcmp ( haystack, needle, len ) == 0 ) + return ( ( char * ) haystack ); + } + return NULL; } -#endif -#ifndef __HAVE_ARCH_STRSTR /** - * strstr - Find the first substring in a %NUL terminated string - * @s1: The string to be searched - * @s2: The string to search for + * Copy string + * + * @v dest Destination string + * @v src Source string + * @ret dest Destination string */ -char * strstr(const char * s1,const char * s2) -{ - int l1, l2; - - l2 = strlen(s2); - if (!l2) - return (char *) s1; - l1 = strlen(s1); - while (l1 >= l2) { - l1--; - if (!memcmp(s1,s2,l2)) - return (char *) s1; - s1++; +char * strcpy ( char *dest, const char *src ) { + const uint8_t *src_bytes = ( ( const uint8_t * ) src ); + uint8_t *dest_bytes = ( ( uint8_t * ) dest ); + + /* We cannot use strncpy(), since that would pad the destination */ + for ( ; ; src_bytes++, dest_bytes++ ) { + *dest_bytes = *src_bytes; + if ( ! *dest_bytes ) + break; } - return NULL; + return dest; } -#endif -#ifndef __HAVE_ARCH_MEMCHR /** - * memchr - Find a character in an area of memory. - * @s: The memory area - * @c: The byte to search for - * @n: The size of the area. + * Copy string * - * returns the address of the first occurrence of @c, or %NULL - * if @c is not found + * @v dest Destination string + * @v src Source string + * @v max Maximum length + * @ret dest Destination string */ -void * memchr(const void *s, int c, size_t n) -{ - const unsigned char *p = s; - while (n-- != 0) { - if ((unsigned char)c == *p++) { - return (void *)(p-1); - } +char * strncpy ( char *dest, const char *src, size_t max ) { + const uint8_t *src_bytes = ( ( const uint8_t * ) src ); + uint8_t *dest_bytes = ( ( uint8_t * ) dest ); + + for ( ; max ; max--, src_bytes++, dest_bytes++ ) { + *dest_bytes = *src_bytes; + if ( ! *dest_bytes ) + break; } - return NULL; + while ( max-- ) + *(dest_bytes++) = '\0'; + return dest; } -#endif +/** + * Concatenate string + * + * @v dest Destination string + * @v src Source string + * @ret dest Destination string + */ +char * strcat ( char *dest, const char *src ) { + + strcpy ( ( dest + strlen ( dest ) ), src ); + return dest; +} -char * strndup(const char *s, size_t n) -{ - size_t len = strnlen(s,n); - char *new; +/** + * Duplicate string + * + * @v src Source string + * @ret dup Duplicated string, or NULL if allocation failed + */ +char * strdup ( const char *src ) { - new = malloc(len+1); - if (new) { - new[len] = '\0'; - memcpy(new,s,len); - } - return new; + return strndup ( src, ~( ( size_t ) 0 ) ); } -char * strdup(const char *s) { - return strndup(s, ~((size_t)0)); +/** + * Duplicate string + * + * @v src Source string + * @v max Maximum length + * @ret dup Duplicated string, or NULL if allocation failed + */ +char * strndup ( const char *src, size_t max ) { + size_t len = strnlen ( src, max ); + char *dup; + + dup = malloc ( len + 1 /* NUL */ ); + if ( dup ) { + memcpy ( dup, src, len ); + dup[len] = '\0'; + } + return dup; } diff --git a/src/hci/strerror.c b/src/hci/strerror.c index 4e97d957..56300b12 100644 --- a/src/hci/strerror.c +++ b/src/hci/strerror.c @@ -75,7 +75,7 @@ static struct errortab * find_closest_error ( int errno ) { * call to strerror(). * */ -const char * strerror ( int errno ) { +char * strerror ( int errno ) { static char errbuf[64]; struct errortab *errortab; diff --git a/src/include/string.h b/src/include/string.h index dfd78a69..59696dd8 100644 --- a/src/include/string.h +++ b/src/include/string.h @@ -1,46 +1,53 @@ -/* - * Copyright (C) 1991, 1992 Linus Torvalds - * Copyright (C) 2004 Tobias Lorenz +#ifndef _STRING_H +#define _STRING_H + +/** @file * - * string handling functions - * based on linux/include/linux/ctype.h - * and linux/include/linux/string.h + * String functions * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. */ -FILE_LICENCE ( GPL2_ONLY ); - -#ifndef ETHERBOOT_STRING_H -#define ETHERBOOT_STRING_H +FILE_LICENCE ( GPL2_OR_LATER ); #include <stddef.h> #include <bits/string.h> -char * strcpy(char * dest,const char *src) __nonnull; -char * strncpy(char * dest,const char *src,size_t count) __nonnull; -char * strcat(char * dest, const char * src) __nonnull; -int __pure strcmp(const char * cs,const char * ct) __nonnull; -int __pure strncmp(const char * cs,const char * ct, - size_t count) __nonnull; -char * __pure strchr(const char * s, int c) __nonnull; -char * __pure strrchr(const char * s, int c) __nonnull; -size_t __pure strlen(const char * s) __nonnull; -size_t __pure strnlen(const char * s, size_t count) __nonnull; -char * __pure strpbrk(const char * cs,const char * ct) __nonnull; -char * strsep(char **s, const char *ct) __nonnull; -void * memset(void * s,int c,size_t count) __nonnull; +/* Architecture-specific code is expected to provide these functions, + * but may instead explicitly choose to use the generic versions. + */ +void * memset ( void *dest, int character, size_t len ) __nonnull; void * memcpy ( void *dest, const void *src, size_t len ) __nonnull; -void * memmove(void * dest,const void *src,size_t count) __nonnull; -int __pure memcmp(const void * cs,const void * ct, - size_t count) __nonnull; -char * __pure strstr(const char * s1,const char * s2) __nonnull; -void * __pure memchr(const void *s, int c, size_t n) __nonnull; -char * __malloc strdup(const char *s) __nonnull; -char * __malloc strndup(const char *s, size_t n) __nonnull; +void * memmove ( void *dest, const void *src, size_t len ) __nonnull; +extern void * generic_memset ( void *dest, int character, + size_t len ) __nonnull; +extern void * generic_memcpy ( void *dest, const void *src, + size_t len ) __nonnull; +extern void * generic_memmove ( void *dest, const void *src, + size_t len ) __nonnull; + +extern int __pure memcmp ( const void *first, const void *second, + size_t len ) __nonnull; +extern void * __pure memchr ( const void *src, int character, + size_t len ) __nonnull; +extern void * memswap ( void *dest, void *src, size_t len ) __nonnull; +extern int __pure strcmp ( const char *first, const char *second ) __nonnull; +extern int __pure strncmp ( const char *first, const char *second, + size_t max ) __nonnull; +extern size_t __pure strlen ( const char *src ) __nonnull; +extern size_t __pure strnlen ( const char *src, size_t max ) __nonnull; +extern char * __pure strchr ( const char *src, int character ) __nonnull; +extern char * __pure strrchr ( const char *src, int character ) __nonnull; +extern char * __pure strstr ( const char *haystack, + const char *needle ) __nonnull; +extern char * strcpy ( char *dest, const char *src ) __nonnull; +extern char * strncpy ( char *dest, const char *src, size_t max ) __nonnull; +extern char * strcat ( char *dest, const char *src ) __nonnull; +extern char * __malloc strdup ( const char *src ) __nonnull; +extern char * __malloc strndup ( const char *src, size_t max ) __nonnull; +extern char * __pure strpbrk ( const char *string, + const char *delim ) __nonnull; +extern char * strsep ( char **string, const char *delim ) __nonnull; -extern const char * __pure strerror ( int errno ); +extern char * __pure strerror ( int errno ); -#endif /* ETHERBOOT_STRING */ +#endif /* _STRING_H */ diff --git a/src/include/strings.h b/src/include/strings.h index 6912a1e4..8b57a40a 100644 --- a/src/include/strings.h +++ b/src/include/strings.h @@ -1,12 +1,23 @@ #ifndef _STRINGS_H #define _STRINGS_H +/** @file + * + * String functions + * + */ + FILE_LICENCE ( GPL2_OR_LATER ); -#include <limits.h> #include <string.h> #include <bits/strings.h> +/** + * Find last (i.e. most significant) set bit + * + * @v x Value + * @ret msb Most significant bit set in value (LSB=1), or zero + */ static inline __attribute__ (( always_inline )) int __constant_flsll ( unsigned long long x ) { int r = 0; @@ -41,6 +52,12 @@ __constant_flsll ( unsigned long long x ) { return r; } +/** + * Find last (i.e. most significant) set bit + * + * @v x Value + * @ret msb Most significant bit set in value (LSB=1), or zero + */ static inline __attribute__ (( always_inline )) int __constant_flsl ( unsigned long x ) { return __constant_flsll ( x ); @@ -49,24 +66,55 @@ __constant_flsl ( unsigned long x ) { int __flsll ( long long x ); int __flsl ( long x ); +/** + * Find last (i.e. most significant) set bit + * + * @v x Value + * @ret msb Most significant bit set in value (LSB=1), or zero + */ #define flsll( x ) \ ( __builtin_constant_p ( x ) ? __constant_flsll ( x ) : __flsll ( x ) ) +/** + * Find last (i.e. most significant) set bit + * + * @v x Value + * @ret msb Most significant bit set in value (LSB=1), or zero + */ #define flsl( x ) \ ( __builtin_constant_p ( x ) ? __constant_flsl ( x ) : __flsl ( x ) ) +/** + * Find last (i.e. most significant) set bit + * + * @v x Value + * @ret msb Most significant bit set in value (LSB=1), or zero + */ #define fls( x ) flsl ( x ) -extern int strcasecmp ( const char *s1, const char *s2 ); - +/** + * Copy memory + * + * @v src Source + * @v dest Destination + * @v len Length + */ static inline __attribute__ (( always_inline )) void -bcopy ( const void *src, void *dest, size_t n ) { - memmove ( dest, src, n ); +bcopy ( const void *src, void *dest, size_t len ) { + memmove ( dest, src, len ); } +/** + * Zero memory + * + * @v dest Destination + * @v len Length + */ static inline __attribute__ (( always_inline )) void -bzero ( void *s, size_t n ) { - memset ( s, 0, n ); +bzero ( void *dest, size_t len ) { + memset ( dest, 0, len ); } +int __pure strcasecmp ( const char *first, const char *second ) __nonnull; + #endif /* _STRINGS_H */ |