From mboxrd@z Thu Jan 1 00:00:00 1970 From: Simon Glass Subject: [PATCH 3/4] fdtget: Add -l to list the children of a node Date: Fri, 2 Mar 2012 17:12:09 -0800 Message-ID: <1330737130-29600-3-git-send-email-sjg@chromium.org> References: <1330737130-29600-1-git-send-email-sjg@chromium.org> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Return-path: In-Reply-To: <1330737130-29600-1-git-send-email-sjg-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: devicetree-discuss-bounces+gldd-devicetree-discuss=m.gmane.org-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org Sender: devicetree-discuss-bounces+gldd-devicetree-discuss=m.gmane.org-uLR06cmDAlY/bJ5BZ2RsiQ@public.gmane.org To: Devicetree Discuss List-Id: devicetree@vger.kernel.org This option lists the children of each node given as a parameter, one child per line. Signed-off-by: Simon Glass --- fdtget.c | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 files changed, 84 insertions(+), 12 deletions(-) diff --git a/fdtget.c b/fdtget.c index 874bcbf..9ed5edd 100644 --- a/fdtget.c +++ b/fdtget.c @@ -37,6 +37,7 @@ enum display_mode { MODE_SHOW_VALUE, /* show values for node properties */ MODE_LIST_PROPS, /* list the properties for a node */ + MODE_LIST_CHILDREN, /* list the children of a node */ }; /* Holds information which controls our output and options */ @@ -136,6 +137,61 @@ static int list_properties(const void *blob, int node) } while (1); } +#define MAX_LEVEL 32 /* how deeply nested we will go */ + +/** + * List all children in a node, one per line + * + * @param blob FDT blob + * @param node Node to display + * @return 0 if ok, or FDT_ERR... if not. + */ +static int list_children(const void *blob, int node) +{ + int nextoffset; /* next node offset from libfdt */ + uint32_t tag; /* current tag */ + int level = 0; /* keep track of nesting level */ + const char *pathp; + int depth = 1; /* the assumed depth of this node */ + + while (level >= 0) { + tag = fdt_next_tag(blob, node, &nextoffset); + switch (tag) { + case FDT_BEGIN_NODE: + pathp = fdt_get_name(blob, node, NULL); + if (level <= depth) { + if (pathp == NULL) + pathp = "/* NULL pointer error */"; + if (*pathp == '\0') + pathp = "/"; /* root is nameless */ + if (level == 1) + puts(pathp); + } + level++; + if (level >= MAX_LEVEL) { + printf("Nested too deep, aborting.\n"); + return 1; + } + break; + case FDT_END_NODE: + level--; + if (level == 0) + level = -1; /* exit the loop */ + break; + case FDT_END: + return 1; + case FDT_PROP: + break; + default: + if (level <= depth) + printf("Unknown tag 0x%08X\n", tag); + return 1; + } + node = nextoffset; + } + return 0; +} + /** * Show the data for a given node (and perhaps property) according to the * display option provided. @@ -152,20 +208,30 @@ static int show_data_for_item(const void *blob, struct display_info *disp, const void *value = NULL; int len, err = 0; - if (disp->mode == MODE_LIST_PROPS) - return list_properties(blob, node); + switch (disp->mode) { + case MODE_LIST_PROPS: + err = list_properties(blob, node); + break; + + case MODE_LIST_CHILDREN: + err = list_children(blob, node); + break; - assert(property); - value = fdt_getprop(blob, node, property, &len); - if (value) { - if (show_data(disp, value, len)) + default: + assert(property); + value = fdt_getprop(blob, node, property, &len); + if (value) { + if (show_data(disp, value, len)) + err = -1; + else + printf("\n"); + } else { + report_error(property, len); err = -1; - else - printf("\n"); - } else { - report_error(property, len); - err = -1; + } + break; } + return err; } @@ -213,6 +279,7 @@ static const char *usage_msg = "Options:\n" "\t-t \tType of data\n" "\t-p\t\tList properties for each node\n" + "\t-l\t\tList children for each node\n" "\t-h\t\tPrint this help\n\n" USAGE_TYPE_MSG; @@ -236,7 +303,7 @@ int main(int argc, char *argv[]) disp.size = -1; disp.mode = MODE_SHOW_VALUE; for (;;) { - int c = getopt(argc, argv, "hpt:"); + int c = getopt(argc, argv, "hlpt:"); if (c == -1) break; @@ -255,6 +322,11 @@ int main(int argc, char *argv[]) disp.mode = MODE_LIST_PROPS; args_per_step = 1; break; + + case 'l': + disp.mode = MODE_LIST_CHILDREN; + args_per_step = 1; + break; } } -- 1.7.7.3