These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / scripts / dtc / dtc-parser.y
index f412460..5a897e3 100644 (file)
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
  *                                                                   USA
  */
-
 %{
 #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);
+#define ERROR(loc, ...) \
+       do { \
+               srcpos_error((loc), "Error", __VA_ARGS__); \
+               treesource_error = true; \
+       } while (0)
 
 extern struct boot_info *the_boot_info;
-extern int treesource_error;
-
-static unsigned long long eval_literal(const char *s, int base, int bits);
-static unsigned char eval_char_literal(const char *s);
+extern bool treesource_error;
 %}
 
 %union {
        char *propnodename;
-       char *literal;
        char *labelref;
-       unsigned int cbase;
        uint8_t byte;
        struct data data;
 
@@ -65,9 +61,8 @@ static unsigned char eval_char_literal(const char *s);
 %token DT_DEL_PROP
 %token DT_DEL_NODE
 %token <propnodename> DT_PROPNODENAME
-%token <literal> DT_LITERAL
-%token <literal> DT_CHAR_LITERAL
-%token <cbase> DT_BASE
+%token <integer> DT_LITERAL
+%token <integer> DT_CHAR_LITERAL
 %token <byte> DT_BYTE
 %token <data> DT_STRING
 %token <labelref> DT_LABEL
@@ -145,6 +140,18 @@ devicetree:
                {
                        $$ = merge_nodes($1, $3);
                }
+
+       | devicetree DT_LABEL DT_REF nodedef
+               {
+                       struct node *target = get_node_by_ref($1, $3);
+
+                       add_label(&target->labels, $2);
+                       if (target)
+                               merge_nodes(target, $4);
+                       else
+                               ERROR(&@3, "Label or path %s not found", $3);
+                       $$ = $1;
+               }
        | devicetree DT_REF nodedef
                {
                        struct node *target = get_node_by_ref($1, $2);
@@ -152,17 +159,18 @@ devicetree:
                        if (target)
                                merge_nodes(target, $3);
                        else
-                               print_error("label or path, '%s', not found", $2);
+                               ERROR(&@2, "Label or path %s not found", $2);
                        $$ = $1;
                }
        | devicetree DT_DEL_NODE DT_REF ';'
                {
                        struct node *target = get_node_by_ref($1, $3);
 
-                       if (!target)
-                               print_error("label or path, '%s', not found", $3);
-                       else
+                       if (target)
                                delete_node(target);
+                       else
+                               ERROR(&@3, "Label or path %s not found", $3);
+
 
                        $$ = $1;
                }
@@ -230,10 +238,9 @@ propdata:
 
                        if ($6 != 0)
                                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));
+                                       die("Couldn't seek to offset %llu in \"%s\": %s",
+                                           (unsigned long long)$6, $4.val,
+                                           strerror(errno));
 
                        d = data_copy_file(f, $8);
 
@@ -274,18 +281,19 @@ propdataprefix:
 arrayprefix:
        DT_BITS DT_LITERAL '<'
                {
-                       $$.data = empty_data;
-                       $$.bits = eval_literal($2, 0, 7);
-
-                       if (($$.bits !=  8) &&
-                           ($$.bits != 16) &&
-                           ($$.bits != 32) &&
-                           ($$.bits != 64))
-                       {
-                               print_error("Only 8, 16, 32 and 64-bit elements"
-                                           " are currently supported");
-                               $$.bits = 32;
+                       unsigned long long bits;
+
+                       bits = $2;
+
+                       if ((bits !=  8) && (bits != 16) &&
+                           (bits != 32) && (bits != 64)) {
+                               ERROR(&@2, "Array elements must be"
+                                     " 8, 16, 32 or 64-bits");
+                               bits = 32;
                        }
+
+                       $$.data = empty_data;
+                       $$.bits = bits;
                }
        | '<'
                {
@@ -305,9 +313,8 @@ arrayprefix:
                                 * mask), all bits are one.
                                 */
                                if (($2 > mask) && (($2 | mask) != -1ULL))
-                                       print_error(
-                                               "integer value out of range "
-                                               "%016lx (%d bits)", $1.bits);
+                                       ERROR(&@2, "Value out of range for"
+                                             " %d-bit array element", $1.bits);
                        }
 
                        $$.data = data_append_integer($1.data, $2, $1.bits);
@@ -321,7 +328,7 @@ arrayprefix:
                                                          REF_PHANDLE,
                                                          $2);
                        else
-                               print_error("References are only allowed in "
+                               ERROR(&@2, "References are only allowed in "
                                            "arrays with 32-bit elements.");
 
                        $$.data = data_append_integer($1.data, val, $1.bits);
@@ -334,13 +341,7 @@ arrayprefix:
 
 integer_prim:
          DT_LITERAL
-               {
-                       $$ = eval_literal($1, 0, 64);
-               }
        | DT_CHAR_LITERAL
-               {
-                       $$ = eval_char_literal($1);
-               }
        | '(' integer_expr ')'
                {
                        $$ = $2;
@@ -447,7 +448,7 @@ subnodes:
                }
        | subnode propdef
                {
-                       print_error("syntax error: properties must precede subnodes");
+                       ERROR(&@2, "Properties must precede subnodes");
                        YYERROR;
                }
        ;
@@ -470,63 +471,7 @@ subnode:
 
 %%
 
-void print_error(char const *fmt, ...)
-{
-       va_list va;
-
-       va_start(va, fmt);
-       srcpos_verror(&yylloc, fmt, va);
-       va_end(va);
-
-       treesource_error = 1;
-}
-
-void yyerror(char const *s) {
-       print_error("%s", s);
-}
-
-static unsigned long long eval_literal(const char *s, int base, int bits)
-{
-       unsigned long long val;
-       char *e;
-
-       errno = 0;
-       val = strtoull(s, &e, base);
-       if (*e) {
-               size_t uls = strspn(e, "UL");
-               if (e[uls])
-                       print_error("bad characters in literal");
-       }
-       if ((errno == ERANGE)
-                || ((bits < 64) && (val >= (1ULL << bits))))
-               print_error("literal out of range");
-       else if (errno != 0)
-               print_error("bad literal");
-       return val;
-}
-
-static unsigned char eval_char_literal(const char *s)
+void yyerror(char const *s)
 {
-       int i = 1;
-       char c = s[0];
-
-       if (c == '\0')
-       {
-               print_error("empty character literal");
-               return 0;
-       }
-
-       /*
-        * If the first character in the character literal is a \ then process
-        * the remaining characters as an escape encoding. If the first
-        * character is neither an escape or a terminator it should be the only
-        * character in the literal and will be returned.
-        */
-       if (c == '\\')
-               c = get_escape_char(s, &i);
-
-       if (s[i] != '\0')
-               print_error("malformed character literal");
-
-       return c;
+       ERROR(&yylloc, "%s", s);
 }