Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[list] Add list_for_each_entry_continue() and _continue_reverse()
Signed-off-by: Michael Brown <mcb30@ipxe.org>
  • Loading branch information
mcb30 committed May 4, 2012
1 parent 69fa290 commit f91995f
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 14 deletions.
26 changes: 26 additions & 0 deletions src/include/ipxe/list.h
Expand Up @@ -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
*
Expand Down
91 changes: 77 additions & 14 deletions src/tests/list_test.c
Expand Up @@ -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
*
Expand All @@ -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 ) );
Expand Down Expand Up @@ -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 );
Expand All @@ -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 );
Expand All @@ -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 );
Expand Down

0 comments on commit f91995f

Please sign in to comment.