This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 6e87f110833363d353b7c3e849d510d72749b67d
Author: yangguangcai <[email protected]>
AuthorDate: Fri Jan 26 10:50:25 2024 +0800

    Merge the newlibc string into NuttX.
    
    Signed-off-by: yangguangcai <[email protected]>
---
 LICENSE                          |  31 +++++++++++
 libs/libc/string/Kconfig         |   7 +++
 libs/libc/string/lib_memccpy.c   |  96 +++++++++++++++++++++++++++++++++
 libs/libc/string/lib_memchr.c    | 103 +++++++++++++++++++++++++++++++++++
 libs/libc/string/lib_memcmp.c    |  69 ++++++++++++++++++++++++
 libs/libc/string/lib_memcpy.c    |  70 ++++++++++++++++++++++++
 libs/libc/string/lib_memmove.c   |   8 +--
 libs/libc/string/lib_memrchr.c   | 103 +++++++++++++++++++++++++++++++++++
 libs/libc/string/lib_stpcpy.c    |  48 +++++++++++++++++
 libs/libc/string/lib_stpncpy.c   |  72 +++++++++++++++++++++++++
 libs/libc/string/lib_strcat.c    |  53 ++++++++++++++++++
 libs/libc/string/lib_strchr.c    | 113 +++++++++++++++++++++++++++++++++++++++
 libs/libc/string/lib_strchrnul.c |   6 +++
 libs/libc/string/lib_strcmp.c    |  66 +++++++++++++++++++++++
 libs/libc/string/lib_strcoll.c   |   2 +-
 libs/libc/string/lib_strcpy.c    |  53 ++++++++++++++++++
 libs/libc/string/lib_strdup.c    |   2 +-
 libs/libc/string/lib_strlen.c    |  60 +++++++++++++++++++++
 libs/libc/string/lib_strncmp.c   |  85 +++++++++++++++++++++++++++++
 libs/libc/string/lib_strncpy.c   |  71 ++++++++++++++++++++++++
 libs/libc/string/lib_strrchr.c   |  19 +++++++
 21 files changed, 1128 insertions(+), 9 deletions(-)

diff --git a/LICENSE b/LICENSE
index c51bac1eed..0ea7752a49 100644
--- a/LICENSE
+++ b/LICENSE
@@ -8664,3 +8664,34 @@ drivers/i3c/internals.h
  Author: Boris Brezillon <[email protected]>
 
  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
+======================
+
+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.
diff --git a/libs/libc/string/Kconfig b/libs/libc/string/Kconfig
index e7180cddff..c8e0630e59 100644
--- a/libs/libc/string/Kconfig
+++ b/libs/libc/string/Kconfig
@@ -36,6 +36,13 @@ config LIBC_STRERROR_ERRNUM
                for unknown errors like "Unknown error 101". Default enabled 
when
                LIBC_STRERROR is not selected.
 
+config LIBC_STRING_OPTIMIZE
+       bool "optimized string function"
+       depends on ALLOW_BSD_COMPONENTS
+       default y
+       --help--
+               Use optimized string function implementation based on newlib.
+
 config LIBC_PERROR_STDOUT
        bool "perror() to stdout"
        default n
diff --git a/libs/libc/string/lib_memccpy.c b/libs/libc/string/lib_memccpy.c
index 283e5650cf..3cb34c0d2d 100644
--- a/libs/libc/string/lib_memccpy.c
+++ b/libs/libc/string/lib_memccpy.c
@@ -28,6 +28,36 @@
 #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
  ****************************************************************************/
@@ -51,6 +81,71 @@
 #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;
 
@@ -75,4 +170,5 @@ 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
 }
diff --git a/libs/libc/string/lib_memchr.c b/libs/libc/string/lib_memchr.c
index 2c24e3256f..e651f21b67 100644
--- a/libs/libc/string/lib_memchr.c
+++ b/libs/libc/string/lib_memchr.c
@@ -30,6 +30,38 @@
 
 #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
  ****************************************************************************/
@@ -52,6 +84,76 @@
 #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--)
@@ -63,6 +165,7 @@ FAR void *memchr(FAR const void *s, int c, size_t n)
 
       p++;
     }
+#endif
 
   return NULL;
 }
diff --git a/libs/libc/string/lib_memcmp.c b/libs/libc/string/lib_memcmp.c
index 251cbf7bba..4960a810fb 100644
--- a/libs/libc/string/lib_memcmp.c
+++ b/libs/libc/string/lib_memcmp.c
@@ -30,6 +30,26 @@
 
 #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
  ****************************************************************************/
@@ -39,6 +59,54 @@
 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;
 
@@ -56,6 +124,7 @@ int memcmp(FAR const void *s1, FAR const void *s2, size_t n)
       p1++;
       p2++;
     }
+#endif
 
   return 0;
 }
diff --git a/libs/libc/string/lib_memcpy.c b/libs/libc/string/lib_memcpy.c
index c1ff6ae1e8..66367cb2f2 100644
--- a/libs/libc/string/lib_memcpy.c
+++ b/libs/libc/string/lib_memcpy.c
@@ -30,6 +30,30 @@
 
 #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
  ****************************************************************************/
@@ -43,12 +67,58 @@
 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;
 }
diff --git a/libs/libc/string/lib_memmove.c b/libs/libc/string/lib_memmove.c
index fd6d43383a..7864902f02 100644
--- a/libs/libc/string/lib_memmove.c
+++ b/libs/libc/string/lib_memmove.c
@@ -44,13 +44,7 @@ FAR void *memmove(FAR void *dest, FAR const void *src, 
size_t count)
 
   if (dest <= src)
     {
-      tmp = (FAR char *) dest;
-      s   = (FAR char *) src;
-
-      while (count--)
-        {
-          *tmp++ = *s++;
-        }
+      memcpy(dest, src, count);
     }
   else
     {
diff --git a/libs/libc/string/lib_memrchr.c b/libs/libc/string/lib_memrchr.c
index 9a8f4a69d6..e8a07e7565 100644
--- a/libs/libc/string/lib_memrchr.c
+++ b/libs/libc/string/lib_memrchr.c
@@ -28,6 +28,37 @@
 
 #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
  ****************************************************************************/
@@ -49,6 +80,77 @@
 #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--)
@@ -58,6 +160,7 @@ FAR void *memrchr(FAR const void *s, int c, size_t n)
           return (FAR void *)p;
         }
     }
+#endif
 
   return NULL;
 }
diff --git a/libs/libc/string/lib_stpcpy.c b/libs/libc/string/lib_stpcpy.c
index ae1a9cbfb9..c9eff7ad14 100644
--- a/libs/libc/string/lib_stpcpy.c
+++ b/libs/libc/string/lib_stpcpy.c
@@ -28,6 +28,28 @@
 
 #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
  ****************************************************************************/
@@ -49,7 +71,33 @@
 #undef stpcpy /* See mm/README.txt */
 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
diff --git a/libs/libc/string/lib_stpncpy.c b/libs/libc/string/lib_stpncpy.c
index acbc1f3a45..b33c0b77d4 100644
--- a/libs/libc/string/lib_stpncpy.c
+++ b/libs/libc/string/lib_stpncpy.c
@@ -28,6 +28,34 @@
 #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
  ****************************************************************************/
@@ -59,6 +87,49 @@
 #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 */
 
@@ -91,5 +162,6 @@ FAR char *stpncpy(FAR char *dest, FAR const char *src, 
size_t n)
     }
 
   return ret;
+#endif
 }
 #endif
diff --git a/libs/libc/string/lib_strcat.c b/libs/libc/string/lib_strcat.c
index 7dcc5e4ee8..5d7dc8dcb0 100644
--- a/libs/libc/string/lib_strcat.c
+++ b/libs/libc/string/lib_strcat.c
@@ -30,6 +30,27 @@
 
 #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
  ****************************************************************************/
@@ -38,6 +59,37 @@
 #undef strcat /* See mm/README.txt */
 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);
@@ -47,6 +99,7 @@ FAR char *strcat(FAR char *dest, FAR const char *src)
     }
 
   *dest = '\0';
+#endif
 
   return ret;
 }
diff --git a/libs/libc/string/lib_strchr.c b/libs/libc/string/lib_strchr.c
index 98538abbb5..463b485001 100644
--- a/libs/libc/string/lib_strchr.c
+++ b/libs/libc/string/lib_strchr.c
@@ -30,6 +30,32 @@
 
 #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
  ****************************************************************************/
@@ -52,6 +78,92 @@
 #undef strchr /* See mm/README.txt */
 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)
@@ -64,6 +176,7 @@ FAR char *strchr(FAR const char *s, int c)
           break;
         }
     }
+#endif
 
   return NULL;
 }
diff --git a/libs/libc/string/lib_strchrnul.c b/libs/libc/string/lib_strchrnul.c
index d8433b695c..9cccb44ce9 100644
--- a/libs/libc/string/lib_strchrnul.c
+++ b/libs/libc/string/lib_strchrnul.c
@@ -52,6 +52,11 @@
 #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)
@@ -61,5 +66,6 @@ FAR char *strchrnul(FAR const char *s, int c)
     }
 
   return (FAR char *)s;
+#endif
 }
 #endif
diff --git a/libs/libc/string/lib_strcmp.c b/libs/libc/string/lib_strcmp.c
index f445d5f99a..1a99f8109c 100644
--- a/libs/libc/string/lib_strcmp.c
+++ b/libs/libc/string/lib_strcmp.c
@@ -30,6 +30,28 @@
 
 #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
  ****************************************************************************/
@@ -38,6 +60,49 @@
 #undef strcmp /* See mm/README.txt */
 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 (; ; )
     {
@@ -49,5 +114,6 @@ int strcmp(FAR const char *cs, FAR const char *ct)
     }
 
   return result;
+#endif
 }
 #endif
diff --git a/libs/libc/string/lib_strcoll.c b/libs/libc/string/lib_strcoll.c
index 31d49db473..1c592aaf3a 100644
--- a/libs/libc/string/lib_strcoll.c
+++ b/libs/libc/string/lib_strcoll.c
@@ -52,7 +52,7 @@
  *
  ****************************************************************************/
 
-int strcoll(const char *a, const char *b)
+int strcoll(FAR const char *a, FAR const char *b)
 {
   return strcmp(a, b);
 }
diff --git a/libs/libc/string/lib_strcpy.c b/libs/libc/string/lib_strcpy.c
index 38c73c3a48..27cddca36f 100644
--- a/libs/libc/string/lib_strcpy.c
+++ b/libs/libc/string/lib_strcpy.c
@@ -30,6 +30,28 @@
 
 #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
  ****************************************************************************/
@@ -50,8 +72,39 @@
 #undef strcpy /* See mm/README.txt */
 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 long *aligned_dst;
+  FAR const long *aligned_src;
+
+  /* If SRC or DEST is unaligned, then copy bytes. */
+
+  if (!UNALIGNED(src0, dst0))
+    {
+      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 (!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
diff --git a/libs/libc/string/lib_strdup.c b/libs/libc/string/lib_strdup.c
index f876d0b240..40e7fef4b1 100644
--- a/libs/libc/string/lib_strdup.c
+++ b/libs/libc/string/lib_strdup.c
@@ -42,7 +42,7 @@ FAR char *strdup(FAR const char *s)
 
   if (news)
     {
-      strlcpy(news, s, size);
+      memcpy(news, s, size);
     }
 
   return news;
diff --git a/libs/libc/string/lib_strlen.c b/libs/libc/string/lib_strlen.c
index 594f01a481..d13968c26d 100644
--- a/libs/libc/string/lib_strlen.c
+++ b/libs/libc/string/lib_strlen.c
@@ -30,6 +30,27 @@
 
 #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
  ****************************************************************************/
@@ -38,8 +59,47 @@
 #undef strlen /* See mm/README.txt */
 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
diff --git a/libs/libc/string/lib_strncmp.c b/libs/libc/string/lib_strncmp.c
index e46c7abbce..8000c17be3 100644
--- a/libs/libc/string/lib_strncmp.c
+++ b/libs/libc/string/lib_strncmp.c
@@ -30,6 +30,31 @@
 
 #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
  ****************************************************************************/
@@ -38,6 +63,65 @@
 #undef strncmp /* See mm/README.txt */
 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--)
     {
@@ -49,5 +133,6 @@ int strncmp(FAR const char *cs, FAR const char *ct, size_t 
nb)
     }
 
   return result;
+#endif
 }
 #endif
diff --git a/libs/libc/string/lib_strncpy.c b/libs/libc/string/lib_strncpy.c
index 3e36df4ff5..ccceb5d87b 100644
--- a/libs/libc/string/lib_strncpy.c
+++ b/libs/libc/string/lib_strncpy.c
@@ -30,6 +30,33 @@
 
 #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
  ****************************************************************************/
@@ -59,6 +86,49 @@
 #undef strncpy /* See mm/README.txt */
 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 */
 
@@ -80,5 +150,6 @@ FAR char *strncpy(FAR char *dest, FAR const char *src, 
size_t n)
     }
 
   return ret;
+#endif
 }
 #endif
diff --git a/libs/libc/string/lib_strrchr.c b/libs/libc/string/lib_strrchr.c
index d19afc743b..a448f27757 100644
--- a/libs/libc/string/lib_strrchr.c
+++ b/libs/libc/string/lib_strrchr.c
@@ -42,6 +42,24 @@
 #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
@@ -54,5 +72,6 @@ FAR char *strrchr(FAR const char *s, int c)
   while (*s++ != '\0');
 
   return (FAR char *)r;
+#endif
 }
 #endif


Reply via email to