On Wed, Oct 20, 2010 at 02:45:13PM -0700, John Bonesio wrote:
> 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]>

As already mentioned, but I'm reposting here for the list archive
record, this syntax conflicts with existing convention for referencing
nodes by names defined in the /aliases node.

One more comment below.

> ---
> 
>  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);

For clarity, the above hunk should be in a separate patch applied
between patches #1 and #2.  That will avoid having one patch introduce
the DT_REMOVENODE hunk below, and then immediately modify it again in
this patch.  The switch to get_node_by_ref() is useful even without
the label+path syntax, and it should also include a matching testcase.

>                       $$ = $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