Changes to allow us to specify a node by it's path. A path can be used in
place of a label.

This is particularly useful when overriding existing nodes.
This way we don't have to label every possible node in a device tree we know
is a base device tree for a class of systems, and we know the tree will be
modified for the specific systems.

Signed-off-by: John Bonesio <[email protected]>
---

 dtc-lexer.l  |   26 ++++++++++++++++++++++----
 dtc-parser.y |   10 ++++------
 livetree.c   |   20 +++++++++++++++++++-
 3 files changed, 45 insertions(+), 11 deletions(-)

diff --git a/dtc-lexer.l b/dtc-lexer.l
index 80a886a..216a3d2 100644
--- a/dtc-lexer.l
+++ b/dtc-lexer.l
@@ -115,13 +115,31 @@ static int pop_input_file(void);
                        return DT_LITERAL;
                }
 
-<*>\&{LABEL}   {       /* label reference */
-                       DPRINT("Ref: %s\n", yytext+1);
-                       yylval.labelref = xstrdup(yytext+1);
+
+<*>\&{LABEL}    {       /* label reference without the braces*/
+                        DPRINT("Ref: %s\n", yytext+1);
+                        yylval.labelref = xstrdup(yytext+1);
+                        return DT_REF;
+               }
+
+<*>"&{"{LABEL}{PATHCHAR}*\} { /* label and/or path refererence with braces */
+                       /*
+                        * Possibly this could be parsed by the parser rather
+                        * than as a lexical element.
+                        *
+                        * What is intended here is to support the following
+                        * type of references:
+                        * a) &{/path/to/the/node/reference}
+                        * b) &{label}
+                        * c) &{label/path/from/labeled/node/to/reference}
+                        */
+                       yytext[yyleng-1] = '\0';
+                       DPRINT("Ref: %s\n", yytext+2);
+                       yylval.labelref = xstrdup(yytext+2);
                        return DT_REF;
                }
 
-"&{/"{PATHCHAR}+\}     {       /* new-style path reference */
+<*>"&{/"{PATHCHAR}+\}  {       /* new-style path reference (with braces) */
                        yytext[yyleng-1] = '\0';
                        DPRINT("Ref: %s\n", yytext+2);
                        yylval.labelref = xstrdup(yytext+2);
diff --git a/dtc-parser.y b/dtc-parser.y
index 1ba0478..0a74c86 100644
--- a/dtc-parser.y
+++ b/dtc-parser.y
@@ -132,24 +132,22 @@ devicetree:
                }
        | devicetree DT_REF nodedef
                {
-                       struct node *target;
+                       struct node *target = get_node_by_ref($1, $2);
 
-                       target = get_node_by_label($1, $2);
                        if (target)
                                merge_nodes(target, $3);
                        else
-                               print_error("label, '%s' not found", $2);
+                               print_error("label or path, '%s', not found", 
$2);
                        $$ = $1;
                }
        | devicetree DT_REMOVENODE DT_REF ';'
                {
-                       struct node *target;
+                       struct node *target = get_node_by_ref($1, $3);
 
-                       target = get_node_by_label($1, $3);
                        if (target)
                                remove_child(target->parent, target);
                        else
-                               print_error("label, '%s' not found", $3);
+                               print_error("label or path, '%s', not found", 
$3);
                }
        ;
 
diff --git a/livetree.c b/livetree.c
index 21a4c48..bf8796b 100644
--- a/livetree.c
+++ b/livetree.c
@@ -429,10 +429,28 @@ struct node *get_node_by_phandle(struct node *tree, 
cell_t phandle)
 
 struct node *get_node_by_ref(struct node *tree, const char *ref)
 {
+       struct node *node;
+
        if (ref[0] == '/')
                return get_node_by_path(tree, ref);
-       else
+       else {
+               /*
+                * Support finding a node reference that is rooted by
+                * a label reference.
+                *
+                * References rooted by a label have a '/' in them.
+                */
+               char *p = strchr(ref, '/');
+
+               if (p) {
+                       *p = '\0';
+                       node = get_node_by_label(tree, ref);
+                       *p = '/';
+                       return get_node_by_path(node, p+1);
+               }
+
                return get_node_by_label(tree, ref);
+       }
 }
 
 cell_t get_node_phandle(struct node *root, struct node *node)

_______________________________________________
devicetree-discuss mailing list
[email protected]
https://lists.ozlabs.org/listinfo/devicetree-discuss

Reply via email to