libc string:Separate code.

Separate the code that follows the BSD license into independent files.

Signed-off-by: yangguangcai <yangguangcai@xiaomi.com>
This commit is contained in:
yangguangcai 2024-10-22 14:03:24 +08:00 committed by Xiang Xiao
parent cdccce48ac
commit f07aba5c1e
35 changed files with 1841 additions and 1134 deletions

32
LICENSE
View File

@ -8667,22 +8667,22 @@ drivers/i3c/internals.h
SPDX-License-Identifier: Apache-2.0
libs/libc/string/lib_memccpy.c
libs/libc/string/lib_memchr.c
libs/libc/string/lib_memcmp.c
libs/libc/string/lib_memcpy.c
libs/libc/string/lib_memrchr.c
libs/libc/string/lib_stpcpy.c
libs/libc/string/lib_stpncpy.c
libs/libc/string/lib_strcat.c
libs/libc/string/lib_strchr.c
libs/libc/string/lib_strchrnul.c
libs/libc/string/lib_strcmp.c
libs/libc/string/lib_strcpy.c
libs/libc/string/lib_strlen.c
libs/libc/string/lib_strncmp.c
libs/libc/string/lib_strncpy.c
libs/libc/string/lib_strrchr.c
libs/libc/string/lib_bsdmemccpy.c
libs/libc/string/lib_bsdmemchr.c
libs/libc/string/lib_bsdmemcmp.c
libs/libc/string/lib_bsdmemcpy.c
libs/libc/string/lib_bsdmemrchr.c
libs/libc/string/lib_bsdstpcpy.c
libs/libc/string/lib_bsdstpncpy.c
libs/libc/string/lib_bsdstrcat.c
libs/libc/string/lib_bsdstrchr.c
libs/libc/string/lib_bsdstrchrnul.c
libs/libc/string/lib_bsdstrcmp.c
libs/libc/string/lib_bsdstrcpy.c
libs/libc/string/lib_bsdstrlen.c
libs/libc/string/lib_bsdstrncmp.c
libs/libc/string/lib_bsdstrncpy.c
libs/libc/string/lib_bsdstrrchr.c
======================
Copyright (c) 1994-2009 Red Hat, Inc. All rights reserved.

View File

