[U-Boot] [RFC PATCH 04/44] libfdt: Add fdt_next_subnode() to permit easy subnode iteration

Simon Glass
2013-01-05T01:51:33Z

This allows use to replace code like this:

for (ndepth = 0, count = 0,
noffset = fdt_next_node(fit, images_noffset, &ndepth);
(noffset >= 0) && (ndepth > 0);
noffset = fdt_next_node(fit, noffset, &ndepth)) {
if (ndepth == 1)
...

with:

for (ndepth = 0,
noffset = fdt_next_subnode(fit, image_noffset, &ndepth);
noffset >= 0;
noffset = fdt_next_subnode(fit, noffset, &ndepth)) {

which is slightly better, and doesn't require two levels of indentation for
code in the loop.

Signed-off-by: Simon Glass <sjg@chromium.org>
---
include/libfdt.h | 17 +++++++++++++++++
lib/libfdt/fdt.c | 12 ++++++++++++
2 files changed, 29 insertions(+), 0 deletions(-)

diff --git a/include/libfdt.h b/include/libfdt.h
index c93ae28..0dfb8a0 100644
--- a/include/libfdt.h
+++ b/include/libfdt.h
@@ -136,6 +136,23 @@ uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset);

int fdt_next_node(const void *fdt, int offset, int *depth);

+/**
+ * fdt_next_subnode() - get offset of next direct child
+ *
+ * Set depth to 0, offset to parent, then call this function repeatedly
+ * to get direct subnodes of a parent node.
+ *
+ * @fdt: FDT blob
+ * @offset: Set this to offset of parent for the first call. For
+ * subsquent calls, pass in the value returns from the last
+ * call.
+ * @depth: Used internally to monitor depth - set this to 0 for the
+ * first call.
+ * @return offset of next subnode, or -FDT_ERR_NOTFOUND if there are no more
+ * children
+ */
+int fdt_next_subnode(const void *fdt, int offset, int *depth);
+
/**********************************************************************/
/* General functions */
/**********************************************************************/
diff --git a/lib/libfdt/fdt.c b/lib/libfdt/fdt.c
index 4157b21..8a0f323 100644
--- a/lib/libfdt/fdt.c
+++ b/lib/libfdt/fdt.c
@@ -202,6 +202,18 @@ int fdt_next_node(const void *fdt, int offset, int *depth)
return offset;
}

+int fdt_next_subnode(const void *fdt, int offset, int *depth)
+{
+ /* Loop until we find a direct child of the parent (depth == 1) */
+ do {
+ offset = fdt_next_node(fdt, offset, depth);
+ if (offset < 0 || *depth < 1)
+ return -FDT_ERR_NOTFOUND;
+ } while (*depth > 1);
+
+ return offset;
+}
+
const char *_fdt_find_string(const char *strtab, int tabsize, const char *s)
{
int len = strlen(s) + 1;
--
1.7.7.3