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

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


The following commit(s) were added to refs/heads/master by this push:
     new fdcee827b testing/libc/lsearch: Test lfind(), lsearch(), insque() and 
remque().
fdcee827b is described below

commit fdcee827bb897f3cb73db311a1ba145d2956e50f
Author: Marco Casaroli <[email protected]>
AuthorDate: Tue Nov 10 22:20:47 2026 +0100

    testing/libc/lsearch: Test lfind(), lsearch(), insque() and remque().
    
    Check lfind() and lsearch() on a table of 6-byte elements: the first
    match, a missing key, an empty table, the key as the first argument of
    the comparison function, and a missing key that lsearch() adds at the
    end with all of its bytes.  Check insque() and remque() on a linear
    queue (insque() with no predecessor, after the last element and between
    two elements; remque() of a middle, the last and the first element) and
    on a circular queue.  The test prints one line for each check and
    returns EXIT_FAILURE if a check fails.
    
    Assisted-by: Claude Code:claude-opus-5-5
    Signed-off-by: Marco Casaroli <[email protected]>
---
 testing/libc/lsearch/CMakeLists.txt |  35 ++++++
 testing/libc/lsearch/Kconfig        |  30 +++++
 testing/libc/lsearch/Make.defs      |  25 ++++
 testing/libc/lsearch/Makefile       |  36 ++++++
 testing/libc/lsearch/lsearch_main.c | 242 ++++++++++++++++++++++++++++++++++++
 5 files changed, 368 insertions(+)

diff --git a/testing/libc/lsearch/CMakeLists.txt 
b/testing/libc/lsearch/CMakeLists.txt
new file mode 100644
index 000000000..0c690fba9
--- /dev/null
+++ b/testing/libc/lsearch/CMakeLists.txt
@@ -0,0 +1,35 @@
+# 
##############################################################################
+# apps/testing/libc/lsearch/CMakeLists.txt
+#
+# 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.
+#
+# 
##############################################################################
+
+if(CONFIG_TESTING_LSEARCH)
+  nuttx_add_application(
+    NAME
+    ${CONFIG_TESTING_LSEARCH_PROGNAME}
+    PRIORITY
+    ${CONFIG_TESTING_LSEARCH_PRIORITY}
+    STACKSIZE
+    ${CONFIG_TESTING_LSEARCH_STACKSIZE}
+    MODULE
+    ${CONFIG_TESTING_LSEARCH}
+    SRCS
+    lsearch_main.c)
+endif()
diff --git a/testing/libc/lsearch/Kconfig b/testing/libc/lsearch/Kconfig
new file mode 100644
index 000000000..db4234857
--- /dev/null
+++ b/testing/libc/lsearch/Kconfig
@@ -0,0 +1,30 @@
+#
+# For a description of the syntax of this configuration file,
+# see the file kconfig-language.txt in the NuttX tools repository.
+#
+
+config TESTING_LSEARCH
+       tristate "lfind(), lsearch(), insque() and remque() test"
+       default n
+       ---help---
+               Check lfind() and lsearch() of <search.h>, and insque() and
+               remque() on a linear and on a circular queue.
+
+if TESTING_LSEARCH
+
+config TESTING_LSEARCH_PROGNAME
+       string "Program name"
+       default "lsearch_test"
+       ---help---
+               This is the name of the program that will be used when the NSH 
ELF
+               program is installed.
+
+config TESTING_LSEARCH_PRIORITY
+       int "lsearch_test task priority"
+       default 100
+
+config TESTING_LSEARCH_STACKSIZE
+       int "lsearch_test stack size"
+       default DEFAULT_TASK_STACKSIZE
+
+endif
diff --git a/testing/libc/lsearch/Make.defs b/testing/libc/lsearch/Make.defs
new file mode 100644
index 000000000..6181411ed
--- /dev/null
+++ b/testing/libc/lsearch/Make.defs
@@ -0,0 +1,25 @@
+############################################################################
+# apps/testing/libc/lsearch/Make.defs
+#
+# 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.
+#
+############################################################################
+
+ifneq ($(CONFIG_TESTING_LSEARCH),)
+CONFIGURED_APPS += $(APPDIR)/testing/libc/lsearch
+endif
diff --git a/testing/libc/lsearch/Makefile b/testing/libc/lsearch/Makefile
new file mode 100644
index 000000000..0c1a1d33b
--- /dev/null
+++ b/testing/libc/lsearch/Makefile
@@ -0,0 +1,36 @@
+############################################################################
+# apps/testing/libc/lsearch/Makefile
+#
+# 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.
+#
+############################################################################
+
+include $(APPDIR)/Make.defs
+
+# lsearch test built-in application info
+
+PROGNAME  = $(CONFIG_TESTING_LSEARCH_PROGNAME)
+PRIORITY  = $(CONFIG_TESTING_LSEARCH_PRIORITY)
+STACKSIZE = $(CONFIG_TESTING_LSEARCH_STACKSIZE)
+MODULE    = $(CONFIG_TESTING_LSEARCH)
+
+# lsearch test files
+
+MAINSRC = lsearch_main.c
+
+include $(APPDIR)/Application.mk
diff --git a/testing/libc/lsearch/lsearch_main.c 
b/testing/libc/lsearch/lsearch_main.c
new file mode 100644
index 000000000..8863cf88e
--- /dev/null
+++ b/testing/libc/lsearch/lsearch_main.c
@@ -0,0 +1,242 @@
+/****************************************************************************
+ * apps/testing/libc/lsearch/lsearch_main.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 <search.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* The width of a table element: not the size of a basic type */
+
+#define NAME_WIDTH 6
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/* An element of a queue: the forward and the backward pointer first */
+
+struct qelem_s
+{
+  FAR struct qelem_s *forw;
+  FAR struct qelem_s *back;
+  int value;
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/* The key starts with '=' and the elements do not: a match also means that
+ * lfind() passed the key as the first argument, as POSIX requires.
+ */
+
+static int compare_key(FAR const void *key, FAR const void *elem)
+{
+  FAR const char *k = key;
+
+  if (k[0] != '=')
+    {
+      return -1;
+    }
+
+  return strncmp(k + 1, elem, NAME_WIDTH - 1);
+}
+
+static int compare_name(FAR const void *key, FAR const void *elem)
+{
+  return strncmp(key, elem, NAME_WIDTH);
+}
+
+static int check(FAR const char *name, bool ok)
+{
+  printf("%s: %s\n", name, ok ? "OK" : "ERROR");
+  return ok ? 0 : 1;
+}
+
+static int test_lfind(void)
+{
+  char table[4][NAME_WIDTH] =
+  {
+    "cat", "dog", "emu", "dog"
+  };
+
+  char key[NAME_WIDTH] = "=dog";
+  FAR char *p;
+  size_t nel = 4;
+  int nerrors = 0;
+
+  p = lfind(key, table, &nel, NAME_WIDTH, compare_key);
+  nerrors += check("lfind() returns the first match",
+                   p == table[1] && nel == 4);
+
+  strcpy(key, "=yak");
+  p = lfind(key, table, &nel, NAME_WIDTH, compare_key);
+  nerrors += check("lfind() returns NULL for a missing key",
+                   p == NULL && nel == 4);
+
+  strcpy(key, "=cat");
+  nel = 0;
+  p = lfind(key, table, &nel, NAME_WIDTH, compare_key);
+  nerrors += check("lfind() finds nothing in an empty table",
+                   p == NULL && nel == 0);
+
+  return nerrors;
+}
+
+static int test_lsearch(void)
+{
+  char table[4][NAME_WIDTH] =
+  {
+    "cat", "dog"
+  };
+
+  char key[NAME_WIDTH] = "dog";
+  FAR char *p;
+  size_t nel = 2;
+  int nerrors = 0;
+
+  p = lsearch(key, table, &nel, NAME_WIDTH, compare_name);
+  nerrors += check("lsearch() finds a present key and adds nothing",
+                   p == table[1] && nel == 2);
+
+  /* A missing key is copied to the end of the table, all of its bytes */
+
+  memcpy(key, "emu\0xy", NAME_WIDTH);
+  p = lsearch(key, table, &nel, NAME_WIDTH, compare_name);
+  nerrors += check("lsearch() adds a missing key at the end",
+                   p == table[2] && nel == 3 &&
+                   memcmp(table[2], key, NAME_WIDTH) == 0);
+
+  p = lsearch(key, table, &nel, NAME_WIDTH, compare_name);
+  nerrors += check("lsearch() then finds the key it added",
+                   p == table[2] && nel == 3);
+
+  nel = 0;
+  p = lsearch(key, table, &nel, NAME_WIDTH, compare_name);
+  nerrors += check("lsearch() adds to an empty table",
+                   p == table[0] && nel == 1 &&
+                   memcmp(table[0], key, NAME_WIDTH) == 0);
+
+  return nerrors;
+}
+
+static int test_linear_queue(void)
+{
+  struct qelem_s a;
+  struct qelem_s b;
+  struct qelem_s c;
+  struct qelem_s d;
+  int nerrors = 0;
+
+  memset(&a, 0xff, sizeof(a));
+  insque(&a, NULL);
+  nerrors += check("insque(e, NULL) starts a linear queue",
+                   a.forw == NULL && a.back == NULL);
+
+  /* Insert after the last element, then between two elements */
+
+  insque(&c, &a);
+  insque(&b, &a);
+  nerrors += check("insque() links after an element",
+                   a.forw == &b && b.back == &a && b.forw == &c &&
+                   c.back == &b && c.forw == NULL && a.back == NULL);
+
+  insque(&d, &c);
+  nerrors += check("insque() links after the last element",
+                   c.forw == &d && d.back == &c && d.forw == NULL);
+
+  /* a b c d: remove the middle, the last and then the first element */
+
+  remque(&b);
+  nerrors += check("remque() unlinks a middle element",
+                   a.forw == &c && c.back == &a);
+
+  remque(&d);
+  nerrors += check("remque() unlinks the last element", c.forw == NULL);
+
+  remque(&a);
+  nerrors += check("remque() unlinks the first element",
+                   c.back == NULL && c.forw == NULL);
+
+  return nerrors;
+}
+
+static int test_circular_queue(void)
+{
+  struct qelem_s h;
+  struct qelem_s a;
+  struct qelem_s b;
+  int nerrors = 0;
+
+  /* The head of a circular queue points to itself */
+
+  h.forw = &h;
+  h.back = &h;
+
+  insque(&a, &h);
+  nerrors += check("insque() into an empty circular queue",
+                   h.forw == &a && h.back == &a &&
+                   a.forw == &h && a.back == &h);
+
+  insque(&b, &a);
+  nerrors += check("insque() closes the circle",
+                   h.forw == &a && a.forw == &b && b.forw == &h &&
+                   h.back == &b && b.back == &a && a.back == &h);
+
+  remque(&a);
+  nerrors += check("remque() from a circular queue",
+                   h.forw == &b && b.back == &h &&
+                   b.forw == &h && h.back == &b);
+
+  remque(&b);
+  nerrors += check("remque() of the last element leaves the head",
+                   h.forw == &h && h.back == &h);
+
+  return nerrors;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+int main(int argc, FAR char *argv[])
+{
+  int nerrors = 0;
+
+  nerrors += test_lfind();
+  nerrors += test_lsearch();
+  nerrors += test_linear_queue();
+  nerrors += test_circular_queue();
+
+  printf("lsearch test: %d errors\n", nerrors);
+  return nerrors > 0 ? EXIT_FAILURE : EXIT_SUCCESS;
+}

Reply via email to