Przeglądaj źródła

[list] Add list_for_each_entry_continue() and _continue_reverse()

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 12 lat temu
rodzic
commit
f91995f193
2 zmienionych plików z 103 dodań i 14 usunięć
  1. 26
    0
      src/include/ipxe/list.h
  2. 77
    14
      src/tests/list_test.c

+ 26
- 0
src/include/ipxe/list.h Wyświetl plik

@@ -378,6 +378,32 @@ static inline void list_splice_tail_init ( struct list_head *list,
378 378
 	      pos = tmp,						      \
379 379
 	      tmp = list_entry ( tmp->member.next, typeof ( *tmp ), member ) )
380 380
 
381
+/**
382
+ * Iterate over entries in a list, starting after current position
383
+ *
384
+ * @v pos		Iterator
385
+ * @v head		List head
386
+ * @v member		Name of list field within iterator's type
387
+ */
388
+#define list_for_each_entry_continue( pos, head, member )		      \
389
+	for ( list_check ( (head) ),					      \
390
+	      pos = list_entry ( pos->member.next, typeof ( *pos ), member ); \
391
+	      &pos->member != (head);					      \
392
+	      pos = list_entry ( pos->member.next, typeof ( *pos ), member ) )
393
+
394
+/**
395
+ * Iterate over entries in a list in reverse, starting after current position
396
+ *
397
+ * @v pos		Iterator
398
+ * @v head		List head
399
+ * @v member		Name of list field within iterator's type
400
+ */
401
+#define list_for_each_entry_continue_reverse( pos, head, member )	      \
402
+	for ( list_check ( (head) ),					      \
403
+	      pos = list_entry ( pos->member.prev, typeof ( *pos ), member ); \
404
+	      &pos->member != (head);					      \
405
+	      pos = list_entry ( pos->member.prev, typeof ( *pos ), member ) )
406
+
381 407
 /**
382 408
  * Test if list contains a specified entry
383 409
  *

+ 77
- 14
src/tests/list_test.c Wyświetl plik

@@ -118,6 +118,41 @@ static int list_check_contents ( struct list_head *list,
118 118
 	ok ( list_check_contents ( (list), (expected) ) );	\
119 119
 	} while ( 0 )
120 120
 
121
+/**
122
+ * Report list iteration test result
123
+ *
124
+ * @v macro		Iterator macro
125
+ * @v expected		Expected contents
126
+ * @v pos		Iterator
127
+ * @v ...		Arguments to iterator macro
128
+ */
129
+#define list_iterate_ok( macro, expected, pos, ... ) do {	\
130
+	const char *check = expected;				\
131
+	macro ( pos, __VA_ARGS__ ) {				\
132
+		struct list_test *entry =			\
133
+			list_entry ( pos, struct list_test,	\
134
+				     list );			\
135
+		ok ( entry->label == *(check++) );		\
136
+	}							\
137
+	ok ( *check == '\0' );					\
138
+	} while ( 0 )
139
+
140
+/**
141
+ * Report list entry iteration test result
142
+ *
143
+ * @v macro		Iterator macro
144
+ * @v expected		Expected contents
145
+ * @v pos		Iterator
146
+ * @v ...		Arguments to iterator macro
147
+ */
148
+#define list_iterate_entry_ok( macro, expected, pos, ... ) do {	\
149
+	const char *check = expected;				\
150
+	macro ( pos, __VA_ARGS__ ) {				\
151
+		ok ( (pos)->label == *(check++) );		\
152
+	}							\
153
+	ok ( *check == '\0' );					\
154
+	} while ( 0 )
155
+
121 156
 /**
122 157
  * Perform list self-test
123 158
  *
@@ -126,6 +161,9 @@ static void list_test_exec ( void ) {
126 161
 	struct list_head *list = &test_list;
127 162
 	struct list_head target_list;
128 163
 	struct list_head *target = &target_list;
164
+	struct list_head *raw_pos;
165
+	struct list_test *pos;
166
+	struct list_test *tmp;
129 167
 
130 168
 	/* Test initialiser and list_empty() */
