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;
+}