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

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

commit 797f4d74e3b04adf7a07235071eda33e8b642016
Author: Marco Casaroli <[email protected]>
AuthorDate: Tue Oct 27 13:32:42 2026 +0100

    libs/libc/wchar: Add wcsdup(), wcsnlen(), wcpcpy(), wcpncpy() and two more.
    
    POSIX.1-2008 <wchar.h> has wcsdup(), wcsnlen(), wcpcpy(), wcpncpy(),
    wcscasecmp() and wcsncasecmp(), the wide-character forms of strdup(),
    strnlen(), stpcpy(), stpncpy(), strcasecmp() and strncasecmp().  NuttX
    did not have them: programs that use them did not compile (util-linux's
    column uses wcsdup()).
    
    Add them.  wcscasecmp() and wcsncasecmp() compare with towlower().
    
    Assisted-by: Claude Code:claude-opus-5-5
    Signed-off-by: Marco Casaroli <[email protected]>
---
 include/wchar.h                   |  7 +++++
 libs/libc/libc.csv                |  6 ++++
 libs/libc/wchar/CMakeLists.txt    |  8 +++++-
 libs/libc/wchar/Make.defs         |  2 ++
 libs/libc/wchar/lib_wcpcpy.c      | 51 +++++++++++++++++++++++++++++++++
 libs/libc/wchar/lib_wcpncpy.c     | 51 +++++++++++++++++++++++++++++++++
 libs/libc/wchar/lib_wcscasecmp.c  | 56 +++++++++++++++++++++++++++++++++++++
 libs/libc/wchar/lib_wcsdup.c      | 55 ++++++++++++++++++++++++++++++++++++
 libs/libc/wchar/lib_wcsncasecmp.c | 59 +++++++++++++++++++++++++++++++++++++++
 libs/libc/wchar/lib_wcsnlen.c     | 53 +++++++++++++++++++++++++++++++++++
 10 files changed, 347 insertions(+), 1 deletion(-)

diff --git a/include/wchar.h b/include/wchar.h
index 066369b24f0..ffe4d662a72 100644
--- a/include/wchar.h
+++ b/include/wchar.h
@@ -176,21 +176,28 @@ int               vswprintf(FAR wchar_t *, size_t, FAR 
const wchar_t *,
                       va_list);
 int               vswscanf(FAR const wchar_t *, FAR const wchar_t *,
                       va_list);
+FAR wchar_t      *wcpcpy(FAR wchar_t *, FAR const wchar_t *);
+FAR wchar_t      *wcpncpy(FAR wchar_t *, FAR const wchar_t *, size_t);
 size_t            wcrtomb(FAR char *, wchar_t, FAR mbstate_t *);
+int               wcscasecmp(FAR const wchar_t *, FAR const wchar_t *);
 FAR wchar_t      *wcscat(FAR wchar_t *, FAR const wchar_t *);
 FAR wchar_t      *wcschr(FAR const wchar_t *, wchar_t);
 int               wcscmp(FAR const wchar_t *, FAR const wchar_t *);
 int               wcscoll(FAR const wchar_t *, FAR const wchar_t *);
 FAR wchar_t      *wcscpy(FAR wchar_t *, FAR const wchar_t *);
 size_t            wcscspn(FAR const wchar_t *, FAR const wchar_t *);
+FAR wchar_t      *wcsdup(FAR const wchar_t *);
 size_t            wcsftime(FAR wchar_t *, size_t, FAR const wchar_t *,
                       FAR const struct tm *);
 size_t            wcslen(FAR const wchar_t *);
 size_t            wcslcpy(FAR wchar_t *, FAR const wchar_t *, size_t);
 size_t            wcslcat(FAR wchar_t *, FAR const wchar_t *, size_t);