@ -31,28 +31,20 @@ set(SRCS
lib_flsl.c
lib_flsll.c
lib_isbasedigit.c
lib_memccpy.c
lib_memrchr.c
lib_memmem.c
lib_popcount.c
lib_popcountl.c
lib_popcountll.c
lib_skipspace.c
lib_stpcpy.c
lib_stpncpy.c
lib_strcasecmp.c
lib_strcat.c
lib_strcspn.c
lib_strchrnul.c
lib_strdup.c
lib_strerror.c
lib_strncasecmp.c
lib_strncat.c
lib_strncmp.c
lib_strndup.c
lib_strcasestr.c
lib_strpbrk.c
lib_strrchr.c
lib_strspn.c
lib_strstr.c
lib_strtok.c
@ -68,21 +60,16 @@ set(SRCS
lib_strverscmp.c
lib_mempcpy.c
lib_rawmemchr.c
lib_memchr.c
lib_memcmp.c
lib_memmove.c
lib_memset.c
lib_strchr.c
lib_strcmp.c
lib_strcpy.c
lib_strlcat.c
lib_strlcpy.c
lib_strlen.c
lib_strncpy.c
lib_strnlen.c)
if(CONFIG_MEMCPY_VIK)
list(APPEND SRCS lib_vikmemcpy.c)
elseif(CONFIG_LIBC_STRING_OPTIMIZE)
list(APPEND SRCS lib_bsdmemcpy.c)
else()
list(APPEND SRCS lib_memcpy.c)
endif()
@ -91,4 +78,44 @@ if(CONFIG_LIBC_LOCALE)
list(APPEND SRCS lib_strcoll.c lib_strxfrm.c)
endif()
if(CONFIG_LIBC_STRING_OPTIMIZE)
list(
APPEND
SRCS
lib_bsdmemccpy.c
lib_bsdmemcmp.c
lib_bsdmemrchr.c
lib_bsdstpncpy.c
lib_bsdstrchr.c
lib_bsdstrcmp.c
lib_bsdstrlen.c
lib_bsdstrncpy.c
lib_bsdmemchr.c
lib_bsdstpcpy.c
lib_bsdstrcat.c
lib_bsdstrchrnul.c
lib_bsdstrcpy.c
lib_bsdstrncmp.c
lib_bsdstrrchr.c)
else()
list(
APPEND
SRCS
lib_memccpy.c
lib_memcmp.c
lib_memrchr.c
lib_stpncpy.c
lib_strchr.c
lib_strcmp.c
lib_strlen.c
lib_strncpy.c
lib_memchr.c
lib_stpcpy.c
lib_strcat.c
lib_strchrnul.c
lib_strcpy.c
lib_strncmp.c
lib_strrchr.c)
endif()
target_sources(c PRIVATE ${SRCS})

View File

@ -23,23 +23,25 @@
# Add the string C files to the build
CSRCS += lib_ffs.c lib_ffsl.c lib_ffsll.c lib_fls.c lib_flsl.c
CSRCS += lib_flsll.c lib_isbasedigit.c lib_memccpy.c lib_memrchr.c lib_memmem.c
CSRCS += lib_flsll.c lib_isbasedigit.c lib_memmem.c
CSRCS += lib_popcount.c lib_popcountl.c lib_popcountll.c
CSRCS += lib_skipspace.c lib_stpcpy.c lib_stpncpy.c lib_strcasecmp.c
CSRCS += lib_strcat.c lib_strcspn.c lib_strchrnul.c lib_strdup.c
CSRCS += lib_strerror.c lib_strncasecmp.c lib_strncat.c lib_strncmp.c
CSRCS += lib_strndup.c lib_strcasestr.c lib_strpbrk.c lib_strrchr.c
CSRCS += lib_skipspace.c lib_strcasecmp.c
CSRCS += lib_strcspn.c lib_strdup.c
CSRCS += lib_strerror.c lib_strncasecmp.c lib_strncat.c
CSRCS += lib_strndup.c lib_strcasestr.c lib_strpbrk.c
CSRCS += lib_strspn.c lib_strstr.c lib_strtok.c lib_strtokr.c
CSRCS += lib_strsep.c lib_strerrorr.c lib_explicit_bzero.c lib_strsignal.c
CSRCS += lib_index.c lib_rindex.c lib_timingsafe_bcmp.c lib_strverscmp.c
CSRCS += lib_mempcpy.c lib_rawmemchr.c lib_bzero.c
CSRCS += lib_memchr.c lib_memcmp.c lib_memmove.c lib_memset.c
CSRCS += lib_strchr.c lib_strcmp.c lib_strcpy.c lib_strlcat.c
CSRCS += lib_strlcpy.c lib_strlen.c lib_strncpy.c lib_strnlen.c
CSRCS += lib_memmove.c lib_memset.c
CSRCS += lib_strlcat.c
CSRCS += lib_strlcpy.c lib_strnlen.c
ifeq ($(CONFIG_MEMCPY_VIK),y)
CSRCS += lib_vikmemcpy.c
else ifeq ($(CONFIG_LIBC_STRING_OPTIMIZE),y)
CSRCS += lib_bsdmemcpy.c
else
CSRCS += lib_memcpy.c
endif
@ -48,6 +50,18 @@ ifeq ($(CONFIG_LIBC_LOCALE),y)
CSRCS += lib_strcoll.c lib_strxfrm.c
endif
ifeq ($(CONFIG_LIBC_STRING_OPTIMIZE),y)
CSRCS += lib_bsdmemccpy.c lib_bsdmemcmp.c lib_bsdmemrchr.c lib_bsdstpncpy.c
CSRCS += lib_bsdstrchr.c lib_bsdstrcmp.c lib_bsdstrlen.c lib_bsdstrncpy.c
CSRCS += lib_bsdmemchr.c lib_bsdstpcpy.c lib_bsdstrcat.c lib_bsdstrchrnul.c
CSRCS += lib_bsdstrcpy.c lib_bsdstrncmp.c lib_bsdstrrchr.c
else
CSRCS += lib_memccpy.c lib_memcmp.c lib_memrchr.c lib_stpncpy.c
CSRCS += lib_strchr.c lib_strcmp.c lib_strlen.c lib_strncpy.c
CSRCS += lib_memchr.c lib_stpcpy.c lib_strcat.c lib_strchrnul.c
CSRCS += lib_strcpy.c lib_strncmp.c lib_strrchr.c
endif
# Add the string directory to the build
DEPPATH += --dep-path string

View File

@ -0,0 +1,140 @@
/****************************************************************************
* libs/libc/string/lib_bsdmemccpy.c
*
* Copyright (c) 1994-2009 Red Hat, Inc. All rights reserved.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the BSD License. This program is distributed in the hope that
* it will be useful, but WITHOUT ANY WARRANTY expressed or implied,
* including the implied warranties of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. A copy of this license is available at
* http://www.opensource.org/licenses. Any Red Hat trademarks that are
* incorporated in the source code or documentation are not subject to
* the BSD License and may only be used or replicated with the express
* permission of Red Hat, Inc.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sys/types.h>
#include <string.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Nonzero if either x or y is not aligned on a "long" boundary. */
#define UNALIGNED(x, y) \
(((long)(uintptr_t)(x) & (sizeof(long) - 1)) | ((long)(uintptr_t)(y) & (sizeof(long) - 1)))
/* How many bytes are copied each iteration of the word copy loop. */
#define LITTLEBLOCKSIZE (sizeof(long))
/* Threshhold for punting to the byte copier. */
#define TOO_SMALL(len) ((len) < LITTLEBLOCKSIZE)
/* Macros for detecting endchar */
#if LONG_MAX == 2147483647
# define DETECTNULL(x) (((x) - 0x01010101) & ~(x) & 0x80808080)
#elif LONG_MAX == 9223372036854775807
/* Nonzero if x (a long int) contains a NULL byte. */
# define DETECTNULL(x) (((x) - 0x0101010101010101) & ~(x) & 0x8080808080808080)
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: memccpy
*
* Description:
* The memccpy() function copies bytes from memory area s2 into s1,
* stopping after the first occurrence of byte c (converted to an unsigned
* char) is copied, or after n bytes are copied, whichever comes first. If
* copying takes place between objects that overlap, the behavior is
* undefined.
*
* Returned Value:
* The memccpy() function returns a pointer to the byte after the copy of c
* in s1, or a null pointer if c was not found in the first n bytes of s2.
*
****************************************************************************/
#undef memccpy /* See mm/README.txt */
FAR void *memccpy(FAR void *s1, FAR const void *s2, int c, size_t n)
{
FAR void *ptr = NULL;
FAR unsigned char *pout = (FAR unsigned char *)s1;
FAR const unsigned char *pin = (FAR const unsigned char *)s2;
FAR long *paligned_out;
FAR const long *paligned_in;
unsigned char endchar = c & 0xff;
/* If the size is small, or either pin or pout is unaligned,
* then punt into the byte copy loop. This should be rare.
*/
if (!TOO_SMALL(n) && !UNALIGNED(pin, pout))
{
unsigned int i;
unsigned long mask = 0;
paligned_out = (FAR long *)pout;
paligned_in = (FAR long *)pin;
/* The fast code reads the ASCII one word at a time and only
* performs the bytewise search on word-sized segments if they
* contain the search character, which is detected by XORing
* the word-sized segment with a word-sized block of the search
* character and then detecting for the presence of NULL in the
* result.
*/
for (i = 0; i < LITTLEBLOCKSIZE; i++)
{
mask = (mask << 8) + endchar;
}
/* Copy one long word at a time if possible. */
while (n >= LITTLEBLOCKSIZE)
{
unsigned long buffer = (unsigned long)(*paligned_in);
buffer ^= mask;
if (DETECTNULL(buffer))
{
break; /* endchar is found, go byte by byte from here */
}
*paligned_out++ = *paligned_in++;
n -= LITTLEBLOCKSIZE;
}
/* Pick up any residual with a byte copier. */
pout = (FAR unsigned char *)paligned_out;
pin = (FAR unsigned char *)paligned_in;
}
while (n--)
{
if ((*pout++ = *pin++) == endchar)
{
ptr = pout;
break;
}
}
return ptr;
}

View File

@ -0,0 +1,150 @@
/****************************************************************************
* libs/libc/string/lib_bsdmemchr.c
*
* Copyright (c) 1994-2009 Red Hat, Inc. All rights reserved.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the BSD License. This program is distributed in the hope that
* it will be useful, but WITHOUT ANY WARRANTY expressed or implied,
* including the implied warranties of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. A copy of this license is available at
* http://www.opensource.org/licenses. Any Red Hat trademarks that are
* incorporated in the source code or documentation are not subject to
* the BSD License and may only be used or replicated with the express
* permission of Red Hat, Inc.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <string.h>
#include "libc.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define UNALIGNED(x) ((long)(uintptr_t)(x) & (sizeof(long) - 1))
/* How many bytes are loaded each iteration of the word copy loop. */
#define LBLOCKSIZE (sizeof(long))
/* Threshhold for punting to the bytewise iterator. */
#define TOO_SMALL(len) ((len) < LBLOCKSIZE)
#if LONG_MAX == 2147483647
# define DETECTNULL(x) (((x) - 0x01010101) & ~(x) & 0x80808080)
#elif LONG_MAX == 9223372036854775807
/* Nonzero if x (a long int) contains a NULL byte. */
# define DETECTNULL(x) (((x) - 0x0101010101010101) & ~(x) & 0x8080808080808080)
#endif
/* DETECTCHAR returns nonzero if (long)x contains the byte used
* to fill (long)mask.
*/
#define DETECTCHAR(x, mask) (DETECTNULL((x) ^ (mask)))
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: memchr
*
* Description:
* The memchr() function locates the first occurrence of 'c' (converted to
* an unsigned char) in the initial 'n' bytes (each interpreted as
* unsigned char) of the object pointed to by s.
*
* Returned Value:
* The memchr() function returns a pointer to the located byte, or a null
* pointer if the byte does not occur in the object.
*
****************************************************************************/
#if !defined(CONFIG_LIBC_ARCH_MEMCHR) && defined(LIBC_BUILD_MEMCHR)
#undef memchr /* See mm/README.txt */
FAR void *memchr(FAR const void *s, int c, size_t n)
{
FAR const unsigned char *p = (FAR const unsigned char *)s;
FAR unsigned long *asrc;
unsigned char d = c;
unsigned long mask;
unsigned int i;
while (UNALIGNED(p))
{
if (!n--)
{
return NULL;
}
if (*p == d)
{
return (FAR void *)p;
}
p++;
}
if (!TOO_SMALL(n))
{
/* If we get this far, we know that n is large and p is
* word-aligned.
* The fast code reads the source one word at a time and only
* performs the bytewise search on word-sized segments if they
* contain the search character, which is detected by XORing
* the word-sized segment with a word-sized block of the search
* character and then detecting for the presence of NUL in the
* result.
*/
asrc = (FAR unsigned long *)p;
mask = d << 8 | d;
mask = mask << 16 | mask;
for (i = 32; i < LBLOCKSIZE * 8; i <<= 1)
{
mask = (mask << i) | mask;
}
while (n >= LBLOCKSIZE)
{
if (DETECTCHAR(*asrc, mask))
{
break;
}
n -= LBLOCKSIZE;
asrc++;
}
/* If there are fewer than LBLOCKSIZE characters left,
* then we resort to the bytewise loop.
*/
p = (FAR unsigned char *)asrc;
}
while (n--)
{
if (*p == d)
{
return (FAR void *)p;
}
p++;
}
return NULL;
}
#endif

View File

@ -0,0 +1,104 @@
/****************************************************************************
* libs/libc/string/lib_bsdmemcmp.c
*
* Copyright (c) 1994-2009 Red Hat, Inc. All rights reserved.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the BSD License. This program is distributed in the hope that
* it will be useful, but WITHOUT ANY WARRANTY expressed or implied,
* including the implied warranties of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. A copy of this license is available at
* http://www.opensource.org/licenses. Any Red Hat trademarks that are
* incorporated in the source code or documentation are not subject to
* the BSD License and may only be used or replicated with the express
* permission of Red Hat, Inc.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sys/types.h>
#include <string.h>
#include "libc.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Nonzero if either x or y is not aligned on a "long" boundary. */
#define UNALIGNED(x, y) \
(((long)(uintptr_t)(x) & (sizeof(long) - 1)) | ((long)(uintptr_t)(y) & (sizeof(long) - 1)))
/* How many bytes are copied each iteration of the word copy loop. */
#define LBLOCKSIZE (sizeof(long))
/* Threshhold for punting to the byte copier. */
#define TOO_SMALL(len) ((len) < LBLOCKSIZE)
/****************************************************************************
* Public Functions
****************************************************************************/
#if !defined(CONFIG_LIBC_ARCH_MEMCMP) && defined(LIBC_BUILD_MEMCMP)
#undef memcmp /* See mm/README.txt */
no_builtin("memcmp")
int memcmp(FAR const void *s1, FAR const void *s2, size_t n)
{
FAR unsigned char *p1 = (FAR unsigned char *)s1;
FAR unsigned char *p2 = (FAR unsigned char *)s2;
FAR unsigned long *a1;
FAR unsigned long *a2;
/* If the size is too small, or either pointer is unaligned,
* then we punt to the byte compare loop. Hopefully this will
* not turn up in inner loops.
*/
if (!TOO_SMALL(n) && !UNALIGNED(p1, p2))
{
/* Otherwise, load and compare the blocks of memory one
* word at a time.
*/
a1 = (FAR unsigned long *)p1;
a2 = (FAR unsigned long *)p2;
while (n >= LBLOCKSIZE)
{
if (*a1 != *a2)
{
break;
}
a1++;
a2++;
n -= LBLOCKSIZE;
}
/* check s mod LBLOCKSIZE remaining characters */
p1 = (FAR unsigned char *)a1;
p2 = (FAR unsigned char *)a2;
}
while (n--)
{
if (*p1 != *p2)
{
return *p1 - *p2;
}
p1++;
p2++;
}
return 0;
}
#endif

View File

@ -0,0 +1,109 @@
/****************************************************************************
* libs/libc/string/lib_bsdmemcpy.c
*
* Copyright (c) 1994-2009 Red Hat, Inc. All rights reserved.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the BSD License. This program is distributed in the hope that
* it will be useful, but WITHOUT ANY WARRANTY expressed or implied,
* including the implied warranties of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. A copy of this license is available at
* http://www.opensource.org/licenses. Any Red Hat trademarks that are
* incorporated in the source code or documentation are not subject to
* the BSD License and may only be used or replicated with the express
* permission of Red Hat, Inc.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sys/types.h>
#include <string.h>
#include "libc.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Nonzero if either x or y is not aligned on a "long" boundary. */
#define UNALIGNED(x, y) \
(((long)(uintptr_t)(x) & (sizeof(long) - 1)) | ((long)(uintptr_t)(y) & (sizeof(long) - 1)))
/* How many bytes are copied each iteration of the 4X unrolled loop. */
#define BIGBLOCKSIZE (sizeof(long) << 2)
/* How many bytes are copied each iteration of the word copy loop. */
#define LITTLEBLOCKSIZE (sizeof(long))
/* Threshhold for punting to the byte copier. */
#define TOO_SMALL(len) ((len) < BIGBLOCKSIZE)
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: memcpy
****************************************************************************/
#if !defined(CONFIG_LIBC_ARCH_MEMCPY) && defined(LIBC_BUILD_MEMCPY)
#undef memcpy /* See mm/README.txt */
no_builtin("memcpy")
FAR void *memcpy(FAR void *dest, FAR const void *src, size_t n)
{
FAR char *pout = dest;
FAR const char *pin = src;
FAR long *paligned_out;
FAR const long *paligned_in;
/* If the size is small, or either pin or pout is unaligned,
* then punt into the byte copy loop. This should be rare.
*/
if (!TOO_SMALL(n) && !UNALIGNED(pin, pout))
{
paligned_out = (FAR long *)pout;
paligned_in = (FAR long *)pin;
/* Copy 4X long words at a time if possible. */
while (n >= BIGBLOCKSIZE)
{
*paligned_out++ = *paligned_in++;
*paligned_out++ = *paligned_in++;
*paligned_out++ = *paligned_in++;
*paligned_out++ = *paligned_in++;
n -= BIGBLOCKSIZE;
}
/* Copy one long word at a time if possible. */
while (n >= LITTLEBLOCKSIZE)
{
*paligned_out++ = *paligned_in++;
n -= LITTLEBLOCKSIZE;
}
/* Pick up any residual with a byte copier. */
pout = (FAR char *)paligned_out;
pin = (FAR char *)paligned_in;
}
while (n--)
{
*pout++ = *pin++;
}
return dest;
}
#endif

View File

@ -0,0 +1,147 @@
/****************************************************************************
* libs/libc/string/lib_bsdmemrchr.c
*
* Copyright (c) 1994-2009 Red Hat, Inc. All rights reserved.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the BSD License. This program is distributed in the hope that
* it will be useful, but WITHOUT ANY WARRANTY expressed or implied,
* including the implied warranties of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. A copy of this license is available at
* http://www.opensource.org/licenses. Any Red Hat trademarks that are
* incorporated in the source code or documentation are not subject to
* the BSD License and may only be used or replicated with the express
* permission of Red Hat, Inc.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <string.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Nonzero if x is not aligned on a "long" boundary. */
#define UNALIGNED(x) ((long)(uintptr_t)((x) + 1) & (sizeof(long) - 1))
/* How many bytes are loaded each iteration of the word copy loop. */
#define LBLOCKSIZE (sizeof(long))
/* Threshhold for punting to the bytewise iterator. */
#define TOO_SMALL(len) ((len) < LBLOCKSIZE)
/* Macros for detecting endchar */
#if LONG_MAX == 2147483647
# define DETECTNULL(x) (((x) - 0x01010101) & ~(x) & 0x80808080)
#elif LONG_MAX == 9223372036854775807
/* Nonzero if x (a long int) contains a NULL byte. */
# define DETECTNULL(x) (((x) - 0x0101010101010101) & ~(x) & 0x8080808080808080)
#endif
#define DETECTCHAR(x, mask) (DETECTNULL((x) ^ (mask)))
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: memrchr
*
* Description:
* The memrchr() function locates the last occurrence of 'c' (converted to
* an unsigned char) in the initial 'n' bytes (each interpreted as
* unsigned char) of the object pointed to by s.
*
* Returned Value:
* The memrchr() function returns a pointer to the located byte, or a null
* pointer if the byte does not occur in the object.
*
****************************************************************************/
#undef memrchr /* See mm/README.txt */
FAR void *memrchr(FAR const void *s, int c, size_t n)
{
FAR const unsigned char *src0 =
(FAR const unsigned char *)s + n - 1;
FAR unsigned long *asrc;
unsigned char d = c;
unsigned long mask;
unsigned int i;
while (UNALIGNED(src0))
{
if (!n--)
{
return NULL;
}
if (*src0 == d)
{
return (FAR void *)src0;
}
src0--;
}
if (!TOO_SMALL(n))
{
/* If we get this far, we know that n is large and src0 is
* word-aligned.
* The fast code reads the source one word at a time and only
* performs the bytewise search on word-sized segments if they
* contain the search character, which is detected by XORing
* the word-sized segment with a word-sized block of the search
* character and then detecting for the presence of NUL in the
* result.
*/
asrc = (FAR unsigned long *)(src0 - LBLOCKSIZE + 1);
mask = d << 8 | d;
mask = mask << 16 | mask;
for (i = 32; i < LBLOCKSIZE * 8; i <<= 1)
{
mask = (mask << i) | mask;
}
while (n >= LBLOCKSIZE)
{
if (DETECTCHAR(*asrc, mask))
{
break;
}
n -= LBLOCKSIZE;
asrc--;
}
/* If there are fewer than LBLOCKSIZE characters left,
* then we resort to the bytewise loop.
*/
src0 = (FAR unsigned char *)asrc + LBLOCKSIZE - 1;
}
while (n--)
{
if (*src0 == d)
{
return (FAR void *)src0;
}
src0--;
}
return NULL;
}

View File

@ -0,0 +1,95 @@
/****************************************************************************
* libs/libc/string/lib_bsdstpcpy.c
*
* Copyright (c) 1994-2009 Red Hat, Inc. All rights reserved.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the BSD License. This program is distributed in the hope that
* it will be useful, but WITHOUT ANY WARRANTY expressed or implied,
* including the implied warranties of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. A copy of this license is available at
* http://www.opensource.org/licenses. Any Red Hat trademarks that are
* incorporated in the source code or documentation are not subject to
* the BSD License and may only be used or replicated with the express
* permission of Red Hat, Inc.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <string.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Nonzero if either x or y is not aligned on a "long" boundary. */
#define UNALIGNED(x, y) \
(((long)(uintptr_t)(x) & (sizeof(long) - 1)) | ((long)(uintptr_t)(y) & (sizeof(long) - 1)))
/* Macros for detecting endchar */
#if LONG_MAX == 2147483647
# define DETECTNULL(x) (((x) - 0x01010101) & ~(x) & 0x80808080)
#elif LONG_MAX == 9223372036854775807
/* Nonzero if x (a long int) contains a NULL byte. */
# define DETECTNULL(x) (((x) - 0x0101010101010101) & ~(x) & 0x8080808080808080)
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: stpcpy
*
* Description:
* Copies the string pointed to by 'src' (including the terminating NUL
* character) into the array pointed to by 'dest'.
*
* Returned Value:
* The stpcpy() function returns a pointer to the terminating NUL
* character copied into the 'dest' buffer
*
****************************************************************************/
#ifndef CONFIG_LIBC_ARCH_STPCPY
#undef stpcpy /* See mm/README.txt */
nosanitize_address
FAR char *stpcpy(FAR char *dest, FAR const char *src)
{
FAR long *aligned_dst;
FAR const long *aligned_src;
/* If src or dest is unaligned, then copy bytes. */
if (!UNALIGNED(src, dest))
{
aligned_dst = (FAR long *)dest;
aligned_src = (FAR long *)src;
/* src and dest are both "long int" aligned, try to do "long int"
* sized copies.
*/
while (!DETECTNULL(*aligned_src))
{
*aligned_dst++ = *aligned_src++;
}
dest = (FAR char *)aligned_dst;
src = (FAR char *)aligned_src;
}
while ((*dest++ = *src++) != '\0');
return --dest;
}
#endif

View File

@ -0,0 +1,125 @@
/****************************************************************************
* libs/libc/string/lib_bsdstpncpy.c
*
* Copyright (c) 1994-2009 Red Hat, Inc. All rights reserved.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the BSD License. This program is distributed in the hope that
* it will be useful, but WITHOUT ANY WARRANTY expressed or implied,
* including the implied warranties of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. A copy of this license is available at
* http://www.opensource.org/licenses. Any Red Hat trademarks that are
* incorporated in the source code or documentation are not subject to
* the BSD License and may only be used or replicated with the express
* permission of Red Hat, Inc.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sys/types.h>
#include <string.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Nonzero if either x or y is not aligned on a "long" boundary. */
#define UNALIGNED(x, y) \
(((long)(uintptr_t)(x) & (sizeof(long) - 1)) | ((long)(uintptr_t)(y) & (sizeof(long) - 1)))
/* How many bytes are loaded each iteration of the word copy loop. */
#define LBLOCKSIZE (sizeof(long))
/* Macros for detecting endchar */
#if LONG_MAX == 2147483647
#define DETECTNULL(x) (((x) - 0x01010101) & ~(x) & 0x80808080)
#elif LONG_MAX == 9223372036854775807
/* Nonzero if x (a long int) contains a NULL byte. */
#define DETECTNULL(x) (((x) - 0x0101010101010101) & ~(x) & 0x8080808080808080)
#endif
#define TOO_SMALL(len) ((len) < sizeof(long))
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: stpncpy
*
* Description:
* Copies the string pointed to by 'src' (including the terminating NUL
* character) into the array pointed to by 'dest'. strncpy() will not
* copy more than 'n' bytes from 'src' to 'dest' array (including the
* NUL terminator).
*
* If the array pointed to by 'src' is a string that is shorter than 'n'
* bytes, NUL characters will be appended to the copy in the array
* pointed to by 'dest', until 'n' bytes in all are written.
*
* If copying takes place between objects that overlap, the behavior is
* undefined.
*
* Returned Value:
* If a NUL character is written to the destination, the stpncpy()
* function will return the address of the first such NUL character.
* Otherwise, it will return &dest[n]
*
****************************************************************************/
#ifndef CONFIG_LIBC_ARCH_STPNCPY
#undef stpncpy /* See mm/README.txt */
FAR char *stpncpy(FAR char *dest, FAR const char *src, size_t n)
{
FAR char *ret = NULL;
FAR long *aligned_dst;
FAR const long *aligned_src;
/* If src and dest is aligned and n large enough, then copy words. */
if (!UNALIGNED(src, dest) && !TOO_SMALL(n))
{
aligned_dst = (FAR long *)dest;
aligned_src = (FAR long *)src;
/* src and dest are both "long int" aligned, try to do "long int"
* sized copies.
*/
while (n >= LBLOCKSIZE && !DETECTNULL(*aligned_src))
{
n -= LBLOCKSIZE;
*aligned_dst++ = *aligned_src++;
}
dest = (FAR char *)aligned_dst;
src = (FAR char *)aligned_src;
}
while (n > 0)
{
--n;
if ((*dest++ = *src++) == '\0')
{
ret = dest - 1;
break;
}
}
while (n-- > 0)
{
*dest++ = '\0';
}
return ret ? ret : dest;
}
#endif

View File

@ -0,0 +1,87 @@
/****************************************************************************
* libs/libc/string/lib_bsdstrcat.c
*
* Copyright (c) 1994-2009 Red Hat, Inc. All rights reserved.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the BSD License. This program is distributed in the hope that
* it will be useful, but WITHOUT ANY WARRANTY expressed or implied,
* including the implied warranties of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. A copy of this license is available at
* http://www.opensource.org/licenses. Any Red Hat trademarks that are
* incorporated in the source code or documentation are not subject to
* the BSD License and may only be used or replicated with the express
* permission of Red Hat, Inc.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <string.h>
#include "libc.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define ALIGNED(x) \
(((long)(uintptr_t)(x) & (sizeof(long) - 1)) == 0)
/* Macros for detecting endchar */
#if LONG_MAX == 2147483647
# define DETECTNULL(x) (((x) - 0x01010101) & ~(x) & 0x80808080)
#elif LONG_MAX == 9223372036854775807
/* Nonzero if x (a long int) contains a NULL byte. */
# define DETECTNULL(x) (((x) - 0x0101010101010101) & ~(x) & 0x8080808080808080)
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
#if !defined(CONFIG_LIBC_ARCH_STRCAT) && defined(LIBC_BUILD_STRCAT)
#undef strcat /* See mm/README.txt */
nosanitize_address
FAR char *strcat(FAR char *dest, FAR const char *src)
{
FAR char *ret = dest;
/* Skip over the data in dest as quickly as possible. */
if (ALIGNED(dest))
{
FAR unsigned long *aligned_s1 = (FAR unsigned long *)dest;
while (!DETECTNULL(*aligned_s1))
{
aligned_s1++;
}
dest = (FAR char *)aligned_s1;
}
while (*dest)
{
dest++;
}
/* dest now points to the its trailing null character, we can
* just use strcpy to do the work for us now.
* ?!? We might want to just include strcpy here.
* Also, this will cause many more unaligned string copies because
* dest is much less likely to be aligned. I don't know if its worth
* tweaking strcpy to handle this better.
*/
strcpy(dest, src);
return ret;
}
#endif

View File

@ -0,0 +1,161 @@
/****************************************************************************
* libs/libc/string/lib_bsdstrchr.c
*
* Copyright (c) 1994-2009 Red Hat, Inc. All rights reserved.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the BSD License. This program is distributed in the hope that
* it will be useful, but WITHOUT ANY WARRANTY expressed or implied,
* including the implied warranties of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. A copy of this license is available at
* http://www.opensource.org/licenses. Any Red Hat trademarks that are
* incorporated in the source code or documentation are not subject to
* the BSD License and may only be used or replicated with the express
* permission of Red Hat, Inc.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <string.h>
#include "libc.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define UNALIGNED(x) ((long)(uintptr_t)(x) & (sizeof(long) - 1))
/* How many bytes are loaded each iteration of the word copy loop. */
#define LBLOCKSIZE (sizeof(long))
/* Macros for detecting endchar */
#if LONG_MAX == 2147483647
# define DETECTNULL(x) (((x) - 0x01010101) & ~(x) & 0x80808080)
#elif LONG_MAX == 9223372036854775807
/* Nonzero if x (a long int) contains a NULL byte. */
# define DETECTNULL(x) (((x) - 0x0101010101010101) & ~(x) & 0x8080808080808080)
#endif
#define DETECTCHAR(x, mask) (DETECTNULL((x) ^ (mask)))
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: strchr
*
* Description:
* The strchr() function locates the first occurrence of 'c' (converted to
* a char) in the string pointed to by 's'. The terminating null byte is
* considered to be part of the string.
*
* Returned Value:
* Upon completion, strchr() returns a pointer to the byte, or a null
* pointer if the byte was not found.
*
****************************************************************************/
#if !defined(CONFIG_LIBC_ARCH_STRCHR) && defined(LIBC_BUILD_STRCHR)
#undef strchr /* See mm/README.txt */
nosanitize_address
FAR char *strchr(FAR const char *s, int c)
{
FAR const unsigned char *s1 = (FAR const unsigned char *)s;
FAR unsigned long *aligned_addr;
unsigned char i = c;
unsigned long mask;
unsigned long j;
/* Special case for finding 0. */
if (!i)
{
while (UNALIGNED(s1))
{
if (!*s1)
{
return (FAR char *)s1;
}
s1++;
}
/* Operate a word at a time. */
aligned_addr = (FAR unsigned long *)s1;
while (!DETECTNULL(*aligned_addr))
{
aligned_addr++;
}
/* Found the end of string. */
s1 = (FAR const unsigned char *)aligned_addr;
while (*s1)
{
s1++;
}
return (FAR char *)s1;
}
/* All other bytes. Align the pointer, then search a long at a time. */
while (UNALIGNED(s1))
{
if (!*s1)
{
return NULL;
}
if (*s1 == i)
{
return (FAR char *)s1;
}
s1++;
}
mask = i;
for (j = 8; j < LBLOCKSIZE * 8; j <<= 1)
{
mask = (mask << j) | mask;
}
aligned_addr = (FAR unsigned long *)s1;
while (!DETECTNULL(*aligned_addr) && !DETECTCHAR(*aligned_addr, mask))
{
aligned_addr++;
}
/* The block of bytes currently pointed to by aligned_addr
* contains either a null or the target char, or both. We
* catch it using the bytewise search.
*/
s1 = (FAR unsigned char *)aligned_addr;
while (*s1 && *s1 != i)
{
s1++;
}
if (*s1 == i)
{
return (FAR char *)s1;
}
return NULL;
}
#endif

View File

@ -0,0 +1,55 @@
/****************************************************************************
* libs/libc/string/lib_bsdstrchrnul.c
*
* Copyright (c) 1994-2009 Red Hat, Inc. All rights reserved.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the BSD License. This program is distributed in the hope that
* it will be useful, but WITHOUT ANY WARRANTY expressed or implied,
* including the implied warranties of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. A copy of this license is available at
* http://www.opensource.org/licenses. Any Red Hat trademarks that are
* incorporated in the source code or documentation are not subject to
* the BSD License and may only be used or replicated with the express
* permission of Red Hat, Inc.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <string.h>
#include "libc.h"
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: strchrnul
*
* Description:
* The strchrnul() function locates the first occurrence of 'c' (converted
* to a char) in the string pointed to by 's'. The terminating null byte is
* considered to be part of the string.
*
* Returned Value:
* Upon completion, strchrnul() returns a pointer to the byte, or a
* pointer to null if the byte was not found.
*
****************************************************************************/
#if !defined(CONFIG_LIBC_ARCH_STRCHRNUL) && defined(LIBC_BUILD_STRCHRNUL)
#undef strchrnul /* See mm/README.txt */
FAR char *strchrnul(FAR const char *s, int c)
{
FAR char *s1 = strchr(s, c);
return s1 ? s1 : (FAR char *)s + strlen(s);
}
#endif

View File

@ -0,0 +1,99 @@
/****************************************************************************
* libs/libc/string/lib_bsdstrcmp.c
*
* Copyright (c) 1994-2009 Red Hat, Inc. All rights reserved.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the BSD License. This program is distributed in the hope that
* it will be useful, but WITHOUT ANY WARRANTY expressed or implied,
* including the implied warranties of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. A copy of this license is available at
* http://www.opensource.org/licenses. Any Red Hat trademarks that are
* incorporated in the source code or documentation are not subject to
* the BSD License and may only be used or replicated with the express
* permission of Red Hat, Inc.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <string.h>
#include "libc.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Nonzero if either x or y is not aligned on a "long" boundary. */
#define UNALIGNED(x, y) \
(((long)(uintptr_t)(x) & (sizeof(long) - 1)) | ((long)(uintptr_t)(y) & (sizeof(long) - 1)))
/* Macros for detecting endchar */
#if LONG_MAX == 2147483647
# define DETECTNULL(x) (((x) - 0x01010101) & ~(x) & 0x80808080)
#elif LONG_MAX == 9223372036854775807
/* Nonzero if x (a long int) contains a NULL byte. */
# define DETECTNULL(x) (((x) - 0x0101010101010101) & ~(x) & 0x8080808080808080)
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
#if !defined(CONFIG_LIBC_ARCH_STRCMP) && defined(LIBC_BUILD_STRCMP)
#undef strcmp /* See mm/README.txt */
nosanitize_address
int strcmp(FAR const char *cs, FAR const char *ct)
{
FAR unsigned long *a1;
FAR unsigned long *a2;
/* If cs or ct are unaligned, then compare bytes. */
if (!UNALIGNED(cs, ct))
{
/* If cs and ct are word-aligned, compare them a word at a time. */
a1 = (FAR unsigned long *)cs;
a2 = (FAR unsigned long *)ct;
while (*a1 == *a2)
{
/* To get here, *a1 == *a2, thus if we find a null in *a1,
* then the strings must be equal, so return zero.
*/
if (DETECTNULL(*a1))
{
return 0;
}
a1++;
a2++;
}
/* A difference was detected in last few bytes of cs,
* so search bytewise.
*/
cs = (FAR char *)a1;
ct = (FAR char *)a2;
}
while (*cs != '\0' && *cs == *ct)
{
cs++;
ct++;
}
return (*(FAR unsigned char *)cs) - (*(FAR unsigned char *)ct);
}
#endif

View File

@ -0,0 +1,98 @@
/****************************************************************************
* libs/libc/string/lib_bsdstrcpy.c
*
* Copyright (c) 1994-2009 Red Hat, Inc. All rights reserved.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the BSD License. This program is distributed in the hope that
* it will be useful, but WITHOUT ANY WARRANTY expressed or implied,
* including the implied warranties of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. A copy of this license is available at
* http://www.opensource.org/licenses. Any Red Hat trademarks that are
* incorporated in the source code or documentation are not subject to
* the BSD License and may only be used or replicated with the express
* permission of Red Hat, Inc.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <string.h>
#include "libc.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Nonzero if either x or y is not aligned on a "long" boundary. */
#define UNALIGNED(x, y) \
(((long)(uintptr_t)(x) & (sizeof(long) - 1)) | ((long)(uintptr_t)(y) & (sizeof(long) - 1)))
/* Macros for detecting endchar */
#if LONG_MAX == 2147483647
# define DETECTNULL(x) (((x) - 0x01010101) & ~(x) & 0x80808080)
#elif LONG_MAX == 9223372036854775807
/* Nonzero if x (a long int) contains a NULL byte. */
# define DETECTNULL(x) (((x) - 0x0101010101010101) & ~(x) & 0x8080808080808080)
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: strcpy
*
* Description:
* Copies the string pointed to by 'src' (including the terminating NUL
* character) into the array pointed to by 'des'.
*
* Returned Value:
* The strcpy() function returns the 'dest' pointer
*
****************************************************************************/
#if !defined(CONFIG_LIBC_ARCH_STRCPY) && defined(LIBC_BUILD_STRCPY)
#undef strcpy /* See mm/README.txt */
nosanitize_address
FAR char *strcpy(FAR char *dest, FAR const char *src)
{
FAR char *dst0 = dest;
FAR const char *src0 = src;
FAR unsigned long *aligned_dst;
FAR const unsigned long *aligned_src;
/* If SRC or DEST is unaligned, then copy bytes. */
if (!UNALIGNED(src0, dst0))
{
aligned_dst = (FAR unsigned long *)dst0;
aligned_src = (FAR unsigned long *)src0;
/* SRC and DEST are both "long int" aligned, try to do "long int"
* sized copies.
*/
while (!DETECTNULL(*aligned_src))
{
*aligned_dst++ = *aligned_src++;
}
dst0 = (FAR char *)aligned_dst;
src0 = (FAR char *)aligned_src;
}
while ((*dst0++ = *src0++) != '\0');
return dest;
}
#endif

View File

@ -0,0 +1,92 @@
/****************************************************************************
* libs/libc/string/lib_bsdstrlen.c
*
* Copyright (c) 1994-2009 Red Hat, Inc. All rights reserved.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the BSD License. This program is distributed in the hope that
* it will be useful, but WITHOUT ANY WARRANTY expressed or implied,
* including the implied warranties of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. A copy of this license is available at
* http://www.opensource.org/licenses. Any Red Hat trademarks that are
* incorporated in the source code or documentation are not subject to
* the BSD License and may only be used or replicated with the express
* permission of Red Hat, Inc.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sys/types.h>
#include <string.h>
#include "libc.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define LBLOCKSIZE (sizeof(long))
#define UNALIGNED(x) ((long)(uintptr_t)(x) & (LBLOCKSIZE - 1))
/* Macros for detecting endchar */
#if LONG_MAX == 2147483647
# define DETECTNULL(x) (((x) - 0x01010101) & ~(x) & 0x80808080)
#elif LONG_MAX == 9223372036854775807
/* Nonzero if x (a long int) contains a NULL byte. */
# define DETECTNULL(x) (((x) - 0x0101010101010101) & ~(x) & 0x8080808080808080)
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
#if !defined(CONFIG_LIBC_ARCH_STRLEN) && defined(LIBC_BUILD_STRLEN)
#undef strlen /* See mm/README.txt */
nosanitize_address
size_t strlen(FAR const char *s)
{
FAR const char *start = s;
FAR unsigned long *aligned_addr;
/* Align the pointer, so we can search a word at a time. */
while (UNALIGNED(s))
{
if (!*s)
{
return s - start;
}
s++;
}
/* If the string is word-aligned, we can check for the presence of
* a null in each word-sized block.
*/
aligned_addr = (FAR unsigned long *)s;
while (!DETECTNULL(*aligned_addr))
{
aligned_addr++;
}
/* Once a null is detected, we check each byte in that block for a
* precise position of the null.
*/
s = (FAR char *)aligned_addr;
while (*s)
{
s++;
}
return s - start;
}
#endif

View File

@ -0,0 +1,117 @@
/****************************************************************************
* libs/libc/string/lib_bsdstrncmp.c
*
* Copyright (c) 1994-2009 Red Hat, Inc. All rights reserved.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the BSD License. This program is distributed in the hope that
* it will be useful, but WITHOUT ANY WARRANTY expressed or implied,
* including the implied warranties of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. A copy of this license is available at
* http://www.opensource.org/licenses. Any Red Hat trademarks that are
* incorporated in the source code or documentation are not subject to
* the BSD License and may only be used or replicated with the express
* permission of Red Hat, Inc.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sys/types.h>
#include <string.h>
#include "libc.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define LBLOCKSIZE (sizeof(long))
/* Nonzero if either x or y is not aligned on a "long" boundary. */
#define UNALIGNED(x, y) \
(((long)(uintptr_t)(x) & (sizeof(long) - 1)) | ((long)(uintptr_t)(y) & (sizeof(long) - 1)))
/* Macros for detecting endchar */
#if LONG_MAX == 2147483647
# define DETECTNULL(x) (((x) - 0x01010101) & ~(x) & 0x80808080)
#elif LONG_MAX == 9223372036854775807
/* Nonzero if x (a long int) contains a NULL byte. */
# define DETECTNULL(x) (((x) - 0x0101010101010101) & ~(x) & 0x8080808080808080)
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
#if !defined(CONFIG_LIBC_ARCH_STRNCMP) && defined(LIBC_BUILD_STRNCMP)
#undef strncmp /* See mm/README.txt */
nosanitize_address
int strncmp(FAR const char *cs, FAR const char *ct, size_t nb)
{
FAR unsigned long *a1;
FAR unsigned long *a2;
if (nb == 0)
{
return 0;
}
/* If cs or ct are unaligned, then compare bytes. */
if (!UNALIGNED(cs, ct))
{
/* If cs and ct are word-aligned, compare them a word at a time. */
a1 = (FAR unsigned long *)cs;
a2 = (FAR unsigned long *)ct;
while (nb >= LBLOCKSIZE && *a1 == *a2)
{
nb -= LBLOCKSIZE;
/* If we've run out of bytes or hit a null, return zero
* since we already know *a1 == *a2.
*/
if (nb == 0 || DETECTNULL(*a1))
{
return 0;
}
a1++;
a2++;
}
/* A difference was detected in last few bytes of cs, so search
* bytewise.
*/
cs = (FAR char *)a1;
ct = (FAR char *)a2;
}
while (nb-- > 0 && *cs == *ct)
{
/* If we've run out of bytes or hit a null, return zero
* since we already know *cs == *ct.
*/
if (nb == 0 || *cs == '\0')
{
return 0;
}
cs++;
ct++;
}
return *cs - *ct;
}
#endif

View File

@ -0,0 +1,124 @@
/****************************************************************************
* libs/libc/string/lib_bsdstrncpy.c
*
* Copyright (c) 1994-2009 Red Hat, Inc. All rights reserved.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the BSD License. This program is distributed in the hope that
* it will be useful, but WITHOUT ANY WARRANTY expressed or implied,
* including the implied warranties of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. A copy of this license is available at
* http://www.opensource.org/licenses. Any Red Hat trademarks that are
* incorporated in the source code or documentation are not subject to
* the BSD License and may only be used or replicated with the express
* permission of Red Hat, Inc.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sys/types.h>
#include <string.h>
#include "libc.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define LBLOCKSIZE (sizeof(long))
/* Nonzero if either x or y is not aligned on a "long" boundary. */
#define UNALIGNED(x, y) \
(((long)(uintptr_t)(x) & (sizeof(long) - 1)) | ((long)(uintptr_t)(y) & (sizeof(long) - 1)))
/* Macros for detecting endchar */
#if LONG_MAX == 2147483647
# define DETECTNULL(x) (((x) - 0x01010101) & ~(x) & 0x80808080)
#elif LONG_MAX == 9223372036854775807
/* Nonzero if x (a long int) contains a NULL byte. */
# define DETECTNULL(x) (((x) - 0x0101010101010101) & ~(x) & 0x8080808080808080)
#endif
#define TOO_SMALL(len) ((len) < sizeof(long))
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: strncpy
*
* Description:
* Copies the string pointed to by 'src' (including the terminating NUL
* character) into the array pointed to by 'dest'. strncpy() will not
* copy more than 'n' bytes from 'src' to 'dest' array (including the
* NUL terminator).
*
* If the array pointed to by 'src' is a string that is shorter than 'n'
* bytes, NUL characters will be appended to the copy in the array
* pointed to by 'dest', until 'n' bytes in all are written.
*
* If copying takes place between objects that overlap, the behavior is
* undefined.
*
* Returned Value:
* The strncpy() function returns the pointer to 'dest'
*
****************************************************************************/
#if !defined(CONFIG_LIBC_ARCH_STRNCPY) && defined(LIBC_BUILD_STRNCPY)
#undef strncpy /* See mm/README.txt */
nosanitize_address
FAR char *strncpy(FAR char *dest, FAR const char *src, size_t n)
{
FAR char *dst0 = dest;
FAR const char *src0 = src;
FAR long *aligned_dst;
FAR const long *aligned_src;
/* If src and dest is aligned and n large enough, then copy words. */
if (!UNALIGNED(src0, dst0) && !TOO_SMALL(n))
{
aligned_dst = (FAR long *)dst0;
aligned_src = (FAR long *)src0;
/* src and dest are both "long int" aligned, try to do "long int"
* sized copies.
*/
while (n >= LBLOCKSIZE && !DETECTNULL(*aligned_src))
{
n -= LBLOCKSIZE;
*aligned_dst++ = *aligned_src++;
}
dst0 = (FAR char *)aligned_dst;
src0 = (FAR char *)aligned_src;
}
while (n > 0)
{
--n;
if ((*dst0++ = *src0++) == '\0')
{
break;
}
}
while (n-- > 0)
{
*dst0++ = '\0';
}
return dest;
}
#endif

View File

@ -0,0 +1,58 @@
/****************************************************************************
* libs/libc/string/lib_bsdstrrchr.c
*
* Copyright (c) 1994-2009 Red Hat, Inc. All rights reserved.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the BSD License. This program is distributed in the hope that
* it will be useful, but WITHOUT ANY WARRANTY expressed or implied,
* including the implied warranties of MERCHANTABILITY or FITNESS FOR
* A PARTICULAR PURPOSE. A copy of this license is available at
* http://www.opensource.org/licenses. Any Red Hat trademarks that are
* incorporated in the source code or documentation are not subject to
* the BSD License and may only be used or replicated with the express
* permission of Red Hat, Inc.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <string.h>
#include "libc.h"
/****************************************************************************
* Public Functions
****************************************************************************/
/* The strrchr() function returns a pointer to the last
* occurrence of the character c in the string s.
*/
#if !defined(CONFIG_LIBC_ARCH_STRRCHR) && defined(LIBC_BUILD_STRRCHR)
#undef strrchr /* See mm/README.txt */
FAR char *strrchr(FAR const char *s, int c)
{
FAR const char *last = NULL;
if (c)
{
while ((s = strchr(s, c)))
{
last = s;
s++;
}
}
else
{
last = strchr(s, c);
}
return (FAR char *)last;
}
#endif

View File

@ -28,36 +28,6 @@
#include <sys/types.h>
#include <string.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#ifdef CONFIG_LIBC_STRING_OPTIMIZE
/* Nonzero if either x or y is not aligned on a "long" boundary. */
#define UNALIGNED(x, y) \
(((long)(uintptr_t)(x) & (sizeof(long) - 1)) | ((long)(uintptr_t)(y) & (sizeof(long) - 1)))
/* How many bytes are copied each iteration of the word copy loop. */
#define LITTLEBLOCKSIZE (sizeof(long))
/* Threshhold for punting to the byte copier. */
#define TOO_SMALL(len) ((len) < LITTLEBLOCKSIZE)
/* Macros for detecting endchar */
#if LONG_MAX == 2147483647
# define DETECTNULL(x) (((x) - 0x01010101) & ~(x) & 0x80808080)
#elif LONG_MAX == 9223372036854775807
/* Nonzero if x (a long int) contains a NULL byte. */
# define DETECTNULL(x) (((x) - 0x0101010101010101) & ~(x) & 0x8080808080808080)
#endif
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
@ -81,71 +51,6 @@
#undef memccpy /* See mm/README.txt */
FAR void *memccpy(FAR void *s1, FAR const void *s2, int c, size_t n)
{
#ifdef CONFIG_LIBC_STRING_OPTIMIZE
FAR void *ptr = NULL;
FAR unsigned char *pout = (FAR unsigned char *)s1;
FAR const unsigned char *pin = (FAR const unsigned char *)s2;
FAR long *paligned_out;
FAR const long *paligned_in;
unsigned char endchar = c & 0xff;
/* If the size is small, or either pin or pout is unaligned,
* then punt into the byte copy loop. This should be rare.
*/
if (!TOO_SMALL(n) && !UNALIGNED(pin, pout))
{
unsigned int i;
unsigned long mask = 0;
paligned_out = (FAR long *)pout;
paligned_in = (FAR long *)pin;
/* The fast code reads the ASCII one word at a time and only
* performs the bytewise search on word-sized segments if they
* contain the search character, which is detected by XORing
* the word-sized segment with a word-sized block of the search
* character and then detecting for the presence of NULL in the
* result.
*/
for (i = 0; i < LITTLEBLOCKSIZE; i++)
{
mask = (mask << 8) + endchar;
}
/* Copy one long word at a time if possible. */
while (n >= LITTLEBLOCKSIZE)
{
unsigned long buffer = (unsigned long)(*paligned_in);
buffer ^= mask;
if (DETECTNULL(buffer))
{
break; /* endchar is found, go byte by byte from here */
}
*paligned_out++ = *paligned_in++;
n -= LITTLEBLOCKSIZE;
}
/* Pick up any residual with a byte copier. */
pout = (FAR unsigned char *)paligned_out;
pin = (FAR unsigned char *)paligned_in;
}
while (n--)
{
if ((*pout++ = *pin++) == endchar)
{
ptr = pout;
break;
}
}
return ptr;
#else
FAR unsigned char *pout = (FAR unsigned char *)s1;
FAR unsigned char *pin = (FAR unsigned char *)s2;
@ -170,5 +75,4 @@ FAR void *memccpy(FAR void *s1, FAR const void *s2, int c, size_t n)
/* C was not found in the first n bytes of s2 */
return NULL;
#endif
}

View File

@ -30,38 +30,6 @@
#include "libc.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#ifdef CONFIG_LIBC_STRING_OPTIMIZE
#define UNALIGNED(x) ((long)(uintptr_t)(x) & (sizeof(long) - 1))
/* How many bytes are loaded each iteration of the word copy loop. */
#define LBLOCKSIZE (sizeof(long))
/* Threshhold for punting to the bytewise iterator. */
#define TOO_SMALL(len) ((len) < LBLOCKSIZE)
#if LONG_MAX == 2147483647
# define DETECTNULL(x) (((x) - 0x01010101) & ~(x) & 0x80808080)
#elif LONG_MAX == 9223372036854775807
/* Nonzero if x (a long int) contains a NULL byte. */
# define DETECTNULL(x) (((x) - 0x0101010101010101) & ~(x) & 0x8080808080808080)
#endif
/* DETECTCHAR returns nonzero if (long)x contains the byte used
* to fill (long)mask.
*/
#define DETECTCHAR(x, mask) (DETECTNULL((x) ^ (mask)))
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
@ -84,76 +52,6 @@
#undef memchr /* See mm/README.txt */
FAR void *memchr(FAR const void *s, int c, size_t n)
{
#ifdef CONFIG_LIBC_STRING_OPTIMIZE
FAR const unsigned char *p = (FAR const unsigned char *)s;
FAR unsigned long *asrc;
unsigned char d = c;
unsigned long mask;
unsigned int i;
while (UNALIGNED(p))
{
if (!n--)
{
return NULL;
}
if (*p == d)
{
return (FAR void *)p;
}
p++;
}
if (!TOO_SMALL(n))
{
/* If we get this far, we know that n is large and p is
* word-aligned.
* The fast code reads the source one word at a time and only
* performs the bytewise search on word-sized segments if they
* contain the search character, which is detected by XORing
* the word-sized segment with a word-sized block of the search
* character and then detecting for the presence of NUL in the
* result.
*/
asrc = (FAR unsigned long *)p;
mask = d << 8 | d;
mask = mask << 16 | mask;
for (i = 32; i < LBLOCKSIZE * 8; i <<= 1)
{
mask = (mask << i) | mask;
}
while (n >= LBLOCKSIZE)
{
if (DETECTCHAR(*asrc, mask))
{
break;
}
n -= LBLOCKSIZE;
asrc++;
}
/* If there are fewer than LBLOCKSIZE characters left,
* then we resort to the bytewise loop.
*/
p = (FAR unsigned char *)asrc;
}
while (n--)
{
if (*p == d)
{
return (FAR void *)p;
}
p++;
}
#else
FAR const unsigned char *p = (FAR const unsigned char *)s;
while (n--)
@ -165,7 +63,6 @@ FAR void *memchr(FAR const void *s, int c, size_t n)
p++;
}
#endif
return NULL;
}

