of/flattree: Update dtc to current mainline.
[linux-2.6.git] / scripts / dtc / dtc-parser.y
index b2ab562..5e84a67 100644 (file)
  *                                                                   USA
  */
 
-%locations
-
 %{
 #include <stdio.h>
 
 #include "dtc.h"
 #include "srcpos.h"
 
+YYLTYPE yylloc;
+
 extern int yylex(void);
+extern void print_error(char const *fmt, ...);
+extern void yyerror(char const *s);
 
 extern struct boot_info *the_boot_info;
 extern int treesource_error;
@@ -55,7 +57,6 @@ static unsigned long long eval_literal(const char *s, int base, int bits);
 %token DT_MEMRESERVE
 %token <propnodename> DT_PROPNODENAME
 %token <literal> DT_LITERAL
-%token <literal> DT_LEGACYLITERAL
 %token <cbase> DT_BASE
 %token <byte> DT_BYTE
 %token <data> DT_STRING
@@ -67,11 +68,8 @@ static unsigned long long eval_literal(const char *s, int base, int bits);
 %type <data> propdataprefix
 %type <re> memreserve
 %type <re> memreserves
-%type <re> v0_memreserve
-%type <re> v0_memreserves
 %type <addr> addr
 %type <data> celllist
-%type <cbase> cellbase
 %type <cell> cellval
 %type <data> bytestring
 %type <prop> propdef
@@ -81,18 +79,14 @@ static unsigned long long eval_literal(const char *s, int base, int bits);
 %type <node> nodedef
 %type <node> subnode
 %type <nodelist> subnodes
-%type <labelref> label
 
 %%
 
 sourcefile:
          DT_V1 ';' memreserves devicetree
                {
-                       the_boot_info = build_boot_info($3, $4, 0);
-               }
-       | v0_memreserves devicetree
-               {
-                       the_boot_info = build_boot_info($1, $2, 0);
+                       the_boot_info = build_boot_info($3, $4,
+                                                       guess_boot_cpuid($4));
                }
        ;
 
@@ -108,31 +102,14 @@ memreserves:
        ;
 
 memreserve:
-         label DT_MEMRESERVE addr addr ';'
+         DT_MEMRESERVE addr addr ';'
                {
-                       $$ = build_reserve_entry($3, $4, $1);
+                       $$ = build_reserve_entry($2, $3);
                }
-       ;
-
-v0_memreserves:
-         /* empty */
+       | DT_LABEL memreserve
                {
-                       $$ = NULL;
-               }
-       | v0_memreserve v0_memreserves
-               {
-                       $$ = chain_reserve_entry($1, $2);
-               };
-       ;
-
-v0_memreserve:
-         memreserve
-               {
-                       $$ = $1;
-               }
-       | label DT_MEMRESERVE addr '-' addr ';'
-               {
-                       $$ = build_reserve_entry($3, $5 - $3 + 1, $1);
+                       add_label(&$2->labels, $1);
+                       $$ = $2;
                }
        ;
 
@@ -141,16 +118,26 @@ addr:
                {
                        $$ = eval_literal($1, 0, 64);
                }
-       | DT_LEGACYLITERAL
-               {
-                       $$ = eval_literal($1, 16, 64);
-               }
          ;
 
 devicetree:
          '/' nodedef
                {
-                       $$ = name_node($2, "", NULL);
+                       $$ = name_node($2, "");
+               }
+       | devicetree '/' nodedef
+               {
+                       $$ = merge_nodes($1, $3);
+               }
+       | devicetree DT_REF nodedef
+               {
+                       struct node *target = get_node_by_ref($1, $2);
+
+                       if (target)
+                               merge_nodes(target, $3);
+                       else
+                               print_error("label or path, '%s', not found", $2);
+                       $$ = $1;
                }
        ;
 
@@ -173,13 +160,18 @@ proplist:
        ;
 
 propdef:
-         label DT_PROPNODENAME '=' propdata ';'
+         DT_PROPNODENAME '=' propdata ';'
+               {
+                       $$ = build_property($1, $3);
+               }
+       | DT_PROPNODENAME ';'
                {
-                       $$ = build_property($2, $4, $1);
+                       $$ = build_property($1, empty_data);
                }
-       | label DT_PROPNODENAME ';'
+       | DT_LABEL propdef
                {
-                       $$ = build_property($2, empty_data, $1);
+                       add_label(&$2->labels, $1);
+                       $$ = $2;
                }
        ;
 
@@ -202,31 +194,30 @@ propdata:
                }
        | propdataprefix DT_INCBIN '(' DT_STRING ',' addr ',' addr ')'
                {
-                       struct search_path path = { srcpos_file->dir, NULL, NULL };
-                       struct dtc_file *file = dtc_open_file($4.val, &path);
-                       struct data d = empty_data;
+                       FILE *f = srcfile_relative_open($4.val, NULL);
+                       struct data d;
 
                        if ($6 != 0)
-                               if (fseek(file->file, $6, SEEK_SET) != 0)
-                                       yyerrorf("Couldn't seek to offset %llu in \"%s\": %s",
-                                                (unsigned long long)$6,
-                                                $4.val, strerror(errno));
+                               if (fseek(f, $6, SEEK_SET) != 0)
+                                       print_error("Couldn't seek to offset %llu in \"%s\": %s",
+                                                    (unsigned long long)$6,
+                                                    $4.val,
+                                                    strerror(errno));
 
-                       d = data_copy_file(file->file, $8);
+                       d = data_copy_file(f, $8);
 
                        $$ = data_merge($1, d);
-                       dtc_close_file(file);
+                       fclose(f);
                }
        | propdataprefix DT_INCBIN '(' DT_STRING ')'
                {
-                       struct search_path path = { srcpos_file->dir, NULL, NULL };
-                       struct dtc_file *file = dtc_open_file($4.val, &path);
+                       FILE *f = srcfile_relative_open($4.val, NULL);
                        struct data d = empty_data;
 
-                       d = data_copy_file(file->file, -1);
+                       d = data_copy_file(f, -1);
 
                        $$ = data_merge($1, d);
-                       dtc_close_file(file);
+                       fclose(f);
                }
        | propdata DT_LABEL
                {
@@ -269,23 +260,11 @@ celllist:
                }
        ;
 