+int               wcsncasecmp(FAR const wchar_t *, FAR const wchar_t *,
+                      size_t);
 FAR wchar_t      *wcsncat(FAR wchar_t *, FAR const wchar_t *, size_t);
 int               wcsncmp(FAR const wchar_t *, FAR const wchar_t *, size_t);
 FAR wchar_t      *wcsncpy(FAR wchar_t *, FAR const wchar_t *, size_t);
+size_t            wcsnlen(FAR const wchar_t *, size_t);
 size_t            wcsnrtombs(FAR char *, FAR const wchar_t **, size_t,
                       size_t, FAR mbstate_t *);
 FAR wchar_t      *wcspbrk(FAR const wchar_t *, FAR const wchar_t *);
diff --git a/libs/libc/libc.csv b/libs/libc/libc.csv
index 082797bd84a..53f49225e80 100644
--- a/libs/libc/libc.csv
+++ b/libs/libc/libc.csv
@@ -383,20 +383,26 @@
 "vsprintf","stdio.h","","int","FAR char *","FAR const IPTR char *","va_list"
 "vsscanf","stdio.h","","int","FAR const char *","FAR const IPTR char 
*","va_list"
 "vsyslog","syslog.h","","void","int","FAR const IPTR char *","va_list"
+"wcpcpy","wchar.h","","FAR wchar_t *","FAR wchar_t *","FAR const wchar_t *"
+"wcpncpy","wchar.h","","FAR wchar_t *","FAR wchar_t *","FAR const wchar_t 
*","size_t"
 "wcrtomb","wchar.h","","size_t","FAR char *","wchar_t","FAR mbstate_t *"
+"wcscasecmp","wchar.h","","int","FAR const wchar_t *","FAR const wchar_t *"
 "wcscat","wchar.h","","FAR wchar_t *","FAR wchar_t *","FAR const wchar_t *"
 "wcschr","wchar.h","","FAR wchar_t *","FAR const wchar_t *","wchar_t"
 "wcscmp","wchar.h","","int","FAR const wchar_t *","FAR const wchar_t *"
 "wcscoll","wchar.h","","int","FAR const wchar_t *","FAR const wchar_t *"
 "wcscpy","wchar.h","","FAR wchar_t *","FAR wchar_t *","FAR const wchar_t *"
 "wcscspn","wchar.h","","size_t","FAR const wchar_t *","FAR const wchar_t *"
+"wcsdup","wchar.h","","FAR wchar_t *","FAR const wchar_t *"
 "wcsftime","wchar.h","","size_t","FAR wchar_t *","size_t","FAR const wchar_t 
*","FAR const struct tm *"
 "wcslcat","wchar.h","","size_t","FAR wchar_t *","FAR const wchar_t *","size_t"
+"wcsncasecmp","wchar.h","","int","FAR const wchar_t *","FAR const wchar_t 
*","size_t"
 "wcsncat","wchar.h","","FAR wchar_t *","FAR wchar_t *","FAR const wchar_t 
*","size_t"
 "wcsncmp","wchar.h","","int","FAR const wchar_t *","FAR const wchar_t 
*","size_t"
 "wcsncpy","wchar.h","","FAR wchar_t *","FAR wchar_t *","FAR const wchar_t 
*","size_t"
 "wcslcpy","wchar.h","","size_t","FAR wchar_t *","FAR const wchar_t *","size_t"
 "wcslen","wchar.h","","size_t","FAR const wchar_t *"
+"wcsnlen","wchar.h","","size_t","FAR const wchar_t *","size_t"
 "wcsnrtombs","wchar.h","","size_t","FAR char *","FAR const wchar_t 
**","size_t","size_t","FAR mbstate_t *"
 "wcspbrk","wchar.h","","FAR wchar_t *","FAR const wchar_t *","FAR const 
wchar_t *"
 "wcsrchr","wchar.h","","FAR wchar_t *","FAR const wchar_t *","wchar_t"