View File

@ -30,26 +30,6 @@
#include "libc.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#ifdef CONFIG_LIBC_STRING_OPTIMIZE
/* Nonzero if either x or y is not aligned on a "long" boundary. */
#define UNALIGNED(x, y) \
(((long)(uintptr_t)(x) & (sizeof(long) - 1)) | ((long)(uintptr_t)(y) & (sizeof(long) - 1)))
/* How many bytes are copied each iteration of the word copy loop. */
#define LBLOCKSIZE (sizeof(long))
/* Threshhold for punting to the byte copier. */
#define TOO_SMALL(len) ((len) < LBLOCKSIZE)
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
@ -59,54 +39,6 @@
no_builtin("memcmp")
int memcmp(FAR const void *s1, FAR const void *s2, size_t n)
{
#ifdef CONFIG_LIBC_STRING_OPTIMIZE
FAR unsigned char *p1 = (FAR unsigned char *)s1;
FAR unsigned char *p2 = (FAR unsigned char *)s2;
FAR unsigned long *a1;
FAR unsigned long *a2;
/* If the size is too small, or either pointer is unaligned,
* then we punt to the byte compare loop. Hopefully this will
* not turn up in inner loops.
*/
if (!TOO_SMALL(n) && !UNALIGNED(p1, p2))
{
/* Otherwise, load and compare the blocks of memory one
* word at a time.
*/
a1 = (FAR unsigned long *)p1;
a2 = (FAR unsigned long *)p2;
while (n >= LBLOCKSIZE)
{
if (*a1 != *a2)
{
break;
}
a1++;
a2++;
n -= LBLOCKSIZE;
}
/* check s mod LBLOCKSIZE remaining characters */
p1 = (FAR unsigned char *)a1;
p2 = (FAR unsigned char *)a2;
}
while (n--)
{
if (*p1 != *p2)
{
return *p1 - *p2;
}
p1++;
p2++;
}
#else
FAR unsigned char *p1 = (FAR unsigned char *)s1;
FAR unsigned char *p2 = (FAR unsigned char *)s2;
@ -124,7 +56,6 @@ int memcmp(FAR const void *s1, FAR const void *s2, size_t n)
p1++;
p2++;
}
#endif
return 0;
}

