Browse Source

[list] Add list_last_entry()

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 12 years ago
parent
commit
6ba7fb7c5c
2 changed files with 26 additions and 1 deletions
  1. 13
    0
      src/include/ipxe/list.h
  2. 13
    1
      src/tests/list_test.c

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

324
 	  ( type * ) NULL :				\
324
 	  ( type * ) NULL :				\
325
 	  list_entry ( (list)->next, type, member ) )
325
 	  list_entry ( (list)->next, type, member ) )
326
 
326
 
327
+/**
328
+ * Get the container of the last entry in a list
329
+ *
330
+ * @v list		List head
331
+ * @v type		Containing type
332
+ * @v member		Name of list field within containing type
333
+ * @ret first		First list entry, or NULL
334
+ */
335
+#define list_last_entry( list, type, member )		\
336
+	( list_empty ( (list) ) ?			\
337
+	  ( type * ) NULL :				\
338
+	  list_entry ( (list)->prev, type, member ) )
339
+
327
 /**
340
 /**
328
  * Iterate over a list
341
  * Iterate over a list
329
  *
342
  *

+ 13
- 1
src/tests/list_test.c View File

368
 	ok ( list_entry ( &list_tests[3].list, struct list_test, list )
368
 	ok ( list_entry ( &list_tests[3].list, struct list_test, list )
369
 	     == &list_tests[3] );
369
 	     == &list_tests[3] );
370
 
370
 
371
-	/* Test list_first_entry() */
371
+	/* Test list_first_entry() and list_last_entry() */
372
 	INIT_LIST_HEAD ( list );
372
 	INIT_LIST_HEAD ( list );
373
 	list_add_tail ( &list_tests[9].list, list );
373
 	list_add_tail ( &list_tests[9].list, list );
374
 	list_add_tail ( &list_tests[5].list, list );
374
 	list_add_tail ( &list_tests[5].list, list );
375
 	list_add_tail ( &list_tests[6].list, list );
375
 	list_add_tail ( &list_tests[6].list, list );
376
 	ok ( list_first_entry ( list, struct list_test, list )
376
 	ok ( list_first_entry ( list, struct list_test, list )
377
 	     == &list_tests[9] );
377
 	     == &list_tests[9] );
378
+	ok ( list_last_entry ( list, struct list_test, list )
379
+	     == &list_tests[6] );
378
 	list_del ( &list_tests[9].list );
380
 	list_del ( &list_tests[9].list );
379
 	ok ( list_first_entry ( list, struct list_test, list )
381
 	ok ( list_first_entry ( list, struct list_test, list )
380
 	     == &list_tests[5] );
382
 	     == &list_tests[5] );
383
+	ok ( list_last_entry ( list, struct list_test, list )
384
+	     == &list_tests[6] );
385
+	list_del ( &list_tests[6].list );
386
+	ok ( list_first_entry ( list, struct list_test, list )
387
+	     == &list_tests[5] );
388
+	ok ( list_last_entry ( list, struct list_test, list )
389
+	     == &list_tests[5] );
390
+	list_del ( &list_tests[5].list );
391
+	ok ( list_first_entry ( list, struct list_test, list ) == NULL );
392
+	ok ( list_last_entry ( list, struct list_test, list ) == NULL );
381
 
393
 
382
 	/* Test list_for_each() */
394
 	/* Test list_for_each() */
383
 	INIT_LIST_HEAD ( list );
395
 	INIT_LIST_HEAD ( list );

Loading…
Cancel
Save