131 169
 	ok ( list_empty ( list ) );
@@ -346,19 +384,18 @@ static void list_test_exec ( void ) {
346 384
 	list_add_tail ( &list_tests[6].list, list );
347 385
 	list_add_tail ( &list_tests[7].list, list );
348 386
 	list_add_tail ( &list_tests[3].list, list );
349
-	{
350
-		char *expected = "673";
351
-		struct list_head *pos;
352
-		struct list_test *entry;
353
-		list_for_each ( pos, list ) {
354
-			entry = list_entry ( pos, struct list_test, list );
355
-			ok ( entry->label == *(expected++) );
356
-		}
357
-	}
387
+	list_iterate_ok ( list_for_each, "673", raw_pos, list );
358 388
 
359
-	/* list_for_each_entry() and list_for_each_entry_reverse() are
360
-	 * already tested as part of list_contents_ok()
361
-	 */
389
+	/* Test list_for_each_entry() and list_for_each_entry_reverse() */
390
+	INIT_LIST_HEAD ( list );
391
+	list_add_tail ( &list_tests[3].list, list );
392
+	list_add_tail ( &list_tests[2].list, list );
393
+	list_add_tail ( &list_tests[6].list, list );
394
+	list_add_tail ( &list_tests[9].list, list );
395
+	list_iterate_entry_ok ( list_for_each_entry, "3269",
396
+				pos, list, list );
397
+	list_iterate_entry_ok ( list_for_each_entry_reverse, "9623",
398
+				pos, list, list );
362 399
 
363 400
 	/* Test list_for_each_entry_safe() */
364 401
 	INIT_LIST_HEAD ( list );
@@ -367,8 +404,6 @@ static void list_test_exec ( void ) {
367 404
 	list_add_tail ( &list_tests[1].list, list );
368 405
 	{
369 406
 		char *expected = "241";
370
-		struct list_test *pos;
371
-		struct list_test *tmp;
372 407
 		list_for_each_entry_safe ( pos, tmp, list, list ) {
373 408
 			list_contents_ok ( list, expected );
374 409
 			list_del ( &pos->list );
@@ -378,6 +413,34 @@ static void list_test_exec ( void ) {
378 413
 	}
379 414
 	ok ( list_empty ( list ) );
380 415
 
416
+	/* Test list_for_each_entry_continue() and
417
+	 * list_for_each_entry_continue_reverse()
418
+	 */
419
+	INIT_LIST_HEAD ( list );
420
+	list_add_tail ( &list_tests[4].list, list );
421
+	list_add_tail ( &list_tests[7].list, list );
422
+	list_add_tail ( &list_tests[2].list, list );
423
+	list_add_tail ( &list_tests[9].list, list );
424
+	list_add_tail ( &list_tests[3].list, list );
425
+	pos = &list_tests[7];
426
+	list_iterate_entry_ok ( list_for_each_entry_continue, "293",
427
+				pos, list, list );
428
+	pos = list_entry ( list, struct list_test, list );
429
+	list_iterate_entry_ok ( list_for_each_entry_continue, "47293",
430
+				pos, list, list );
431
+	pos = &list_tests[3];
432
+	list_iterate_entry_ok ( list_for_each_entry_continue, "",
433
+				pos, list, list );
434
+	pos = &list_tests[2];
435
+	list_iterate_entry_ok ( list_for_each_entry_continue_reverse, "74",
436
+				pos, list, list );
437
+	pos = list_entry ( list, struct list_test, list );
438
+	list_iterate_entry_ok ( list_for_each_entry_continue_reverse, "39274",
439
+				pos, list, list );
440
+	pos = &list_tests[4];
441
+	list_iterate_entry_ok ( list_for_each_entry_continue_reverse, "",
442
+				pos, list, list );
443
+
381 444
 	/* Test list_contains() and list_contains_entry() */
382 445
 	INIT_LIST_HEAD ( list );
383 446
 	INIT_LIST_HEAD ( &list_tests[3].list );

Ładowanie…
Anuluj
Zapisz