View File

@ -30,30 +30,6 @@
#include "libc.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#ifdef CONFIG_LIBC_STRING_OPTIMIZE
/* Nonzero if either x or y is not aligned on a "long" boundary. */
#define UNALIGNED(x, y) \
(((long)(uintptr_t)(x) & (sizeof(long) - 1)) | ((long)(uintptr_t)(y) & (sizeof(long) - 1)))
/* How many bytes are copied each iteration of the 4X unrolled loop. */
#define BIGBLOCKSIZE (sizeof(long) << 2)
/* How many bytes are copied each iteration of the word copy loop. */
#define LITTLEBLOCKSIZE (sizeof(long))
/* Threshhold for punting to the byte copier. */
#define TOO_SMALL(len) ((len) < BIGBLOCKSIZE)
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
@ -67,58 +43,12 @@
no_builtin("memcpy")
FAR void *memcpy(FAR void *dest, FAR const void *src, size_t n)
{
#ifdef CONFIG_LIBC_STRING_OPTIMIZE
FAR char *pout = dest;
FAR const char *pin = src;
FAR long *paligned_out;
FAR const long *paligned_in;
/* If the size is small, or either pin or pout is unaligned,
* then punt into the byte copy loop. This should be rare.
*/
if (!TOO_SMALL(n) && !UNALIGNED(pin, pout))
{
paligned_out = (FAR long *)pout;
paligned_in = (FAR long *)pin;
/* Copy 4X long words at a time if possible. */
while (n >= BIGBLOCKSIZE)
{
*paligned_out++ = *paligned_in++;
*paligned_out++ = *paligned_in++;
*paligned_out++ = *paligned_in++;
*paligned_out++ = *paligned_in++;
n -= BIGBLOCKSIZE;
}
/* Copy one long word at a time if possible. */
while (n >= LITTLEBLOCKSIZE)
{
*paligned_out++ = *paligned_in++;
n -= LITTLEBLOCKSIZE;
}
/* Pick up any residual with a byte copier. */
pout = (FAR char *)paligned_out;
pin = (FAR char *)paligned_in;
}
while (n--)
{
*pout++ = *pin++;
}
#else
FAR unsigned char *pout = (FAR unsigned char *)dest;
FAR unsigned char *pin = (FAR unsigned char *)src;
while (n-- > 0)
{
*pout++ = *pin++;
}
#endif
return dest;
}

