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
32
LICENSE
32
LICENSE
|
@ -8667,22 +8667,22 @@ drivers/i3c/internals.h
|
|||
|
||||
SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
libs/libc/string/lib_memccpy.c
|
||||
libs/libc/string/lib_memchr.c
|
||||
libs/libc/string/lib_memcmp.c
|
||||
libs/libc/string/lib_memcpy.c
|
||||
libs/libc/string/lib_memrchr.c
|
||||
libs/libc/string/lib_stpcpy.c
|
||||
libs/libc/string/lib_stpncpy.c
|
||||
libs/libc/string/lib_strcat.c
|
||||
libs/libc/string/lib_strchr.c
|
||||
libs/libc/string/lib_strchrnul.c
|
||||
libs/libc/string/lib_strcmp.c
|
||||
libs/libc/string/lib_strcpy.c
|
||||
libs/libc/string/lib_strlen.c
|
||||
libs/libc/string/lib_strncmp.c
|
||||
libs/libc/string/lib_strncpy.c
|
||||
libs/libc/string/lib_strrchr.c
|
||||
libs/libc/string/lib_bsdmemccpy.c
|
||||
libs/libc/string/lib_bsdmemchr.c
|
||||
libs/libc/string/lib_bsdmemcmp.c
|
||||
libs/libc/string/lib_bsdmemcpy.c
|
||||
libs/libc/string/lib_bsdmemrchr.c
|
||||
libs/libc/string/lib_bsdstpcpy.c
|
||||
libs/libc/string/lib_bsdstpncpy.c
|
||||
libs/libc/string/lib_bsdstrcat.c
|
||||
libs/libc/string/lib_bsdstrchr.c
|
||||
libs/libc/string/lib_bsdstrchrnul.c
|
||||
libs/libc/string/lib_bsdstrcmp.c
|
||||
libs/libc/string/lib_bsdstrcpy.c
|
||||
libs/libc/string/lib_bsdstrlen.c
|
||||
libs/libc/string/lib_bsdstrncmp.c
|
||||
libs/libc/string/lib_bsdstrncpy.c
|
||||
libs/libc/string/lib_bsdstrrchr.c
|
||||
======================
|
||||
|
||||
Copyright (c) 1994-2009 Red Hat, Inc. All rights reserved.
|
||||
|
|
|
@ -31,28 +31,20 @@ set(SRCS
|
|||
lib_flsl.c
|
||||
lib_flsll.c
|
||||
lib_isbasedigit.c
|
||||
lib_memccpy.c
|
||||
lib_memrchr.c
|
||||
lib_memmem.c
|
||||
lib_popcount.c
|
||||
lib_popcountl.c
|
||||
lib_popcountll.c
|
||||
lib_skipspace.c
|
||||
lib_stpcpy.c
|
||||
lib_stpncpy.c
|
||||
lib_strcasecmp.c
|
||||
lib_strcat.c
|
||||
lib_strcspn.c
|
||||
lib_strchrnul.c
|
||||
lib_strdup.c
|
||||
lib_strerror.c
|
||||
lib_strncasecmp.c
|
||||
lib_strncat.c
|
||||
lib_strncmp.c
|
||||
lib_strndup.c
|
||||
lib_strcasestr.c
|
||||
lib_strpbrk.c
|
||||
lib_strrchr.c
|
||||
lib_strspn.c
|
||||
lib_strstr.c
|
||||
lib_strtok.c
|
||||
|
@ -68,21 +60,16 @@ set(SRCS
|
|||
lib_strverscmp.c
|
||||
lib_mempcpy.c
|
||||
lib_rawmemchr.c
|
||||
lib_memchr.c
|
||||
lib_memcmp.c
|
||||
lib_memmove.c
|
||||
lib_memset.c
|
||||
lib_strchr.c
|
||||
lib_strcmp.c
|
||||
lib_strcpy.c
|
||||
lib_strlcat.c
|
||||
lib_strlcpy.c
|
||||
lib_strlen.c
|
||||
lib_strncpy.c
|
||||
lib_strnlen.c)
|
||||
|
||||
if(CONFIG_MEMCPY_VIK)
|
||||
list(APPEND SRCS lib_vikmemcpy.c)
|
||||
elseif(CONFIG_LIBC_STRING_OPTIMIZE)
|
||||
list(APPEND SRCS lib_bsdmemcpy.c)
|
||||
else()
|
||||
list(APPEND SRCS lib_memcpy.c)
|
||||
endif()
|
||||
|
@ -91,4 +78,44 @@ if(CONFIG_LIBC_LOCALE)
|
|||
list(APPEND SRCS lib_strcoll.c lib_strxfrm.c)
|
||||
endif()
|
||||
|
||||
if(CONFIG_LIBC_STRING_OPTIMIZE)
|
||||
list(
|
||||
APPEND
|
||||
SRCS
|
||||
lib_bsdmemccpy.c
|
||||
lib_bsdmemcmp.c
|
||||
lib_bsdmemrchr.c
|
||||
lib_bsdstpncpy.c
|
||||
lib_bsdstrchr.c
|
||||
lib_bsdstrcmp.c
|
||||
lib_bsdstrlen.c
|
||||
lib_bsdstrncpy.c
|
||||
lib_bsdmemchr.c
|
||||
lib_bsdstpcpy.c
|
||||
lib_bsdstrcat.c
|
||||
lib_bsdstrchrnul.c
|
||||
lib_bsdstrcpy.c
|
||||
lib_bsdstrncmp.c
|
||||
lib_bsdstrrchr.c)
|
||||
else()
|
||||
list(
|
||||
APPEND
|
||||
SRCS
|
||||
lib_memccpy.c
|
||||
lib_memcmp.c
|
||||
lib_memrchr.c
|
||||
lib_stpncpy.c
|
||||
lib_strchr.c
|
||||
lib_strcmp.c
|
||||
lib_strlen.c
|
||||
lib_strncpy.c
|
||||
lib_memchr.c
|
||||
lib_stpcpy.c
|
||||
lib_strcat.c
|
||||
lib_strchrnul.c
|
||||
lib_strcpy.c
|
||||
lib_strncmp.c
|
||||
lib_strrchr.c)
|
||||
endif()
|
||||
|
||||
target_sources(c PRIVATE ${SRCS})
|
||||
|
|
|
@ -23,23 +23,25 @@
|
|||
# Add the string C files to the build
|
||||
|
||||
CSRCS += lib_ffs.c lib_ffsl.c lib_ffsll.c lib_fls.c lib_flsl.c
|
||||
CSRCS += lib_flsll.c lib_isbasedigit.c lib_memccpy.c lib_memrchr.c lib_memmem.c
|
||||
CSRCS += lib_flsll.c lib_isbasedigit.c lib_memmem.c
|
||||
CSRCS += lib_popcount.c lib_popcountl.c lib_popcountll.c
|
||||
CSRCS += lib_skipspace.c lib_stpcpy.c lib_stpncpy.c lib_strcasecmp.c
|
||||
CSRCS += lib_strcat.c lib_strcspn.c lib_strchrnul.c lib_strdup.c
|
||||
CSRCS += lib_strerror.c lib_strncasecmp.c lib_strncat.c lib_strncmp.c
|
||||
CSRCS += lib_strndup.c lib_strcasestr.c lib_strpbrk.c lib_strrchr.c
|
||||
CSRCS += lib_skipspace.c lib_strcasecmp.c
|
||||
CSRCS += lib_strcspn.c lib_strdup.c
|
||||
CSRCS += lib_strerror.c lib_strncasecmp.c lib_strncat.c
|
||||
CSRCS += lib_strndup.c lib_strcasestr.c lib_strpbrk.c
|
||||
CSRCS += lib_strspn.c lib_strstr.c lib_strtok.c lib_strtokr.c
|
||||
CSRCS += lib_strsep.c lib_strerrorr.c lib_explicit_bzero.c lib_strsignal.c
|
||||
CSRCS += lib_index.c lib_rindex.c lib_timingsafe_bcmp.c lib_strverscmp.c
|
||||
CSRCS += lib_mempcpy.c lib_rawmemchr.c lib_bzero.c
|
||||
|
||||
CSRCS += lib_memchr.c lib_memcmp.c lib_memmove.c lib_memset.c
|
||||
CSRCS += lib_strchr.c lib_strcmp.c lib_strcpy.c lib_strlcat.c
|
||||
CSRCS += lib_strlcpy.c lib_strlen.c lib_strncpy.c lib_strnlen.c
|
||||
CSRCS += lib_memmove.c lib_memset.c
|
||||
CSRCS += lib_strlcat.c
|
||||
CSRCS += lib_strlcpy.c lib_strnlen.c
|
||||
|
||||
ifeq ($(CONFIG_MEMCPY_VIK),y)
|
||||
CSRCS += lib_vikmemcpy.c
|
||||
else ifeq ($(CONFIG_LIBC_STRING_OPTIMIZE),y)
|
||||
CSRCS += lib_bsdmemcpy.c
|
||||
else
|
||||
CSRCS += lib_memcpy.c
|
||||
endif
|
||||
|
@ -48,6 +50,18 @@ ifeq ($(CONFIG_LIBC_LOCALE),y)
|
|||
CSRCS += lib_strcoll.c lib_strxfrm.c
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_LIBC_STRING_OPTIMIZE),y)
|
||||
CSRCS += lib_bsdmemccpy.c lib_bsdmemcmp.c lib_bsdmemrchr.c lib_bsdstpncpy.c
|
||||
CSRCS += lib_bsdstrchr.c lib_bsdstrcmp.c lib_bsdstrlen.c lib_bsdstrncpy.c
|
||||
CSRCS += lib_bsdmemchr.c lib_bsdstpcpy.c lib_bsdstrcat.c lib_bsdstrchrnul.c
|
||||
CSRCS += lib_bsdstrcpy.c lib_bsdstrncmp.c lib_bsdstrrchr.c
|
||||
else
|
||||
CSRCS += lib_memccpy.c lib_memcmp.c lib_memrchr.c lib_stpncpy.c
|
||||
CSRCS += lib_strchr.c lib_strcmp.c lib_strlen.c lib_strncpy.c
|
||||
CSRCS += lib_memchr.c lib_stpcpy.c lib_strcat.c lib_strchrnul.c
|
||||
CSRCS += lib_strcpy.c lib_strncmp.c lib_strrchr.c
|
||||
endif
|
||||
|
||||
# Add the string directory to the build
|
||||
|
||||
DEPPATH += --dep-path string
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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 <string.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_LIBC_STRING_OPTIMIZE
|
||||
/* Nonzero if either x or y is not aligned on a "long" boundary. */
|
||||
|
||||
#define UNALIGNED(x, y) \
|
||||
(((long)(uintptr_t)(x) & (sizeof(long) - 1)) | ((long)(uintptr_t)(y) & (sizeof(long) - 1)))
|
||||
|
||||
/* How many bytes are copied each iteration of the word copy loop. */
|
||||
|
||||
#define LITTLEBLOCKSIZE (sizeof(long))
|
||||
|
||||
/* Threshhold for punting to the byte copier. */
|
||||
|
||||
#define TOO_SMALL(len) ((len) < LITTLEBLOCKSIZE)
|
||||
|
||||
/* Macros for detecting endchar */
|
||||
|
||||
#if LONG_MAX == 2147483647
|
||||
# define DETECTNULL(x) (((x) - 0x01010101) & ~(x) & 0x80808080)
|
||||
#elif LONG_MAX == 9223372036854775807
|
||||
/* Nonzero if x (a long int) contains a NULL byte. */
|
||||
|
||||
# define DETECTNULL(x) (((x) - 0x0101010101010101) & ~(x) & 0x8080808080808080)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
@ -81,71 +51,6 @@
|
|||
#undef memccpy /* See mm/README.txt */
|
||||
FAR void *memccpy(FAR void *s1, FAR const void *s2, int c, size_t n)
|
||||
{
|
||||
#ifdef CONFIG_LIBC_STRING_OPTIMIZE
|
||||
FAR void *ptr = NULL;
|
||||
FAR unsigned char *pout = (FAR unsigned char *)s1;
|
||||
FAR const unsigned char *pin = (FAR const unsigned char *)s2;
|
||||
FAR long *paligned_out;
|
||||
FAR const long *paligned_in;
|
||||
unsigned char endchar = c & 0xff;
|
||||
|
||||
/* If the size is small, or either pin or pout is unaligned,
|
||||
* then punt into the byte copy loop. This should be rare.
|
||||
*/
|
||||
|
||||
if (!TOO_SMALL(n) && !UNALIGNED(pin, pout))
|
||||
{
|
||||
unsigned int i;
|
||||
unsigned long mask = 0;
|
||||
|
||||
paligned_out = (FAR long *)pout;
|
||||
paligned_in = (FAR long *)pin;
|
||||
|
||||
/* The fast code reads the ASCII one word at a time and only
|
||||
* performs the bytewise search on word-sized segments if they
|
||||
* contain the search character, which is detected by XORing
|
||||
* the word-sized segment with a word-sized block of the search
|
||||
* character and then detecting for the presence of NULL in the
|
||||
* result.
|
||||
*/
|
||||
|
||||
for (i = 0; i < LITTLEBLOCKSIZE; i++)
|
||||
{
|
||||
mask = (mask << 8) + endchar;
|
||||
}
|
||||
|
||||
/* Copy one long word at a time if possible. */
|
||||
|
||||
while (n >= LITTLEBLOCKSIZE)
|
||||
{
|
||||
unsigned long buffer = (unsigned long)(*paligned_in);
|
||||
buffer ^= mask;
|
||||
if (DETECTNULL(buffer))
|
||||
{
|
||||
break; /* endchar is found, go byte by byte from here */
|
||||
}
|
||||
|
||||
*paligned_out++ = *paligned_in++;
|
||||
n -= LITTLEBLOCKSIZE;
|
||||
}
|
||||
|
||||
/* Pick up any residual with a byte copier. */
|
||||
|
||||
pout = (FAR unsigned char *)paligned_out;
|
||||
pin = (FAR unsigned char *)paligned_in;
|
||||
}
|
||||
|
||||
while (n--)
|
||||
{
|
||||
if ((*pout++ = *pin++) == endchar)
|
||||
{
|
||||
ptr = pout;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ptr;
|
||||
#else
|
||||
FAR unsigned char *pout = (FAR unsigned char *)s1;
|
||||
FAR unsigned char *pin = (FAR unsigned char *)s2;
|
||||
|
||||
|
@ -170,5 +75,4 @@ FAR void *memccpy(FAR void *s1, FAR const void *s2, int c, size_t n)
|
|||
/* C was not found in the first n bytes of s2 */
|
||||
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -30,38 +30,6 @@
|
|||
|
||||
#include "libc.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_LIBC_STRING_OPTIMIZE
|
||||
|
||||
#define UNALIGNED(x) ((long)(uintptr_t)(x) & (sizeof(long) - 1))
|
||||
|
||||
/* How many bytes are loaded each iteration of the word copy loop. */
|
||||
|
||||
#define LBLOCKSIZE (sizeof(long))
|
||||
|
||||
/* Threshhold for punting to the bytewise iterator. */
|
||||
|
||||
#define TOO_SMALL(len) ((len) < LBLOCKSIZE)
|
||||
|
||||
#if LONG_MAX == 2147483647
|
||||
# define DETECTNULL(x) (((x) - 0x01010101) & ~(x) & 0x80808080)
|
||||
#elif LONG_MAX == 9223372036854775807
|
||||
/* Nonzero if x (a long int) contains a NULL byte. */
|
||||
|
||||
# define DETECTNULL(x) (((x) - 0x0101010101010101) & ~(x) & 0x8080808080808080)
|
||||
#endif
|
||||
|
||||
/* DETECTCHAR returns nonzero if (long)x contains the byte used
|
||||
* to fill (long)mask.
|
||||
*/
|
||||
|
||||
#define DETECTCHAR(x, mask) (DETECTNULL((x) ^ (mask)))
|
||||
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
@ -84,76 +52,6 @@
|
|||
#undef memchr /* See mm/README.txt */
|
||||
FAR void *memchr(FAR const void *s, int c, size_t n)
|
||||
{
|
||||
#ifdef CONFIG_LIBC_STRING_OPTIMIZE
|
||||
FAR const unsigned char *p = (FAR const unsigned char *)s;
|
||||
FAR unsigned long *asrc;
|
||||
unsigned char d = c;
|
||||
unsigned long mask;
|
||||
unsigned int i;
|
||||
|
||||
while (UNALIGNED(p))
|
||||
{
|
||||
if (!n--)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (*p == d)
|
||||
{
|
||||
return (FAR void *)p;
|
||||
}
|
||||
|
||||
p++;
|
||||
}
|
||||
|
||||
if (!TOO_SMALL(n))
|
||||
{
|
||||
/* If we get this far, we know that n is large and p is
|
||||
* word-aligned.
|
||||
* The fast code reads the source one word at a time and only
|
||||
* performs the bytewise search on word-sized segments if they
|
||||
* contain the search character, which is detected by XORing
|
||||
* the word-sized segment with a word-sized block of the search
|
||||
* character and then detecting for the presence of NUL in the
|
||||
* result.
|
||||
*/
|
||||
|
||||
asrc = (FAR unsigned long *)p;
|
||||
mask = d << 8 | d;
|
||||
mask = mask << 16 | mask;
|
||||
for (i = 32; i < LBLOCKSIZE * 8; i <<= 1)
|
||||
{
|
||||
mask = (mask << i) | mask;
|
||||
}
|
||||
|
||||
while (n >= LBLOCKSIZE)
|
||||
{
|
||||
if (DETECTCHAR(*asrc, mask))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
n -= LBLOCKSIZE;
|
||||
asrc++;
|
||||
}
|
||||
|
||||
/* If there are fewer than LBLOCKSIZE characters left,
|
||||
* then we resort to the bytewise loop.
|
||||
*/
|
||||
|
||||
p = (FAR unsigned char *)asrc;
|
||||
}
|
||||
|
||||
while (n--)
|
||||
{
|
||||
if (*p == d)
|
||||
{
|
||||
return (FAR void *)p;
|
||||
}
|
||||
|
||||
p++;
|
||||
}
|
||||
#else
|
||||
FAR const unsigned char *p = (FAR const unsigned char *)s;
|
||||
|
||||
while (n--)
|
||||
|
@ -165,7 +63,6 @@ FAR void *memchr(FAR const void *s, int c, size_t n)
|
|||
|
||||
p++;
|
||||
}
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -30,26 +30,6 @@
|
|||
|
||||
#include "libc.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_LIBC_STRING_OPTIMIZE
|
||||
/* Nonzero if either x or y is not aligned on a "long" boundary. */
|
||||
|
||||
#define UNALIGNED(x, y) \
|
||||
(((long)(uintptr_t)(x) & (sizeof(long) - 1)) | ((long)(uintptr_t)(y) & (sizeof(long) - 1)))
|
||||
|
||||
/* How many bytes are copied each iteration of the word copy loop. */
|
||||
|
||||
#define LBLOCKSIZE (sizeof(long))
|
||||
|
||||
/* Threshhold for punting to the byte copier. */
|
||||
|
||||
#define TOO_SMALL(len) ((len) < LBLOCKSIZE)
|
||||
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
@ -59,54 +39,6 @@
|
|||
no_builtin("memcmp")
|
||||
int memcmp(FAR const void *s1, FAR const void *s2, size_t n)
|
||||
{
|
||||
#ifdef CONFIG_LIBC_STRING_OPTIMIZE
|
||||
FAR unsigned char *p1 = (FAR unsigned char *)s1;
|
||||
FAR unsigned char *p2 = (FAR unsigned char *)s2;
|
||||
FAR unsigned long *a1;
|
||||
FAR unsigned long *a2;
|
||||
|
||||
/* If the size is too small, or either pointer is unaligned,
|
||||
* then we punt to the byte compare loop. Hopefully this will
|
||||
* not turn up in inner loops.
|
||||
*/
|
||||
|
||||
if (!TOO_SMALL(n) && !UNALIGNED(p1, p2))
|
||||
{
|
||||
/* Otherwise, load and compare the blocks of memory one
|
||||
* word at a time.
|
||||
*/
|
||||
|
||||
a1 = (FAR unsigned long *)p1;
|
||||
a2 = (FAR unsigned long *)p2;
|
||||
while (n >= LBLOCKSIZE)
|
||||
{
|
||||
if (*a1 != *a2)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
a1++;
|
||||
a2++;
|
||||
n -= LBLOCKSIZE;
|
||||
}
|
||||
|
||||
/* check s mod LBLOCKSIZE remaining characters */
|
||||
|
||||
p1 = (FAR unsigned char *)a1;
|
||||
p2 = (FAR unsigned char *)a2;
|
||||
}
|
||||
|
||||
while (n--)
|
||||
{
|
||||
if (*p1 != *p2)
|
||||
{
|
||||
return *p1 - *p2;
|
||||
}
|
||||
|
||||
p1++;
|
||||
p2++;
|
||||
}
|
||||
#else
|
||||
FAR unsigned char *p1 = (FAR unsigned char *)s1;
|
||||
FAR unsigned char *p2 = (FAR unsigned char *)s2;
|
||||
|
||||
|
@ -124,7 +56,6 @@ int memcmp(FAR const void *s1, FAR const void *s2, size_t n)
|
|||
p1++;
|
||||
p2++;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -30,30 +30,6 @@
|
|||
|
||||
#include "libc.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_LIBC_STRING_OPTIMIZE
|
||||
/* Nonzero if either x or y is not aligned on a "long" boundary. */
|
||||
|
||||
#define UNALIGNED(x, y) \
|
||||
(((long)(uintptr_t)(x) & (sizeof(long) - 1)) | ((long)(uintptr_t)(y) & (sizeof(long) - 1)))
|
||||
|
||||
/* How many bytes are copied each iteration of the 4X unrolled loop. */
|
||||
|
||||
#define BIGBLOCKSIZE (sizeof(long) << 2)
|
||||
|
||||
/* How many bytes are copied each iteration of the word copy loop. */
|
||||
|
||||
#define LITTLEBLOCKSIZE (sizeof(long))
|
||||
|
||||
/* Threshhold for punting to the byte copier. */
|
||||
|
||||
#define TOO_SMALL(len) ((len) < BIGBLOCKSIZE)
|
||||
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
@ -67,58 +43,12 @@
|
|||
no_builtin("memcpy")
|
||||
FAR void *memcpy(FAR void *dest, FAR const void *src, size_t n)
|
||||
{
|
||||
#ifdef CONFIG_LIBC_STRING_OPTIMIZE
|
||||
FAR char *pout = dest;
|
||||
FAR const char *pin = src;
|
||||
FAR long *paligned_out;
|
||||
FAR const long *paligned_in;
|
||||
|
||||
/* If the size is small, or either pin or pout is unaligned,
|
||||
* then punt into the byte copy loop. This should be rare.
|
||||
*/
|
||||
|
||||
if (!TOO_SMALL(n) && !UNALIGNED(pin, pout))
|
||||
{
|
||||
paligned_out = (FAR long *)pout;
|
||||
paligned_in = (FAR long *)pin;
|
||||
|
||||
/* Copy 4X long words at a time if possible. */
|
||||
|
||||
while (n >= BIGBLOCKSIZE)
|
||||
{
|
||||
*paligned_out++ = *paligned_in++;
|
||||
*paligned_out++ = *paligned_in++;
|
||||
*paligned_out++ = *paligned_in++;
|
||||
*paligned_out++ = *paligned_in++;
|
||||
n -= BIGBLOCKSIZE;
|
||||
}
|
||||
|
||||
/* Copy one long word at a time if possible. */
|
||||
|
||||
while (n >= LITTLEBLOCKSIZE)
|
||||
{
|
||||
*paligned_out++ = *paligned_in++;
|
||||
n -= LITTLEBLOCKSIZE;
|
||||
}
|
||||
|
||||
/* Pick up any residual with a byte copier. */
|
||||
|
||||
pout = (FAR char *)paligned_out;
|
||||
pin = (FAR char *)paligned_in;
|
||||
}
|
||||
|
||||
while (n--)
|
||||
{
|
||||
*pout++ = *pin++;
|
||||
}
|
||||
#else
|
||||
FAR unsigned char *pout = (FAR unsigned char *)dest;
|
||||
FAR unsigned char *pin = (FAR unsigned char *)src;
|
||||
while (n-- > 0)
|
||||
{
|
||||
*pout++ = *pin++;
|
||||
}
|
||||
#endif
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
|
|
@ -28,37 +28,6 @@
|
|||
|
||||
#include <string.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_LIBC_STRING_OPTIMIZE
|
||||
/* Nonzero if x is not aligned on a "long" boundary. */
|
||||
|
||||
#define UNALIGNED(x) ((long)(uintptr_t)((x) + 1) & (sizeof(long) - 1))
|
||||
|
||||
/* How many bytes are loaded each iteration of the word copy loop. */
|
||||
|
||||
#define LBLOCKSIZE (sizeof(long))
|
||||
|
||||
/* Threshhold for punting to the bytewise iterator. */
|
||||
|
||||
#define TOO_SMALL(len) ((len) < LBLOCKSIZE)
|
||||
|
||||
/* Macros for detecting endchar */
|
||||
|
||||
#if LONG_MAX == 2147483647
|
||||
# define DETECTNULL(x) (((x) - 0x01010101) & ~(x) & 0x80808080)
|
||||
#elif LONG_MAX == 9223372036854775807
|
||||
/* Nonzero if x (a long int) contains a NULL byte. */
|
||||
|
||||
# define DETECTNULL(x) (((x) - 0x0101010101010101) & ~(x) & 0x8080808080808080)
|
||||
#endif
|
||||
|
||||
#define DETECTCHAR(x, mask) (DETECTNULL((x) ^ (mask)))
|
||||
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
@ -80,77 +49,6 @@
|
|||
#undef memrchr /* See mm/README.txt */
|
||||
FAR void *memrchr(FAR const void *s, int c, size_t n)
|
||||
{
|
||||
#ifdef CONFIG_LIBC_STRING_OPTIMIZE
|
||||
FAR const unsigned char *src0 =
|
||||
(FAR const unsigned char *)s + n - 1;
|
||||
FAR unsigned long *asrc;
|
||||
unsigned char d = c;
|
||||
unsigned long mask;
|
||||
unsigned int i;
|
||||
|
||||
while (UNALIGNED(src0))
|
||||
{
|
||||
if (!n--)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (*src0 == d)
|
||||
{
|
||||
return (FAR void *)src0;
|
||||
}
|
||||
|
||||
src0--;
|
||||
}
|
||||
|
||||
if (!TOO_SMALL(n))
|
||||
{
|
||||
/* If we get this far, we know that n is large and src0 is
|
||||
* word-aligned.
|
||||
* The fast code reads the source one word at a time and only
|
||||
* performs the bytewise search on word-sized segments if they
|
||||
* contain the search character, which is detected by XORing
|
||||
* the word-sized segment with a word-sized block of the search
|
||||
* character and then detecting for the presence of NUL in the
|
||||
* result.
|
||||
*/
|
||||
|
||||
asrc = (FAR unsigned long *)(src0 - LBLOCKSIZE + 1);
|
||||
mask = d << 8 | d;
|
||||
mask = mask << 16 | mask;
|
||||
for (i = 32; i < LBLOCKSIZE * 8; i <<= 1)
|
||||
{
|
||||
mask = (mask << i) | mask;
|
||||
}
|
||||
|
||||
while (n >= LBLOCKSIZE)
|
||||
{
|
||||
if (DETECTCHAR(*asrc, mask))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
n -= LBLOCKSIZE;
|
||||
asrc--;
|
||||
}
|
||||
|
||||
/* If there are fewer than LBLOCKSIZE characters left,
|
||||
* then we resort to the bytewise loop.
|
||||
*/
|
||||
|
||||
src0 = (FAR unsigned char *)asrc + LBLOCKSIZE - 1;
|
||||
}
|
||||
|
||||
while (n--)
|
||||
{
|
||||
if (*src0 == d)
|
||||
{
|
||||
return (FAR void *)src0;
|
||||
}
|
||||
|
||||
src0--;
|
||||
}
|
||||
#else
|
||||
FAR const unsigned char *p = (FAR const unsigned char *)s + n;
|
||||
|
||||
while (n--)
|
||||
|
@ -160,7 +58,6 @@ FAR void *memrchr(FAR const void *s, int c, size_t n)
|
|||
return (FAR void *)p;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -28,28 +28,6 @@
|
|||
|
||||
#include <string.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_LIBC_STRING_OPTIMIZE
|
||||
/* Nonzero if either x or y is not aligned on a "long" boundary. */
|
||||
|
||||
#define UNALIGNED(x, y) \
|
||||
(((long)(uintptr_t)(x) & (sizeof(long) - 1)) | ((long)(uintptr_t)(y) & (sizeof(long) - 1)))
|
||||
|
||||
/* Macros for detecting endchar */
|
||||
|
||||
#if LONG_MAX == 2147483647
|
||||
# define DETECTNULL(x) (((x) - 0x01010101) & ~(x) & 0x80808080)
|
||||
#elif LONG_MAX == 9223372036854775807
|
||||
/* Nonzero if x (a long int) contains a NULL byte. */
|
||||
|
||||
# define DETECTNULL(x) (((x) - 0x0101010101010101) & ~(x) & 0x8080808080808080)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
@ -69,36 +47,9 @@
|
|||
|
||||
#ifndef CONFIG_LIBC_ARCH_STPCPY
|
||||
#undef stpcpy /* See mm/README.txt */
|
||||
nosanitize_address
|
||||
FAR char *stpcpy(FAR char *dest, FAR const char *src)
|
||||
{
|
||||
#ifdef CONFIG_LIBC_STRING_OPTIMIZE
|
||||
FAR long *aligned_dst;
|
||||
FAR const long *aligned_src;
|
||||
|
||||
/* If src or dest is unaligned, then copy bytes. */
|
||||
|
||||
if (!UNALIGNED(src, dest))
|
||||
{
|
||||
aligned_dst = (FAR long *)dest;
|
||||
aligned_src = (FAR long *)src;
|
||||
|
||||
/* src and dest are both "long int" aligned, try to do "long int"
|
||||
* sized copies.
|
||||
*/
|
||||
|
||||
while (!DETECTNULL(*aligned_src))
|
||||
{
|
||||
*aligned_dst++ = *aligned_src++;
|
||||
}
|
||||
|
||||
dest = (FAR char *)aligned_dst;
|
||||
src = (FAR char *)aligned_src;
|
||||
}
|
||||
#endif
|
||||
|
||||
while ((*dest++ = *src++) != '\0');
|
||||
|
||||
return --dest;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -28,34 +28,6 @@
|
|||
#include <sys/types.h>
|
||||
#include <string.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_LIBC_STRING_OPTIMIZE
|
||||
/* Nonzero if either x or y is not aligned on a "long" boundary. */
|
||||
|
||||
#define UNALIGNED(x, y) \
|
||||
(((long)(uintptr_t)(x) & (sizeof(long) - 1)) | ((long)(uintptr_t)(y) & (sizeof(long) - 1)))
|
||||
|
||||
/* How many bytes are loaded each iteration of the word copy loop. */
|
||||
|
||||
#define LBLOCKSIZE (sizeof(long))
|
||||
|
||||
/* Macros for detecting endchar */
|
||||
|
||||
#if LONG_MAX == 2147483647
|
||||
#define DETECTNULL(x) (((x) - 0x01010101) & ~(x) & 0x80808080)
|
||||
#elif LONG_MAX == 9223372036854775807
|
||||
/* Nonzero if x (a long int) contains a NULL byte. */
|
||||
|
||||
#define DETECTNULL(x) (((x) - 0x0101010101010101) & ~(x) & 0x8080808080808080)
|
||||
#endif
|
||||
|
||||
#define TOO_SMALL(len) ((len) < sizeof(long))
|
||||
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
@ -87,49 +59,6 @@
|
|||
#undef stpncpy /* See mm/README.txt */
|
||||
FAR char *stpncpy(FAR char *dest, FAR const char *src, size_t n)
|
||||
{
|
||||
#ifdef CONFIG_LIBC_STRING_OPTIMIZE
|
||||
FAR char *ret = NULL;
|
||||
FAR long *aligned_dst;
|
||||
FAR const long *aligned_src;
|
||||
|
||||
/* If src and dest is aligned and n large enough, then copy words. */
|
||||
|
||||
if (!UNALIGNED(src, dest) && !TOO_SMALL(n))
|
||||
{
|
||||
aligned_dst = (FAR long *)dest;
|
||||
aligned_src = (FAR long *)src;
|
||||
|
||||
/* src and dest are both "long int" aligned, try to do "long int"
|
||||
* sized copies.
|
||||
*/
|
||||
|
||||
while (n >= LBLOCKSIZE && !DETECTNULL(*aligned_src))
|
||||
{
|
||||
n -= LBLOCKSIZE;
|
||||
*aligned_dst++ = *aligned_src++;
|
||||
}
|
||||
|
||||
dest = (FAR char *)aligned_dst;
|
||||
src = (FAR char *)aligned_src;
|
||||
}
|
||||
|
||||
while (n > 0)
|
||||
{
|
||||
--n;
|
||||
if ((*dest++ = *src++) == '\0')
|
||||
{
|
||||
ret = dest - 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
while (n-- > 0)
|
||||
{
|
||||
*dest++ = '\0';
|
||||
}
|
||||
|
||||
return ret ? ret : dest;
|
||||
#else
|
||||
FAR char *end = dest + n; /* End of dest buffer + 1 byte */
|
||||
FAR char *ret; /* Value to be returned */
|
||||
|
||||
|
@ -162,6 +91,5 @@ FAR char *stpncpy(FAR char *dest, FAR const char *src, size_t n)
|
|||
}
|
||||
|
||||
return ret;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -30,67 +30,14 @@
|
|||
|
||||
#include "libc.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_LIBC_STRING_OPTIMIZE
|
||||
|
||||
#define ALIGNED(x) \
|
||||
(((long)(uintptr_t)(x) & (sizeof(long) - 1)) == 0)
|
||||
|
||||
/* Macros for detecting endchar */
|
||||
|
||||
#if LONG_MAX == 2147483647
|
||||
# define DETECTNULL(x) (((x) - 0x01010101) & ~(x) & 0x80808080)
|
||||
#elif LONG_MAX == 9223372036854775807
|
||||
/* Nonzero if x (a long int) contains a NULL byte. */
|
||||
|
||||
# define DETECTNULL(x) (((x) - 0x0101010101010101) & ~(x) & 0x8080808080808080)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
#if !defined(CONFIG_LIBC_ARCH_STRCAT) && defined(LIBC_BUILD_STRCAT)
|
||||
#undef strcat /* See mm/README.txt */
|
||||
nosanitize_address
|
||||
FAR char *strcat(FAR char *dest, FAR const char *src)
|
||||
{
|
||||
#ifdef CONFIG_LIBC_STRING_OPTIMIZE
|
||||
FAR char *ret = dest;
|
||||
|
||||
/* Skip over the data in dest as quickly as possible. */
|
||||
|
||||
if (ALIGNED(dest))
|
||||
{
|
||||
FAR unsigned long *aligned_s1 = (FAR unsigned long *)dest;
|
||||
while (!DETECTNULL(*aligned_s1))
|
||||
{
|
||||
aligned_s1++;
|
||||
}
|
||||
|
||||
dest = (FAR char *)aligned_s1;
|
||||
}
|
||||
|
||||
while (*dest)
|
||||
{
|
||||
dest++;
|
||||
}
|
||||
|
||||
/* dest now points to the its trailing null character, we can
|
||||
* just use strcpy to do the work for us now.
|
||||
* ?!? We might want to just include strcpy here.
|
||||
* Also, this will cause many more unaligned string copies because
|
||||
* dest is much less likely to be aligned. I don't know if its worth
|
||||
* tweaking strcpy to handle this better.
|
||||
*/
|
||||
|
||||
strcpy(dest, src);
|
||||
#else
|
||||
FAR char *ret = dest;
|
||||
|
||||
dest += strlen(dest);
|
||||
|
@ -100,7 +47,6 @@ FAR char *strcat(FAR char *dest, FAR const char *src)
|
|||
}
|
||||
|
||||
*dest = '\0';
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -30,32 +30,6 @@
|
|||
|
||||
#include "libc.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_LIBC_STRING_OPTIMIZE
|
||||
|
||||
#define UNALIGNED(x) ((long)(uintptr_t)(x) & (sizeof(long) - 1))
|
||||
|
||||
/* How many bytes are loaded each iteration of the word copy loop. */
|
||||
|
||||
#define LBLOCKSIZE (sizeof(long))
|
||||
|
||||
/* Macros for detecting endchar */
|
||||
|
||||
#if LONG_MAX == 2147483647
|
||||
# define DETECTNULL(x) (((x) - 0x01010101) & ~(x) & 0x80808080)
|
||||
#elif LONG_MAX == 9223372036854775807
|
||||
/* Nonzero if x (a long int) contains a NULL byte. */
|
||||
|
||||
# define DETECTNULL(x) (((x) - 0x0101010101010101) & ~(x) & 0x8080808080808080)
|
||||
#endif
|
||||
|
||||
#define DETECTCHAR(x, mask) (DETECTNULL((x) ^ (mask)))
|
||||
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
@ -76,95 +50,8 @@
|
|||
|
||||
#if !defined(CONFIG_LIBC_ARCH_STRCHR) && defined(LIBC_BUILD_STRCHR)
|
||||
#undef strchr /* See mm/README.txt */
|
||||
nosanitize_address
|
||||
FAR char *strchr(FAR const char *s, int c)
|
||||
{
|
||||
#ifdef CONFIG_LIBC_STRING_OPTIMIZE
|
||||
FAR const unsigned char *s1 = (FAR const unsigned char *)s;
|
||||
FAR unsigned long *aligned_addr;
|
||||
unsigned char i = c;
|
||||
unsigned long mask;
|
||||
unsigned long j;
|
||||
|
||||
/* Special case for finding 0. */
|
||||
|
||||
if (!i)
|
||||
{
|
||||
while (UNALIGNED(s1))
|
||||
{
|
||||
if (!*s1)
|
||||
{
|
||||
return (FAR char *)s1;
|
||||
}
|
||||
|
||||
s1++;
|
||||
}
|
||||
|
||||
/* Operate a word at a time. */
|
||||
|
||||
aligned_addr = (FAR unsigned long *)s1;
|
||||
while (!DETECTNULL(*aligned_addr))
|
||||
{
|
||||
aligned_addr++;
|
||||
}
|
||||
|
||||
/* Found the end of string. */
|
||||
|
||||
s1 = (FAR const unsigned char *)aligned_addr;
|
||||
while (*s1)
|
||||
{
|
||||
s1++;
|
||||
}
|
||||
|
||||
return (FAR char *)s1;
|
||||
}
|
||||
|
||||
/* All other bytes. Align the pointer, then search a long at a time. */
|
||||
|
||||
while (UNALIGNED(s1))
|
||||
{
|
||||
if (!*s1)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (*s1 == i)
|
||||
{
|
||||
return (FAR char *)s1;
|
||||
}
|
||||
|
||||
s1++;
|
||||
}
|
||||
|
||||
mask = i;
|
||||
for (j = 8; j < LBLOCKSIZE * 8; j <<= 1)
|
||||
{
|
||||
mask = (mask << j) | mask;
|
||||
}
|
||||
|
||||
aligned_addr = (FAR unsigned long *)s1;
|
||||
while (!DETECTNULL(*aligned_addr) && !DETECTCHAR(*aligned_addr, mask))
|
||||
{
|
||||
aligned_addr++;
|
||||
}
|
||||
|
||||
/* The block of bytes currently pointed to by aligned_addr
|
||||
* contains either a null or the target char, or both. We
|
||||
* catch it using the bytewise search.
|
||||
*/
|
||||
|
||||
s1 = (FAR unsigned char *)aligned_addr;
|
||||
|
||||
while (*s1 && *s1 != i)
|
||||
{
|
||||
s1++;
|
||||
}
|
||||
|
||||
if (*s1 == i)
|
||||
{
|
||||
return (FAR char *)s1;
|
||||
}
|
||||
#else
|
||||
for (; ; s++)
|
||||
{
|
||||
if (*s == c)
|
||||
|
@ -177,7 +64,6 @@ FAR char *strchr(FAR const char *s, int c)
|
|||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -52,11 +52,6 @@
|
|||
#undef strchrnul /* See mm/README.txt */
|
||||
FAR char *strchrnul(FAR const char *s, int c)
|
||||
{
|
||||
#ifdef CONFIG_LIBC_STRING_OPTIMIZE
|
||||
FAR char *s1 = strchr(s, c);
|
||||
|
||||
return s1 ? s1 : (FAR char *)s + strlen(s);
|
||||
#else
|
||||
if (s)
|
||||
{
|
||||
while (*s != '\0' && *s != c)
|
||||
|
@ -66,6 +61,5 @@ FAR char *strchrnul(FAR const char *s, int c)
|
|||
}
|
||||
|
||||
return (FAR char *)s;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -30,80 +30,14 @@
|
|||
|
||||
#include "libc.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_LIBC_STRING_OPTIMIZE
|
||||
/* Nonzero if either x or y is not aligned on a "long" boundary. */
|
||||
|
||||
#define UNALIGNED(x, y) \
|
||||
(((long)(uintptr_t)(x) & (sizeof(long) - 1)) | ((long)(uintptr_t)(y) & (sizeof(long) - 1)))
|
||||
|
||||
/* Macros for detecting endchar */
|
||||
|
||||
#if LONG_MAX == 2147483647
|
||||
# define DETECTNULL(x) (((x) - 0x01010101) & ~(x) & 0x80808080)
|
||||
#elif LONG_MAX == 9223372036854775807
|
||||
/* Nonzero if x (a long int) contains a NULL byte. */
|
||||
|
||||
# define DETECTNULL(x) (((x) - 0x0101010101010101) & ~(x) & 0x8080808080808080)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
#if !defined(CONFIG_LIBC_ARCH_STRCMP) && defined(LIBC_BUILD_STRCMP)
|
||||
#undef strcmp /* See mm/README.txt */
|
||||
nosanitize_address
|
||||
int strcmp(FAR const char *cs, FAR const char *ct)
|
||||
{
|
||||
#ifdef CONFIG_LIBC_STRING_OPTIMIZE
|
||||
FAR unsigned long *a1;
|
||||
FAR unsigned long *a2;
|
||||
|
||||
/* If cs or ct are unaligned, then compare bytes. */
|
||||
|
||||
if (!UNALIGNED(cs, ct))
|
||||
{
|
||||
/* If cs and ct are word-aligned, compare them a word at a time. */
|
||||
|
||||
a1 = (FAR unsigned long *)cs;
|
||||
a2 = (FAR unsigned long *)ct;
|
||||
while (*a1 == *a2)
|
||||
{
|
||||
/* To get here, *a1 == *a2, thus if we find a null in *a1,
|
||||
* then the strings must be equal, so return zero.
|
||||
*/
|
||||
|
||||
if (DETECTNULL(*a1))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
a1++;
|
||||
a2++;
|
||||
}
|
||||
|
||||
/* A difference was detected in last few bytes of cs,
|
||||
* so search bytewise.
|
||||
*/
|
||||
|
||||
cs = (FAR char *)a1;
|
||||
ct = (FAR char *)a2;
|
||||
}
|
||||
|
||||
while (*cs != '\0' && *cs == *ct)
|
||||
{
|
||||
cs++;
|
||||
ct++;
|
||||
}
|
||||
|
||||
return (*(FAR unsigned char *)cs) - (*(FAR unsigned char *)ct);
|
||||
#else
|
||||
register int result;
|
||||
for (; ; )
|
||||
{
|
||||
|
@ -115,6 +49,5 @@ int strcmp(FAR const char *cs, FAR const char *ct)
|
|||
}
|
||||
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -30,28 +30,6 @@
|
|||
|
||||
#include "libc.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_LIBC_STRING_OPTIMIZE
|
||||
/* Nonzero if either x or y is not aligned on a "long" boundary. */
|
||||
|
||||
#define UNALIGNED(x, y) \
|
||||
(((long)(uintptr_t)(x) & (sizeof(long) - 1)) | ((long)(uintptr_t)(y) & (sizeof(long) - 1)))
|
||||
|
||||
/* Macros for detecting endchar */
|
||||
|
||||
#if LONG_MAX == 2147483647
|
||||
# define DETECTNULL(x) (((x) - 0x01010101) & ~(x) & 0x80808080)
|
||||
#elif LONG_MAX == 9223372036854775807
|
||||
/* Nonzero if x (a long int) contains a NULL byte. */
|
||||
|
||||
# define DETECTNULL(x) (((x) - 0x0101010101010101) & ~(x) & 0x8080808080808080)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
@ -70,42 +48,10 @@
|
|||
|
||||
#if !defined(CONFIG_LIBC_ARCH_STRCPY) && defined(LIBC_BUILD_STRCPY)
|
||||
#undef strcpy /* See mm/README.txt */
|
||||
nosanitize_address
|
||||
FAR char *strcpy(FAR char *dest, FAR const char *src)
|
||||
{
|
||||
#ifdef CONFIG_LIBC_STRING_OPTIMIZE
|
||||
FAR char *dst0 = dest;
|
||||
FAR const char *src0 = src;
|
||||
FAR unsigned long *aligned_dst;
|
||||
FAR const unsigned long *aligned_src;
|
||||
|
||||
/* If SRC or DEST is unaligned, then copy bytes. */
|
||||
|
||||
if (!UNALIGNED(src0, dst0))
|
||||
{
|
||||
aligned_dst = (FAR unsigned long *)dst0;
|
||||
aligned_src = (FAR unsigned long *)src0;
|
||||
|
||||
/* SRC and DEST are both "long int" aligned, try to do "long int"
|
||||
* sized copies.
|
||||
*/
|
||||
|
||||
while (!DETECTNULL(*aligned_src))
|
||||
{
|
||||
*aligned_dst++ = *aligned_src++;
|
||||
}
|
||||
|
||||
dst0 = (FAR char *)aligned_dst;
|
||||
src0 = (FAR char *)aligned_src;
|
||||
}
|
||||
|
||||
while ((*dst0++ = *src0++) != '\0');
|
||||
|
||||
return dest;
|
||||
#else
|
||||
FAR char *tmp = dest;
|
||||
while ((*dest++ = *src++) != '\0');
|
||||
return tmp;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -30,77 +30,16 @@
|
|||
|
||||
#include "libc.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_LIBC_STRING_OPTIMIZE
|
||||
|
||||
#define LBLOCKSIZE (sizeof(long))
|
||||
#define UNALIGNED(x) ((long)(uintptr_t)(x) & (LBLOCKSIZE - 1))
|
||||
|
||||
/* Macros for detecting endchar */
|
||||
|
||||
#if LONG_MAX == 2147483647
|
||||
# define DETECTNULL(x) (((x) - 0x01010101) & ~(x) & 0x80808080)
|
||||
#elif LONG_MAX == 9223372036854775807
|
||||
/* Nonzero if x (a long int) contains a NULL byte. */
|
||||
|
||||
# define DETECTNULL(x) (((x) - 0x0101010101010101) & ~(x) & 0x8080808080808080)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
#if !defined(CONFIG_LIBC_ARCH_STRLEN) && defined(LIBC_BUILD_STRLEN)
|
||||
#undef strlen /* See mm/README.txt */
|
||||
nosanitize_address
|
||||
size_t strlen(FAR const char *s)
|
||||
{
|
||||
#ifdef CONFIG_LIBC_STRING_OPTIMIZE
|
||||
FAR const char *start = s;
|
||||
FAR unsigned long *aligned_addr;
|
||||
|
||||
/* Align the pointer, so we can search a word at a time. */
|
||||
|
||||
while (UNALIGNED(s))
|
||||
{
|
||||
if (!*s)
|
||||
{
|
||||
return s - start;
|
||||
}
|
||||
|
||||
s++;
|
||||
}
|
||||
|
||||
/* If the string is word-aligned, we can check for the presence of
|
||||
* a null in each word-sized block.
|
||||
*/
|
||||
|
||||
aligned_addr = (FAR unsigned long *)s;
|
||||
while (!DETECTNULL(*aligned_addr))
|
||||
{
|
||||
aligned_addr++;
|
||||
}
|
||||
|
||||
/* Once a null is detected, we check each byte in that block for a
|
||||
* precise position of the null.
|
||||
*/
|
||||
|
||||
s = (FAR char *)aligned_addr;
|
||||
while (*s)
|
||||
{
|
||||
s++;
|
||||
}
|
||||
|
||||
return s - start;
|
||||
#else
|
||||
FAR const char *sc;
|
||||
for (sc = s; *sc != '\0'; ++sc);
|
||||
return sc - s;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -30,99 +30,14 @@
|
|||
|
||||
#include "libc.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_LIBC_STRING_OPTIMIZE
|
||||
|
||||
#define LBLOCKSIZE (sizeof(long))
|
||||
|
||||
/* Nonzero if either x or y is not aligned on a "long" boundary. */
|
||||
|
||||
#define UNALIGNED(x, y) \
|
||||
(((long)(uintptr_t)(x) & (sizeof(long) - 1)) | ((long)(uintptr_t)(y) & (sizeof(long) - 1)))
|
||||
|
||||
/* Macros for detecting endchar */
|
||||
|
||||
#if LONG_MAX == 2147483647
|
||||
# define DETECTNULL(x) (((x) - 0x01010101) & ~(x) & 0x80808080)
|
||||
#elif LONG_MAX == 9223372036854775807
|
||||
/* Nonzero if x (a long int) contains a NULL byte. */
|
||||
|
||||
# define DETECTNULL(x) (((x) - 0x0101010101010101) & ~(x) & 0x8080808080808080)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
#if !defined(CONFIG_LIBC_ARCH_STRNCMP) && defined(LIBC_BUILD_STRNCMP)
|
||||
#undef strncmp /* See mm/README.txt */
|
||||
nosanitize_address
|
||||
int strncmp(FAR const char *cs, FAR const char *ct, size_t nb)
|
||||
{
|
||||
#ifdef CONFIG_LIBC_STRING_OPTIMIZE
|
||||
FAR unsigned long *a1;
|
||||
FAR unsigned long *a2;
|
||||
|
||||
if (nb == 0)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If cs or ct are unaligned, then compare bytes. */
|
||||
|
||||
if (!UNALIGNED(cs, ct))
|
||||
{
|
||||
/* If cs and ct are word-aligned, compare them a word at a time. */
|
||||
|
||||
a1 = (FAR unsigned long *)cs;
|
||||
a2 = (FAR unsigned long *)ct;
|
||||
while (nb >= LBLOCKSIZE && *a1 == *a2)
|
||||
{
|
||||
nb -= LBLOCKSIZE;
|
||||
|
||||
/* If we've run out of bytes or hit a null, return zero
|
||||
* since we already know *a1 == *a2.
|
||||
*/
|
||||
|
||||
if (nb == 0 || DETECTNULL(*a1))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
a1++;
|
||||
a2++;
|
||||
}
|
||||
|
||||
/* A difference was detected in last few bytes of cs, so search
|
||||
* bytewise.
|
||||
*/
|
||||
|
||||
cs = (FAR char *)a1;
|
||||
ct = (FAR char *)a2;
|
||||
}
|
||||
|
||||
while (nb-- > 0 && *cs == *ct)
|
||||
{
|
||||
/* If we've run out of bytes or hit a null, return zero
|
||||
* since we already know *cs == *ct.
|
||||
*/
|
||||
|
||||
if (nb == 0 || *cs == '\0')
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
cs++;
|
||||
ct++;
|
||||
}
|
||||
|
||||
return *cs - *ct;
|
||||
#else
|
||||
register int result = 0;
|
||||
for (; nb > 0; nb--)
|
||||
{
|
||||
|
@ -134,6 +49,5 @@ int strncmp(FAR const char *cs, FAR const char *ct, size_t nb)
|
|||
}
|
||||
|
||||
return result;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -30,33 +30,6 @@
|
|||
|
||||
#include "libc.h"
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_LIBC_STRING_OPTIMIZE
|
||||
|
||||
#define LBLOCKSIZE (sizeof(long))
|
||||
|
||||
/* Nonzero if either x or y is not aligned on a "long" boundary. */
|
||||
|
||||
#define UNALIGNED(x, y) \
|
||||
(((long)(uintptr_t)(x) & (sizeof(long) - 1)) | ((long)(uintptr_t)(y) & (sizeof(long) - 1)))
|
||||
|
||||
/* Macros for detecting endchar */
|
||||
|
||||
#if LONG_MAX == 2147483647
|
||||
# define DETECTNULL(x) (((x) - 0x01010101) & ~(x) & 0x80808080)
|
||||
#elif LONG_MAX == 9223372036854775807
|
||||
/* Nonzero if x (a long int) contains a NULL byte. */
|
||||
|
||||
# define DETECTNULL(x) (((x) - 0x0101010101010101) & ~(x) & 0x8080808080808080)
|
||||
#endif
|
||||
|
||||
#define TOO_SMALL(len) ((len) < sizeof(long))
|
||||
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
@ -84,52 +57,8 @@
|
|||
|
||||
#if !defined(CONFIG_LIBC_ARCH_STRNCPY) && defined(LIBC_BUILD_STRNCPY)
|
||||
#undef strncpy /* See mm/README.txt */
|
||||
nosanitize_address
|
||||
FAR char *strncpy(FAR char *dest, FAR const char *src, size_t n)
|
||||
{
|
||||
#ifdef CONFIG_LIBC_STRING_OPTIMIZE
|
||||
FAR char *dst0 = dest;
|
||||
FAR const char *src0 = src;
|
||||
FAR long *aligned_dst;
|
||||
FAR const long *aligned_src;
|
||||
|
||||
/* If src and dest is aligned and n large enough, then copy words. */
|
||||
|
||||
if (!UNALIGNED(src0, dst0) && !TOO_SMALL(n))
|
||||
{
|
||||
aligned_dst = (FAR long *)dst0;
|
||||
aligned_src = (FAR long *)src0;
|
||||
|
||||
/* src and dest are both "long int" aligned, try to do "long int"
|
||||
* sized copies.
|
||||
*/
|
||||
|
||||
while (n >= LBLOCKSIZE && !DETECTNULL(*aligned_src))
|
||||
{
|
||||
n -= LBLOCKSIZE;
|
||||
*aligned_dst++ = *aligned_src++;
|
||||
}
|
||||
|
||||
dst0 = (FAR char *)aligned_dst;
|
||||
src0 = (FAR char *)aligned_src;
|
||||
}
|
||||
|
||||
while (n > 0)
|
||||
{
|
||||
--n;
|
||||
if ((*dst0++ = *src0++) == '\0')
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
while (n-- > 0)
|
||||
{
|
||||
*dst0++ = '\0';
|
||||
}
|
||||
|
||||
return dest;
|
||||
#else
|
||||
FAR char *ret = dest; /* Value to be returned */
|
||||
FAR char *end = dest + n; /* End of dest buffer + 1 byte */
|
||||
|
||||
|
@ -151,6 +80,5 @@ FAR char *strncpy(FAR char *dest, FAR const char *src, size_t n)
|
|||
}
|
||||
|
||||
return ret;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -42,24 +42,6 @@
|
|||
#undef strrchr /* See mm/README.txt */
|
||||
FAR char *strrchr(FAR const char *s, int c)
|
||||
{
|
||||
#ifdef CONFIG_LIBC_STRING_OPTIMIZE
|
||||
FAR const char *last = NULL;
|
||||
|
||||
if (c)
|
||||
{
|
||||
while ((s = strchr(s, c)))
|
||||
{
|
||||
last = s;
|
||||
s++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
last = strchr(s, c);
|
||||
}
|
||||
|
||||
return (FAR char *)last;
|
||||
#else
|
||||
FAR const char *r = NULL;
|
||||
|
||||
do
|
||||
|
@ -72,6 +54,5 @@ FAR char *strrchr(FAR const char *s, int c)
|
|||
while (*s++ != '\0');
|
||||
|
||||
return (FAR char *)r;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue