Commit 47605971 authored by Rob Herring's avatar Rob Herring

scripts/dtc: Update to upstream version 9d3649bd3be245c9

Sync dtc with upstream as of commit 9d3649bd3be2 (Add testcases for
fdt_path_offset_namelen()).
Signed-off-by: default avatarRob Herring <robh@kernel.org>
Cc: Grant Likely <grant.likely@linaro.org>
Cc: devicetree@vger.kernel.org
parent f1ec7187
......@@ -53,7 +53,7 @@ struct check {
void *data;
bool warn, error;
enum checkstatus status;
int inprogress;
bool inprogress;
int num_prereqs;
struct check **prereq;
};
......@@ -113,6 +113,7 @@ static inline void check_msg(struct check *c, const char *fmt, ...)
vfprintf(stderr, fmt, ap);
fprintf(stderr, "\n");
}
va_end(ap);
}
#define FAIL(c, ...) \
......@@ -141,9 +142,9 @@ static void check_nodes_props(struct check *c, struct node *dt, struct node *nod
check_nodes_props(c, dt, child);
}
static int run_check(struct check *c, struct node *dt)
static bool run_check(struct check *c, struct node *dt)
{
int error = 0;
bool error = false;
int i;
assert(!c->inprogress);
......@@ -151,11 +152,11 @@ static int run_check(struct check *c, struct node *dt)
if (c->status != UNCHECKED)
goto out;
c->inprogress = 1;
c->inprogress = true;
for (i = 0; i < c->num_prereqs; i++) {
struct check *prq = c->prereq[i];
error |= run_check(prq, dt);
error = error || run_check(prq, dt);
if (prq->status != PASSED) {
c->status = PREREQ;
check_msg(c, "Failed prerequisite '%s'",
......@@ -177,9 +178,9 @@ static int run_check(struct check *c, struct node *dt)
TRACE(c, "\tCompleted, status %d", c->status);
out:
c->inprogress = 0;
c->inprogress = false;
if ((c->status != PASSED) && (c->error))
error = 1;
error = true;
return error;
}
......@@ -624,11 +625,11 @@ static void check_avoid_default_addr_size(struct check *c, struct node *dt,
if (!reg && !ranges)
return;
if ((node->parent->addr_cells == -1))
if (node->parent->addr_cells == -1)
FAIL(c, "Relying on default #address-cells value for %s",
node->fullpath);
if ((node->parent->size_cells == -1))
if (node->parent->size_cells == -1)
FAIL(c, "Relying on default #size-cells value for %s",
node->fullpath);
}
......@@ -706,15 +707,15 @@ static void disable_warning_error(struct check *c, bool warn, bool error)
c->error = c->error && !error;
}
void parse_checks_option(bool warn, bool error, const char *optarg)
void parse_checks_option(bool warn, bool error, const char *arg)
{
int i;
const char *name = optarg;
const char *name = arg;
bool enable = true;
if ((strncmp(optarg, "no-", 3) == 0)
|| (strncmp(optarg, "no_", 3) == 0)) {
name = optarg + 3;
if ((strncmp(arg, "no-", 3) == 0)
|| (strncmp(arg, "no_", 3) == 0)) {
name = arg + 3;
enable = false;
}
......@@ -733,7 +734,7 @@ void parse_checks_option(bool warn, bool error, const char *optarg)
die("Unrecognized check name \"%s\"\n", name);
}
void process_checks(int force, struct boot_info *bi)
void process_checks(bool force, struct boot_info *bi)
{
struct node *dt = bi->dt;
int i;
......
......@@ -74,7 +74,7 @@ struct data data_copy_escape_string(const char *s, int len)
struct data d;
char *q;
d = data_grow_for(empty_data, strlen(s)+1);
d = data_grow_for(empty_data, len + 1);
q = d.val;
while (i < len) {
......@@ -250,20 +250,20 @@ struct data data_add_marker(struct data d, enum markertype type, char *ref)
return data_append_markers(d, m);
}
int data_is_one_string(struct data d)
bool data_is_one_string(struct data d)
{
int i;
int len = d.len;
if (len == 0)
return 0;
return false;
for (i = 0; i < len-1; i++)
if (d.val[i] == '\0')
return 0;
return false;
if (d.val[len-1] != '\0')
return 0;
return false;
return 1;
return true;
}
......@@ -20,7 +20,6 @@
%option noyywrap nounput noinput never-interactive
%x INCLUDE
%x BYTESTRING
%x PROPNODENAME
%s V1
......@@ -40,6 +39,7 @@ LINECOMMENT "//".*\n
#include "dtc-parser.tab.h"
YYLTYPE yylloc;
extern bool treesource_error;
/* CAUTION: this will stop working if we ever use yyless() or yyunput() */
#define YY_USER_ACTION \
......@@ -61,7 +61,8 @@ static int dts_version = 1;
BEGIN(V1); \
static void push_input_file(const char *filename);
static int pop_input_file(void);
static bool pop_input_file(void);
static void lexical_error(const char *fmt, ...);
%}
%%
......@@ -75,11 +76,11 @@ static int pop_input_file(void);
char *line, *tmp, *fn;
/* skip text before line # */
line = yytext;
while (!isdigit(*line))
while (!isdigit((unsigned char)*line))
line++;
/* skip digits in line # */
tmp = line;
while (!isspace(*tmp))
while (!isspace((unsigned char)*tmp))
tmp++;
/* "NULL"-terminate line # */
*tmp = '\0';
......@@ -146,15 +147,42 @@ static int pop_input_file(void);
}
<V1>([0-9]+|0[xX][0-9a-fA-F]+)(U|L|UL|LL|ULL)? {
yylval.literal = xstrdup(yytext);
DPRINT("Literal: '%s'\n", yylval.literal);
char *e;
DPRINT("Integer Literal: '%s'\n", yytext);
errno = 0;
yylval.integer = strtoull(yytext, &e, 0);
assert(!(*e) || !e[strspn(e, "UL")]);
if (errno == ERANGE)
lexical_error("Integer literal '%s' out of range",
yytext);
else
/* ERANGE is the only strtoull error triggerable
* by strings matching the pattern */
assert(errno == 0);
return DT_LITERAL;
}
<*>{CHAR_LITERAL} {
yytext[yyleng-1] = '\0';
yylval.literal = xstrdup(yytext+1);
DPRINT("Character literal: %s\n", yylval.literal);
struct data d;
DPRINT("Character literal: %s\n", yytext);
d = data_copy_escape_string(yytext+1, yyleng-2);
if (d.len == 1) {
lexical_error("Empty character literal");
yylval.integer = 0;
return DT_CHAR_LITERAL;
}
yylval.integer = (unsigned char)d.val[0];
if (d.len > 2)
lexical_error("Character literal has %d"
" characters instead of 1",
d.len - 1);
return DT_CHAR_LITERAL;
}
......@@ -164,7 +192,7 @@ static int pop_input_file(void);
return DT_REF;
}
<*>"&{/"{PATHCHAR}+\} { /* new-style path reference */
<*>"&{/"{PATHCHAR}*\} { /* new-style path reference */
yytext[yyleng-1] = '\0';
DPRINT("Ref: %s\n", yytext+2);
yylval.labelref = xstrdup(yytext+2);
......@@ -238,13 +266,24 @@ static void push_input_file(const char *filename)
}
static int pop_input_file(void)
static bool pop_input_file(void)
{
if (srcfile_pop() == 0)
return 0;
return false;
yypop_buffer_state();
yyin = current_srcfile->f;
return 1;
return true;
}
static void lexical_error(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
srcpos_verror(&yylloc, "Lexical error", fmt, ap);
va_end(ap);
treesource_error = true;
}
This diff is collapsed.
This diff is collapsed.
/* A Bison parser, made by GNU Bison 2.7.12-4996. */
/* A Bison parser, made by GNU Bison 3.0.2. */
/* Bison interface for Yacc-like parsers in C
Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc.
Copyright (C) 1984, 1989-1990, 2000-2013 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. */
......@@ -26,13 +26,13 @@
special exception, which will cause the skeleton and the resulting
Bison output files to be licensed under the GNU General Public
License without this special exception.
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
#ifndef YY_YY_DTC_PARSER_TAB_H_INCLUDED
# define YY_YY_DTC_PARSER_TAB_H_INCLUDED
/* Enabling traces. */
/* Debug traces. */
#ifndef YYDEBUG
# define YYDEBUG 0
#endif
......@@ -40,48 +40,44 @@
extern int yydebug;
#endif
/* Tokens. */
/* Token type. */
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
/* Put the tokens into the symbol table, so that GDB and other debuggers
know about them. */
enum yytokentype {
DT_V1 = 258,
DT_MEMRESERVE = 259,
DT_LSHIFT = 260,
DT_RSHIFT = 261,
DT_LE = 262,
DT_GE = 263,
DT_EQ = 264,
DT_NE = 265,
DT_AND = 266,
DT_OR = 267,
DT_BITS = 268,
DT_DEL_PROP = 269,
DT_DEL_NODE = 270,
DT_PROPNODENAME = 271,
DT_LITERAL = 272,
DT_CHAR_LITERAL = 273,
DT_BASE = 274,
DT_BYTE = 275,
DT_STRING = 276,
DT_LABEL = 277,
DT_REF = 278,
DT_INCBIN = 279
};
enum yytokentype
{
DT_V1 = 258,
DT_MEMRESERVE = 259,
DT_LSHIFT = 260,
DT_RSHIFT = 261,
DT_LE = 262,
DT_GE = 263,
DT_EQ = 264,
DT_NE = 265,
DT_AND = 266,
DT_OR = 267,
DT_BITS = 268,
DT_DEL_PROP = 269,
DT_DEL_NODE = 270,
DT_PROPNODENAME = 271,
DT_LITERAL = 272,
DT_CHAR_LITERAL = 273,
DT_BYTE = 274,
DT_STRING = 275,
DT_LABEL = 276,
DT_REF = 277,
DT_INCBIN = 278
};
#endif
/* Value type. */
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE
typedef union YYSTYPE YYSTYPE;
union YYSTYPE
{
/* Line 2053 of yacc.c */
#line 40 "dtc-parser.y"
#line 38 "dtc-parser.y" /* yacc.c:1909 */
char *propnodename;
char *literal;
char *labelref;
unsigned int cbase;
uint8_t byte;
struct data data;
......@@ -97,29 +93,29 @@ typedef union YYSTYPE
struct reserve_info *re;
uint64_t integer;
/* Line 2053 of yacc.c */
#line 103 "dtc-parser.tab.h"
} YYSTYPE;
#line 97 "dtc-parser.tab.h" /* yacc.c:1909 */
};
# define YYSTYPE_IS_TRIVIAL 1
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
#endif
extern YYSTYPE yylval;
#ifdef YYPARSE_PARAM
#if defined __STDC__ || defined __cplusplus
int yyparse (void *YYPARSE_PARAM);
#else
int yyparse ();
/* Location type. */
#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
typedef struct YYLTYPE YYLTYPE;
struct YYLTYPE
{
int first_line;
int first_column;
int last_line;
int last_column;
};
# define YYLTYPE_IS_DECLARED 1
# define YYLTYPE_IS_TRIVIAL 1
#endif
#else /* ! YYPARSE_PARAM */
#if defined __STDC__ || defined __cplusplus
extern YYSTYPE yylval;
extern YYLTYPE yylloc;
int yyparse (void);
#else
int yyparse ();
#endif
#endif /* ! YYPARSE_PARAM */
#endif /* !YY_YY_DTC_PARSER_TAB_H_INCLUDED */
......@@ -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);
}
......@@ -48,6 +48,8 @@ static void fill_fullpaths(struct node *tree, const char *prefix)
}
/* Usage related data. */
#define FDT_VERSION(version) _FDT_VERSION(version)
#define _FDT_VERSION(version) #version
static const char usage_synopsis[] = "dtc [options] <input file>";
static const char usage_short_opts[] = "qI:O:o:V:d:R:S:p:fb:i:H:sW:E:hv";
static struct option const usage_long_opts[] = {
......@@ -82,9 +84,9 @@ static const char * const usage_opts_help[] = {
"\t\tdts - device tree source text\n"
"\t\tdtb - device tree blob\n"
"\t\tasm - assembler source",
"\n\tBlob version to produce, defaults to %d (for dtb and asm output)", //, DEFAULT_FDT_VERSION);
"\n\tBlob version to produce, defaults to "FDT_VERSION(DEFAULT_FDT_VERSION)" (for dtb and asm output)",
"\n\tOutput dependency file",
"\n\ttMake space for <number> reserve map entries (for dtb and asm output)",
"\n\tMake space for <number> reserve map entries (for dtb and asm output)",
"\n\tMake the blob at least <bytes> long (extra space)",
"\n\tAdd padding to the blob of <bytes> long (extra space)",
"\n\tSet the physical boot cpu",
......@@ -109,7 +111,7 @@ int main(int argc, char *argv[])
const char *outform = "dts";
const char *outname = "-";
const char *depname = NULL;
int force = 0, sort = 0;
bool force = false, sort = false;
const char *arg;
int opt;
FILE *outf = NULL;
......@@ -148,7 +150,7 @@ int main(int argc, char *argv[])
padsize = strtol(optarg, NULL, 0);
break;
case 'f':
force = 1;
force = true;
break;
case 'q':
quiet++;
......@@ -174,7 +176,7 @@ int main(int argc, char *argv[])
break;
case 's':
sort = 1;
sort = true;
break;
case 'W':
......@@ -237,7 +239,7 @@ int main(int argc, char *argv[])
if (streq(outname, "-")) {
outf = stdout;
} else {
outf = fopen(outname, "w");
outf = fopen(outname, "wb");
if (! outf)
die("Couldn't open output file %s: %s\n",
outname, strerror(errno));
......
......@@ -38,9 +38,9 @@
#include "util.h"
#ifdef DEBUG
#define debug(fmt,args...) printf(fmt, ##args)
#define debug(...) printf(__VA_ARGS__)
#else
#define debug(fmt,args...)
#define debug(...)
#endif
......@@ -88,7 +88,7 @@ struct data {
};
#define empty_data ((struct data){ /* all .members = 0 or NULL */ })
#define empty_data ((struct data){ 0 /* all .members = 0 or NULL */ })
#define for_each_marker(m) \
for (; (m); (m) = (m)->next)
......@@ -118,7 +118,7 @@ struct data data_append_align(struct data d, int align);
struct data data_add_marker(struct data d, enum markertype type, char *ref);
int data_is_one_string(struct data d);
bool data_is_one_string(struct data d);
/* DT constraints */
......@@ -127,13 +127,13 @@ int data_is_one_string(struct data d);
/* Live trees */
struct label {
int deleted;
bool deleted;
char *label;
struct label *next;
};
struct property {
int deleted;
bool deleted;
char *name;
struct data val;
......@@ -143,7 +143,7 @@ struct property {
};
struct node {
int deleted;
bool deleted;
char *name;
struct property *proplist;
struct node *children;
......@@ -247,8 +247,8 @@ void sort_tree(struct boot_info *bi);