Browse Source

[list] Add list_next_entry() and list_prev_entry()

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 7 years ago
parent
commit
161c80af5b
2 changed files with 51 additions and 0 deletions
  1. 28
    0
      src/include/ipxe/list.h
  2. 23
    0
      src/tests/list_test.c

+ 28
- 0
src/include/ipxe/list.h View File

@@ -348,6 +348,34 @@ extern void extern_list_splice_tail_init ( struct list_head *list,
348 348
 	  ( type * ) NULL :					\
349 349
 	  list_entry ( (list)->prev, type, member ) )
350 350
 
351
+/**
352
+ * Get the container of the next entry in a list
353
+ *
354
+ * @v pos		Current list entry
355
+ * @v head		List head
356
+ * @v member		Name of list field within iterator's type
357
+ * @ret next		Next list entry, or NULL at end of list
358
+ */
359
+#define list_next_entry( pos, head, member ) ( {		\
360
+	typeof (pos) next = list_entry ( (pos)->member.next,	\
361
+					 typeof ( *(pos) ),	\
362
+					 member );		\
363
+	( ( &next->member == (head) ) ? NULL : next ); } )
364
+
365
+/**
366
+ * Get the container of the previous entry in a list
367
+ *
368
+ * @v pos		Current list entry
369
+ * @v head		List head
370
+ * @v member		Name of list field within iterator's type
371
+ * @ret next		Next list entry, or NULL at end of list
372
+ */
373
+#define list_prev_entry( pos, head, member ) ( {		\
374
+	typeof (pos) prev = list_entry ( (pos)->member.prev,	\
375
+					 typeof ( *(pos) ),	\
376
+					 member );		\
377
+	( ( &prev->member == (head) ) ? NULL : prev ); } )
378
+
351 379
 /**
352 380
  * Iterate over a list
353 381
  *

+ 23
- 0
src/tests/list_test.c View File

@@ -396,6 +396,29 @@ static void list_test_exec ( void ) {
396 396
 	ok ( list_first_entry ( list, struct list_test, list ) == NULL );
397 397
 	ok ( list_last_entry ( list, struct list_test, list ) == NULL );
398 398
 
399
+	/* Test list_next_entry() and list_prev_entry() */
400
+	INIT_LIST_HEAD ( list );
401
+	list_add_tail ( &list_tests[5].list, list );
402
+	list_add_tail ( &list_tests[3].list, list );
403
+	list_add_tail ( &list_tests[1].list, list );
404
+	list_add_tail ( &list_tests[7].list, list );
405
+	ok ( list_prev_entry ( &list_tests[5], list, list ) == NULL );
406
+	ok ( list_next_entry ( &list_tests[5], list, list ) == &list_tests[3] );
407
+	ok ( list_prev_entry ( &list_tests[3], list, list ) == &list_tests[5] );
408
+	ok ( list_next_entry ( &list_tests[3], list, list ) == &list_tests[1] );
409
+	ok ( list_prev_entry ( &list_tests[1], list, list ) == &list_tests[3] );
410
+	ok ( list_next_entry ( &list_tests[1], list, list ) == &list_tests[7] );
411
+	ok ( list_prev_entry ( &list_tests[7], list, list ) == &list_tests[1] );
412
+	ok ( list_next_entry ( &list_tests[7], list, list ) == NULL );
413
+	list_del ( &list_tests[7].list );
414
+	ok ( list_prev_entry ( &list_tests[1], list, list ) == &list_tests[3] );
415
+	ok ( list_next_entry ( &list_tests[1], list, list ) == NULL );
416
+	list_del ( &list_tests[3].list );
417
+	ok ( list_prev_entry ( &list_tests[5], list, list ) == NULL );
418
+	ok ( list_next_entry ( &list_tests[5], list, list ) == &list_tests[1] );
419
+	ok ( list_prev_entry ( &list_tests[1], list, list ) == &list_tests[5] );
420
+	ok ( list_next_entry ( &list_tests[1], list, list ) == NULL );
421
+
399 422
 	/* Test list_for_each() */
400 423
 	INIT_LIST_HEAD ( list );
401 424
 	list_add_tail ( &list_tests[6].list, list );

Loading…
Cancel
Save