-cellbase:
-         /* empty */
-               {
-                       $$ = 16;
-               }
-       | DT_BASE
-       ;
-
 cellval:
          DT_LITERAL
                {
                        $$ = eval_literal($1, 0, 32);
                }
-       | cellbase DT_LEGACYLITERAL
-               {
-                       $$ = eval_literal($2, $1, 32);
-               }
        ;
 
 bytestring:
@@ -308,57 +287,44 @@ subnodes:
                {
                        $$ = NULL;
                }
-       |  subnode subnodes
+       | subnode subnodes
                {
                        $$ = chain_node($1, $2);
                }
        | subnode propdef
                {
-                       yyerror("syntax error: properties must precede subnodes");
+                       print_error("syntax error: properties must precede subnodes");
                        YYERROR;
                }
        ;
 
 subnode:
-         label DT_PROPNODENAME nodedef
+         DT_PROPNODENAME nodedef
                {
-                       $$ = name_node($3, $2, $1);
+                       $$ = name_node($2, $1);
                }
-       ;
-
-label:
-         /* empty */
+       | DT_LABEL subnode
                {
-                       $$ = NULL;
-               }
-       | DT_LABEL
-               {
-                       $$ = $1;
+                       add_label(&$2->labels, $1);
+                       $$ = $2;
                }
        ;
 
 %%
 
-void yyerrorf(char const *s, ...)
+void print_error(char const *fmt, ...)
 {
-       const char *fname = srcpos_file ? srcpos_file->name : "<no-file>";
        va_list va;
-       va_start(va, s);
-
-       if (strcmp(fname, "-") == 0)
-               fname = "stdin";
 
-       fprintf(stderr, "%s:%d ", fname, yylloc.first_line);
-       vfprintf(stderr, s, va);
-       fprintf(stderr, "\n");
+       va_start(va, fmt);
+       srcpos_verror(&yylloc, fmt, va);
+       va_end(va);
 
        treesource_error = 1;
-       va_end(va);
 }
 
-void yyerror (char const *s)
-{
-       yyerrorf("%s", s);
+void yyerror(char const *s) {
+       print_error("%s", s);
 }
 
 static unsigned long long eval_literal(const char *s, int base, int bits)
@@ -369,11 +335,11 @@ static unsigned long long eval_literal(const char *s, int base, int bits)
        errno = 0;
        val = strtoull(s, &e, base);
        if (*e)
-               yyerror("bad characters in literal");
+               print_error("bad characters in literal");
        else if ((errno == ERANGE)
                 || ((bits < 64) && (val >= (1ULL << bits))))
-               yyerror("literal out of range");
+               print_error("literal out of range");
        else if (errno != 0)
-               yyerror("bad literal");
+               print_error("bad literal");
        return val;
 }