forked from nuttx/nuttx-update
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:
parent
cdccce48ac
commit
f07aba5c1e
35 changed files with 1841 additions and 1134 deletions
32
LICENSE
32
LICENSE
|
@ -8667,22 +8667,22 @@ drivers/i3c/internals.h
|
||||||
|
|
||||||
SPDX-License-Identifier: Apache-2.0
|
SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
libs/libc/string/lib_memccpy.c
|
libs/libc/string/lib_bsdmemccpy.c
|
||||||
libs/libc/string/lib_memchr.c
|
libs/libc/string/lib_bsdmemchr.c
|
||||||
libs/libc/string/lib_memcmp.c
|
libs/libc/string/lib_bsdmemcmp.c
|
||||||
libs/libc/string/lib_memcpy.c
|
libs/libc/string/lib_bsdmemcpy.c
|
||||||
libs/libc/string/lib_memrchr.c
|
libs/libc/string/lib_bsdmemrchr.c
|
||||||
libs/libc/string/lib_stpcpy.c
|
libs/libc/string/lib_bsdstpcpy.c
|
||||||
libs/libc/string/lib_stpncpy.c
|
libs/libc/string/lib_bsdstpncpy.c
|
||||||
libs/libc/string/lib_strcat.c
|
libs/libc/string/lib_bsdstrcat.c
|
||||||
libs/libc/string/lib_strchr.c
|
libs/libc/string/lib_bsdstrchr.c
|
||||||
libs/libc/string/lib_strchrnul.c
|
libs/libc/string/lib_bsdstrchrnul.c
|
||||||
libs/libc/string/lib_strcmp.c
|
libs/libc/string/lib_bsdstrcmp.c
|
||||||
libs/libc/string/lib_strcpy.c
|
libs/libc/string/lib_bsdstrcpy.c
|
||||||
libs/libc/string/lib_strlen.c
|
libs/libc/string/lib_bsdstrlen.c
|
||||||
libs/libc/string/lib_strncmp.c
|
libs/libc/string/lib_bsdstrncmp.c
|
||||||
libs/libc/string/lib_strncpy.c
|
libs/libc/string/lib_bsdstrncpy.c
|
||||||
libs/libc/string/lib_strrchr.c
|
libs/libc/string/lib_bsdstrrchr.c
|
||||||
======================
|
======================
|
||||||
|
|
||||||
Copyright (c) 1994-2009 Red Hat, Inc. All rights reserved.
|
Copyright (c) 1994-2009 Red Hat, Inc. All rights reserved.
|
||||||
|
|
|
@ -31,28 +31,20 @@ set(SRCS
|
||||||
lib_flsl.c
|
lib_flsl.c
|
||||||
lib_flsll.c
|
lib_flsll.c
|
||||||
lib_isbasedigit.c
|
lib_isbasedigit.c
|
||||||
lib_memccpy.c
|
|
||||||
lib_memrchr.c
|
|
||||||
lib_memmem.c
|
lib_memmem.c
|
||||||
lib_popcount.c
|
lib_popcount.c
|
||||||
lib_popcountl.c
|
lib_popcountl.c
|
||||||
lib_popcountll.c
|
lib_popcountll.c
|
||||||
lib_skipspace.c
|
lib_skipspace.c
|
||||||
lib_stpcpy.c
|
|
||||||
lib_stpncpy.c
|
|
||||||
lib_strcasecmp.c
|
lib_strcasecmp.c
|
||||||
lib_strcat.c
|
|
||||||
lib_strcspn.c
|
lib_strcspn.c
|
||||||
lib_strchrnul.c
|
|
||||||
lib_strdup.c
|
lib_strdup.c
|
||||||
lib_strerror.c
|
lib_strerror.c
|
||||||
lib_strncasecmp.c
|
lib_strncasecmp.c
|
||||||
lib_strncat.c
|
lib_strncat.c
|
||||||
lib_strncmp.c
|
|
||||||
lib_strndup.c
|
lib_strndup.c
|
||||||
lib_strcasestr.c
|
lib_strcasestr.c
|
||||||
lib_strpbrk.c
|
lib_strpbrk.c
|
||||||
lib_strrchr.c
|
|
||||||
lib_strspn.c
|
lib_strspn.c
|
||||||
lib_strstr.c
|
lib_strstr.c
|
||||||
lib_strtok.c
|
lib_strtok.c
|
||||||
|
@ -68,21 +60,16 @@ set(SRCS
|
||||||
lib_strverscmp.c
|
lib_strverscmp.c
|
||||||
lib_mempcpy.c
|
lib_mempcpy.c
|
||||||
lib_rawmemchr.c
|
lib_rawmemchr.c
|
||||||
lib_memchr.c
|
|
||||||
lib_memcmp.c
|
|
||||||
lib_memmove.c
|
lib_memmove.c
|
||||||
lib_memset.c
|
lib_memset.c
|
||||||
lib_strchr.c
|
|
||||||
lib_strcmp.c
|
|
||||||
lib_strcpy.c
|
|
||||||
lib_strlcat.c
|
lib_strlcat.c
|
||||||
lib_strlcpy.c
|
lib_strlcpy.c
|
||||||
lib_strlen.c
|
|
||||||
lib_strncpy.c
|
|
||||||
lib_strnlen.c)
|
lib_strnlen.c)
|
||||||
|
|
||||||
if(CONFIG_MEMCPY_VIK)
|
if(CONFIG_MEMCPY_VIK)
|
||||||
list(APPEND SRCS lib_vikmemcpy.c)
|
list(APPEND SRCS lib_vikmemcpy.c)
|
||||||
|
elseif(CONFIG_LIBC_STRING_OPTIMIZE)
|
||||||
|
list(APPEND SRCS lib_bsdmemcpy.c)
|
||||||
else()
|
else()
|
||||||
list(APPEND SRCS lib_memcpy.c)
|
list(APPEND SRCS lib_memcpy.c)
|
||||||
endif()
|
endif()
|
||||||
|
@ -91,4 +78,44 @@ if(CONFIG_LIBC_LOCALE)
|
||||||
list(APPEND SRCS lib_strcoll.c lib_strxfrm.c)
|
list(APPEND SRCS lib_strcoll.c lib_strxfrm.c)
|
||||||
endif()
|
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})
|
target_sources(c PRIVATE ${SRCS})
|
||||||
|
|
|
@ -23,23 +23,25 @@
|
||||||
# Add the string C files to the build
|
# 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_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_popcount.c lib_popcountl.c lib_popcountll.c
|
||||||
CSRCS += lib_skipspace.c lib_stpcpy.c lib_stpncpy.c lib_strcasecmp.c
|
CSRCS += lib_skipspace.c lib_strcasecmp.c
|
||||||
CSRCS += lib_strcat.c lib_strcspn.c lib_strchrnul.c lib_strdup.c
|
CSRCS += lib_strcspn.c lib_strdup.c
|
||||||
CSRCS += lib_strerror.c lib_strncasecmp.c lib_strncat.c lib_strncmp.c
|
CSRCS += lib_strerror.c lib_strncasecmp.c lib_strncat.c
|
||||||
CSRCS += lib_strndup.c lib_strcasestr.c lib_strpbrk.c lib_strrchr.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_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_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_index.c lib_rindex.c lib_timingsafe_bcmp.c lib_strverscmp.c
|
||||||
CSRCS += lib_mempcpy.c lib_rawmemchr.c lib_bzero.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_memmove.c lib_memset.c
|
||||||
CSRCS += lib_strchr.c lib_strcmp.c lib_strcpy.c lib_strlcat.c
|
CSRCS += lib_strlcat.c
|
||||||
CSRCS += lib_strlcpy.c lib_strlen.c lib_strncpy.c lib_strnlen.c
|
CSRCS += lib_strlcpy.c lib_strnlen.c
|
||||||
|
|
||||||
ifeq ($(CONFIG_MEMCPY_VIK),y)
|
ifeq ($(CONFIG_MEMCPY_VIK),y)
|
||||||
CSRCS += lib_vikmemcpy.c
|
CSRCS += lib_vikmemcpy.c
|
||||||
|
else ifeq ($(CONFIG_LIBC_STRING_OPTIMIZE),y)
|
||||||
|
CSRCS += lib_bsdmemcpy.c
|
||||||
else
|
else
|
||||||
CSRCS += lib_memcpy.c
|
CSRCS += lib_memcpy.c
|
||||||
endif
|
endif
|
||||||
|
@ -48,6 +50,18 @@ ifeq ($(CONFIG_LIBC_LOCALE),y)
|
||||||
CSRCS += lib_strcoll.c lib_strxfrm.c
|
CSRCS += lib_strcoll.c lib_strxfrm.c
|
||||||
endif
|
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
|
# Add the string directory to the build
|
||||||
|
|
||||||
DEPPATH += --dep-path string
|
DEPPATH += --dep-path string
|
||||||
|
|
140
libs/libc/string/lib_bsdmemccpy.c
Normal file
140
libs/libc/string/lib_bsdmemccpy.c
Normal 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;
|
||||||
|
}
|
150
libs/libc/string/lib_bsdmemchr.c
Normal file
150
libs/libc/string/lib_bsdmemchr.c
Normal 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
|
104
libs/libc/string/lib_bsdmemcmp.c
Normal file
104
libs/libc/string/lib_bsdmemcmp.c
Normal 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
|
109
libs/libc/string/lib_bsdmemcpy.c
Normal file
109
libs/libc/string/lib_bsdmemcpy.c
Normal 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
|
147
libs/libc/string/lib_bsdmemrchr.c
Normal file
147
libs/libc/string/lib_bsdmemrchr.c
Normal 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;
|
||||||
|
}
|
95
libs/libc/string/lib_bsdstpcpy.c
Normal file
95
libs/libc/string/lib_bsdstpcpy.c
Normal 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
|
125
libs/libc/string/lib_bsdstpncpy.c
Normal file
125
libs/libc/string/lib_bsdstpncpy.c
Normal 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
|
87
libs/libc/string/lib_bsdstrcat.c
Normal file
87
libs/libc/string/lib_bsdstrcat.c
Normal 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
|
161
libs/libc/string/lib_bsdstrchr.c
Normal file
161
libs/libc/string/lib_bsdstrchr.c
Normal 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
|
55
libs/libc/string/lib_bsdstrchrnul.c
Normal file
55
libs/libc/string/lib_bsdstrchrnul.c
Normal 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
|
99
libs/libc/string/lib_bsdstrcmp.c
Normal file
99
libs/libc/string/lib_bsdstrcmp.c
Normal 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
|
98
libs/libc/string/lib_bsdstrcpy.c
Normal file
98
libs/libc/string/lib_bsdstrcpy.c
Normal 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
|
92
libs/libc/string/lib_bsdstrlen.c
Normal file
92
libs/libc/string/lib_bsdstrlen.c
Normal 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
|
117
libs/libc/string/lib_bsdstrncmp.c
Normal file
117
libs/libc/string/lib_bsdstrncmp.c
Normal 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
|
124
libs/libc/string/lib_bsdstrncpy.c
Normal file
124
libs/libc/string/lib_bsdstrncpy.c
Normal 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
|
58
libs/libc/string/lib_bsdstrrchr.c
Normal file
58
libs/libc/string/lib_bsdstrrchr.c
Normal 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
|
|
@ -28,36 +28,6 @@
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <string.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
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
@ -81,71 +51,6 @@
|
||||||
#undef memccpy /* See mm/README.txt */
|
#undef memccpy /* See mm/README.txt */
|
||||||
FAR void *memccpy(FAR void *s1, FAR const void *s2, int c, size_t n)
|
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 *pout = (FAR unsigned char *)s1;
|
||||||
FAR unsigned char *pin = (FAR unsigned char *)s2;
|
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 */
|
/* C was not found in the first n bytes of s2 */
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,38 +30,6 @@
|
||||||
|
|
||||||
#include "libc.h"
|
#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
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
@ -84,76 +52,6 @@
|
||||||
#undef memchr /* See mm/README.txt */
|
#undef memchr /* See mm/README.txt */
|
||||||
FAR void *memchr(FAR const void *s, int c, size_t n)
|
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;
|
FAR const unsigned char *p = (FAR const unsigned char *)s;
|
||||||
|
|
||||||
while (n--)
|
while (n--)
|
||||||
|
@ -165,7 +63,6 @@ FAR void *memchr(FAR const void *s, int c, size_t n)
|
||||||
|
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,26 +30,6 @@
|
||||||
|
|
||||||
#include "libc.h"
|
#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
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
@ -59,54 +39,6 @@
|
||||||
no_builtin("memcmp")
|
no_builtin("memcmp")
|
||||||
int memcmp(FAR const void *s1, FAR const void *s2, size_t n)
|
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 *p1 = (FAR unsigned char *)s1;
|
||||||
FAR unsigned char *p2 = (FAR unsigned char *)s2;
|
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++;
|
p1++;
|
||||||
p2++;
|
p2++;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,30 +30,6 @@
|
||||||
|
|
||||||
#include "libc.h"
|
#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
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
@ -67,58 +43,12 @@
|
||||||
no_builtin("memcpy")
|
no_builtin("memcpy")
|
||||||
FAR void *memcpy(FAR void *dest, FAR const void *src, size_t n)
|
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 *pout = (FAR unsigned char *)dest;
|
||||||
FAR unsigned char *pin = (FAR unsigned char *)src;
|
FAR unsigned char *pin = (FAR unsigned char *)src;
|
||||||
while (n-- > 0)
|
while (n-- > 0)
|
||||||
{
|
{
|
||||||
*pout++ = *pin++;
|
*pout++ = *pin++;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
return dest;
|
return dest;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,37 +28,6 @@
|
||||||
|
|
||||||
#include <string.h>
|
#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
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
@ -80,77 +49,6 @@
|
||||||
#undef memrchr /* See mm/README.txt */
|
#undef memrchr /* See mm/README.txt */
|
||||||
FAR void *memrchr(FAR const void *s, int c, size_t n)
|
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;
|
FAR const unsigned char *p = (FAR const unsigned char *)s + n;
|
||||||
|
|
||||||
while (n--)
|
while (n--)
|
||||||
|
@ -160,7 +58,6 @@ FAR void *memrchr(FAR const void *s, int c, size_t n)
|
||||||
return (FAR void *)p;
|
return (FAR void *)p;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,28 +28,6 @@
|
||||||
|
|
||||||
#include <string.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)))
|
|
||||||
|
|
||||||
/* 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
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
@ -69,36 +47,9 @@
|
||||||
|
|
||||||
#ifndef CONFIG_LIBC_ARCH_STPCPY
|
#ifndef CONFIG_LIBC_ARCH_STPCPY
|
||||||
#undef stpcpy /* See mm/README.txt */
|
#undef stpcpy /* See mm/README.txt */
|
||||||
nosanitize_address
|
|
||||||
FAR char *stpcpy(FAR char *dest, FAR const char *src)
|
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');
|
while ((*dest++ = *src++) != '\0');
|
||||||
|
|
||||||
return --dest;
|
return --dest;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -28,34 +28,6 @@
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <string.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
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
@ -87,49 +59,6 @@
|
||||||
#undef stpncpy /* See mm/README.txt */
|
#undef stpncpy /* See mm/README.txt */
|
||||||
FAR char *stpncpy(FAR char *dest, FAR const char *src, size_t n)
|
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 *end = dest + n; /* End of dest buffer + 1 byte */
|
||||||
FAR char *ret; /* Value to be returned */
|
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;
|
return ret;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -30,67 +30,14 @@
|
||||||
|
|
||||||
#include "libc.h"
|
#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
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#if !defined(CONFIG_LIBC_ARCH_STRCAT) && defined(LIBC_BUILD_STRCAT)
|
#if !defined(CONFIG_LIBC_ARCH_STRCAT) && defined(LIBC_BUILD_STRCAT)
|
||||||
#undef strcat /* See mm/README.txt */
|
#undef strcat /* See mm/README.txt */
|
||||||
nosanitize_address
|
|
||||||
FAR char *strcat(FAR char *dest, FAR const char *src)
|
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;
|
FAR char *ret = dest;
|
||||||
|
|
||||||
dest += strlen(dest);
|
dest += strlen(dest);
|
||||||
|
@ -100,7 +47,6 @@ FAR char *strcat(FAR char *dest, FAR const char *src)
|
||||||
}
|
}
|
||||||
|
|
||||||
*dest = '\0';
|
*dest = '\0';
|
||||||
#endif
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,32 +30,6 @@
|
||||||
|
|
||||||
#include "libc.h"
|
#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
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
@ -76,95 +50,8 @@
|
||||||
|
|
||||||
#if !defined(CONFIG_LIBC_ARCH_STRCHR) && defined(LIBC_BUILD_STRCHR)
|
#if !defined(CONFIG_LIBC_ARCH_STRCHR) && defined(LIBC_BUILD_STRCHR)
|
||||||
#undef strchr /* See mm/README.txt */
|
#undef strchr /* See mm/README.txt */
|
||||||
nosanitize_address
|
|
||||||
FAR char *strchr(FAR const char *s, int c)
|
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++)
|
for (; ; s++)
|
||||||
{
|
{
|
||||||
if (*s == c)
|
if (*s == c)
|
||||||
|
@ -177,7 +64,6 @@ FAR char *strchr(FAR const char *s, int c)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,11 +52,6 @@
|
||||||
#undef strchrnul /* See mm/README.txt */
|
#undef strchrnul /* See mm/README.txt */
|
||||||
FAR char *strchrnul(FAR const char *s, int c)
|
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)
|
if (s)
|
||||||
{
|
{
|
||||||
while (*s != '\0' && *s != c)
|
while (*s != '\0' && *s != c)
|
||||||
|
@ -66,6 +61,5 @@ FAR char *strchrnul(FAR const char *s, int c)
|
||||||
}
|
}
|
||||||
|
|
||||||
return (FAR char *)s;
|
return (FAR char *)s;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -30,80 +30,14 @@
|
||||||
|
|
||||||
#include "libc.h"
|
#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
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#if !defined(CONFIG_LIBC_ARCH_STRCMP) && defined(LIBC_BUILD_STRCMP)
|
#if !defined(CONFIG_LIBC_ARCH_STRCMP) && defined(LIBC_BUILD_STRCMP)
|
||||||
#undef strcmp /* See mm/README.txt */
|
#undef strcmp /* See mm/README.txt */
|
||||||
nosanitize_address
|
|
||||||
int strcmp(FAR const char *cs, FAR const char *ct)
|
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;
|
register int result;
|
||||||
for (; ; )
|
for (; ; )
|
||||||
{
|
{
|
||||||
|
@ -115,6 +49,5 @@ int strcmp(FAR const char *cs, FAR const char *ct)
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -30,28 +30,6 @@
|
||||||
|
|
||||||
#include "libc.h"
|
#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
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
@ -70,42 +48,10 @@
|
||||||
|
|
||||||
#if !defined(CONFIG_LIBC_ARCH_STRCPY) && defined(LIBC_BUILD_STRCPY)
|
#if !defined(CONFIG_LIBC_ARCH_STRCPY) && defined(LIBC_BUILD_STRCPY)
|
||||||
#undef strcpy /* See mm/README.txt */
|
#undef strcpy /* See mm/README.txt */
|
||||||
nosanitize_address
|
|
||||||
FAR char *strcpy(FAR char *dest, FAR const char *src)
|
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;
|
FAR char *tmp = dest;
|
||||||
while ((*dest++ = *src++) != '\0');
|
while ((*dest++ = *src++) != '\0');
|
||||||
return tmp;
|
return tmp;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -30,77 +30,16 @@
|
||||||
|
|
||||||
#include "libc.h"
|
#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
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#if !defined(CONFIG_LIBC_ARCH_STRLEN) && defined(LIBC_BUILD_STRLEN)
|
#if !defined(CONFIG_LIBC_ARCH_STRLEN) && defined(LIBC_BUILD_STRLEN)
|
||||||
#undef strlen /* See mm/README.txt */
|
#undef strlen /* See mm/README.txt */
|
||||||
nosanitize_address
|
|
||||||
size_t strlen(FAR const char *s)
|
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;
|
FAR const char *sc;
|
||||||
for (sc = s; *sc != '\0'; ++sc);
|
for (sc = s; *sc != '\0'; ++sc);
|
||||||
return sc - s;
|
return sc - s;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -30,99 +30,14 @@
|
||||||
|
|
||||||
#include "libc.h"
|
#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
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#if !defined(CONFIG_LIBC_ARCH_STRNCMP) && defined(LIBC_BUILD_STRNCMP)
|
#if !defined(CONFIG_LIBC_ARCH_STRNCMP) && defined(LIBC_BUILD_STRNCMP)
|
||||||
#undef strncmp /* See mm/README.txt */
|
#undef strncmp /* See mm/README.txt */
|
||||||
nosanitize_address
|
|
||||||
int strncmp(FAR const char *cs, FAR const char *ct, size_t nb)
|
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;
|
register int result = 0;
|
||||||
for (; nb > 0; nb--)
|
for (; nb > 0; nb--)
|
||||||
{
|
{
|
||||||
|
@ -134,6 +49,5 @@ int strncmp(FAR const char *cs, FAR const char *ct, size_t nb)
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -30,33 +30,6 @@
|
||||||
|
|
||||||
#include "libc.h"
|
#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
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
@ -84,52 +57,8 @@
|
||||||
|
|
||||||
#if !defined(CONFIG_LIBC_ARCH_STRNCPY) && defined(LIBC_BUILD_STRNCPY)
|
#if !defined(CONFIG_LIBC_ARCH_STRNCPY) && defined(LIBC_BUILD_STRNCPY)
|
||||||
#undef strncpy /* See mm/README.txt */
|
#undef strncpy /* See mm/README.txt */
|
||||||
nosanitize_address
|
|
||||||
FAR char *strncpy(FAR char *dest, FAR const char *src, size_t n)
|
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 *ret = dest; /* Value to be returned */
|
||||||
FAR char *end = dest + n; /* End of dest buffer + 1 byte */
|
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;
|
return ret;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -42,24 +42,6 @@
|
||||||
#undef strrchr /* See mm/README.txt */
|
#undef strrchr /* See mm/README.txt */
|
||||||
FAR char *strrchr(FAR const char *s, int c)
|
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;
|
FAR const char *r = NULL;
|
||||||
|
|
||||||
do
|
do
|
||||||
|
@ -72,6 +54,5 @@ FAR char *strrchr(FAR const char *s, int c)
|
||||||
while (*s++ != '\0');
|
while (*s++ != '\0');
|
||||||
|
|
||||||
return (FAR char *)r;
|
return (FAR char *)r;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue