llx: New function llx_find() to find a pointer in a list.
authorBen Pfaff <blp@gnu.org>
Wed, 3 Feb 2010 04:15:38 +0000 (20:15 -0800)
committerBen Pfaff <blp@gnu.org>
Sat, 6 Feb 2010 04:14:20 +0000 (20:14 -0800)
src/libpspp/llx.c
src/libpspp/llx.h
tests/libpspp/llx-test.c

index c58f840c40a6db106d250e0cb6b5a9dec39efa5f..905850bc41c13ec74be83289e0571c0972f464dc 100644 (file)
@@ -219,6 +219,20 @@ llx_remove_if (struct llx *r0, struct llx *r1,
   return count;
 }
 
+/* Returns the first node in R0...R1 that has data TARGET.
+   Returns NULL if no node in R0...R1 equals TARGET. */
+struct llx *
+llx_find (const struct llx *r0, const struct llx *r1, const void *target)
+{
+  const struct llx *x;
+
+  for (x = r0; x != r1; x = llx_next (x))
+    if (llx_data (x) == target)
+      return CONST_CAST (struct llx *, x);
+
+  return NULL;
+}
+
 /* Returns the first node in R0...R1 that equals TARGET
    according to COMPARE given auxiliary data AUX.
    Returns R1 if no node in R0...R1 equals TARGET. */
index 23c3bdaf8ebd0d7ebd2b3741db12106ef38952de..2aa18e7ba5694bced71cbe32a3feb69700e23f9b 100644 (file)
@@ -186,6 +186,8 @@ size_t llx_remove_if (struct llx *r0, struct llx *r1,
                       const struct llx_manager *);
 
 /* Non-mutating algorithms. */
+struct llx *llx_find (const struct llx *r0, const struct llx *r1,
+                      const void *target);
 struct llx *llx_find_equal (const struct llx *r0, const struct llx *r1,
                             const void *target,
                             llx_compare_func *, void *aux);
index 2befd51a4451c899f18fac5a23146444ba9d35a2..f8fe9b73618578f50f8dad56f18a3c261122b3f3 100644 (file)
@@ -1,5 +1,5 @@
 /* PSPP - a program for statistical analysis.
-   Copyright (C) 2006 Free Software Foundation, Inc.
+   Copyright (C) 2006, 2010 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -865,6 +865,34 @@ test_find_equal (void)
   test_examine_equal_range (test_find_equal_helper);
 }
 
+/* Tests llx_find(). */
+static void
+test_find (void)
+{
+  const int max_elems = 8;
+
+  int cnt;
+
+  for (cnt = 0; cnt <= max_elems; cnt++)
+    {
+      struct llx_list list;
+      struct element **elems;
+      struct llx **elemp;
+      int *values;
+
+      int i;
+
+      allocate_ascending (cnt, &list, &elems, &elemp, &values);
+
+      for (i = 0; i < cnt; i++)
+        check (llx_find (llx_head (&list), llx_null (&list), elems[i])
+               == elemp[i]);
+      check (llx_find (llx_head (&list), llx_null (&list), NULL) == NULL);
+
+      free_elements (cnt, &list, elems, elemp, values);
+    }
+}
+
 /* Helper function for testing llx_find_if. */
 static void
 test_find_if_helper (int r0, int r1, int eq_pat, struct llx **elemp)
@@ -2040,6 +2068,7 @@ main (void)
   run_test (test_remove_equal, "remove_equal");
   run_test (test_remove_if, "remove_if");
   run_test (test_find_equal, "find_equal");
+  run_test (test_find, "find");
   run_test (test_find_if, "find_if");
   run_test (test_find_adjacent_equal, "find_adjacent_equal");
   run_test (test_count_range, "count_range");