diff options
| author | Simon Glass <sjg@chromium.org> | 2013-05-07 06:11:50 +0000 | 
|---|---|---|
| committer | Tom Rini <trini@ti.com> | 2013-05-14 15:37:25 -0400 | 
| commit | 88f95bbadda89bfaf6a8e817bb66fd114afc1caf (patch) | |
| tree | 17a3c26a6ef0df9a2469c55848a3949bebd3b3d8 | |
| parent | 816cb037adf94ead77593812ccd3244d506175fa (diff) | |
| download | olio-uboot-2014.01-88f95bbadda89bfaf6a8e817bb66fd114afc1caf.tar.xz olio-uboot-2014.01-88f95bbadda89bfaf6a8e817bb66fd114afc1caf.zip | |
libfdt: Add fdt_next_subnode() to permit easy subnode iteration
Iterating through subnodes with libfdt is a little painful to write as we
need something like this:
for (depth = 0, count = 0,
	offset = fdt_next_node(fdt, parent_offset, &depth);
     (offset >= 0) && (depth > 0);
     offset = fdt_next_node(fdt, offset, &depth)) {
	if (depth == 1) {
		/* code body */
	}
}
Using fdt_next_subnode() we can instead write this, which is shorter and
easier to get right:
for (offset = fdt_first_subnode(fdt, parent_offset);
     offset >= 0;
     offset = fdt_next_subnode(fdt, offset)) {
	/* code body */
}
Also, it doesn't require two levels of indentation for the loop body.
Signed-off-by: Simon Glass <sjg@chromium.org>
(Cherry-picked from dtc commit 4e76ec79)
Acked-by: Gerald Van Baren <vanbaren@cideas.com>
| -rw-r--r-- | include/libfdt.h | 22 | ||||
| -rw-r--r-- | lib/libfdt/fdt.c | 28 | 
2 files changed, 50 insertions, 0 deletions
| diff --git a/include/libfdt.h b/include/libfdt.h index 7403d5a6d..c5ec2acfd 100644 --- a/include/libfdt.h +++ b/include/libfdt.h @@ -136,6 +136,28 @@ uint32_t fdt_next_tag(const void *fdt, int offset, int *nextoffset);  int fdt_next_node(const void *fdt, int offset, int *depth); +/** + * fdt_first_subnode() - get offset of first direct subnode + * + * @fdt:	FDT blob + * @offset:	Offset of node to check + * @return offset of first subnode, or -FDT_ERR_NOTFOUND if there is none + */ +int fdt_first_subnode(const void *fdt, int offset); + +/** + * fdt_next_subnode() - get offset of next direct subnode + * + * After first calling fdt_first_subnode(), call this function repeatedly to + * get direct subnodes of a parent node. + * + * @fdt:	FDT blob + * @offset:	Offset of previous subnode + * @return offset of next subnode, or -FDT_ERR_NOTFOUND if there are no more + * subnodes + */ +int fdt_next_subnode(const void *fdt, int offset); +  /**********************************************************************/  /* General functions                                                  */  /**********************************************************************/ diff --git a/lib/libfdt/fdt.c b/lib/libfdt/fdt.c index 387e3544b..154e9a446 100644 --- a/lib/libfdt/fdt.c +++ b/lib/libfdt/fdt.c @@ -202,6 +202,34 @@ int fdt_next_node(const void *fdt, int offset, int *depth)  	return offset;  } +int fdt_first_subnode(const void *fdt, int offset) +{ +	int depth = 0; + +	offset = fdt_next_node(fdt, offset, &depth); +	if (offset < 0 || depth != 1) +		return -FDT_ERR_NOTFOUND; + +	return offset; +} + +int fdt_next_subnode(const void *fdt, int offset) +{ +	int depth = 1; + +	/* +	 * With respect to the parent, the depth of the next subnode will be +	 * the same as the last. +	 */ +	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; |