summaryrefslogtreecommitdiff
path: root/scripts/dtc/dtc-parser.y
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/dtc/dtc-parser.y')
-rw-r--r--scripts/dtc/dtc-parser.y147
1 files changed, 46 insertions, 101 deletions
diff --git a/scripts/dtc/dtc-parser.y b/scripts/dtc/dtc-parser.y
index f412460f9..5a897e365 100644
--- a/scripts/dtc/dtc-parser.y
+++ b/scripts/dtc/dtc-parser.y
@@ -17,31 +17,27 @@
* 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);
}