layout: Introduce layout_next()

Also, a `layout.c` internal version mutable_layout_next() that
allows to modify layout entries.

Use the new functions where applicable and the code is not
dropped later in this train, and also to compare the layouts
in flashrom_layout_read_from_ifd() in depth.

flashrom-stable: Dropped _layout_entry_by_name()

Change-Id: I284958471c61344d29d92c95d88475065a9ca9aa
Signed-off-by: Nico Huber <nico.h@gmx.de>
Original-Reviewed-on: https://review.coreboot.org/c/flashrom/+/33542
Original-Reviewed-by: Angel Pons <th3fanbus@gmail.com>
Original-Reviewed-by: Anastasia Klimchuk <aklm@chromium.org>
Original-Reviewed-by: Peter Marheine <pmarheine@chromium.org>
Original-Reviewed-by: Edward O'Callaghan <quasisec@chromium.org>
Reviewed-on: https://review.coreboot.org/c/flashrom-stable/+/72211
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
diff --git a/layout.c b/layout.c
index 880a416..a604a7b 100644
--- a/layout.c
+++ b/layout.c
@@ -40,6 +40,21 @@
 		return &flashctx->fallback_layout.base;
 }
 
+static struct romentry *mutable_layout_next(
+		const struct flashrom_layout *const layout, struct romentry *iterator)
+{
+	const struct romentry *const end = layout->entries + layout->num_entries;
+
+	if (iterator)
+		++iterator;
+	else
+		iterator = &layout->entries[0];
+
+	if (iterator < end)
+		return iterator;
+	return NULL;
+}
+
 #ifndef __LIBPAYLOAD__
 int read_romlayout(const char *name)
 {
@@ -217,17 +232,17 @@
 	chipsize_t total_size = flash->chip->total_size * 1024;
 	int ret = 0;
 
-	unsigned int i;
-	for (i = 0; i < layout->num_entries; i++) {
-		if (layout->entries[i].start >= total_size || layout->entries[i].end >= total_size) {
-			msg_gwarn("Warning: Address range of region \"%s\" exceeds the current chip's "
-				  "address space.\n", layout->entries[i].name);
-			if (layout->entries[i].included)
+	const struct romentry *entry = NULL;
+	while ((entry = layout_next(layout, entry))) {
+		if (entry->start >= total_size || entry->end >= total_size) {
+			msg_gwarn("Warning: Address range of region \"%s\" "
+				  "exceeds the current chip's address space.\n", entry->name);
+			if (entry->included)
 				ret = 1;
 		}
-		if (layout->entries[i].start > layout->entries[i].end) {
+		if (entry->start > entry->end) {
 			msg_gerr("Error: Size of the address range of region \"%s\" is not positive.\n",
-				  layout->entries[i].name);
+				  entry->name);
 			ret = 1;
 		}
 	}
@@ -238,16 +253,15 @@
 const struct romentry *layout_next_included_region(
 		const struct flashrom_layout *const l, const chipoff_t where)
 {
-	unsigned int i;
-	const struct romentry *lowest = NULL;
+	const struct romentry *entry = NULL, *lowest = NULL;
 
-	for (i = 0; i < l->num_entries; ++i) {
-		if (!l->entries[i].included)
+	while ((entry = layout_next(l, entry))) {
+		if (!entry->included)
 			continue;
-		if (l->entries[i].end < where)
+		if (entry->end < where)
 			continue;
-		if (!lowest || lowest->start > l->entries[i].start)
-			lowest = &l->entries[i];
+		if (!lowest || lowest->start > entry->start)
+			lowest = entry;
 	}
 
 	return lowest;
@@ -256,19 +270,17 @@
 const struct romentry *layout_next_included(
 		const struct flashrom_layout *const layout, const struct romentry *iterator)
 {
-	const struct romentry *const end = layout->entries + layout->num_entries;
-
-	if (iterator)
-		++iterator;
-	else
-		iterator = &layout->entries[0];
-
-	for (; iterator < end; ++iterator) {
-		if (!iterator->included)
-			continue;
-		return iterator;
+	while ((iterator = layout_next(layout, iterator))) {
+		if (iterator->included)
+			break;
 	}
-	return NULL;
+	return iterator;
+}
+
+const struct romentry *layout_next(
+		const struct flashrom_layout *const layout, const struct romentry *iterator)
+{
+	return mutable_layout_next(layout, (struct romentry *)iterator);
 }
 
 /**
@@ -287,10 +299,10 @@
  */
 int flashrom_layout_include_region(struct flashrom_layout *const layout, const char *name)
 {
-	size_t i;
-	for (i = 0; i < layout->num_entries; ++i) {
-		if (!strcmp(layout->entries[i].name, name)) {
-			layout->entries[i].included = true;
+	struct romentry *entry = NULL;
+	while ((entry = mutable_layout_next(layout, entry))) {
+		if (!strcmp(entry->name, name)) {
+			entry->included = true;
 			return 0;
 		}
 	}
diff --git a/layout.h b/layout.h
index cceedd1..65a49ad 100644
--- a/layout.h
+++ b/layout.h
@@ -66,5 +66,6 @@
 int process_include_args(struct flashrom_layout *l, const struct layout_include_args *const args);
 const struct romentry *layout_next_included_region(const struct flashrom_layout *, chipoff_t);
 const struct romentry *layout_next_included(const struct flashrom_layout *, const struct romentry *);
+const struct romentry *layout_next(const struct flashrom_layout *, const struct romentry *);
 
 #endif /* !__LAYOUT_H__ */
diff --git a/libflashrom.c b/libflashrom.c
index fd3648f..e390a02 100644
--- a/libflashrom.c
+++ b/libflashrom.c
@@ -351,8 +351,13 @@
 			goto _finalize_ret;
 		}
 
-		if (chip_layout->base.num_entries != dump_layout.base.num_entries ||
-		    memcmp(chip_layout->entries, dump_layout.entries, sizeof(dump_layout.entries))) {
+		const struct romentry *chip_entry = layout_next(&chip_layout->base, NULL);
+		const struct romentry *dump_entry = layout_next(&dump_layout.base, NULL);
+		while (chip_entry && dump_entry && !memcmp(chip_entry, dump_entry, sizeof(*chip_entry))) {
+			chip_entry = layout_next(&chip_layout->base, chip_entry);
+			dump_entry = layout_next(&dump_layout.base, dump_entry);
+		}
+		if (chip_entry || dump_entry) {
 			msg_cerr("Descriptors don't match!\n");
 			ret = 5;
 			goto _finalize_ret;