diff --git a/libs/libc/wchar/CMakeLists.txt b/libs/libc/wchar/CMakeLists.txt
index 1bdd3cbb76d..abf03b74047 100644
--- a/libs/libc/wchar/CMakeLists.txt
+++ b/libs/libc/wchar/CMakeLists.txt
@@ -66,4 +66,10 @@ target_sources(
           lib_wcstok.c
           lib_wcswcs.c
           lib_wcwidth.c
-          lib_wcswidth.c)
+          lib_wcswidth.c
+          lib_wcsnlen.c
+          lib_wcsdup.c
+          lib_wcpcpy.c
+          lib_wcpncpy.c
+          lib_wcscasecmp.c
+          lib_wcsncasecmp.c)
diff --git a/libs/libc/wchar/Make.defs b/libs/libc/wchar/Make.defs
index c43484f4c84..baff150c0f3 100644
--- a/libs/libc/wchar/Make.defs
+++ b/libs/libc/wchar/Make.defs
@@ -32,6 +32,8 @@ CSRCS += lib_mbrlen.c lib_mbsrtowcs.c lib_wcsrtombs.c 
lib_wcscpy.c
 CSRCS += lib_wcscat.c lib_wcslcat.c lib_wcsncat.c lib_wcsrchr.c lib_wcschr.c
 CSRCS += lib_wcsncpy.c lib_wcsncmp.c lib_wcscspn.c lib_wcspbrk.c lib_wcsspn.c
 CSRCS += lib_wcsstr.c lib_wcstok.c lib_wcswcs.c lib_wcwidth.c lib_wcswidth.c
+CSRCS += lib_wcsnlen.c lib_wcsdup.c lib_wcpcpy.c lib_wcpncpy.c
+CSRCS += lib_wcscasecmp.c lib_wcsncasecmp.c
 
 # Add the wchar directory to the build
 
