]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[list] Add list_for_each_entry_continue() and _continue_reverse()
authorMichael Brown <mcb30@ipxe.org>
Fri, 4 May 2012 14:12:22 +0000 (15:12 +0100)
committerMichael Brown <mcb30@ipxe.org>
Fri, 4 May 2012 14:15:34 +0000 (15:15 +0100)
Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/include/ipxe/list.h
src/tests/list_test.c

index 231383d19109d08e70081cef3486f74aefb7fca1..4daf12b2e0282d2b914d8e35aab359aaeec1f594 100644 (file)
@@ -378,6 +378,32 @@ static inline void list_splice_tail_init ( struct list_head *list,
              pos = tmp,                                                      \
              tmp = list_entry ( tmp->member.next, typeof ( *tmp ), member ) )
 
+/**
+ * Iterate over entries in a list, starting after current position
+ *
+ * @v pos              Iterator
+ * @v head             List head
+ * @v member           Name of list field within iterator's type
+ */
+#define list_for_each_entry_continue( pos, head, member )                    \
+       for ( list_check ( (head) ),                                          \
+             pos = list_entry ( pos->member.next, typeof ( *pos ), member ); \
+             &pos->member != (head);                                         \
+             pos = list_entry ( pos->member.next, typeof ( *pos ), member ) )
+
+/**
+ * Iterate over entries in a list in reverse, starting after current position
+ *
+ * @v pos              Iterator
+ * @v head             List head
+ * @v member           Name of list field within iterator's type
+ */
+#define list_for_each_entry_continue_reverse( pos, head, member )            \
+       for ( list_check ( (head) ),                                          \
+             pos = list_entry ( pos->member.prev, typeof ( *pos ), member ); \
+             &pos->member != (head);                                         \
+             pos = list_entry ( pos->member.prev, typeof ( *pos ), member ) )
+
 /**
  * Test if list contains a specified entry
  *
index d75f8324230d53bd9f3ce0b3b5ce31589af0cc08..39698553dc85c596c71d2c4a8c3db5324f0b2870 100644 (file)
@@ -118,6 +118,41 @@ static int list_check_contents ( struct list_head *list,
        ok ( list_check_contents ( (list), (expected) ) );      \
        } while ( 0 )
 
+/**
+ * Report list iteration test result
+ *
+ * @v macro            Iterator macro
+ * @v expected         Expected contents
+ * @v pos              Iterator
+ * @v ...              Arguments to iterator macro
+ */
+#define list_iterate_ok( macro, expected, pos, ... ) do {      \
+       const char *check = expected;                           \
+       macro ( pos, __VA_ARGS__ ) {                            \
+               struct list_test *entry =                       \
+                       list_entry ( pos, struct list_test,     \
+                                    list );                    \
+               ok ( entry->label == *(check++) );              \
+       }                                                       \
+       ok ( *check == '\0' );                                  \
+       } while ( 0 )
+
+/**
+ * Report list entry iteration test result
+ *
+ * @v macro            Iterator macro
+ * @v expected         Expected contents
+ * @v pos              Iterator
+ * @v ...              Arguments to iterator macro
+ */
+#define list_iterate_entry_ok( macro, expected, pos, ... ) do {        \
+       const char *check = expected;                           \
+       macro ( pos, __VA_ARGS__ ) {                            \
+               ok ( (pos)->label == *(check++) );              \
+       }                                                       \
+       ok ( *check == '\0' );                                  \
+       } while ( 0 )
+
 /**
  * Perform list self-test
  *
@@ -126,6 +161,9 @@ static void list_test_exec ( void ) {
        struct list_head *list = &test_list;
        struct list_head target_list;
        struct list_head *target = &target_list;
+       struct list_head *raw_pos;
+       struct list_test *pos;
+       struct list_test *tmp;
 
        /* Test initialiser and list_empty() */
        ok ( list_empty ( list ) );
@@ -346,19 +384,18 @@ static void list_test_exec ( void ) {
        list_add_tail ( &list_tests[6].list, list );
        list_add_tail ( &list_tests[7].list, list );
        list_add_tail ( &list_tests[3].list, list );
-       {
-               char *expected = "673";
-               struct list_head *pos;
-               struct list_test *entry;
-               list_for_each ( pos, list ) {
-                       entry = list_entry ( pos, struct list_test, list );
-                       ok ( entry->label == *(expected++) );
-               }
-       }
+       list_iterate_ok ( list_for_each, "673", raw_pos, list );
 
-       /* list_for_each_entry() and list_for_each_entry_reverse() are
-        * already tested as part of list_contents_ok()
-        */
+       /* Test list_for_each_entry() and list_for_each_entry_reverse() */
+       INIT_LIST_HEAD ( list );
+       list_add_tail ( &list_tests[3].list, list );
+       list_add_tail ( &list_tests[2].list, list );
+       list_add_tail ( &list_tests[6].list, list );
+       list_add_tail ( &list_tests[9].list, list );
+       list_iterate_entry_ok ( list_for_each_entry, "3269",
+                               pos, list, list );
+       list_iterate_entry_ok ( list_for_each_entry_reverse, "9623",
+                               pos, list, list );
 
        /* Test list_for_each_entry_safe() */
        INIT_LIST_HEAD ( list );
@@ -367,8 +404,6 @@ static void list_test_exec ( void ) {
        list_add_tail ( &list_tests[1].list, list );
        {
                char *expected = "241";
-               struct list_test *pos;
-               struct list_test *tmp;
                list_for_each_entry_safe ( pos, tmp, list, list ) {
                        list_contents_ok ( list, expected );
                        list_del ( &pos->list );
@@ -378,6 +413,34 @@ static void list_test_exec ( void ) {
        }
        ok ( list_empty ( list ) );
 
+       /* Test list_for_each_entry_continue() and
+        * list_for_each_entry_continue_reverse()
+        */
+       INIT_LIST_HEAD ( list );
+       list_add_tail ( &list_tests[4].list, list );
+       list_add_tail ( &list_tests[7].list, list );
+       list_add_tail ( &list_tests[2].list, list );
+       list_add_tail ( &list_tests[9].list, list );
+       list_add_tail ( &list_tests[3].list, list );
+       pos = &list_tests[7];
+       list_iterate_entry_ok ( list_for_each_entry_continue, "293",
+                               pos, list, list );
+       pos = list_entry ( list, struct list_test, list );
+       list_iterate_entry_ok ( list_for_each_entry_continue, "47293",
+                               pos, list, list );
+       pos = &list_tests[3];
+       list_iterate_entry_ok ( list_for_each_entry_continue, "",
+                               pos, list, list );
+       pos = &list_tests[2];
+       list_iterate_entry_ok ( list_for_each_entry_continue_reverse, "74",
+                               pos, list, list );
+       pos = list_entry ( list, struct list_test, list );
+       list_iterate_entry_ok ( list_for_each_entry_continue_reverse, "39274",
+                               pos, list, list );
+       pos = &list_tests[4];
+       list_iterate_entry_ok ( list_for_each_entry_continue_reverse, "",
+                               pos, list, list );
+
        /* Test list_contains() and list_contains_entry() */
        INIT_LIST_HEAD ( list );
        INIT_LIST_HEAD ( &list_tests[3].list );