View File

@ -28,37 +28,6 @@
#include <string.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#ifdef CONFIG_LIBC_STRING_OPTIMIZE
/* Nonzero if x is not aligned on a "long" boundary. */
#define UNALIGNED(x) ((long)(uintptr_t)((x) + 1) & (sizeof(long) - 1))
/* How many bytes are loaded each iteration of the word copy loop. */
#define LBLOCKSIZE (sizeof(long))
/* Threshhold for punting to the bytewise iterator. */
#define TOO_SMALL(len) ((len) < LBLOCKSIZE)
/* Macros for detecting endchar */
#if LONG_MAX == 2147483647
# define DETECTNULL(x) (((x) - 0x01010101) & ~(x) & 0x80808080)
#elif LONG_MAX == 9223372036854775807
/* Nonzero if x (a long int) contains a NULL byte. */
# define DETECTNULL(x) (((x) - 0x0101010101010101) & ~(x) & 0x8080808080808080)
#endif
#define DETECTCHAR(x, mask) (DETECTNULL((x) ^ (mask)))
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
@ -80,77 +49,6 @@
#undef memrchr /* See mm/README.txt */
FAR void *memrchr(FAR const void *s, int c, size_t n)
{
#ifdef CONFIG_LIBC_STRING_OPTIMIZE
FAR const unsigned char *src0 =
(FAR const unsigned char *)s + n - 1;
FAR unsigned long *asrc;
unsigned char d = c;
unsigned long mask;
unsigned int i;
while (UNALIGNED(src0))
{
if (!n--)
{
return NULL;
}
if (*src0 == d)
{
return (FAR void *)src0;
}
src0--;
}
if (!TOO_SMALL(n))
{
/* If we get this far, we know that n is large and src0 is
* word-aligned.
* The fast code reads the source one word at a time and only
* performs the bytewise search on word-sized segments if they
* contain the search character, which is detected by XORing
* the word-sized segment with a word-sized block of the search
* character and then detecting for the presence of NUL in the
* result.
*/
asrc = (FAR unsigned long *)(src0 - LBLOCKSIZE + 1);
mask = d << 8 | d;
mask = mask << 16 | mask;
for (i = 32; i < LBLOCKSIZE * 8; i <<= 1)
{
mask = (mask << i) | mask;
}
while (n >= LBLOCKSIZE)
{
if (DETECTCHAR(*asrc, mask))
{
break;
}
n -= LBLOCKSIZE;
asrc--;
}
/* If there are fewer than LBLOCKSIZE characters left,
* then we resort to the bytewise loop.
*/
src0 = (FAR unsigned char *)asrc + LBLOCKSIZE - 1;
}
while (n--)
{
if (*src0 == d)
{
return (FAR void *)src0;
}
src0--;
}
#else
FAR const unsigned char *p = (FAR const unsigned char *)s + n;
while (n--)
@ -160,7 +58,6 @@ FAR void *memrchr(FAR const void *s, int c, size_t n)
return (FAR void *)p;
}
}
#endif
return NULL;
}