diff --git a/libs/libc/wchar/lib_wcpcpy.c b/libs/libc/wchar/lib_wcpcpy.c
new file mode 100644
index 00000000000..0aac6e02504
--- /dev/null
+++ b/libs/libc/wchar/lib_wcpcpy.c
@@ -0,0 +1,51 @@
+/****************************************************************************
+ * libs/libc/wchar/lib_wcpcpy.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <wchar.h>
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: wcpcpy
+ *
+ * Description:
+ *   Copy the wide-character string src, with its terminating null wide
+ *   character, to dest.  Return a pointer to the terminating null wide
+ *   character of dest.
+ *
+ ****************************************************************************/
+
+FAR wchar_t *wcpcpy(FAR wchar_t *dest, FAR const wchar_t *src)
+{
+  while ((*dest = *src++) != L'\0')
+    {
+      dest++;
+    }
+
+  return dest;
+}
diff --git a/libs/libc/wchar/lib_wcpncpy.c b/libs/libc/wchar/lib_wcpncpy.c
new file mode 100644
index 00000000000..f9173a113d8
--- /dev/null
+++ b/libs/libc/wchar/lib_wcpncpy.c
@@ -0,0 +1,51 @@
+/****************************************************************************
+ * libs/libc/wchar/lib_wcpncpy.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <wchar.h>
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: wcpncpy
+ *
+ * Description:
+ *   Copy at most n wide characters of src to dest, and fill the rest of the
+ *   n wide characters of dest with null wide characters.  Return a pointer
+ *   to the first null wide character written to dest, or dest + n if src
+ *   has n or more wide characters (then dest is not terminated).
+ *
+ ****************************************************************************/
+
+FAR wchar_t *wcpncpy(FAR wchar_t *dest, FAR const wchar_t *src, size_t n)
+{
+  size_t len = wcsnlen(src, n);
+
+  wmemcpy(dest, src, len);
+  wmemset(dest + len, L'\0', n - len);
+  return dest + len;
+}
diff --git a/libs/libc/wchar/lib_wcscasecmp.c b/libs/libc/wchar/lib_wcscasecmp.c
new file mode 100644
index 00000000000..0c89c0b821c
--- /dev/null
+++ b/libs/libc/wchar/lib_wcscasecmp.c
@@ -0,0 +1,56 @@
+/****************************************************************************
+ * libs/libc/wchar/lib_wcscasecmp.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <wchar.h>
+#include <wctype.h>
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: wcscasecmp
+ *
+ * Description:
+ *   Compare the wide-character strings s1 and s2 as wcscmp() does, but
+ *   without the difference of case (towlower() of each wide character).
+ *
+ ****************************************************************************/
+
+int wcscasecmp(FAR const wchar_t *s1, FAR const wchar_t *s2)
+{
+  wint_t c1;
+  wint_t c2;
+
+  do
+    {
+      c1 = towlower(*s1++);
+      c2 = towlower(*s2++);
+    }
+  while (c1 == c2 && c1 != L'\0');
+
+  return c1 < c2 ? -1 : c1 > c2;
+}
diff --git a/libs/libc/wchar/lib_wcsdup.c b/libs/libc/wchar/lib_wcsdup.c
new file mode 100644
index 00000000000..91eda5c27b0
--- /dev/null
+++ b/libs/libc/wchar/lib_wcsdup.c
@@ -0,0 +1,55 @@
+/****************************************************************************
+ * libs/libc/wchar/lib_wcsdup.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <wchar.h>
+
+#include "libc.h"
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: wcsdup
+ *
+ * Description:
+ *   Return a copy of the wide-character string s in memory from malloc(),
+ *   or NULL if there is not enough memory.
+ *
+ ****************************************************************************/
+
+FAR wchar_t *wcsdup(FAR const wchar_t *s)
+{
+  size_t size = (wcslen(s) + 1) * sizeof(wchar_t);
+  FAR wchar_t *news = lib_malloc(size);
+
+  if (news != NULL)
+    {
+      wmemcpy(news, s, size / sizeof(wchar_t));
+    }
+
+  return news;
+}
diff --git a/libs/libc/wchar/lib_wcsncasecmp.c 
b/libs/libc/wchar/lib_wcsncasecmp.c
new file mode 100644
index 00000000000..45299771097
--- /dev/null
+++ b/libs/libc/wchar/lib_wcsncasecmp.c
@@ -0,0 +1,59 @@
+/****************************************************************************
+ * libs/libc/wchar/lib_wcsncasecmp.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <wchar.h>
+#include <wctype.h>
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: wcsncasecmp
+ *
+ * Description:
+ *   Compare at most n wide characters of s1 and s2 as wcsncmp() does, but
+ *   without the difference of case (towlower() of each wide character).
+ *
+ ****************************************************************************/
+
+int wcsncasecmp(FAR const wchar_t *s1, FAR const wchar_t *s2, size_t n)
+{
+  wint_t c1 = 0;
+  wint_t c2 = 0;
+
+  while (n-- > 0)
+    {
+      c1 = towlower(*s1++);
+      c2 = towlower(*s2++);
+      if (c1 != c2 || c1 == L'\0')
+        {
+          break;
+        }
+    }
+
+  return c1 < c2 ? -1 : c1 > c2;
+}
diff --git a/libs/libc/wchar/lib_wcsnlen.c b/libs/libc/wchar/lib_wcsnlen.c
new file mode 100644
index 00000000000..f4a6e697441
--- /dev/null
+++ b/libs/libc/wchar/lib_wcsnlen.c
@@ -0,0 +1,53 @@
+/****************************************************************************
+ * libs/libc/wchar/lib_wcsnlen.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <wchar.h>
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: wcsnlen
+ *
+ * Description:
+ *   Return the number of wide characters in s before the terminating null
+ *   wide character, but at most maxlen: only the first maxlen wide
+ *   characters of s are read.
+ *
+ ****************************************************************************/
+
+size_t wcsnlen(FAR const wchar_t *s, size_t maxlen)
+{
+  size_t len = 0;
+
+  while (len < maxlen && s[len] != L'\0')
+    {
+      len++;
+    }
+
+  return len;
+}

Reply via email to