View File

@ -28,28 +28,6 @@
#include <string.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#ifdef CONFIG_LIBC_STRING_OPTIMIZE
/* Nonzero if either x or y is not aligned on a "long" boundary. */
#define UNALIGNED(x, y) \
(((long)(uintptr_t)(x) & (sizeof(long) - 1)) | ((long)(uintptr_t)(y) & (sizeof(long) - 1)))
/* Macros for detecting endchar */
#if LONG_MAX == 2147483647
# define DETECTNULL(x) (((x) - 0x01010101) & ~(x) & 0x80808080)
#elif LONG_MAX == 9223372036854775807
/* Nonzero if x (a long int) contains a NULL byte. */
# define DETECTNULL(x) (((x) - 0x0101010101010101) & ~(x) & 0x8080808080808080)
#endif
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
@ -69,36 +47,9 @@
#ifndef CONFIG_LIBC_ARCH_STPCPY
#undef stpcpy /* See mm/README.txt */
nosanitize_address
FAR char *stpcpy(FAR char *dest, FAR const char *src)
{
#ifdef CONFIG_LIBC_STRING_OPTIMIZE
FAR long *aligned_dst;
FAR const long *aligned_src;
/* If src or dest is unaligned, then copy bytes. */
if (!UNALIGNED(src, dest))
{
aligned_dst = (FAR long *)dest;
aligned_src = (FAR long *)src;
/* src and dest are both "long int" aligned, try to do "long int"
* sized copies.
*/
while (!DETECTNULL(*aligned_src))
{
*aligned_dst++ = *aligned_src++;
}
dest = (FAR char *)aligned_dst;
src = (FAR char *)aligned_src;
}
#endif
while ((*dest++ = *src++) != '\0');
return --dest;
}
#endif

View File

@ -28,34 +28,6 @@
#include <sys/types.h>
#include <string.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#ifdef CONFIG_LIBC_STRING_OPTIMIZE
/* Nonzero if either x or y is not aligned on a "long" boundary. */
#define UNALIGNED(x, y) \
(((long)(uintptr_t)(x) & (sizeof(long) - 1)) | ((long)(uintptr_t)(y) & (sizeof(long) - 1)))
/* How many bytes are loaded each iteration of the word copy loop. */
#define LBLOCKSIZE (sizeof(long))
/* Macros for detecting endchar */
#if LONG_MAX == 2147483647
#define DETECTNULL(x) (((x) - 0x01010101) & ~(x) & 0x80808080)
#elif LONG_MAX == 9223372036854775807
/* Nonzero if x (a long int) contains a NULL byte. */
#define DETECTNULL(x) (((x) - 0x0101010101010101) & ~(x) & 0x8080808080808080)
#endif
#define TOO_SMALL(len) ((len) < sizeof(long))
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
@ -87,49 +59,6 @@
#undef stpncpy /* See mm/README.txt */
FAR char *stpncpy(FAR char *dest, FAR const char *src, size_t n)
{
#ifdef CONFIG_LIBC_STRING_OPTIMIZE
FAR char *ret = NULL;
FAR long *aligned_dst;
FAR const long *aligned_src;
/* If src and dest is aligned and n large enough, then copy words. */
if (!UNALIGNED(src, dest) && !TOO_SMALL(n))
{
aligned_dst = (FAR long *)dest;
aligned_src = (FAR long *)src;
/* src and dest are both "long int" aligned, try to do "long int"
* sized copies.
*/
while (n >= LBLOCKSIZE && !DETECTNULL(*aligned_src))
{
n -= LBLOCKSIZE;
*aligned_dst++ = *aligned_src++;
}
dest = (FAR char *)aligned_dst;
src = (FAR char *)aligned_src;
}
while (n > 0)
{
--n;
if ((*dest++ = *src++) == '\0')
{
ret = dest - 1;
break;
}
}
while (n-- > 0)
{
*dest++ = '\0';
}
return ret ? ret : dest;
#else
FAR char *end = dest + n; /* End of dest buffer + 1 byte */
FAR char *ret; /* Value to be returned */
@ -162,6 +91,5 @@ FAR char *stpncpy(FAR char *dest, FAR const char *src, size_t n)
}
return ret;
#endif
}
#endif

View File

@ -30,67 +30,14 @@
#include "libc.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#ifdef CONFIG_LIBC_STRING_OPTIMIZE
#define ALIGNED(x) \
(((long)(uintptr_t)(x) & (sizeof(long) - 1)) == 0)
/* Macros for detecting endchar */
#if LONG_MAX == 2147483647
# define DETECTNULL(x) (((x) - 0x01010101) & ~(x) & 0x80808080)
#elif LONG_MAX == 9223372036854775807
/* Nonzero if x (a long int) contains a NULL byte. */
# define DETECTNULL(x) (((x) - 0x0101010101010101) & ~(x) & 0x8080808080808080)
#endif
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
#if !defined(CONFIG_LIBC_ARCH_STRCAT) && defined(LIBC_BUILD_STRCAT)
#undef strcat /* See mm/README.txt */
nosanitize_address
FAR char *strcat(FAR char *dest, FAR const char *src)
{
#ifdef CONFIG_LIBC_STRING_OPTIMIZE
FAR char *ret = dest;
/* Skip over the data in dest as quickly as possible. */
if (ALIGNED(dest))
{
FAR unsigned long *aligned_s1 = (FAR unsigned long *)dest;
while (!DETECTNULL(*aligned_s1))
{
aligned_s1++;
}
dest = (FAR char *)aligned_s1;
}
while (*dest)
{
dest++;
}
/* dest now points to the its trailing null character, we can
* just use strcpy to do the work for us now.
* ?!? We might want to just include strcpy here.
* Also, this will cause many more unaligned string copies because
* dest is much less likely to be aligned. I don't know if its worth
* tweaking strcpy to handle this better.
*/
strcpy(dest, src);
#else
FAR char *ret = dest;
dest += strlen(dest);
@ -100,7 +47,6 @@ FAR char *strcat(FAR char *dest, FAR const char *src)
}
*dest = '\0';
#endif
return ret;
}

View File

@ -30,32 +30,6 @@
#include "libc.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#ifdef CONFIG_LIBC_STRING_OPTIMIZE
#define UNALIGNED(x) ((long)(uintptr_t)(x) & (sizeof(long) - 1))
/* How many bytes are loaded each iteration of the word copy loop. */
#define LBLOCKSIZE (sizeof(long))
/* Macros for detecting endchar */
#if LONG_MAX == 2147483647
# define DETECTNULL(x) (((x) - 0x01010101) & ~(x) & 0x80808080)
#elif LONG_MAX == 9223372036854775807
/* Nonzero if x (a long int) contains a NULL byte. */
# define DETECTNULL(x) (((x) - 0x0101010101010101) & ~(x) & 0x8080808080808080)
#endif
#define DETECTCHAR(x, mask) (DETECTNULL((x) ^ (mask)))
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
@ -76,95 +50,8 @@
#if !defined(CONFIG_LIBC_ARCH_STRCHR) && defined(LIBC_BUILD_STRCHR)
#undef strchr /* See mm/README.txt */
nosanitize_address
FAR char *strchr(FAR const char *s, int c)
{
#ifdef CONFIG_LIBC_STRING_OPTIMIZE
FAR const unsigned char *s1 = (FAR const unsigned char *)s;
FAR unsigned long *aligned_addr;
unsigned char i = c;
unsigned long mask;
unsigned long j;
/* Special case for finding 0. */
if (!i)
{
while (UNALIGNED(s1))
{
if (!*s1)
{
return (FAR char *)s1;
}
s1++;
}
/* Operate a word at a time. */
aligned_addr = (FAR unsigned long *)s1;
while (!DETECTNULL(*aligned_addr))
{
aligned_addr++;
}
/* Found the end of string. */
s1 = (FAR const unsigned char *)aligned_addr;
while (*s1)
{
s1++;
}
return (FAR char *)s1;
}
/* All other bytes. Align the pointer, then search a long at a time. */
while (UNALIGNED(s1))
{
if (!*s1)
{
return NULL;
}
if (*s1 == i)
{
return (FAR char *)s1;
}
s1++;
}
mask = i;
for (j = 8; j < LBLOCKSIZE * 8; j <<= 1)
{
mask = (mask << j) | mask;
}
aligned_addr = (FAR unsigned long *)s1;
while (!DETECTNULL(*aligned_addr) && !DETECTCHAR(*aligned_addr, mask))
{
aligned_addr++;
}
/* The block of bytes currently pointed to by aligned_addr
* contains either a null or the target char, or both. We
* catch it using the bytewise search.
*/
s1 = (FAR unsigned char *)aligned_addr;
while (*s1 && *s1 != i)
{
s1++;
}
if (*s1 == i)
{
return (FAR char *)s1;
}
#else
for (; ; s++)
{
if (*s == c)
@ -177,7 +64,6 @@ FAR char *strchr(FAR const char *s, int c)
break;
}
}
#endif
return NULL;
}

View File

@ -52,11 +52,6 @@
#undef strchrnul /* See mm/README.txt */
FAR char *strchrnul(FAR const char *s, int c)
{
#ifdef CONFIG_LIBC_STRING_OPTIMIZE
FAR char *s1 = strchr(s, c);
return s1 ? s1 : (FAR char *)s + strlen(s);
#else
if (s)
{
while (*s != '\0' && *s != c)
@ -66,6 +61,5 @@ FAR char *strchrnul(FAR const char *s, int c)
}
return (FAR char *)s;
#endif
}
#endif

View File

@ -30,80 +30,14 @@
#include "libc.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#ifdef CONFIG_LIBC_STRING_OPTIMIZE
/* Nonzero if either x or y is not aligned on a "long" boundary. */
#define UNALIGNED(x, y) \
(((long)(uintptr_t)(x) & (sizeof(long) - 1)) | ((long)(uintptr_t)(y) & (sizeof(long) - 1)))
/* Macros for detecting endchar */
#if LONG_MAX == 2147483647
# define DETECTNULL(x) (((x) - 0x01010101) & ~(x) & 0x80808080)
#elif LONG_MAX == 9223372036854775807
/* Nonzero if x (a long int) contains a NULL byte. */
# define DETECTNULL(x) (((x) - 0x0101010101010101) & ~(x) & 0x8080808080808080)
#endif
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
#if !defined(CONFIG_LIBC_ARCH_STRCMP) && defined(LIBC_BUILD_STRCMP)
#undef strcmp /* See mm/README.txt */
nosanitize_address
int strcmp(FAR const char *cs, FAR const char *ct)
{
#ifdef CONFIG_LIBC_STRING_OPTIMIZE
FAR unsigned long *a1;
FAR unsigned long *a2;
/* If cs or ct are unaligned, then compare bytes. */
if (!UNALIGNED(cs, ct))
{
/* If cs and ct are word-aligned, compare them a word at a time. */
a1 = (FAR unsigned long *)cs;
a2 = (FAR unsigned long *)ct;
while (*a1 == *a2)
{
/* To get here, *a1 == *a2, thus if we find a null in *a1,
* then the strings must be equal, so return zero.
*/
if (DETECTNULL(*a1))
{
return 0;
}
a1++;
a2++;
}
/* A difference was detected in last few bytes of cs,
* so search bytewise.
*/
cs = (FAR char *)a1;
ct = (FAR char *)a2;
}
while (*cs != '\0' && *cs == *ct)
{
cs++;
ct++;
}
return (*(FAR unsigned char *)cs) - (*(FAR unsigned char *)ct);
#else
register int result;
for (; ; )
{
@ -115,6 +49,5 @@ int strcmp(FAR const char *cs, FAR const char *ct)
}
return result;
#endif
}
#endif

View File

@ -30,28 +30,6 @@
#include "libc.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#ifdef CONFIG_LIBC_STRING_OPTIMIZE
/* Nonzero if either x or y is not aligned on a "long" boundary. */
#define UNALIGNED(x, y) \
(((long)(uintptr_t)(x) & (sizeof(long) - 1)) | ((long)(uintptr_t)(y) & (sizeof(long) - 1)))
/* Macros for detecting endchar */
#if LONG_MAX == 2147483647
# define DETECTNULL(x) (((x) - 0x01010101) & ~(x) & 0x80808080)
#elif LONG_MAX == 9223372036854775807
/* Nonzero if x (a long int) contains a NULL byte. */
# define DETECTNULL(x) (((x) - 0x0101010101010101) & ~(x) & 0x8080808080808080)
#endif
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
@ -70,42 +48,10 @@
#if !defined(CONFIG_LIBC_ARCH_STRCPY) && defined(LIBC_BUILD_STRCPY)
#undef strcpy /* See mm/README.txt */
nosanitize_address
FAR char *strcpy(FAR char *dest, FAR const char *src)
{
#ifdef CONFIG_LIBC_STRING_OPTIMIZE
FAR char *dst0 = dest;
FAR const char *src0 = src;
FAR unsigned long *aligned_dst;
FAR const unsigned long *aligned_src;
/* If SRC or DEST is unaligned, then copy bytes. */
if (!UNALIGNED(src0, dst0))
{
aligned_dst = (FAR unsigned long *)dst0;
aligned_src = (FAR unsigned long *)src0;
/* SRC and DEST are both "long int" aligned, try to do "long int"
* sized copies.
*/
while (!DETECTNULL(*aligned_src))
{
*aligned_dst++ = *aligned_src++;
}
dst0 = (FAR char *)aligned_dst;
src0 = (FAR char *)aligned_src;
}
while ((*dst0++ = *src0++) != '\0');
return dest;
#else
FAR char *tmp = dest;
while ((*dest++ = *src++) != '\0');
return tmp;
#endif
}
#endif

View File

@ -30,77 +30,16 @@
#include "libc.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#ifdef CONFIG_LIBC_STRING_OPTIMIZE
#define LBLOCKSIZE (sizeof(long))
#define UNALIGNED(x) ((long)(uintptr_t)(x) & (LBLOCKSIZE - 1))
/* Macros for detecting endchar */
#if LONG_MAX == 2147483647
# define DETECTNULL(x) (((x) - 0x01010101) & ~(x) & 0x80808080)
#elif LONG_MAX == 9223372036854775807
/* Nonzero if x (a long int) contains a NULL byte. */
# define DETECTNULL(x) (((x) - 0x0101010101010101) & ~(x) & 0x8080808080808080)
#endif
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
#if !defined(CONFIG_LIBC_ARCH_STRLEN) && defined(LIBC_BUILD_STRLEN)
#undef strlen /* See mm/README.txt */
nosanitize_address
size_t strlen(FAR const char *s)
{
#ifdef CONFIG_LIBC_STRING_OPTIMIZE
FAR const char *start = s;
FAR unsigned long *aligned_addr;
/* Align the pointer, so we can search a word at a time. */
while (UNALIGNED(s))
{
if (!*s)
{
return s - start;
}
s++;
}
/* If the string is word-aligned, we can check for the presence of
* a null in each word-sized block.
*/
aligned_addr = (FAR unsigned long *)s;
while (!DETECTNULL(*aligned_addr))
{
aligned_addr++;
}
/* Once a null is detected, we check each byte in that block for a
* precise position of the null.
*/
s = (FAR char *)aligned_addr;
while (*s)
{
s++;
}
return s - start;
#else
FAR const char *sc;
for (sc = s; *sc != '\0'; ++sc);
return sc - s;
#endif
}
#endif

View File

@ -30,99 +30,14 @@
#include "libc.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#ifdef CONFIG_LIBC_STRING_OPTIMIZE
#define LBLOCKSIZE (sizeof(long))
/* Nonzero if either x or y is not aligned on a "long" boundary. */
#define UNALIGNED(x, y) \
(((long)(uintptr_t)(x) & (sizeof(long) - 1)) | ((long)(uintptr_t)(y) & (sizeof(long) - 1)))
/* Macros for detecting endchar */
#if LONG_MAX == 2147483647
# define DETECTNULL(x) (((x) - 0x01010101) & ~(x) & 0x80808080)
#elif LONG_MAX == 9223372036854775807
/* Nonzero if x (a long int) contains a NULL byte. */
# define DETECTNULL(x) (((x) - 0x0101010101010101) & ~(x) & 0x8080808080808080)
#endif
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
#if !defined(CONFIG_LIBC_ARCH_STRNCMP) && defined(LIBC_BUILD_STRNCMP)
#undef strncmp /* See mm/README.txt */
nosanitize_address
int strncmp(FAR const char *cs, FAR const char *ct, size_t nb)
{
#ifdef CONFIG_LIBC_STRING_OPTIMIZE
FAR unsigned long *a1;
FAR unsigned long *a2;
if (nb == 0)
{
return 0;
}
/* If cs or ct are unaligned, then compare bytes. */
if (!UNALIGNED(cs, ct))
{
/* If cs and ct are word-aligned, compare them a word at a time. */
a1 = (FAR unsigned long *)cs;
a2 = (FAR unsigned long *)ct;
while (nb >= LBLOCKSIZE && *a1 == *a2)
{
nb -= LBLOCKSIZE;
/* If we've run out of bytes or hit a null, return zero
* since we already know *a1 == *a2.
*/
if (nb == 0 || DETECTNULL(*a1))
{
return 0;
}
a1++;
a2++;
}
/* A difference was detected in last few bytes of cs, so search
* bytewise.
*/
cs = (FAR char *)a1;
ct = (FAR char *)a2;
}
while (nb-- > 0 && *cs == *ct)
{
/* If we've run out of bytes or hit a null, return zero
* since we already know *cs == *ct.
*/
if (nb == 0 || *cs == '\0')
{
return 0;
}
cs++;
ct++;
}
return *cs - *ct;
#else
register int result = 0;
for (; nb > 0; nb--)
{
@ -134,6 +49,5 @@ int strncmp(FAR const char *cs, FAR const char *ct, size_t nb)
}
return result;
#endif
}
#endif

View File

@ -30,33 +30,6 @@
#include "libc.h"
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#ifdef CONFIG_LIBC_STRING_OPTIMIZE
#define LBLOCKSIZE (sizeof(long))
/* Nonzero if either x or y is not aligned on a "long" boundary. */
#define UNALIGNED(x, y) \
(((long)(uintptr_t)(x) & (sizeof(long) - 1)) | ((long)(uintptr_t)(y) & (sizeof(long) - 1)))
/* Macros for detecting endchar */
#if LONG_MAX == 2147483647
# define DETECTNULL(x) (((x) - 0x01010101) & ~(x) & 0x80808080)
#elif LONG_MAX == 9223372036854775807
/* Nonzero if x (a long int) contains a NULL byte. */
# define DETECTNULL(x) (((x) - 0x0101010101010101) & ~(x) & 0x8080808080808080)
#endif
#define TOO_SMALL(len) ((len) < sizeof(long))
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
@ -84,52 +57,8 @@
#if !defined(CONFIG_LIBC_ARCH_STRNCPY) && defined(LIBC_BUILD_STRNCPY)
#undef strncpy /* See mm/README.txt */
nosanitize_address
FAR char *strncpy(FAR char *dest, FAR const char *src, size_t n)
{
#ifdef CONFIG_LIBC_STRING_OPTIMIZE
FAR char *dst0 = dest;
FAR const char *src0 = src;
FAR long *aligned_dst;
FAR const long *aligned_src;
/* If src and dest is aligned and n large enough, then copy words. */
if (!UNALIGNED(src0, dst0) && !TOO_SMALL(n))
{
aligned_dst = (FAR long *)dst0;
aligned_src = (FAR long *)src0;
/* src and dest are both "long int" aligned, try to do "long int"
* sized copies.
*/
while (n >= LBLOCKSIZE && !DETECTNULL(*aligned_src))
{
n -= LBLOCKSIZE;
*aligned_dst++ = *aligned_src++;
}
dst0 = (FAR char *)aligned_dst;
src0 = (FAR char *)aligned_src;
}
while (n > 0)
{
--n;
if ((*dst0++ = *src0++) == '\0')
{
break;
}
}
while (n-- > 0)
{
*dst0++ = '\0';
}
return dest;
#else
FAR char *ret = dest; /* Value to be returned */
FAR char *end = dest + n; /* End of dest buffer + 1 byte */
@ -151,6 +80,5 @@ FAR char *strncpy(FAR char *dest, FAR const char *src, size_t n)
}
return ret;
#endif
}
#endif

View File

@ -42,24 +42,6 @@
#undef strrchr /* See mm/README.txt */
FAR char *strrchr(FAR const char *s, int c)
{
#ifdef CONFIG_LIBC_STRING_OPTIMIZE
FAR const char *last = NULL;
if (c)
{
while ((s = strchr(s, c)))
{
last = s;
s++;
}
}
else
{
last = strchr(s, c);
}
return (FAR char *)last;
#else
FAR const char *r = NULL;
do
@ -72,6 +54,5 @@ FAR char *strrchr(FAR const char *s, int c)
while (*s++ != '\0');
return (FAR char *)r;
#endif
}
#endif