[PATCH 1/5] scripts: dtc: Merge in changes from the dtc repository
Grant Likely
grant.likely at secretlab.ca
Wed Nov 17 15:59:35 EST 2010
On Tue, Nov 16, 2010 at 12:49:51PM -0800, John Bonesio wrote:
> Pull in recent changes from the main dtc repository. These changes primarily
> allow multiple device trees to be declared which are merged by dtc. This
> feature allows us to include a basic dts file and then provide more information
> for the specific system through the merging functionality.
>
> Signed-off-by: John Bonesio <bones at secretlab.ca>
Jon & David, I'll need your input on whether or not this is the best
way to handle updating the dtc copy in the kernel tree.
g.
> ---
>
> 0 files changed, 0 insertions(+), 0 deletions(-)
>
> diff --git a/scripts/dtc/Makefile b/scripts/dtc/Makefile
> index 01cdb36..04a31c1 100644
> --- a/scripts/dtc/Makefile
> +++ b/scripts/dtc/Makefile
> @@ -4,7 +4,7 @@ hostprogs-y := dtc
> always := $(hostprogs-y)
>
> dtc-objs := dtc.o flattree.o fstree.o data.o livetree.o treesource.o \
> - srcpos.o checks.o
> + srcpos.o checks.o util.o
> dtc-objs += dtc-lexer.lex.o dtc-parser.tab.o
>
> # Source files need to get at the userspace version of libfdt_env.h to compile
> @@ -19,6 +19,7 @@ HOSTCFLAGS_fstree.o := $(HOSTCFLAGS_DTC)
> HOSTCFLAGS_livetree.o := $(HOSTCFLAGS_DTC)
> HOSTCFLAGS_srcpos.o := $(HOSTCFLAGS_DTC)
> HOSTCFLAGS_treesource.o := $(HOSTCFLAGS_DTC)
> +HOSTCFLAGS_util.o := $(HOSTCFLAGS_DTC)
>
> HOSTCFLAGS_dtc-lexer.lex.o := $(HOSTCFLAGS_DTC)
> HOSTCFLAGS_dtc-parser.tab.o := $(HOSTCFLAGS_DTC)
> diff --git a/scripts/dtc/checks.c b/scripts/dtc/checks.c
> index 9548579..a662a00 100644
> --- a/scripts/dtc/checks.c
> +++ b/scripts/dtc/checks.c
> @@ -278,32 +278,112 @@ static void check_property_name_chars(struct check *c, struct node *dt,
> }
> PROP_CHECK(property_name_chars, PROPNODECHARS, ERROR);
>
> +#define DESCLABEL_FMT "%s%s%s%s%s"
> +#define DESCLABEL_ARGS(node,prop,mark) \
> + ((mark) ? "value of " : ""), \
> + ((prop) ? "'" : ""), \
> + ((prop) ? (prop)->name : ""), \
> + ((prop) ? "' in " : ""), (node)->fullpath
> +
> +static void check_duplicate_label(struct check *c, struct node *dt,
> + const char *label, struct node *node,
> + struct property *prop, struct marker *mark)
> +{
> + struct node *othernode = NULL;
> + struct property *otherprop = NULL;
> + struct marker *othermark = NULL;
> +
> + othernode = get_node_by_label(dt, label);
> +
> + if (!othernode)
> + otherprop = get_property_by_label(dt, label, &othernode);
> + if (!othernode)
> + othermark = get_marker_label(dt, label, &othernode,
> + &otherprop);
> +
> + if (!othernode)
> + return;
> +
> + if ((othernode != node) || (otherprop != prop) || (othermark != mark))
> + FAIL(c, "Duplicate label '%s' on " DESCLABEL_FMT
> + " and " DESCLABEL_FMT,
> + label, DESCLABEL_ARGS(node, prop, mark),
> + DESCLABEL_ARGS(othernode, otherprop, othermark));
> +}
> +
> +static void check_duplicate_label_node(struct check *c, struct node *dt,
> + struct node *node)
> +{
> + struct label *l;
> +
> + for_each_label(node->labels, l)
> + check_duplicate_label(c, dt, l->label, node, NULL, NULL);
> +}
> +static void check_duplicate_label_prop(struct check *c, struct node *dt,
> + struct node *node, struct property *prop)
> +{
> + struct marker *m = prop->val.markers;
> + struct label *l;
> +
> + for_each_label(prop->labels, l)
> + check_duplicate_label(c, dt, l->label, node, prop, NULL);
> +
> + for_each_marker_of_type(m, LABEL)
> + check_duplicate_label(c, dt, m->ref, node, prop, m);
> +}
> +CHECK(duplicate_label, NULL, check_duplicate_label_node,
> + check_duplicate_label_prop, NULL, ERROR);
> +
> static void check_explicit_phandles(struct check *c, struct node *root,
> - struct node *node)
> + struct node *node, struct property *prop)
> {
> - struct property *prop;
> + struct marker *m;
> struct node *other;
> cell_t phandle;
>
> - prop = get_property(node, "linux,phandle");
> - if (! prop)
> - return; /* No phandle, that's fine */
> + if (!streq(prop->name, "phandle")
> + && !streq(prop->name, "linux,phandle"))
> + return;
>
> if (prop->val.len != sizeof(cell_t)) {
> - FAIL(c, "%s has bad length (%d) linux,phandle property",
> - node->fullpath, prop->val.len);
> + FAIL(c, "%s has bad length (%d) %s property",
> + node->fullpath, prop->val.len, prop->name);
> + return;
> + }
> +
> + m = prop->val.markers;
> + for_each_marker_of_type(m, REF_PHANDLE) {
> + assert(m->offset == 0);
> + if (node != get_node_by_ref(root, m->ref))
> + /* "Set this node's phandle equal to some
> + * other node's phandle". That's nonsensical
> + * by construction. */ {
> + FAIL(c, "%s in %s is a reference to another node",
> + prop->name, node->fullpath);
> + return;
> + }
> + /* But setting this node's phandle equal to its own
> + * phandle is allowed - that means allocate a unique
> + * phandle for this node, even if it's not otherwise
> + * referenced. The value will be filled in later, so
> + * no further checking for now. */
> return;
> }
>
> phandle = propval_cell(prop);
> +
> if ((phandle == 0) || (phandle == -1)) {
> - FAIL(c, "%s has invalid linux,phandle value 0x%x",
> - node->fullpath, phandle);
> + FAIL(c, "%s has bad value (0x%x) in %s property",
> + node->fullpath, phandle, prop->name);
> return;
> }
>
> + if (node->phandle && (node->phandle != phandle))
> + FAIL(c, "%s has %s property which replaces existing phandle information",
> + node->fullpath, prop->name);
> +
> other = get_node_by_phandle(root, phandle);
> - if (other) {
> + if (other && (other != node)) {
> FAIL(c, "%s has duplicated phandle 0x%x (seen before at %s)",
> node->fullpath, phandle, other->fullpath);
> return;
> @@ -311,7 +391,7 @@ static void check_explicit_phandles(struct check *c, struct node *root,
>
> node->phandle = phandle;
> }
> -NODE_CHECK(explicit_phandles, NULL, ERROR);
> +PROP_CHECK(explicit_phandles, NULL, ERROR);
>
> static void check_name_properties(struct check *c, struct node *root,
> struct node *node)
> @@ -549,6 +629,9 @@ static struct check *check_table[] = {
> &duplicate_node_names, &duplicate_property_names,
> &node_name_chars, &node_name_format, &property_name_chars,
> &name_is_string, &name_properties,
> +
> + &duplicate_label,
> +
> &explicit_phandles,
> &phandle_references, &path_references,
>
> diff --git a/scripts/dtc/dtc-lexer.l b/scripts/dtc/dtc-lexer.l
> index a627bbe..e866ea5 100644
> --- a/scripts/dtc/dtc-lexer.l
> +++ b/scripts/dtc/dtc-lexer.l
> @@ -18,7 +18,7 @@
> * USA
> */
>
> -%option noyywrap noinput nounput yylineno
> +%option noyywrap nounput noinput never-interactive
>
> %x INCLUDE
> %x BYTESTRING
> @@ -38,6 +38,13 @@ LINECOMMENT "//".*\n
> #include "srcpos.h"
> #include "dtc-parser.tab.h"
>
> +YYLTYPE yylloc;
> +
> +/* CAUTION: this will stop working if we ever use yyless() or yyunput() */
> +#define YY_USER_ACTION \
> + { \
> + srcpos_update(&yylloc, yytext, yyleng); \
> + }
>
> /*#define LEXDEBUG 1*/
>
> @@ -47,15 +54,10 @@ LINECOMMENT "//".*\n
> #define DPRINT(fmt, ...) do { } while (0)
> #endif
>
> -static int dts_version; /* = 0 */
> +static int dts_version = 1;
>
> -#define BEGIN_DEFAULT() if (dts_version == 0) { \
> - DPRINT("<INITIAL>\n"); \
> - BEGIN(INITIAL); \
> - } else { \
> - DPRINT("<V1>\n"); \
> +#define BEGIN_DEFAULT() DPRINT("<V1>\n"); \
> BEGIN(V1); \
> - }
>
> static void push_input_file(const char *filename);
> static int pop_input_file(void);
> @@ -75,18 +77,13 @@ static int pop_input_file(void);
> }
>
> <*>{STRING} {
> - yylloc.file = srcpos_file;
> - yylloc.first_line = yylineno;
> DPRINT("String: %s\n", yytext);
> yylval.data = data_copy_escape_string(yytext+1,
> yyleng-2);
> - yylloc.first_line = yylineno;
> return DT_STRING;
> }
>
> <*>"/dts-v1/" {
> - yylloc.file = srcpos_file;
> - yylloc.first_line = yylineno;
> DPRINT("Keyword: /dts-v1/\n");
> dts_version = 1;
> BEGIN_DEFAULT();
> @@ -94,106 +91,57 @@ static int pop_input_file(void);
> }
>
> <*>"/memreserve/" {
> - yylloc.file = srcpos_file;
> - yylloc.first_line = yylineno;
> DPRINT("Keyword: /memreserve/\n");
> BEGIN_DEFAULT();
> return DT_MEMRESERVE;
> }
>
> <*>{LABEL}: {
> - yylloc.file = srcpos_file;
> - yylloc.first_line = yylineno;
> DPRINT("Label: %s\n", yytext);
> - yylval.labelref = strdup(yytext);
> + yylval.labelref = xstrdup(yytext);
> yylval.labelref[yyleng-1] = '\0';
> return DT_LABEL;
> }
>
> -<INITIAL>[bodh]# {
> - yylloc.file = srcpos_file;
> - yylloc.first_line = yylineno;
> - if (*yytext == 'b')
> - yylval.cbase = 2;
> - else if (*yytext == 'o')
> - yylval.cbase = 8;
> - else if (*yytext == 'd')
> - yylval.cbase = 10;
> - else
> - yylval.cbase = 16;
> - DPRINT("Base: %d\n", yylval.cbase);
> - return DT_BASE;
> - }
> -
> -<INITIAL>[0-9a-fA-F]+ {
> - yylloc.file = srcpos_file;
> - yylloc.first_line = yylineno;
> - yylval.literal = strdup(yytext);
> - DPRINT("Literal: '%s'\n", yylval.literal);
> - return DT_LEGACYLITERAL;
> - }
> -
> <V1>[0-9]+|0[xX][0-9a-fA-F]+ {
> - yylloc.file = srcpos_file;
> - yylloc.first_line = yylineno;
> - yylval.literal = strdup(yytext);
> + yylval.literal = xstrdup(yytext);
> DPRINT("Literal: '%s'\n", yylval.literal);
> return DT_LITERAL;
> }
>
> -\&{LABEL} { /* label reference */
> - yylloc.file = srcpos_file;
> - yylloc.first_line = yylineno;
> +<*>\&{LABEL} { /* label reference */
> DPRINT("Ref: %s\n", yytext+1);
> - yylval.labelref = strdup(yytext+1);
> + yylval.labelref = xstrdup(yytext+1);
> return DT_REF;
> }
>
> -"&{/"{PATHCHAR}+\} { /* new-style path reference */
> - yylloc.file = srcpos_file;
> - yylloc.first_line = yylineno;
> +<*>"&{/"{PATHCHAR}+\} { /* new-style path reference */
> yytext[yyleng-1] = '\0';
> DPRINT("Ref: %s\n", yytext+2);
> - yylval.labelref = strdup(yytext+2);
> - return DT_REF;
> - }
> -
> -<INITIAL>"&/"{PATHCHAR}+ { /* old-style path reference */
> - yylloc.file = srcpos_file;
> - yylloc.first_line = yylineno;
> - DPRINT("Ref: %s\n", yytext+1);
> - yylval.labelref = strdup(yytext+1);
> + yylval.labelref = xstrdup(yytext+2);
> return DT_REF;
> }
>
> <BYTESTRING>[0-9a-fA-F]{2} {
> - yylloc.file = srcpos_file;
> - yylloc.first_line = yylineno;
> yylval.byte = strtol(yytext, NULL, 16);
> DPRINT("Byte: %02x\n", (int)yylval.byte);
> return DT_BYTE;
> }
>
> <BYTESTRING>"]" {
> - yylloc.file = srcpos_file;
> - yylloc.first_line = yylineno;
> DPRINT("/BYTESTRING\n");
> BEGIN_DEFAULT();
> return ']';
> }
>
> <PROPNODENAME>{PROPNODECHAR}+ {
> - yylloc.file = srcpos_file;
> - yylloc.first_line = yylineno;
> DPRINT("PropNodeName: %s\n", yytext);
> - yylval.propnodename = strdup(yytext);
> + yylval.propnodename = xstrdup(yytext);
> BEGIN_DEFAULT();
> return DT_PROPNODENAME;
> }
>
> "/incbin/" {
> - yylloc.file = srcpos_file;
> - yylloc.first_line = yylineno;
> DPRINT("Binary Include\n");
> return DT_INCBIN;
> }
> @@ -203,8 +151,6 @@ static int pop_input_file(void);
> <*>{LINECOMMENT}+ /* eat C++-style comments */
>
> <*>. {
> - yylloc.file = srcpos_file;
> - yylloc.first_line = yylineno;
> DPRINT("Char: %c (\\x%02x)\n", yytext[0],
> (unsigned)yytext[0]);
> if (yytext[0] == '[') {
> @@ -221,100 +167,25 @@ static int pop_input_file(void);
>
> %%
>
> -
> -/*
> - * Stack of nested include file contexts.
> - */
> -
> -struct incl_file {
> - struct dtc_file *file;
> - YY_BUFFER_STATE yy_prev_buf;
> - int yy_prev_lineno;
> - struct incl_file *prev;
> -};
> -
> -static struct incl_file *incl_file_stack;
> -
> -
> -/*
> - * Detect infinite include recursion.
> - */
> -#define MAX_INCLUDE_DEPTH (100)
> -
> -static int incl_depth = 0;
> -
> -
> static void push_input_file(const char *filename)
> {
> - struct incl_file *incl_file;
> - struct dtc_file *newfile;
> - struct search_path search, *searchptr = NULL;
> -
> assert(filename);
>
> - if (incl_depth++ >= MAX_INCLUDE_DEPTH)
> - die("Includes nested too deeply");
> -
> - if (srcpos_file) {
> - search.dir = srcpos_file->dir;
> - search.next = NULL;
> - search.prev = NULL;
> - searchptr = &search;
> - }
> -
> - newfile = dtc_open_file(filename, searchptr);
> + srcfile_push(filename);
>
> - incl_file = xmalloc(sizeof(struct incl_file));
> + yyin = current_srcfile->f;
>
> - /*
> - * Save current context.
> - */
> - incl_file->yy_prev_buf = YY_CURRENT_BUFFER;
> - incl_file->yy_prev_lineno = yylineno;
> - incl_file->file = srcpos_file;
> - incl_file->prev = incl_file_stack;
> -
> - incl_file_stack = incl_file;
> -
> - /*
> - * Establish new context.
> - */
> - srcpos_file = newfile;
> - yylineno = 1;
> - yyin = newfile->file;
> - yy_switch_to_buffer(yy_create_buffer(yyin, YY_BUF_SIZE));
> + yypush_buffer_state(yy_create_buffer(yyin, YY_BUF_SIZE));
> }
>
>
> static int pop_input_file(void)
> {
> - struct incl_file *incl_file;
> -
> - if (incl_file_stack == 0)
> + if (srcfile_pop() == 0)
> return 0;
>
> - dtc_close_file(srcpos_file);
> -
> - /*
> - * Pop.
> - */
> - --incl_depth;
> - incl_file = incl_file_stack;
> - incl_file_stack = incl_file->prev;
> -
> - /*
> - * Recover old context.
> - */
> - yy_delete_buffer(YY_CURRENT_BUFFER);
> - yy_switch_to_buffer(incl_file->yy_prev_buf);
> - yylineno = incl_file->yy_prev_lineno;
> - srcpos_file = incl_file->file;
> - yyin = incl_file->file ? incl_file->file->file : NULL;
> -
> - /*
> - * Free old state.
> - */
> - free(incl_file);
> + yypop_buffer_state();
> + yyin = current_srcfile->f;
>
> return 1;
> }
> diff --git a/scripts/dtc/dtc-lexer.lex.c_shipped b/scripts/dtc/dtc-lexer.lex.c_shipped
> index e27cc63..50c4420 100644
> --- a/scripts/dtc/dtc-lexer.lex.c_shipped
> +++ b/scripts/dtc/dtc-lexer.lex.c_shipped
> @@ -170,20 +170,7 @@ extern FILE *yyin, *yyout;
> #define EOB_ACT_END_OF_FILE 1
> #define EOB_ACT_LAST_MATCH 2
>
> - /* Note: We specifically omit the test for yy_rule_can_match_eol because it requires
> - * access to the local variable yy_act. Since yyless() is a macro, it would break
> - * existing scanners that call yyless() from OUTSIDE yylex.
> - * One obvious solution it to make yy_act a global. I tried that, and saw
> - * a 5% performance hit in a non-yylineno scanner, because yy_act is
> - * normally declared as a register variable-- so it is not worth it.
> - */
> - #define YY_LESS_LINENO(n) \
> - do { \
> - int yyl;\
> - for ( yyl = n; yyl < yyleng; ++yyl )\
> - if ( yytext[yyl] == '\n' )\
> - --yylineno;\
> - }while(0)
> + #define YY_LESS_LINENO(n)
>
> /* Return all but the first "n" matched characters back to the input stream. */
> #define yyless(n) \
> @@ -385,8 +372,8 @@ static void yy_fatal_error (yyconst char msg[] );
> *yy_cp = '\0'; \
> (yy_c_buf_p) = yy_cp;
>
> -#define YY_NUM_RULES 20
> -#define YY_END_OF_BUFFER 21
> +#define YY_NUM_RULES 17
> +#define YY_END_OF_BUFFER 18
> /* This struct is not used in this scanner,
> but its presence is necessary. */
> struct yy_trans_info
> @@ -394,20 +381,19 @@ struct yy_trans_info
> flex_int32_t yy_verify;
> flex_int32_t yy_nxt;
> };
> -static yyconst flex_int16_t yy_accept[104] =
> +static yyconst flex_int16_t yy_accept[94] =
> { 0,
> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
> - 21, 19, 16, 16, 19, 19, 19, 7, 7, 19,
> - 7, 19, 19, 19, 19, 13, 14, 14, 19, 8,
> - 8, 16, 0, 2, 0, 0, 9, 0, 0, 0,
> - 0, 0, 0, 7, 7, 5, 0, 6, 0, 12,
> - 12, 14, 14, 8, 0, 11, 9, 0, 0, 0,
> - 0, 18, 0, 0, 0, 0, 8, 0, 17, 0,
> - 0, 0, 0, 0, 10, 0, 0, 0, 0, 0,
> - 0, 0, 0, 0, 0, 0, 0, 0, 3, 15,
> + 18, 16, 13, 13, 16, 16, 16, 16, 16, 16,
> + 16, 10, 11, 11, 6, 6, 13, 0, 2, 0,
> + 7, 0, 0, 0, 0, 0, 0, 0, 5, 0,
> + 9, 9, 11, 11, 6, 0, 7, 0, 0, 0,
> + 0, 15, 0, 0, 0, 0, 6, 0, 14, 0,
> + 0, 0, 0, 0, 8, 0, 0, 0, 0, 0,
> + 0, 0, 0, 0, 0, 0, 0, 0, 3, 12,
> 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
> -
> 0, 4, 0
> +
> } ;
>
> static yyconst flex_int32_t yy_ec[256] =
> @@ -416,16 +402,16 @@ static yyconst flex_int32_t yy_ec[256] =
> 2, 2, 2, 1, 1, 1, 1, 1, 1, 1,
> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
> 1, 2, 1, 4, 5, 1, 1, 6, 1, 1,
> - 1, 7, 8, 8, 9, 8, 10, 11, 12, 13,
> - 13, 13, 13, 13, 13, 13, 13, 14, 1, 1,
> - 1, 1, 8, 8, 15, 15, 15, 15, 15, 15,
> - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
> - 16, 16, 16, 16, 16, 16, 16, 17, 16, 16,
> - 1, 18, 19, 1, 16, 1, 15, 20, 21, 22,
> -
> - 23, 15, 16, 24, 25, 16, 16, 26, 27, 28,
> - 24, 16, 16, 29, 30, 31, 32, 33, 16, 17,
> - 16, 16, 34, 1, 35, 1, 1, 1, 1, 1,
> + 1, 7, 5, 5, 8, 5, 9, 10, 11, 12,
> + 12, 12, 12, 12, 12, 12, 12, 13, 1, 1,
> + 1, 1, 5, 5, 14, 14, 14, 14, 14, 14,
> + 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
> + 15, 15, 15, 15, 15, 15, 15, 16, 15, 15,
> + 1, 17, 18, 1, 15, 1, 14, 19, 20, 21,
> +
> + 22, 14, 15, 15, 23, 15, 15, 24, 25, 26,
> + 15, 15, 15, 27, 28, 29, 30, 31, 15, 16,
> + 15, 15, 32, 1, 33, 1, 1, 1, 1, 1,
> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
> @@ -442,136 +428,114 @@ static yyconst flex_int32_t yy_ec[256] =
> 1, 1, 1, 1, 1
> } ;
>
> -static yyconst flex_int32_t yy_meta[36] =
> +static yyconst flex_int32_t yy_meta[34] =
> { 0,
> - 1, 1, 1, 1, 2, 1, 2, 2, 2, 3,
> - 4, 4, 4, 5, 6, 7, 7, 1, 1, 6,
> - 6, 6, 6, 7, 7, 7, 7, 7, 7, 7,
> - 7, 7, 7, 8, 1
> + 1, 1, 1, 1, 2, 1, 2, 2, 3, 4,
> + 4, 4, 5, 6, 7, 7, 1, 1, 6, 6,
> + 6, 6, 7, 7, 7, 7, 7, 7, 7, 7,
> + 7, 8, 1
> } ;
>
> -static yyconst flex_int16_t yy_base[117] =
> +static yyconst flex_int16_t yy_base[106] =
> { 0,
> - 0, 0, 30, 0, 44, 0, 67, 0, 97, 105,
> - 302, 303, 35, 44, 40, 94, 112, 0, 129, 152,
> - 296, 295, 159, 0, 176, 303, 0, 116, 95, 165,
> - 49, 46, 102, 303, 296, 0, 0, 288, 290, 293,
> - 264, 266, 270, 0, 0, 303, 0, 303, 264, 303,
> - 0, 0, 195, 101, 0, 0, 0, 0, 284, 125,
> - 277, 265, 225, 230, 216, 218, 0, 202, 224, 221,
> - 217, 107, 196, 188, 303, 206, 179, 186, 178, 185,
> - 183, 162, 161, 150, 169, 160, 145, 125, 303, 303,
> - 137, 109, 190, 103, 203, 167, 108, 197, 303, 123,
> -
> - 29, 303, 303, 215, 221, 226, 229, 234, 240, 246,
> - 250, 257, 265, 270, 275, 282
> + 0, 0, 237, 236, 25, 0, 47, 0, 30, 71,
> + 244, 247, 82, 84, 84, 211, 95, 229, 218, 0,
> + 111, 247, 0, 84, 83, 95, 106, 86, 247, 237,
> + 0, 230, 231, 234, 207, 209, 212, 220, 247, 206,
> + 247, 218, 0, 106, 116, 0, 0, 0, 223, 89,
> + 226, 219, 199, 206, 200, 204, 0, 190, 213, 212,
> + 202, 91, 178, 161, 247, 172, 144, 150, 140, 130,
> + 140, 124, 128, 120, 138, 137, 123, 122, 247, 247,
> + 134, 114, 132, 86, 135, 125, 90, 136, 247, 97,
> + 29, 247, 247, 153, 156, 161, 165, 170, 176, 180,
> +
> + 187, 195, 200, 205, 212
> } ;
>
> -static yyconst flex_int16_t yy_def[117] =
> +static yyconst flex_int16_t yy_def[106] =
> { 0,
> - 103, 1, 1, 3, 3, 5, 103, 7, 3, 3,
> - 103, 103, 103, 103, 104, 105, 103, 106, 103, 19,
> - 19, 20, 103, 107, 20, 103, 108, 109, 105, 103,
> - 103, 103, 104, 103, 104, 110, 111, 103, 112, 113,
> - 103, 103, 103, 106, 19, 103, 20, 103, 103, 103,
> - 20, 108, 109, 103, 114, 110, 111, 115, 112, 112,
> - 113, 103, 103, 103, 103, 103, 114, 115, 103, 103,
> - 103, 103, 103, 103, 103, 103, 103, 103, 103, 103,
> - 103, 103, 103, 103, 103, 103, 103, 103, 103, 103,
> - 103, 103, 103, 103, 103, 116, 103, 116, 103, 116,
> -
> - 103, 103, 0, 103, 103, 103, 103, 103, 103, 103,
> - 103, 103, 103, 103, 103, 103
> + 93, 1, 1, 1, 1, 5, 93, 7, 1, 1,
> + 93, 93, 93, 93, 94, 95, 93, 96, 17, 97,
> + 96, 93, 98, 99, 93, 93, 93, 94, 93, 94,
> + 100, 93, 101, 102, 93, 93, 93, 96, 93, 93,
> + 93, 96, 98, 99, 93, 103, 100, 104, 101, 101,
> + 102, 93, 93, 93, 93, 93, 103, 104, 93, 93,
> + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93,
> + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93,
> + 93, 93, 93, 93, 93, 105, 93, 105, 93, 105,
> + 93, 93, 0, 93, 93, 93, 93, 93, 93, 93,
> +
> + 93, 93, 93, 93, 93
> } ;
>
> -static yyconst flex_int16_t yy_nxt[339] =
> +static yyconst flex_int16_t yy_nxt[281] =
> { 0,
> - 12, 13, 14, 15, 12, 16, 12, 12, 12, 17,
> - 18, 18, 18, 12, 19, 20, 20, 12, 12, 21,
> - 19, 21, 19, 22, 20, 20, 20, 20, 20, 20,
> - 20, 20, 20, 12, 12, 12, 32, 32, 102, 23,
> - 12, 12, 12, 34, 20, 32, 32, 32, 32, 20,
> - 20, 20, 20, 20, 24, 24, 24, 35, 25, 54,
> - 54, 54, 26, 25, 25, 25, 25, 12, 13, 14,
> - 15, 27, 12, 27, 27, 27, 23, 27, 27, 27,
> - 12, 28, 28, 28, 12, 12, 28, 28, 28, 28,
> - 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
> -
> - 12, 12, 29, 36, 103, 34, 17, 30, 31, 31,
> - 29, 54, 54, 54, 17, 30, 31, 31, 39, 35,
> - 52, 40, 52, 52, 52, 103, 78, 38, 38, 46,
> - 101, 60, 79, 41, 69, 97, 42, 94, 43, 45,
> - 45, 45, 46, 45, 47, 47, 93, 92, 45, 45,
> - 45, 45, 47, 47, 47, 47, 47, 47, 47, 47,
> - 47, 47, 47, 47, 47, 39, 47, 91, 40, 90,
> - 99, 47, 47, 47, 47, 54, 54, 54, 89, 88,
> - 41, 55, 87, 49, 100, 43, 51, 51, 51, 86,
> - 51, 95, 95, 96, 85, 51, 51, 51, 51, 52,
> -
> - 99, 52, 52, 52, 95, 95, 96, 84, 46, 83,
> - 82, 81, 39, 79, 100, 33, 33, 33, 33, 33,
> - 33, 33, 33, 37, 80, 77, 37, 37, 37, 44,
> - 40, 44, 50, 76, 50, 52, 75, 52, 74, 52,
> - 52, 53, 73, 53, 53, 53, 53, 56, 56, 56,
> - 72, 56, 56, 57, 71, 57, 57, 59, 59, 59,
> - 59, 59, 59, 59, 59, 61, 61, 61, 61, 61,
> - 61, 61, 61, 67, 70, 67, 68, 68, 68, 62,
> - 68, 68, 98, 98, 98, 98, 98, 98, 98, 98,
> - 60, 66, 65, 64, 63, 62, 60, 58, 103, 48,
> -
> - 48, 103, 11, 103, 103, 103, 103, 103, 103, 103,
> - 103, 103, 103, 103, 103, 103, 103, 103, 103, 103,
> - 103, 103, 103, 103, 103, 103, 103, 103, 103, 103,
> - 103, 103, 103, 103, 103, 103, 103, 103
> + 12, 13, 14, 15, 12, 16, 12, 12, 17, 12,
> + 12, 12, 12, 18, 18, 18, 12, 12, 18, 18,
> + 18, 18, 18, 18, 18, 18, 18, 18, 18, 18,
> + 18, 12, 12, 19, 20, 20, 20, 92, 21, 25,
> + 26, 26, 22, 21, 21, 21, 21, 12, 13, 14,
> + 15, 23, 16, 23, 23, 19, 23, 23, 23, 12,
> + 24, 24, 24, 12, 12, 24, 24, 24, 24, 24,
> + 24, 24, 24, 24, 24, 24, 24, 24, 12, 12,
> + 25, 26, 26, 27, 27, 27, 27, 29, 43, 29,
> + 43, 43, 45, 45, 45, 50, 39, 59, 46, 93,
> +
> + 30, 33, 30, 34, 45, 45, 45, 27, 27, 68,
> + 43, 91, 43, 43, 69, 35, 87, 36, 39, 37,
> + 42, 42, 42, 39, 42, 45, 45, 45, 89, 42,
> + 42, 42, 42, 85, 85, 86, 85, 85, 86, 89,
> + 84, 90, 83, 82, 81, 80, 79, 78, 77, 76,
> + 75, 74, 90, 28, 28, 28, 28, 28, 28, 28,
> + 28, 31, 31, 31, 38, 38, 38, 38, 41, 73,
> + 41, 43, 72, 43, 71, 43, 43, 44, 33, 44,
> + 44, 44, 44, 47, 69, 47, 47, 49, 49, 49,
> + 49, 49, 49, 49, 49, 51, 51, 51, 51, 51,
> +
> + 51, 51, 51, 57, 70, 57, 58, 58, 58, 67,
> + 58, 58, 88, 88, 88, 88, 88, 88, 88, 88,
> + 34, 66, 65, 64, 63, 62, 61, 60, 52, 50,
> + 39, 56, 39, 55, 54, 53, 52, 50, 48, 93,
> + 40, 39, 32, 93, 19, 19, 11, 93, 93, 93,
> + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93,
> + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93,
> + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93
> } ;
>
> -static yyconst flex_int16_t yy_chk[339] =
> +static yyconst flex_int16_t yy_chk[281] =
> { 0,
> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
> - 1, 1, 1, 1, 1, 3, 13, 13, 101, 3,
> - 3, 3, 3, 15, 3, 14, 14, 32, 32, 3,
> - 3, 3, 3, 3, 5, 5, 5, 15, 5, 31,
> - 31, 31, 5, 5, 5, 5, 5, 7, 7, 7,
> + 1, 1, 1, 5, 5, 5, 5, 91, 5, 9,
> + 9, 9, 5, 5, 5, 5, 5, 7, 7, 7,
> 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
> 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
> 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
> -
> - 7, 7, 9, 16, 29, 33, 9, 9, 9, 9,
> - 10, 54, 54, 54, 10, 10, 10, 10, 17, 33,
> - 28, 17, 28, 28, 28, 100, 72, 16, 29, 28,
> - 97, 60, 72, 17, 60, 94, 17, 92, 17, 19,
> - 19, 19, 19, 19, 19, 19, 91, 88, 19, 19,
> - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19,
> - 19, 19, 20, 20, 20, 23, 20, 87, 23, 86,
> - 96, 20, 20, 20, 20, 30, 30, 30, 85, 84,
> - 23, 30, 83, 23, 96, 23, 25, 25, 25, 82,
> - 25, 93, 93, 93, 81, 25, 25, 25, 25, 53,
> -
> - 98, 53, 53, 53, 95, 95, 95, 80, 53, 79,
> - 78, 77, 76, 74, 98, 104, 104, 104, 104, 104,
> - 104, 104, 104, 105, 73, 71, 105, 105, 105, 106,
> - 70, 106, 107, 69, 107, 108, 68, 108, 66, 108,
> - 108, 109, 65, 109, 109, 109, 109, 110, 110, 110,
> - 64, 110, 110, 111, 63, 111, 111, 112, 112, 112,
> - 112, 112, 112, 112, 112, 113, 113, 113, 113, 113,
> - 113, 113, 113, 114, 62, 114, 115, 115, 115, 61,
> - 115, 115, 116, 116, 116, 116, 116, 116, 116, 116,
> - 59, 49, 43, 42, 41, 40, 39, 38, 35, 22,
> -
> - 21, 11, 103, 103, 103, 103, 103, 103, 103, 103,
> - 103, 103, 103, 103, 103, 103, 103, 103, 103, 103,
> - 103, 103, 103, 103, 103, 103, 103, 103, 103, 103,
> - 103, 103, 103, 103, 103, 103, 103, 103
> + 10, 10, 10, 13, 13, 14, 14, 15, 24, 28,
> + 24, 24, 25, 25, 25, 50, 24, 50, 25, 90,
> +
> + 15, 17, 28, 17, 26, 26, 26, 27, 27, 62,
> + 44, 87, 44, 44, 62, 17, 84, 17, 44, 17,
> + 21, 21, 21, 21, 21, 45, 45, 45, 86, 21,
> + 21, 21, 21, 83, 83, 83, 85, 85, 85, 88,
> + 82, 86, 81, 78, 77, 76, 75, 74, 73, 72,
> + 71, 70, 88, 94, 94, 94, 94, 94, 94, 94,
> + 94, 95, 95, 95, 96, 96, 96, 96, 97, 69,
> + 97, 98, 68, 98, 67, 98, 98, 99, 66, 99,
> + 99, 99, 99, 100, 64, 100, 100, 101, 101, 101,
> + 101, 101, 101, 101, 101, 102, 102, 102, 102, 102,
> +
> + 102, 102, 102, 103, 63, 103, 104, 104, 104, 61,
> + 104, 104, 105, 105, 105, 105, 105, 105, 105, 105,
> + 60, 59, 58, 56, 55, 54, 53, 52, 51, 49,
> + 42, 40, 38, 37, 36, 35, 34, 33, 32, 30,
> + 19, 18, 16, 11, 4, 3, 93, 93, 93, 93,
> + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93,
> + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93,
> + 93, 93, 93, 93, 93, 93, 93, 93, 93, 93
> } ;
>
> -/* Table of booleans, true if rule could match eol. */
> -static yyconst flex_int32_t yy_rule_can_match_eol[21] =
> - { 0,
> -1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0,
> - 0, };
> -
> static yy_state_type yy_last_accepting_state;
> static char *yy_last_accepting_cpos;
>
> @@ -616,6 +580,13 @@ char *yytext;
> #include "srcpos.h"
> #include "dtc-parser.tab.h"
>
> +YYLTYPE yylloc;
> +
> +/* CAUTION: this will stop working if we ever use yyless() or yyunput() */
> +#define YY_USER_ACTION \
> + { \
> + srcpos_update(&yylloc, yytext, yyleng); \
> + }
>
> /*#define LEXDEBUG 1*/
>
> @@ -625,19 +596,14 @@ char *yytext;
> #define DPRINT(fmt, ...) do { } while (0)
> #endif
>
> -static int dts_version; /* = 0 */
> +static int dts_version = 1;
>
> -#define BEGIN_DEFAULT() if (dts_version == 0) { \
> - DPRINT("<INITIAL>\n"); \
> - BEGIN(INITIAL); \
> - } else { \
> - DPRINT("<V1>\n"); \
> +#define BEGIN_DEFAULT() DPRINT("<V1>\n"); \
> BEGIN(V1); \
> - }
>
> static void push_input_file(const char *filename);
> static int pop_input_file(void);
> -#line 641 "dtc-lexer.lex.c"
> +#line 607 "dtc-lexer.lex.c"
>
> #define INITIAL 0
> #define INCLUDE 1
> @@ -826,9 +792,9 @@ YY_DECL
> register char *yy_cp, *yy_bp;
> register int yy_act;
>
> -#line 64 "dtc-lexer.l"
> +#line 66 "dtc-lexer.l"
>
> -#line 832 "dtc-lexer.lex.c"
> +#line 798 "dtc-lexer.lex.c"
>
> if ( !(yy_init) )
> {
> @@ -881,35 +847,21 @@ yy_match:
> while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
> {
> yy_current_state = (int) yy_def[yy_current_state];
> - if ( yy_current_state >= 104 )
> + if ( yy_current_state >= 94 )
> yy_c = yy_meta[(unsigned int) yy_c];
> }
> yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
> ++yy_cp;
> }
> - while ( yy_base[yy_current_state] != 303 );
> + while ( yy_current_state != 93 );
> + yy_cp = (yy_last_accepting_cpos);
> + yy_current_state = (yy_last_accepting_state);
>
> yy_find_action:
> yy_act = yy_accept[yy_current_state];
> - if ( yy_act == 0 )
> - { /* have to back up */
> - yy_cp = (yy_last_accepting_cpos);
> - yy_current_state = (yy_last_accepting_state);
> - yy_act = yy_accept[yy_current_state];
> - }
>
> YY_DO_BEFORE_ACTION;
>
> - if ( yy_act != YY_END_OF_BUFFER && yy_rule_can_match_eol[yy_act] )
> - {
> - int yyl;
> - for ( yyl = 0; yyl < yyleng; ++yyl )
> - if ( yytext[yyl] == '\n' )
> -
> - yylineno++;
> -;
> - }
> -
> do_action: /* This label is used only to access EOF actions. */
>
> switch ( yy_act )
> @@ -924,7 +876,7 @@ do_action: /* This label is used only to access EOF actions. */
> case 1:
> /* rule 1 can match eol */
> YY_RULE_SETUP
> -#line 65 "dtc-lexer.l"
> +#line 67 "dtc-lexer.l"
> {
> char *name = strchr(yytext, '\"') + 1;
> yytext[yyleng-1] = '\0';
> @@ -936,7 +888,7 @@ case YY_STATE_EOF(INCLUDE):
> case YY_STATE_EOF(BYTESTRING):
> case YY_STATE_EOF(PROPNODENAME):
> case YY_STATE_EOF(V1):
> -#line 71 "dtc-lexer.l"
> +#line 73 "dtc-lexer.l"
> {
> if (!pop_input_file()) {
> yyterminate();
> @@ -946,23 +898,18 @@ case YY_STATE_EOF(V1):
> case 2:
> /* rule 2 can match eol */
> YY_RULE_SETUP
> -#line 77 "dtc-lexer.l"
> +#line 79 "dtc-lexer.l"
> {
> - yylloc.file = srcpos_file;
> - yylloc.first_line = yylineno;
> DPRINT("String: %s\n", yytext);
> yylval.data = data_copy_escape_string(yytext+1,
> yyleng-2);
> - yylloc.first_line = yylineno;
> return DT_STRING;
> }
> YY_BREAK
> case 3:
> YY_RULE_SETUP
> -#line 87 "dtc-lexer.l"
> +#line 86 "dtc-lexer.l"
> {
> - yylloc.file = srcpos_file;
> - yylloc.first_line = yylineno;
> DPRINT("Keyword: /dts-v1/\n");
> dts_version = 1;
> BEGIN_DEFAULT();
> @@ -971,10 +918,8 @@ YY_RULE_SETUP
> YY_BREAK
> case 4:
> YY_RULE_SETUP
> -#line 96 "dtc-lexer.l"
> +#line 93 "dtc-lexer.l"
> {
> - yylloc.file = srcpos_file;
> - yylloc.first_line = yylineno;
> DPRINT("Keyword: /memreserve/\n");
> BEGIN_DEFAULT();
> return DT_MEMRESERVE;
> @@ -982,158 +927,100 @@ YY_RULE_SETUP
> YY_BREAK
> case 5:
> YY_RULE_SETUP
> -#line 104 "dtc-lexer.l"
> +#line 99 "dtc-lexer.l"
> {
> - yylloc.file = srcpos_file;
> - yylloc.first_line = yylineno;
> DPRINT("Label: %s\n", yytext);
> - yylval.labelref = strdup(yytext);
> + yylval.labelref = xstrdup(yytext);
> yylval.labelref[yyleng-1] = '\0';
> return DT_LABEL;
> }
> YY_BREAK
> case 6:
> YY_RULE_SETUP
> -#line 113 "dtc-lexer.l"
> -{
> - yylloc.file = srcpos_file;
> - yylloc.first_line = yylineno;
> - if (*yytext == 'b')
> - yylval.cbase = 2;
> - else if (*yytext == 'o')
> - yylval.cbase = 8;
> - else if (*yytext == 'd')
> - yylval.cbase = 10;
> - else
> - yylval.cbase = 16;
> - DPRINT("Base: %d\n", yylval.cbase);
> - return DT_BASE;
> - }
> - YY_BREAK
> -case 7:
> -YY_RULE_SETUP
> -#line 128 "dtc-lexer.l"
> +#line 106 "dtc-lexer.l"
> {
> - yylloc.file = srcpos_file;
> - yylloc.first_line = yylineno;
> - yylval.literal = strdup(yytext);
> - DPRINT("Literal: '%s'\n", yylval.literal);
> - return DT_LEGACYLITERAL;
> - }
> - YY_BREAK
> -case 8:
> -YY_RULE_SETUP
> -#line 136 "dtc-lexer.l"
> -{
> - yylloc.file = srcpos_file;
> - yylloc.first_line = yylineno;
> - yylval.literal = strdup(yytext);
> + yylval.literal = xstrdup(yytext);
> DPRINT("Literal: '%s'\n", yylval.literal);
> return DT_LITERAL;
> }
> YY_BREAK
> -case 9:
> +case 7:
> YY_RULE_SETUP
> -#line 144 "dtc-lexer.l"
> +#line 112 "dtc-lexer.l"
> { /* label reference */
> - yylloc.file = srcpos_file;
> - yylloc.first_line = yylineno;
> DPRINT("Ref: %s\n", yytext+1);
> - yylval.labelref = strdup(yytext+1);
> + yylval.labelref = xstrdup(yytext+1);
> return DT_REF;
> }
> YY_BREAK
> -case 10:
> +case 8:
> YY_RULE_SETUP
> -#line 152 "dtc-lexer.l"
> +#line 118 "dtc-lexer.l"
> { /* new-style path reference */
> - yylloc.file = srcpos_file;
> - yylloc.first_line = yylineno;
> yytext[yyleng-1] = '\0';
> DPRINT("Ref: %s\n", yytext+2);
> - yylval.labelref = strdup(yytext+2);
> + yylval.labelref = xstrdup(yytext+2);
> return DT_REF;
> }
> YY_BREAK
> -case 11:
> -YY_RULE_SETUP
> -#line 161 "dtc-lexer.l"
> -{ /* old-style path reference */
> - yylloc.file = srcpos_file;
> - yylloc.first_line = yylineno;
> - DPRINT("Ref: %s\n", yytext+1);
> - yylval.labelref = strdup(yytext+1);
> - return DT_REF;
> - }
> - YY_BREAK
> -case 12:
> +case 9:
> YY_RULE_SETUP
> -#line 169 "dtc-lexer.l"
> +#line 125 "dtc-lexer.l"
> {
> - yylloc.file = srcpos_file;
> - yylloc.first_line = yylineno;
> yylval.byte = strtol(yytext, NULL, 16);
> DPRINT("Byte: %02x\n", (int)yylval.byte);
> return DT_BYTE;
> }
> YY_BREAK
> -case 13:
> +case 10:
> YY_RULE_SETUP
> -#line 177 "dtc-lexer.l"
> +#line 131 "dtc-lexer.l"
> {
> - yylloc.file = srcpos_file;
> - yylloc.first_line = yylineno;
> DPRINT("/BYTESTRING\n");
> BEGIN_DEFAULT();
> return ']';
> }
> YY_BREAK
> -case 14:
> +case 11:
> YY_RULE_SETUP
> -#line 185 "dtc-lexer.l"
> +#line 137 "dtc-lexer.l"
> {
> - yylloc.file = srcpos_file;
> - yylloc.first_line = yylineno;
> DPRINT("PropNodeName: %s\n", yytext);
> - yylval.propnodename = strdup(yytext);
> + yylval.propnodename = xstrdup(yytext);
> BEGIN_DEFAULT();
> return DT_PROPNODENAME;
> }
> YY_BREAK
> -case 15:
> +case 12:
> YY_RULE_SETUP
> -#line 194 "dtc-lexer.l"
> +#line 144 "dtc-lexer.l"
> {
> - yylloc.file = srcpos_file;
> - yylloc.first_line = yylineno;
> DPRINT("Binary Include\n");
> return DT_INCBIN;
> }
> YY_BREAK
> -case 16:
> -/* rule 16 can match eol */
> +case 13:
> +/* rule 13 can match eol */
> YY_RULE_SETUP
> -#line 201 "dtc-lexer.l"
> +#line 149 "dtc-lexer.l"
> /* eat whitespace */
> YY_BREAK
> -case 17:
> -/* rule 17 can match eol */
> +case 14:
> +/* rule 14 can match eol */
> YY_RULE_SETUP
> -#line 202 "dtc-lexer.l"
> +#line 150 "dtc-lexer.l"
> /* eat C-style comments */
> YY_BREAK
> -case 18:
> -/* rule 18 can match eol */
> +case 15:
> +/* rule 15 can match eol */
> YY_RULE_SETUP
> -#line 203 "dtc-lexer.l"
> +#line 151 "dtc-lexer.l"
> /* eat C++-style comments */
> YY_BREAK
> -case 19:
> +case 16:
> YY_RULE_SETUP
> -#line 205 "dtc-lexer.l"
> +#line 153 "dtc-lexer.l"
> {
> - yylloc.file = srcpos_file;
> - yylloc.first_line = yylineno;
> DPRINT("Char: %c (\\x%02x)\n", yytext[0],
> (unsigned)yytext[0]);
> if (yytext[0] == '[') {
> @@ -1148,12 +1035,12 @@ YY_RULE_SETUP
> return yytext[0];
> }
> YY_BREAK
> -case 20:
> +case 17:
> YY_RULE_SETUP
> -#line 222 "dtc-lexer.l"
> +#line 168 "dtc-lexer.l"
> ECHO;
> YY_BREAK
> -#line 1157 "dtc-lexer.lex.c"
> +#line 1044 "dtc-lexer.lex.c"
>
> case YY_END_OF_BUFFER:
> {
> @@ -1218,7 +1105,8 @@ ECHO;
>
> else
> {
> - yy_cp = (yy_c_buf_p);
> + yy_cp = (yy_last_accepting_cpos);
> + yy_current_state = (yy_last_accepting_state);
> goto yy_find_action;
> }
> }
> @@ -1443,7 +1331,7 @@ static int yy_get_next_buffer (void)
> while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
> {
> yy_current_state = (int) yy_def[yy_current_state];
> - if ( yy_current_state >= 104 )
> + if ( yy_current_state >= 94 )
> yy_c = yy_meta[(unsigned int) yy_c];
> }
> yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
> @@ -1471,11 +1359,11 @@ static int yy_get_next_buffer (void)
> while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
> {
> yy_current_state = (int) yy_def[yy_current_state];
> - if ( yy_current_state >= 104 )
> + if ( yy_current_state >= 94 )
> yy_c = yy_meta[(unsigned int) yy_c];
> }
> yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
> - yy_is_jam = (yy_current_state == 103);
> + yy_is_jam = (yy_current_state == 93);
>
> return yy_is_jam ? 0 : yy_current_state;
> }
> @@ -1550,11 +1438,6 @@ static int yy_get_next_buffer (void)
> *(yy_c_buf_p) = '\0'; /* preserve yytext */
> (yy_hold_char) = *++(yy_c_buf_p);
>
> - if ( c == '\n' )
> -
> - yylineno++;
> -;
> -
> return c;
> }
> #endif /* ifndef YY_NO_INPUT */
> @@ -1669,10 +1552,6 @@ static void yy_load_buffer_state (void)
> yyfree((void *) b );
> }
>
> -#ifndef __cplusplus
> -extern int isatty (int );
> -#endif /* __cplusplus */
> -
> /* Initializes or reinitializes a buffer.
> * This function is sometimes called more than once on the same buffer,
> * such as during a yyrestart() or at EOF.
> @@ -1696,7 +1575,7 @@ extern int isatty (int );
> b->yy_bs_column = 0;
> }
>
> - b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
> + b->yy_is_interactive = 0;
>
> errno = oerrno;
> }
> @@ -2025,9 +1904,6 @@ static int yy_init_globals (void)
> * This function is called from yylex_destroy(), so don't allocate here.
> */
>
> - /* We do not touch yylineno unless the option is enabled. */
> - yylineno = 1;
> -
> (yy_buffer_stack) = 0;
> (yy_buffer_stack_top) = 0;
> (yy_buffer_stack_max) = 0;
> @@ -2120,104 +1996,29 @@ void yyfree (void * ptr )
>
> #define YYTABLES_NAME "yytables"
>
> -#line 222 "dtc-lexer.l"
> -
> -
> -
> -
> -/*
> - * Stack of nested include file contexts.
> - */
> -
> -struct incl_file {
> - struct dtc_file *file;
> - YY_BUFFER_STATE yy_prev_buf;
> - int yy_prev_lineno;
> - struct incl_file *prev;
> -};
> -
> -static struct incl_file *incl_file_stack;
> +#line 168 "dtc-lexer.l"
>
>
> -/*
> - * Detect infinite include recursion.
> - */
> -#define MAX_INCLUDE_DEPTH (100)
> -
> -static int incl_depth = 0;
> -
>
> static void push_input_file(const char *filename)
> {
> - struct incl_file *incl_file;
> - struct dtc_file *newfile;
> - struct search_path search, *searchptr = NULL;
> -
> assert(filename);
>
> - if (incl_depth++ >= MAX_INCLUDE_DEPTH)
> - die("Includes nested too deeply");
> -
> - if (srcpos_file) {
> - search.dir = srcpos_file->dir;
> - search.next = NULL;
> - search.prev = NULL;
> - searchptr = &search;
> - }
> -
> - newfile = dtc_open_file(filename, searchptr);
> + srcfile_push(filename);
>
> - incl_file = xmalloc(sizeof(struct incl_file));
> + yyin = current_srcfile->f;
>
> - /*
> - * Save current context.
> - */
> - incl_file->yy_prev_buf = YY_CURRENT_BUFFER;
> - incl_file->yy_prev_lineno = yylineno;
> - incl_file->file = srcpos_file;
> - incl_file->prev = incl_file_stack;
> -
> - incl_file_stack = incl_file;
> -
> - /*
> - * Establish new context.
> - */
> - srcpos_file = newfile;
> - yylineno = 1;
> - yyin = newfile->file;
> - yy_switch_to_buffer(yy_create_buffer(yyin,YY_BUF_SIZE));
> + yypush_buffer_state(yy_create_buffer(yyin,YY_BUF_SIZE));
> }
>
>
> static int pop_input_file(void)
> {
> - struct incl_file *incl_file;
> -
> - if (incl_file_stack == 0)
> + if (srcfile_pop() == 0)
> return 0;
>
> - dtc_close_file(srcpos_file);
> -
> - /*
> - * Pop.
> - */
> - --incl_depth;
> - incl_file = incl_file_stack;
> - incl_file_stack = incl_file->prev;
> -
> - /*
> - * Recover old context.
> - */
> - yy_delete_buffer(YY_CURRENT_BUFFER);
> - yy_switch_to_buffer(incl_file->yy_prev_buf);
> - yylineno = incl_file->yy_prev_lineno;
> - srcpos_file = incl_file->file;
> - yyin = incl_file->file ? incl_file->file->file : NULL;
> -
> - /*
> - * Free old state.
> - */
> - free(incl_file);
> + yypop_buffer_state();
> + yyin = current_srcfile->f;
>
> return 1;
> }
> diff --git a/scripts/dtc/dtc-parser.tab.c_shipped b/scripts/dtc/dtc-parser.tab.c_shipped
> index 2712937..9be2eea 100644
> --- a/scripts/dtc/dtc-parser.tab.c_shipped
> +++ b/scripts/dtc/dtc-parser.tab.c_shipped
> @@ -1,24 +1,23 @@
> -/* A Bison parser, made by GNU Bison 2.3. */
>
> -/* Skeleton implementation for Bison's Yacc-like parsers in C
> +/* A Bison parser, made by GNU Bison 2.4.1. */
>
> - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
> +/* Skeleton implementation for Bison's Yacc-like parsers in C
> +
> + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
> Free Software Foundation, Inc.
> -
> - This program is free software; you can redistribute it and/or modify
> +
> + 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 2, or (at your option)
> - any later version.
> -
> + 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, write to the Free Software
> - Foundation, Inc., 51 Franklin Street, Fifth Floor,
> - Boston, MA 02110-1301, USA. */
> + along with this program. If not, see <http://www.gnu.org/licenses/>. */
>
> /* As a special exception, you may create a larger work that contains
> part or all of the Bison parser skeleton and distribute that work
> @@ -29,7 +28,7 @@
> 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. */
>
> @@ -47,7 +46,7 @@
> #define YYBISON 1
>
> /* Bison version. */
> -#define YYBISON_VERSION "2.3"
> +#define YYBISON_VERSION "2.4.1"
>
> /* Skeleton name. */
> #define YYSKELETON_NAME "yacc.c"
> @@ -55,55 +54,32 @@
> /* Pure parsers. */
> #define YYPURE 0
>
> -/* Using locations. */
> -#define YYLSP_NEEDED 1
> -
> +/* Push parsers. */
> +#define YYPUSH 0
>
> +/* Pull parsers. */
> +#define YYPULL 1
>
> -/* Tokens. */
> -#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_PROPNODENAME = 260,
> - DT_LITERAL = 261,
> - DT_LEGACYLITERAL = 262,
> - DT_BASE = 263,
> - DT_BYTE = 264,
> - DT_STRING = 265,
> - DT_LABEL = 266,
> - DT_REF = 267,
> - DT_INCBIN = 268
> - };
> -#endif
> -/* Tokens. */
> -#define DT_V1 258
> -#define DT_MEMRESERVE 259
> -#define DT_PROPNODENAME 260
> -#define DT_LITERAL 261
> -#define DT_LEGACYLITERAL 262
> -#define DT_BASE 263
> -#define DT_BYTE 264
> -#define DT_STRING 265
> -#define DT_LABEL 266
> -#define DT_REF 267
> -#define DT_INCBIN 268
> -
> +/* Using locations. */
> +#define YYLSP_NEEDED 0
>
>
>
> /* Copy the first part of user declarations. */
> -#line 23 "dtc-parser.y"
> +
> +/* Line 189 of yacc.c */
> +#line 21 "dtc-parser.y"
>
> #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;
> @@ -111,6 +87,9 @@ extern int treesource_error;
> static unsigned long long eval_literal(const char *s, int base, int bits);
>
>
> +/* Line 189 of yacc.c */
> +#line 92 "dtc-parser.tab.c"
> +
> /* Enabling traces. */
> #ifndef YYDEBUG
> # define YYDEBUG 0
> @@ -129,10 +108,35 @@ static unsigned long long eval_literal(const char *s, int base, int bits);
> # define YYTOKEN_TABLE 0
> #endif
>
> +
> +/* Tokens. */
> +#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_PROPNODENAME = 260,
> + DT_LITERAL = 261,
> + DT_BASE = 262,
> + DT_BYTE = 263,
> + DT_STRING = 264,
> + DT_LABEL = 265,
> + DT_REF = 266,
> + DT_INCBIN = 267
> + };
> +#endif
> +
> +
> +
> #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
> typedef union YYSTYPE
> -#line 37 "dtc-parser.y"
> {
> +
> +/* Line 214 of yacc.c */
> +#line 39 "dtc-parser.y"
> +
> char *propnodename;
> char *literal;
> char *labelref;
> @@ -147,34 +151,23 @@ typedef union YYSTYPE
> struct node *node;
> struct node *nodelist;
> struct reserve_info *re;
> -}
> -/* Line 187 of yacc.c. */
> -#line 153 "dtc-parser.tab.c"
> - YYSTYPE;
> +
> +
> +
> +/* Line 214 of yacc.c */
> +#line 159 "dtc-parser.tab.c"
> +} YYSTYPE;
> +# define YYSTYPE_IS_TRIVIAL 1
> # define yystype YYSTYPE /* obsolescent; will be withdrawn */
> # define YYSTYPE_IS_DECLARED 1
> -# define YYSTYPE_IS_TRIVIAL 1
> -#endif
> -
> -#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
> -typedef struct YYLTYPE
> -{
> - int first_line;
> - int first_column;
> - int last_line;
> - int last_column;
> -} YYLTYPE;
> -# define yyltype YYLTYPE /* obsolescent; will be withdrawn */
> -# define YYLTYPE_IS_DECLARED 1
> -# define YYLTYPE_IS_TRIVIAL 1
> #endif
>
>
> /* Copy the second part of user declarations. */
>
>
> -/* Line 216 of yacc.c. */
> -#line 178 "dtc-parser.tab.c"
> +/* Line 264 of yacc.c */
> +#line 171 "dtc-parser.tab.c"
>
> #ifdef short
> # undef short
> @@ -249,14 +242,14 @@ typedef short int yytype_int16;
> #if (defined __STDC__ || defined __C99__FUNC__ \
> || defined __cplusplus || defined _MSC_VER)
> static int
> -YYID (int i)
> +YYID (int yyi)
> #else
> static int
> -YYID (i)
> - int i;
> +YYID (yyi)
> + int yyi;
> #endif
> {
> - return i;
> + return yyi;
> }
> #endif
>
> @@ -332,15 +325,13 @@ void free (void *); /* INFRINGES ON USER NAME SPACE */
>
> #if (! defined yyoverflow \
> && (! defined __cplusplus \
> - || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \
> - && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
> + || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
>
> /* A type that is properly aligned for any stack member. */
> union yyalloc
> {
> - yytype_int16 yyss;
> - YYSTYPE yyvs;
> - YYLTYPE yyls;
> + yytype_int16 yyss_alloc;
> + YYSTYPE yyvs_alloc;
> };
>
> /* The size of the maximum gap between one aligned stack and the next. */
> @@ -349,8 +340,8 @@ union yyalloc
> /* The size of an array large to enough to hold all stacks, each with
> N elements. */
> # define YYSTACK_BYTES(N) \
> - ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE) + sizeof (YYLTYPE)) \
> - + 2 * YYSTACK_GAP_MAXIMUM)
> + ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
> + + YYSTACK_GAP_MAXIMUM)
>
> /* Copy COUNT objects from FROM to TO. The source and destination do
> not overlap. */
> @@ -375,12 +366,12 @@ union yyalloc
> elements in the stack, and YYPTR gives the new location of the
> stack. Advance YYPTR to a properly aligned location for the next
> stack. */
> -# define YYSTACK_RELOCATE(Stack) \
> +# define YYSTACK_RELOCATE(Stack_alloc, Stack) \
> do \
> { \
> YYSIZE_T yynewbytes; \
> - YYCOPY (&yyptr->Stack, Stack, yysize); \
> - Stack = &yyptr->Stack; \
> + YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \
> + Stack = &yyptr->Stack_alloc; \
> yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
> yyptr += yynewbytes / sizeof (*yyptr); \
> } \
> @@ -389,22 +380,22 @@ union yyalloc
> #endif
>
> /* YYFINAL -- State number of the termination state. */
> -#define YYFINAL 9
> +#define YYFINAL 4
> /* YYLAST -- Last index in YYTABLE. */
> -#define YYLAST 73
> +#define YYLAST 56
>
> /* YYNTOKENS -- Number of terminals. */
> -#define YYNTOKENS 27
> +#define YYNTOKENS 25
> /* YYNNTS -- Number of nonterminals. */
> -#define YYNNTS 20
> +#define YYNNTS 16
> /* YYNRULES -- Number of rules. */
> -#define YYNRULES 45
> +#define YYNRULES 39
> /* YYNRULES -- Number of states. */
> -#define YYNSTATES 76
> +#define YYNSTATES 67
>
> /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */
> #define YYUNDEFTOK 2
> -#define YYMAXUTOK 268
> +#define YYMAXUTOK 267
>
> #define YYTRANSLATE(YYX) \
> ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
> @@ -416,15 +407,15 @@ static const yytype_uint8 yytranslate[] =
> 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
> 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
> 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
> - 24, 26, 2, 2, 25, 15, 2, 16, 2, 2,
> - 2, 2, 2, 2, 2, 2, 2, 2, 2, 14,
> - 20, 19, 21, 2, 2, 2, 2, 2, 2, 2,
> + 22, 24, 2, 2, 23, 2, 2, 14, 2, 2,
> + 2, 2, 2, 2, 2, 2, 2, 2, 2, 13,
> + 18, 17, 19, 2, 2, 2, 2, 2, 2, 2,
> 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
> 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
> - 2, 22, 2, 23, 2, 2, 2, 2, 2, 2,
> + 2, 20, 2, 21, 2, 2, 2, 2, 2, 2,
> 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
> 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
> - 2, 2, 2, 17, 2, 18, 2, 2, 2, 2,
> + 2, 2, 2, 15, 2, 16, 2, 2, 2, 2,
> 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
> 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
> 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
> @@ -438,7 +429,7 @@ static const yytype_uint8 yytranslate[] =
> 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
> 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
> 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
> - 5, 6, 7, 8, 9, 10, 11, 12, 13
> + 5, 6, 7, 8, 9, 10, 11, 12
> };
>
> #if YYDEBUG
> @@ -446,41 +437,37 @@ static const yytype_uint8 yytranslate[] =
> YYRHS. */
> static const yytype_uint8 yyprhs[] =
> {
> - 0, 0, 3, 8, 11, 12, 15, 21, 22, 25,
> - 27, 34, 36, 38, 41, 47, 48, 51, 57, 61,
> - 64, 69, 74, 77, 87, 93, 96, 97, 100, 103,
> - 104, 107, 110, 113, 114, 116, 118, 121, 122, 125,
> - 128, 129, 132, 135, 139, 140
> + 0, 0, 3, 8, 9, 12, 17, 20, 22, 25,
> + 29, 33, 39, 40, 43, 48, 51, 54, 57, 62,
> + 67, 70, 80, 86, 89, 90, 93, 96, 97, 100,
> + 103, 106, 108, 109, 112, 115, 116, 119, 122, 125
> };
>
> /* YYRHS -- A `-1'-separated list of the rules' RHS. */
> static const yytype_int8 yyrhs[] =
> {
> - 28, 0, -1, 3, 14, 29, 34, -1, 31, 34,
> - -1, -1, 30, 29, -1, 46, 4, 33, 33, 14,
> - -1, -1, 32, 31, -1, 30, -1, 46, 4, 33,
> - 15, 33, 14, -1, 6, -1, 7, -1, 16, 35,
> - -1, 17, 36, 44, 18, 14, -1, -1, 36, 37,
> - -1, 46, 5, 19, 38, 14, -1, 46, 5, 14,
> - -1, 39, 10, -1, 39, 20, 40, 21, -1, 39,
> - 22, 43, 23, -1, 39, 12, -1, 39, 13, 24,
> - 10, 25, 33, 25, 33, 26, -1, 39, 13, 24,
> - 10, 26, -1, 38, 11, -1, -1, 38, 25, -1,
> - 39, 11, -1, -1, 40, 42, -1, 40, 12, -1,
> - 40, 11, -1, -1, 8, -1, 6, -1, 41, 7,
> - -1, -1, 43, 9, -1, 43, 11, -1, -1, 45,
> - 44, -1, 45, 37, -1, 46, 5, 35, -1, -1,
> - 11, -1
> + 26, 0, -1, 3, 13, 27, 30, -1, -1, 28,
> + 27, -1, 4, 29, 29, 13, -1, 10, 28, -1,
> + 6, -1, 14, 31, -1, 30, 14, 31, -1, 30,
> + 11, 31, -1, 15, 32, 39, 16, 13, -1, -1,
> + 32, 33, -1, 5, 17, 34, 13, -1, 5, 13,
> + -1, 10, 33, -1, 35, 9, -1, 35, 18, 36,
> + 19, -1, 35, 20, 38, 21, -1, 35, 11, -1,
> + 35, 12, 22, 9, 23, 29, 23, 29, 24, -1,
> + 35, 12, 22, 9, 24, -1, 34, 10, -1, -1,
> + 34, 23, -1, 35, 10, -1, -1, 36, 37, -1,
> + 36, 11, -1, 36, 10, -1, 6, -1, -1, 38,
> + 8, -1, 38, 10, -1, -1, 40, 39, -1, 40,
> + 33, -1, 5, 31, -1, 10, 40, -1
> };
>
> /* YYRLINE[YYN] -- source line where rule number YYN was defined. */
> static const yytype_uint16 yyrline[] =
> {
> - 0, 89, 89, 93, 101, 104, 111, 119, 122, 129,
> - 133, 140, 144, 151, 158, 166, 169, 176, 180, 187,
> - 191, 195, 199, 203, 220, 231, 239, 242, 246, 254,
> - 257, 261, 266, 274, 277, 281, 285, 293, 296, 300,
> - 308, 311, 315, 323, 331, 334
> + 0, 86, 86, 95, 98, 105, 109, 117, 124, 128,
> + 132, 145, 153, 156, 163, 167, 171, 179, 183, 187,
> + 191, 195, 212, 222, 230, 233, 237, 245, 248, 252,
> + 257, 264, 272, 275, 279, 287, 290, 294, 302, 306
> };
> #endif
>
> @@ -490,13 +477,12 @@ static const yytype_uint16 yyrline[] =
> static const char *const yytname[] =
> {
> "$end", "error", "$undefined", "DT_V1", "DT_MEMRESERVE",
> - "DT_PROPNODENAME", "DT_LITERAL", "DT_LEGACYLITERAL", "DT_BASE",
> - "DT_BYTE", "DT_STRING", "DT_LABEL", "DT_REF", "DT_INCBIN", "';'", "'-'",
> - "'/'", "'{'", "'}'", "'='", "'<'", "'>'", "'['", "']'", "'('", "','",
> - "')'", "$accept", "sourcefile", "memreserves", "memreserve",
> - "v0_memreserves", "v0_memreserve", "addr", "devicetree", "nodedef",
> - "proplist", "propdef", "propdata", "propdataprefix", "celllist",
> - "cellbase", "cellval", "bytestring", "subnodes", "subnode", "label", 0
> + "DT_PROPNODENAME", "DT_LITERAL", "DT_BASE", "DT_BYTE", "DT_STRING",
> + "DT_LABEL", "DT_REF", "DT_INCBIN", "';'", "'/'", "'{'", "'}'", "'='",
> + "'<'", "'>'", "'['", "']'", "'('", "','", "')'", "$accept", "sourcefile",
> + "memreserves", "memreserve", "addr", "devicetree", "nodedef", "proplist",
> + "propdef", "propdata", "propdataprefix", "celllist", "cellval",
> + "bytestring", "subnodes", "subnode", 0
> };
> #endif
>
> @@ -506,29 +492,27 @@ static const char *const yytname[] =
> static const yytype_uint16 yytoknum[] =
> {
> 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
> - 265, 266, 267, 268, 59, 45, 47, 123, 125, 61,
> - 60, 62, 91, 93, 40, 44, 41
> + 265, 266, 267, 59, 47, 123, 125, 61, 60, 62,
> + 91, 93, 40, 44, 41
> };
> # endif
>
> /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
> static const yytype_uint8 yyr1[] =
> {
> - 0, 27, 28, 28, 29, 29, 30, 31, 31, 32,
> - 32, 33, 33, 34, 35, 36, 36, 37, 37, 38,
> - 38, 38, 38, 38, 38, 38, 39, 39, 39, 40,
> - 40, 40, 40, 41, 41, 42, 42, 43, 43, 43,
> - 44, 44, 44, 45, 46, 46
> + 0, 25, 26, 27, 27, 28, 28, 29, 30, 30,
> + 30, 31, 32, 32, 33, 33, 33, 34, 34, 34,
> + 34, 34, 34, 34, 35, 35, 35, 36, 36, 36,
> + 36, 37, 38, 38, 38, 39, 39, 39, 40, 40
> };
>
> /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
> static const yytype_uint8 yyr2[] =
> {
> - 0, 2, 4, 2, 0, 2, 5, 0, 2, 1,
> - 6, 1, 1, 2, 5, 0, 2, 5, 3, 2,
> - 4, 4, 2, 9, 5, 2, 0, 2, 2, 0,
> - 2, 2, 2, 0, 1, 1, 2, 0, 2, 2,
> - 0, 2, 2, 3, 0, 1
> + 0, 2, 4, 0, 2, 4, 2, 1, 2, 3,
> + 3, 5, 0, 2, 4, 2, 2, 2, 4, 4,
> + 2, 9, 5, 2, 0, 2, 2, 0, 2, 2,
> + 2, 1, 0, 2, 2, 0, 2, 2, 2, 2
> };
>
> /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
> @@ -536,86 +520,79 @@ static const yytype_uint8 yyr2[] =
> means the default is an error. */
> static const yytype_uint8 yydefact[] =
> {
> - 7, 0, 45, 0, 9, 0, 7, 0, 4, 1,
> - 0, 3, 8, 0, 0, 4, 0, 15, 13, 11,
> - 12, 0, 2, 5, 0, 40, 0, 0, 0, 16,
> - 0, 40, 0, 0, 6, 0, 42, 41, 0, 10,
> - 14, 18, 26, 43, 0, 0, 25, 17, 27, 19,
> - 28, 22, 0, 29, 37, 0, 33, 0, 0, 35,
> - 34, 32, 31, 20, 0, 30, 38, 39, 21, 0,
> - 24, 36, 0, 0, 0, 23
> + 0, 0, 0, 3, 1, 0, 0, 0, 3, 7,
> + 0, 6, 0, 2, 4, 0, 12, 8, 0, 0,
> + 5, 35, 10, 9, 0, 0, 13, 0, 35, 15,
> + 24, 38, 16, 39, 0, 37, 36, 0, 0, 11,
> + 23, 14, 25, 17, 26, 20, 0, 27, 32, 0,
> + 0, 0, 0, 31, 30, 29, 18, 28, 33, 34,
> + 19, 0, 22, 0, 0, 0, 21
> };
>
> /* YYDEFGOTO[NTERM-NUM]. */
> static const yytype_int8 yydefgoto[] =
> {
> - -1, 3, 14, 4, 5, 6, 27, 11, 18, 25,
> - 29, 44, 45, 56, 64, 65, 57, 30, 31, 7
> + -1, 2, 7, 8, 10, 13, 17, 21, 26, 37,
> + 38, 50, 57, 51, 27, 28
> };
>
> /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
> STATE-NUM. */
> -#define YYPACT_NINF -14
> +#define YYPACT_NINF -12
> static const yytype_int8 yypact[] =
> {
> - 30, -11, -14, 7, -14, -1, 27, 13, 27, -14,
> - 8, -14, -14, 40, -1, 27, 35, -14, -14, -14,
> - -14, 21, -14, -14, 40, 24, 40, 28, 40, -14,
> - 32, 24, 46, 38, -14, 39, -14, -14, 26, -14,
> - -14, -14, -14, -14, -9, 10, -14, -14, -14, -14,
> - -14, -14, 31, -14, -14, 44, -2, 3, 23, -14,
> - -14, -14, -14, -14, 50, -14, -14, -14, -14, 40,
> - -14, -14, 33, 40, 36, -14
> + 10, -11, 18, -1, -12, 22, -1, 15, -1, -12,
> + 22, -12, 20, 1, -12, 17, -12, -12, 20, 20,
> + -12, 6, -12, -12, 21, 6, -12, 23, 6, -12,
> + -12, -12, -12, -12, 28, -12, -12, -6, 13, -12,
> + -12, -12, -12, -12, -12, -12, 24, -12, -12, 33,
> + -5, 0, -4, -12, -12, -12, -12, -12, -12, -12,
> + -12, 22, -12, 25, 22, 19, -12
> };
>
> /* YYPGOTO[NTERM-NUM]. */
> static const yytype_int8 yypgoto[] =
> {
> - -14, -14, 48, 29, 53, -14, -13, 47, 34, -14,
> - 37, -14, -14, -14, -14, -14, -14, 42, -14, -7
> + -12, -12, 36, 39, -10, -12, 8, -12, 12, -12,
> + -12, -12, -12, -12, 27, 31
> };
>
> /* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
> positive, shift that token. If negative, reduce the rule which
> number is the opposite. If zero, do what YYDEFACT says.
> If YYTABLE_NINF, syntax error. */
> -#define YYTABLE_NINF -45
> -static const yytype_int8 yytable[] =
> +#define YYTABLE_NINF -1
> +static const yytype_uint8 yytable[] =
> {
> - 21, 16, 46, 8, 59, 47, 60, 9, 16, 61,
> - 62, 28, 66, 33, 67, 10, 48, 13, 32, 63,
> - 49, 50, 51, 52, 32, 17, 68, 19, 20, -44,
> - 53, -44, 54, 1, -44, 2, 26, 15, 2, 24,
> - 41, 2, 34, 17, 15, 42, 19, 20, 69, 70,
> - 35, 38, 39, 40, 58, 55, 72, 71, 73, 12,
> - 74, 22, 75, 23, 0, 0, 0, 0, 36, 0,
> - 0, 0, 43, 37
> + 15, 53, 3, 5, 40, 54, 55, 41, 58, 6,
> + 59, 24, 18, 1, 56, 19, 25, 42, 4, 61,
> + 62, 60, 43, 44, 45, 46, 22, 23, 9, 12,
> + 20, 47, 31, 48, 29, 16, 16, 32, 30, 34,
> + 35, 39, 52, 66, 14, 11, 49, 0, 64, 0,
> + 0, 63, 0, 0, 65, 36, 33
> };
>
> static const yytype_int8 yycheck[] =
> {
> - 13, 8, 11, 14, 6, 14, 8, 0, 15, 11,
> - 12, 24, 9, 26, 11, 16, 25, 4, 25, 21,
> - 10, 11, 12, 13, 31, 17, 23, 6, 7, 5,
> - 20, 4, 22, 3, 4, 11, 15, 8, 11, 4,
> - 14, 11, 14, 17, 15, 19, 6, 7, 25, 26,
> - 18, 5, 14, 14, 10, 24, 69, 7, 25, 6,
> - 73, 14, 26, 15, -1, -1, -1, -1, 31, -1,
> - -1, -1, 38, 31
> + 10, 6, 13, 4, 10, 10, 11, 13, 8, 10,
> + 10, 5, 11, 3, 19, 14, 10, 23, 0, 23,
> + 24, 21, 9, 10, 11, 12, 18, 19, 6, 14,
> + 13, 18, 24, 20, 13, 15, 15, 25, 17, 16,
> + 28, 13, 9, 24, 8, 6, 22, -1, 23, -1,
> + -1, 61, -1, -1, 64, 28, 25
> };
>
> /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
> symbol of state STATE-NUM. */
> static const yytype_uint8 yystos[] =
> {
> - 0, 3, 11, 28, 30, 31, 32, 46, 14, 0,
> - 16, 34, 31, 4, 29, 30, 46, 17, 35, 6,
> - 7, 33, 34, 29, 4, 36, 15, 33, 33, 37,
> - 44, 45, 46, 33, 14, 18, 37, 44, 5, 14,
> - 14, 14, 19, 35, 38, 39, 11, 14, 25, 10,
> - 11, 12, 13, 20, 22, 24, 40, 43, 10, 6,
> - 8, 11, 12, 21, 41, 42, 9, 11, 23, 25,
> - 26, 7, 33, 25, 33, 26
> + 0, 3, 26, 13, 0, 4, 10, 27, 28, 6,
> + 29, 28, 14, 30, 27, 29, 15, 31, 11, 14,
> + 13, 32, 31, 31, 5, 10, 33, 39, 40, 13,
> + 17, 31, 33, 40, 16, 33, 39, 34, 35, 13,
> + 10, 13, 23, 9, 10, 11, 12, 18, 20, 22,
> + 36, 38, 9, 6, 10, 11, 19, 37, 8, 10,
> + 21, 23, 24, 29, 23, 29, 24
> };
>
> #define yyerrok (yyerrstatus = 0)
> @@ -728,7 +705,7 @@ do { \
> { \
> YYFPRINTF (stderr, "%s ", Title); \
> yy_symbol_print (stderr, \
> - Type, Value, Location); \
> + Type, Value); \
> YYFPRINTF (stderr, "\n"); \
> } \
> } while (YYID (0))
> @@ -742,19 +719,17 @@ do { \
> #if (defined __STDC__ || defined __C99__FUNC__ \
> || defined __cplusplus || defined _MSC_VER)
> static void
> -yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp)
> +yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
> #else
> static void
> -yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp)
> +yy_symbol_value_print (yyoutput, yytype, yyvaluep)
> FILE *yyoutput;
> int yytype;
> YYSTYPE const * const yyvaluep;
> - YYLTYPE const * const yylocationp;
> #endif
> {
> if (!yyvaluep)
> return;
> - YYUSE (yylocationp);
> # ifdef YYPRINT
> if (yytype < YYNTOKENS)
> YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
> @@ -776,14 +751,13 @@ yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp)
> #if (defined __STDC__ || defined __C99__FUNC__ \
> || defined __cplusplus || defined _MSC_VER)
> static void
> -yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp)
> +yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
> #else
> static void
> -yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp)
> +yy_symbol_print (yyoutput, yytype, yyvaluep)
> FILE *yyoutput;
> int yytype;
> YYSTYPE const * const yyvaluep;
> - YYLTYPE const * const yylocationp;
> #endif
> {
> if (yytype < YYNTOKENS)
> @@ -791,9 +765,7 @@ yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp)
> else
> YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
>
> - YY_LOCATION_PRINT (yyoutput, *yylocationp);
> - YYFPRINTF (yyoutput, ": ");
> - yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp);
> + yy_symbol_value_print (yyoutput, yytype, yyvaluep);
> YYFPRINTF (yyoutput, ")");
> }
>
> @@ -805,17 +777,20 @@ yy_symbol_print (yyoutput, yytype, yyvaluep, yylocationp)
> #if (defined __STDC__ || defined __C99__FUNC__ \
> || defined __cplusplus || defined _MSC_VER)
> static void
> -yy_stack_print (yytype_int16 *bottom, yytype_int16 *top)
> +yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
> #else
> static void
> -yy_stack_print (bottom, top)
> - yytype_int16 *bottom;
> - yytype_int16 *top;
> +yy_stack_print (yybottom, yytop)
> + yytype_int16 *yybottom;
> + yytype_int16 *yytop;
> #endif
> {
> YYFPRINTF (stderr, "Stack now");
> - for (; bottom <= top; ++bottom)
> - YYFPRINTF (stderr, " %d", *bottom);
> + for (; yybottom <= yytop; yybottom++)
> + {
> + int yybot = *yybottom;
> + YYFPRINTF (stderr, " %d", yybot);
> + }
> YYFPRINTF (stderr, "\n");
> }
>
> @@ -833,12 +808,11 @@ do { \
> #if (defined __STDC__ || defined __C99__FUNC__ \
> || defined __cplusplus || defined _MSC_VER)
> static void
> -yy_reduce_print (YYSTYPE *yyvsp, YYLTYPE *yylsp, int yyrule)
> +yy_reduce_print (YYSTYPE *yyvsp, int yyrule)
> #else
> static void
> -yy_reduce_print (yyvsp, yylsp, yyrule)
> +yy_reduce_print (yyvsp, yyrule)
> YYSTYPE *yyvsp;
> - YYLTYPE *yylsp;
> int yyrule;
> #endif
> {
> @@ -850,18 +824,18 @@ yy_reduce_print (yyvsp, yylsp, yyrule)
> /* The symbols being reduced. */
> for (yyi = 0; yyi < yynrhs; yyi++)
> {
> - fprintf (stderr, " $%d = ", yyi + 1);
> + YYFPRINTF (stderr, " $%d = ", yyi + 1);
> yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
> &(yyvsp[(yyi + 1) - (yynrhs)])
> - , &(yylsp[(yyi + 1) - (yynrhs)]) );
> - fprintf (stderr, "\n");
> + );
> + YYFPRINTF (stderr, "\n");
> }
> }
>
> # define YY_REDUCE_PRINT(Rule) \
> do { \
> if (yydebug) \
> - yy_reduce_print (yyvsp, yylsp, Rule); \
> + yy_reduce_print (yyvsp, Rule); \
> } while (YYID (0))
>
> /* Nonzero means print parse trace. It is left uninitialized so that
> @@ -1112,18 +1086,16 @@ yysyntax_error (char *yyresult, int yystate, int yychar)
> #if (defined __STDC__ || defined __C99__FUNC__ \
> || defined __cplusplus || defined _MSC_VER)
> static void
> -yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp)
> +yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep)
> #else
> static void
> -yydestruct (yymsg, yytype, yyvaluep, yylocationp)
> +yydestruct (yymsg, yytype, yyvaluep)
> const char *yymsg;
> int yytype;
> YYSTYPE *yyvaluep;
> - YYLTYPE *yylocationp;
> #endif
> {
> YYUSE (yyvaluep);
> - YYUSE (yylocationp);
>
> if (!yymsg)
> yymsg = "Deleting";
> @@ -1136,10 +1108,8 @@ yydestruct (yymsg, yytype, yyvaluep, yylocationp)
> break;
> }
> }
> -
>
> /* Prevent warnings from -Wmissing-prototypes. */
> -
> #ifdef YYPARSE_PARAM
> #if defined __STDC__ || defined __cplusplus
> int yyparse (void *YYPARSE_PARAM);
> @@ -1155,23 +1125,20 @@ int yyparse ();
> #endif /* ! YYPARSE_PARAM */
>
>
> -
> -/* The look-ahead symbol. */
> +/* The lookahead symbol. */
> int yychar;
>
> -/* The semantic value of the look-ahead symbol. */
> +/* The semantic value of the lookahead symbol. */
> YYSTYPE yylval;
>
> /* Number of syntax errors so far. */
> int yynerrs;
> -/* Location data for the look-ahead symbol. */
> -YYLTYPE yylloc;
>
>
>
> -/*----------.
> -| yyparse. |
> -`----------*/
> +/*-------------------------.
> +| yyparse or yypush_parse. |
> +`-------------------------*/
>
> #ifdef YYPARSE_PARAM
> #if (defined __STDC__ || defined __C99__FUNC__ \
> @@ -1195,79 +1162,70 @@ yyparse ()
> #endif
> #endif
> {
> -
> - int yystate;
> - int yyn;
> - int yyresult;
> - /* Number of tokens to shift before error messages enabled. */
> - int yyerrstatus;
> - /* Look-ahead token as an internal (translated) token number. */
> - int yytoken = 0;
> -#if YYERROR_VERBOSE
> - /* Buffer for error messages, and its allocated size. */
> - char yymsgbuf[128];
> - char *yymsg = yymsgbuf;
> - YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
> -#endif
>
> - /* Three stacks and their tools:
> - `yyss': related to states,
> - `yyvs': related to semantic values,
> - `yyls': related to locations.
>
> - Refer to the stacks thru separate pointers, to allow yyoverflow
> - to reallocate them elsewhere. */
> + int yystate;
> + /* Number of tokens to shift before error messages enabled. */
> + int yyerrstatus;
>
> - /* The state stack. */
> - yytype_int16 yyssa[YYINITDEPTH];
> - yytype_int16 *yyss = yyssa;
> - yytype_int16 *yyssp;
> + /* The stacks and their tools:
> + `yyss': related to states.
> + `yyvs': related to semantic values.
>
> - /* The semantic value stack. */
> - YYSTYPE yyvsa[YYINITDEPTH];
> - YYSTYPE *yyvs = yyvsa;
> - YYSTYPE *yyvsp;
> + Refer to the stacks thru separate pointers, to allow yyoverflow
> + to reallocate them elsewhere. */
>
> - /* The location stack. */
> - YYLTYPE yylsa[YYINITDEPTH];
> - YYLTYPE *yyls = yylsa;
> - YYLTYPE *yylsp;
> - /* The locations where the error started and ended. */
> - YYLTYPE yyerror_range[2];
> + /* The state stack. */
> + yytype_int16 yyssa[YYINITDEPTH];
> + yytype_int16 *yyss;
> + yytype_int16 *yyssp;
>
> -#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N), yylsp -= (N))
> + /* The semantic value stack. */
> + YYSTYPE yyvsa[YYINITDEPTH];
> + YYSTYPE *yyvs;
> + YYSTYPE *yyvsp;
>
> - YYSIZE_T yystacksize = YYINITDEPTH;
> + YYSIZE_T yystacksize;
>
> + int yyn;
> + int yyresult;
> + /* Lookahead token as an internal (translated) token number. */
> + int yytoken;
> /* The variables used to return semantic value and location from the
> action routines. */
> YYSTYPE yyval;
> - YYLTYPE yyloc;
> +
> +#if YYERROR_VERBOSE
> + /* Buffer for error messages, and its allocated size. */
> + char yymsgbuf[128];
> + char *yymsg = yymsgbuf;
> + YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
> +#endif
> +
> +#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N))
>
> /* The number of symbols on the RHS of the reduced rule.
> Keep to zero when no symbol should be popped. */
> int yylen = 0;
>
> + yytoken = 0;
> + yyss = yyssa;
> + yyvs = yyvsa;
> + yystacksize = YYINITDEPTH;
> +
> YYDPRINTF ((stderr, "Starting parse\n"));
>
> yystate = 0;
> yyerrstatus = 0;
> yynerrs = 0;
> - yychar = YYEMPTY; /* Cause a token to be read. */
> + yychar = YYEMPTY; /* Cause a token to be read. */
>
> /* Initialize stack pointers.
> Waste one element of value and location stack
> so that they stay on the same level as the state stack.
> The wasted elements are never initialized. */
> -
> yyssp = yyss;
> yyvsp = yyvs;
> - yylsp = yyls;
> -#if YYLTYPE_IS_TRIVIAL
> - /* Initialize the default location before parsing starts. */
> - yylloc.first_line = yylloc.last_line = 1;
> - yylloc.first_column = yylloc.last_column = 0;
> -#endif
>
> goto yysetstate;
>
> @@ -1294,7 +1252,6 @@ yyparse ()
> memory. */
> YYSTYPE *yyvs1 = yyvs;
> yytype_int16 *yyss1 = yyss;
> - YYLTYPE *yyls1 = yyls;
>
> /* Each stack pointer address is followed by the size of the
> data in use in that stack, in bytes. This used to be a
> @@ -1303,9 +1260,8 @@ yyparse ()
> yyoverflow (YY_("memory exhausted"),
> &yyss1, yysize * sizeof (*yyssp),
> &yyvs1, yysize * sizeof (*yyvsp),
> - &yyls1, yysize * sizeof (*yylsp),
> &yystacksize);
> - yyls = yyls1;
> +
> yyss = yyss1;
> yyvs = yyvs1;
> }
> @@ -1326,9 +1282,8 @@ yyparse ()
> (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
> if (! yyptr)
> goto yyexhaustedlab;
> - YYSTACK_RELOCATE (yyss);
> - YYSTACK_RELOCATE (yyvs);
> - YYSTACK_RELOCATE (yyls);
> + YYSTACK_RELOCATE (yyss_alloc, yyss);
> + YYSTACK_RELOCATE (yyvs_alloc, yyvs);
> # undef YYSTACK_RELOCATE
> if (yyss1 != yyssa)
> YYSTACK_FREE (yyss1);
> @@ -1338,7 +1293,6 @@ yyparse ()
>
> yyssp = yyss + yysize - 1;
> yyvsp = yyvs + yysize - 1;
> - yylsp = yyls + yysize - 1;
>
> YYDPRINTF ((stderr, "Stack size increased to %lu\n",
> (unsigned long int) yystacksize));
> @@ -1349,6 +1303,9 @@ yyparse ()
>
> YYDPRINTF ((stderr, "Entering state %d\n", yystate));
>
> + if (yystate == YYFINAL)
> + YYACCEPT;
> +
> goto yybackup;
>
> /*-----------.
> @@ -1357,16 +1314,16 @@ yyparse ()
> yybackup:
>
> /* Do appropriate processing given the current state. Read a
> - look-ahead token if we need one and don't already have one. */
> + lookahead token if we need one and don't already have one. */
>
> - /* First try to decide what to do without reference to look-ahead token. */
> + /* First try to decide what to do without reference to lookahead token. */
> yyn = yypact[yystate];
> if (yyn == YYPACT_NINF)
> goto yydefault;
>
> - /* Not known => get a look-ahead token if don't already have one. */
> + /* Not known => get a lookahead token if don't already have one. */
>
> - /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */
> + /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
> if (yychar == YYEMPTY)
> {
> YYDPRINTF ((stderr, "Reading a token: "));
> @@ -1398,24 +1355,20 @@ yybackup:
> goto yyreduce;
> }
>
> - if (yyn == YYFINAL)
> - YYACCEPT;
> -
> /* Count tokens shifted since error; after three, turn off error
> status. */
> if (yyerrstatus)
> yyerrstatus--;
>
> - /* Shift the look-ahead token. */
> + /* Shift the lookahead token. */
> YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
>
> - /* Discard the shifted token unless it is eof. */
> - if (yychar != YYEOF)
> - yychar = YYEMPTY;
> + /* Discard the shifted token. */
> + yychar = YYEMPTY;
>
> yystate = yyn;
> *++yyvsp = yylval;
> - *++yylsp = yylloc;
> +
> goto yynewstate;
>
>
> @@ -1446,337 +1399,387 @@ yyreduce:
> GCC warning that YYVAL may be used uninitialized. */
> yyval = yyvsp[1-yylen];
>
> - /* Default location. */
> - YYLLOC_DEFAULT (yyloc, (yylsp - yylen), yylen);
> +
> YY_REDUCE_PRINT (yyn);
> switch (yyn)
> {
> case 2:
> -#line 90 "dtc-parser.y"
> +
> +/* Line 1455 of yacc.c */
> +#line 87 "dtc-parser.y"
> {
> - the_boot_info = build_boot_info((yyvsp[(3) - (4)].re), (yyvsp[(4) - (4)].node), 0);
> + the_boot_info = build_boot_info((yyvsp[(3) - (4)].re), (yyvsp[(4) - (4)].node),
> + guess_boot_cpuid((yyvsp[(4) - (4)].node)));
> ;}
> break;
>
> case 3:
> -#line 94 "dtc-parser.y"
> +
> +/* Line 1455 of yacc.c */
> +#line 95 "dtc-parser.y"
> {
> - the_boot_info = build_boot_info((yyvsp[(1) - (2)].re), (yyvsp[(2) - (2)].node), 0);
> + (yyval.re) = NULL;
> ;}
> break;
>
> case 4:
> -#line 101 "dtc-parser.y"
> +
> +/* Line 1455 of yacc.c */
> +#line 99 "dtc-parser.y"
> {
> - (yyval.re) = NULL;
> + (yyval.re) = chain_reserve_entry((yyvsp[(1) - (2)].re), (yyvsp[(2) - (2)].re));
> ;}
> break;
>
> case 5:
> -#line 105 "dtc-parser.y"
> +
> +/* Line 1455 of yacc.c */
> +#line 106 "dtc-parser.y"
> {
> - (yyval.re) = chain_reserve_entry((yyvsp[(1) - (2)].re), (yyvsp[(2) - (2)].re));
> + (yyval.re) = build_reserve_entry((yyvsp[(2) - (4)].addr), (yyvsp[(3) - (4)].addr));
> ;}
> break;
>
> case 6:
> -#line 112 "dtc-parser.y"
> +
> +/* Line 1455 of yacc.c */
> +#line 110 "dtc-parser.y"
> {
> - (yyval.re) = build_reserve_entry((yyvsp[(3) - (5)].addr), (yyvsp[(4) - (5)].addr), (yyvsp[(1) - (5)].labelref));
> + add_label(&(yyvsp[(2) - (2)].re)->labels, (yyvsp[(1) - (2)].labelref));
> + (yyval.re) = (yyvsp[(2) - (2)].re);
> ;}
> break;
>
> case 7:
> -#line 119 "dtc-parser.y"
> +
> +/* Line 1455 of yacc.c */
> +#line 118 "dtc-parser.y"
> {
> - (yyval.re) = NULL;
> + (yyval.addr) = eval_literal((yyvsp[(1) - (1)].literal), 0, 64);
> ;}
> break;
>
> case 8:
> -#line 123 "dtc-parser.y"
> +
> +/* Line 1455 of yacc.c */
> +#line 125 "dtc-parser.y"
> {
> - (yyval.re) = chain_reserve_entry((yyvsp[(1) - (2)].re), (yyvsp[(2) - (2)].re));
> + (yyval.node) = name_node((yyvsp[(2) - (2)].node), "");
> ;}
> break;
>
> case 9:
> -#line 130 "dtc-parser.y"
> +
> +/* Line 1455 of yacc.c */
> +#line 129 "dtc-parser.y"
> {
> - (yyval.re) = (yyvsp[(1) - (1)].re);
> + (yyval.node) = merge_nodes((yyvsp[(1) - (3)].node), (yyvsp[(3) - (3)].node));
> ;}
> break;
>
> case 10:
> -#line 134 "dtc-parser.y"
> +
> +/* Line 1455 of yacc.c */
> +#line 133 "dtc-parser.y"
> {
> - (yyval.re) = build_reserve_entry((yyvsp[(3) - (6)].addr), (yyvsp[(5) - (6)].addr) - (yyvsp[(3) - (6)].addr) + 1, (yyvsp[(1) - (6)].labelref));
> + struct node *target = get_node_by_ref((yyvsp[(1) - (3)].node), (yyvsp[(2) - (3)].labelref));
> +
> + if (target)
> + merge_nodes(target, (yyvsp[(3) - (3)].node));
> + else
> + print_error("label or path, '%s', not found", (yyvsp[(2) - (3)].labelref));
> + (yyval.node) = (yyvsp[(1) - (3)].node);
> ;}
> break;
>
> case 11:
> -#line 141 "dtc-parser.y"
> +
> +/* Line 1455 of yacc.c */
> +#line 146 "dtc-parser.y"
> {
> - (yyval.addr) = eval_literal((yyvsp[(1) - (1)].literal), 0, 64);
> + (yyval.node) = build_node((yyvsp[(2) - (5)].proplist), (yyvsp[(3) - (5)].nodelist));
> ;}
> break;
>
> case 12:
> -#line 145 "dtc-parser.y"
> +
> +/* Line 1455 of yacc.c */
> +#line 153 "dtc-parser.y"
> {
> - (yyval.addr) = eval_literal((yyvsp[(1) - (1)].literal), 16, 64);
> + (yyval.proplist) = NULL;
> ;}
> break;
>
> case 13:
> -#line 152 "dtc-parser.y"
> +
> +/* Line 1455 of yacc.c */
> +#line 157 "dtc-parser.y"
> {
> - (yyval.node) = name_node((yyvsp[(2) - (2)].node), "", NULL);
> + (yyval.proplist) = chain_property((yyvsp[(2) - (2)].prop), (yyvsp[(1) - (2)].proplist));
> ;}
> break;
>
> case 14:
> -#line 159 "dtc-parser.y"
> +
> +/* Line 1455 of yacc.c */
> +#line 164 "dtc-parser.y"
> {
> - (yyval.node) = build_node((yyvsp[(2) - (5)].proplist), (yyvsp[(3) - (5)].nodelist));
> + (yyval.prop) = build_property((yyvsp[(1) - (4)].propnodename), (yyvsp[(3) - (4)].data));
> ;}
> break;
>
> case 15:
> -#line 166 "dtc-parser.y"
> +
> +/* Line 1455 of yacc.c */
> +#line 168 "dtc-parser.y"
> {
> - (yyval.proplist) = NULL;
> + (yyval.prop) = build_property((yyvsp[(1) - (2)].propnodename), empty_data);
> ;}
> break;
>
> case 16:
> -#line 170 "dtc-parser.y"
> +
> +/* Line 1455 of yacc.c */
> +#line 172 "dtc-parser.y"
> {
> - (yyval.proplist) = chain_property((yyvsp[(2) - (2)].prop), (yyvsp[(1) - (2)].proplist));
> + add_label(&(yyvsp[(2) - (2)].prop)->labels, (yyvsp[(1) - (2)].labelref));
> + (yyval.prop) = (yyvsp[(2) - (2)].prop);
> ;}
> break;
>
> case 17:
> -#line 177 "dtc-parser.y"
> +
> +/* Line 1455 of yacc.c */
> +#line 180 "dtc-parser.y"
> {
> - (yyval.prop) = build_property((yyvsp[(2) - (5)].propnodename), (yyvsp[(4) - (5)].data), (yyvsp[(1) - (5)].labelref));
> + (yyval.data) = data_merge((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].data));
> ;}
> break;
>
> case 18:
> -#line 181 "dtc-parser.y"
> +
> +/* Line 1455 of yacc.c */
> +#line 184 "dtc-parser.y"
> {
> - (yyval.prop) = build_property((yyvsp[(2) - (3)].propnodename), empty_data, (yyvsp[(1) - (3)].labelref));
> + (yyval.data) = data_merge((yyvsp[(1) - (4)].data), (yyvsp[(3) - (4)].data));
> ;}
> break;
>
> case 19:
> +
> +/* Line 1455 of yacc.c */
> #line 188 "dtc-parser.y"
> {
> - (yyval.data) = data_merge((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].data));
> + (yyval.data) = data_merge((yyvsp[(1) - (4)].data), (yyvsp[(3) - (4)].data));
> ;}
> break;
>
> case 20:
> +
> +/* Line 1455 of yacc.c */
> #line 192 "dtc-parser.y"
> {
> - (yyval.data) = data_merge((yyvsp[(1) - (4)].data), (yyvsp[(3) - (4)].data));
> + (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), REF_PATH, (yyvsp[(2) - (2)].labelref));
> ;}
> break;
>
> case 21:
> -#line 196 "dtc-parser.y"
> - {
> - (yyval.data) = data_merge((yyvsp[(1) - (4)].data), (yyvsp[(3) - (4)].data));
> - ;}
> - break;
> -
> - case 22:
> -#line 200 "dtc-parser.y"
> - {
> - (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), REF_PATH, (yyvsp[(2) - (2)].labelref));
> - ;}
> - break;
>
> - case 23:
> -#line 204 "dtc-parser.y"
> +/* Line 1455 of yacc.c */
> +#line 196 "dtc-parser.y"
> {
> - struct search_path path = { srcpos_file->dir, NULL, NULL };
> - struct dtc_file *file = dtc_open_file((yyvsp[(4) - (9)].data).val, &path);
> - struct data d = empty_data;
> + FILE *f = srcfile_relative_open((yyvsp[(4) - (9)].data).val, NULL);
> + struct data d;
>
> if ((yyvsp[(6) - (9)].addr) != 0)
> - if (fseek(file->file, (yyvsp[(6) - (9)].addr), SEEK_SET) != 0)
> - yyerrorf("Couldn't seek to offset %llu in \"%s\": %s",
> - (unsigned long long)(yyvsp[(6) - (9)].addr),
> - (yyvsp[(4) - (9)].data).val, strerror(errno));
> + if (fseek(f, (yyvsp[(6) - (9)].addr), SEEK_SET) != 0)
> + print_error("Couldn't seek to offset %llu in \"%s\": %s",
> + (unsigned long long)(yyvsp[(6) - (9)].addr),
> + (yyvsp[(4) - (9)].data).val,
> + strerror(errno));
>
> - d = data_copy_file(file->file, (yyvsp[(8) - (9)].addr));
> + d = data_copy_file(f, (yyvsp[(8) - (9)].addr));
>
> (yyval.data) = data_merge((yyvsp[(1) - (9)].data), d);
> - dtc_close_file(file);
> + fclose(f);
> ;}
> break;
>
> - case 24:
> -#line 221 "dtc-parser.y"
> + case 22:
> +
> +/* Line 1455 of yacc.c */
> +#line 213 "dtc-parser.y"
> {
> - struct search_path path = { srcpos_file->dir, NULL, NULL };
> - struct dtc_file *file = dtc_open_file((yyvsp[(4) - (5)].data).val, &path);
> + FILE *f = srcfile_relative_open((yyvsp[(4) - (5)].data).val, NULL);
> struct data d = empty_data;
>
> - d = data_copy_file(file->file, -1);
> + d = data_copy_file(f, -1);
>
> (yyval.data) = data_merge((yyvsp[(1) - (5)].data), d);
> - dtc_close_file(file);
> + fclose(f);
> ;}
> break;
>
> - case 25:
> -#line 232 "dtc-parser.y"
> + case 23:
> +
> +/* Line 1455 of yacc.c */
> +#line 223 "dtc-parser.y"
> {
> (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref));
> ;}
> break;
>
> - case 26:
> -#line 239 "dtc-parser.y"
> + case 24:
> +
> +/* Line 1455 of yacc.c */
> +#line 230 "dtc-parser.y"
> {
> (yyval.data) = empty_data;
> ;}
> break;
>
> - case 27:
> -#line 243 "dtc-parser.y"
> + case 25:
> +
> +/* Line 1455 of yacc.c */
> +#line 234 "dtc-parser.y"
> {
> (yyval.data) = (yyvsp[(1) - (2)].data);
> ;}
> break;
>
> - case 28:
> -#line 247 "dtc-parser.y"
> + case 26:
> +
> +/* Line 1455 of yacc.c */
> +#line 238 "dtc-parser.y"
> {
> (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref));
> ;}
> break;
>
> - case 29:
> -#line 254 "dtc-parser.y"
> + case 27:
> +
> +/* Line 1455 of yacc.c */
> +#line 245 "dtc-parser.y"
> {
> (yyval.data) = empty_data;
> ;}
> break;
>
> - case 30:
> -#line 258 "dtc-parser.y"
> + case 28:
> +
> +/* Line 1455 of yacc.c */
> +#line 249 "dtc-parser.y"
> {
> (yyval.data) = data_append_cell((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].cell));
> ;}
> break;
>
> - case 31:
> -#line 262 "dtc-parser.y"
> + case 29:
> +
> +/* Line 1455 of yacc.c */
> +#line 253 "dtc-parser.y"
> {
> (yyval.data) = data_append_cell(data_add_marker((yyvsp[(1) - (2)].data), REF_PHANDLE,
> (yyvsp[(2) - (2)].labelref)), -1);
> ;}
> break;
>
> - case 32:
> -#line 267 "dtc-parser.y"
> + case 30:
> +
> +/* Line 1455 of yacc.c */
> +#line 258 "dtc-parser.y"
> {
> (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref));
> ;}
> break;
>
> - case 33:
> -#line 274 "dtc-parser.y"
> - {
> - (yyval.cbase) = 16;
> - ;}
> - break;
> + case 31:
>
> - case 35:
> -#line 282 "dtc-parser.y"
> +/* Line 1455 of yacc.c */
> +#line 265 "dtc-parser.y"
> {
> (yyval.cell) = eval_literal((yyvsp[(1) - (1)].literal), 0, 32);
> ;}
> break;
>
> - case 36:
> -#line 286 "dtc-parser.y"
> - {
> - (yyval.cell) = eval_literal((yyvsp[(2) - (2)].literal), (yyvsp[(1) - (2)].cbase), 32);
> - ;}
> - break;
> + case 32:
>
> - case 37:
> -#line 293 "dtc-parser.y"
> +/* Line 1455 of yacc.c */
> +#line 272 "dtc-parser.y"
> {
> (yyval.data) = empty_data;
> ;}
> break;
>
> - case 38:
> -#line 297 "dtc-parser.y"
> + case 33:
> +
> +/* Line 1455 of yacc.c */
> +#line 276 "dtc-parser.y"
> {
> (yyval.data) = data_append_byte((yyvsp[(1) - (2)].data), (yyvsp[(2) - (2)].byte));
> ;}
> break;
>
> - case 39:
> -#line 301 "dtc-parser.y"
> + case 34:
> +
> +/* Line 1455 of yacc.c */
> +#line 280 "dtc-parser.y"
> {
> (yyval.data) = data_add_marker((yyvsp[(1) - (2)].data), LABEL, (yyvsp[(2) - (2)].labelref));
> ;}
> break;
>
> - case 40:
> -#line 308 "dtc-parser.y"
> + case 35:
> +
> +/* Line 1455 of yacc.c */
> +#line 287 "dtc-parser.y"
> {
> (yyval.nodelist) = NULL;
> ;}
> break;
>
> - case 41:
> -#line 312 "dtc-parser.y"
> + case 36:
> +
> +/* Line 1455 of yacc.c */
> +#line 291 "dtc-parser.y"
> {
> (yyval.nodelist) = chain_node((yyvsp[(1) - (2)].node), (yyvsp[(2) - (2)].nodelist));
> ;}
> break;
>
> - case 42:
> -#line 316 "dtc-parser.y"
> + case 37:
> +
> +/* Line 1455 of yacc.c */
> +#line 295 "dtc-parser.y"
> {
> - yyerror("syntax error: properties must precede subnodes");
> + print_error("syntax error: properties must precede subnodes");
> YYERROR;
> ;}
> break;
>
> - case 43:
> -#line 324 "dtc-parser.y"
> - {
> - (yyval.node) = name_node((yyvsp[(3) - (3)].node), (yyvsp[(2) - (3)].propnodename), (yyvsp[(1) - (3)].labelref));
> - ;}
> - break;
> + case 38:
>
> - case 44:
> -#line 331 "dtc-parser.y"
> +/* Line 1455 of yacc.c */
> +#line 303 "dtc-parser.y"
> {
> - (yyval.labelref) = NULL;
> + (yyval.node) = name_node((yyvsp[(2) - (2)].node), (yyvsp[(1) - (2)].propnodename));
> ;}
> break;
>
> - case 45:
> -#line 335 "dtc-parser.y"
> + case 39:
> +
> +/* Line 1455 of yacc.c */
> +#line 307 "dtc-parser.y"
> {
> - (yyval.labelref) = (yyvsp[(1) - (1)].labelref);
> + add_label(&(yyvsp[(2) - (2)].node)->labels, (yyvsp[(1) - (2)].labelref));
> + (yyval.node) = (yyvsp[(2) - (2)].node);
> ;}
> break;
>
>
> -/* Line 1267 of yacc.c. */
> -#line 1780 "dtc-parser.tab.c"
> +
> +/* Line 1455 of yacc.c */
> +#line 1783 "dtc-parser.tab.c"
> default: break;
> }
> YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
> @@ -1786,7 +1789,6 @@ yyreduce:
> YY_STACK_PRINT (yyss, yyssp);
>
> *++yyvsp = yyval;
> - *++yylsp = yyloc;
>
> /* Now `shift' the result of the reduction. Determine what state
> that goes to, based on the state we popped back to and the rule
> @@ -1848,11 +1850,11 @@ yyerrlab:
> #endif
> }
>
> - yyerror_range[0] = yylloc;
> +
>
> if (yyerrstatus == 3)
> {
> - /* If just tried and failed to reuse look-ahead token after an
> + /* If just tried and failed to reuse lookahead token after an
> error, discard it. */
>
> if (yychar <= YYEOF)
> @@ -1864,12 +1866,12 @@ yyerrlab:
> else
> {
> yydestruct ("Error: discarding",
> - yytoken, &yylval, &yylloc);
> + yytoken, &yylval);
> yychar = YYEMPTY;
> }
> }
>
> - /* Else will try to reuse look-ahead token after shifting the error
> + /* Else will try to reuse lookahead token after shifting the error
> token. */
> goto yyerrlab1;
>
> @@ -1885,7 +1887,6 @@ yyerrorlab:
> if (/*CONSTCOND*/ 0)
> goto yyerrorlab;
>
> - yyerror_range[0] = yylsp[1-yylen];
> /* Do not reclaim the symbols of the rule which action triggered
> this YYERROR. */
> YYPOPSTACK (yylen);
> @@ -1919,24 +1920,16 @@ yyerrlab1:
> if (yyssp == yyss)
> YYABORT;
>
> - yyerror_range[0] = *yylsp;
> +
> yydestruct ("Error: popping",
> - yystos[yystate], yyvsp, yylsp);
> + yystos[yystate], yyvsp);
> YYPOPSTACK (1);
> yystate = *yyssp;
> YY_STACK_PRINT (yyss, yyssp);
> }
>
> - if (yyn == YYFINAL)
> - YYACCEPT;
> -
> *++yyvsp = yylval;
>
> - yyerror_range[1] = yylloc;
> - /* Using YYLLOC is tempting, but would change the location of
> - the look-ahead. YYLOC is available though. */
> - YYLLOC_DEFAULT (yyloc, (yyerror_range - 1), 2);
> - *++yylsp = yyloc;
>
> /* Shift the error token. */
> YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
> @@ -1959,7 +1952,7 @@ yyabortlab:
> yyresult = 1;
> goto yyreturn;
>
> -#ifndef yyoverflow
> +#if !defined(yyoverflow) || YYERROR_VERBOSE
> /*-------------------------------------------------.
> | yyexhaustedlab -- memory exhaustion comes here. |
> `-------------------------------------------------*/
> @@ -1970,9 +1963,9 @@ yyexhaustedlab:
> #endif
>
> yyreturn:
> - if (yychar != YYEOF && yychar != YYEMPTY)
> + if (yychar != YYEMPTY)
> yydestruct ("Cleanup: discarding lookahead",
> - yytoken, &yylval, &yylloc);
> + yytoken, &yylval);
> /* Do not reclaim the symbols of the rule which action triggered
> this YYABORT or YYACCEPT. */
> YYPOPSTACK (yylen);
> @@ -1980,7 +1973,7 @@ yyreturn:
> while (yyssp != yyss)
> {
> yydestruct ("Cleanup: popping",
> - yystos[*yyssp], yyvsp, yylsp);
> + yystos[*yyssp], yyvsp);
> YYPOPSTACK (1);
> }
> #ifndef yyoverflow
> @@ -1996,29 +1989,24 @@ yyreturn:
> }
>
>
> -#line 340 "dtc-parser.y"
> +
> +/* Line 1675 of yacc.c */
> +#line 313 "dtc-parser.y"
>
>
> -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)
> @@ -2029,12 +2017,12 @@ 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;
> }
>
> diff --git a/scripts/dtc/dtc-parser.tab.h_shipped b/scripts/dtc/dtc-parser.tab.h_shipped
> index ba99100..95c9547 100644
> --- a/scripts/dtc/dtc-parser.tab.h_shipped
> +++ b/scripts/dtc/dtc-parser.tab.h_shipped
> @@ -1,24 +1,23 @@
> -/* A Bison parser, made by GNU Bison 2.3. */
>
> -/* Skeleton interface for Bison's Yacc-like parsers in C
> +/* A Bison parser, made by GNU Bison 2.4.1. */
>
> - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
> +/* Skeleton interface for Bison's Yacc-like parsers in C
> +
> + Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
> Free Software Foundation, Inc.
> -
> - This program is free software; you can redistribute it and/or modify
> +
> + 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 2, or (at your option)
> - any later version.
> -
> + 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, write to the Free Software
> - Foundation, Inc., 51 Franklin Street, Fifth Floor,
> - Boston, MA 02110-1301, USA. */
> + along with this program. If not, see <http://www.gnu.org/licenses/>. */
>
> /* As a special exception, you may create a larger work that contains
> part or all of the Bison parser skeleton and distribute that work
> @@ -29,10 +28,11 @@
> 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. */
>
> +
> /* Tokens. */
> #ifndef YYTOKENTYPE
> # define YYTOKENTYPE
> @@ -43,35 +43,24 @@
> DT_MEMRESERVE = 259,
> DT_PROPNODENAME = 260,
> DT_LITERAL = 261,
> - DT_LEGACYLITERAL = 262,
> - DT_BASE = 263,
> - DT_BYTE = 264,
> - DT_STRING = 265,
> - DT_LABEL = 266,
> - DT_REF = 267,
> - DT_INCBIN = 268
> + DT_BASE = 262,
> + DT_BYTE = 263,
> + DT_STRING = 264,
> + DT_LABEL = 265,
> + DT_REF = 266,
> + DT_INCBIN = 267
> };
> #endif
> -/* Tokens. */
> -#define DT_V1 258
> -#define DT_MEMRESERVE 259
> -#define DT_PROPNODENAME 260
> -#define DT_LITERAL 261
> -#define DT_LEGACYLITERAL 262
> -#define DT_BASE 263
> -#define DT_BYTE 264
> -#define DT_STRING 265
> -#define DT_LABEL 266
> -#define DT_REF 267
> -#define DT_INCBIN 268
> -
>
>
>
> #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
> typedef union YYSTYPE
> -#line 37 "dtc-parser.y"
> {
> +
> +/* Line 1676 of yacc.c */
> +#line 39 "dtc-parser.y"
> +
> char *propnodename;
> char *literal;
> char *labelref;
> @@ -86,28 +75,17 @@ typedef union YYSTYPE
> struct node *node;
> struct node *nodelist;
> struct reserve_info *re;
> -}
> -/* Line 1489 of yacc.c. */
> -#line 92 "dtc-parser.tab.h"
> - YYSTYPE;
> +
> +
> +
> +/* Line 1676 of yacc.c */
> +#line 83 "dtc-parser.tab.h"
> +} YYSTYPE;
> +# define YYSTYPE_IS_TRIVIAL 1
> # define yystype YYSTYPE /* obsolescent; will be withdrawn */
> # define YYSTYPE_IS_DECLARED 1
> -# define YYSTYPE_IS_TRIVIAL 1
> #endif
>
> extern YYSTYPE yylval;
>
> -#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
> -typedef struct YYLTYPE
> -{
> - int first_line;
> - int first_column;
> - int last_line;
> - int last_column;
> -} YYLTYPE;
> -# define yyltype YYLTYPE /* obsolescent; will be withdrawn */
> -# define YYLTYPE_IS_DECLARED 1
> -# define YYLTYPE_IS_TRIVIAL 1
> -#endif
>
> -extern YYLTYPE yylloc;
> diff --git a/scripts/dtc/dtc-parser.y b/scripts/dtc/dtc-parser.y
> index b2ab562..5e84a67 100644
> --- a/scripts/dtc/dtc-parser.y
> +++ b/scripts/dtc/dtc-parser.y
> @@ -18,15 +18,17 @@
> * 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;
> }
> diff --git a/scripts/dtc/dtc.c b/scripts/dtc/dtc.c
> index d8fd43b..cbc0193 100644
> --- a/scripts/dtc/dtc.c
> +++ b/scripts/dtc/dtc.c
> @@ -30,30 +30,7 @@ int quiet; /* Level of quietness */
> int reservenum; /* Number of memory reservation slots */
> int minsize; /* Minimum blob size */
> int padsize; /* Additional padding to blob */
> -
> -char *join_path(const char *path, const char *name)
> -{
> - int lenp = strlen(path);
> - int lenn = strlen(name);
> - int len;
> - int needslash = 1;
> - char *str;
> -
> - len = lenp + lenn + 2;
> - if ((lenp > 0) && (path[lenp-1] == '/')) {
> - needslash = 0;
> - len--;
> - }
> -
> - str = xmalloc(len);
> - memcpy(str, path, lenp);
> - if (needslash) {
> - str[lenp] = '/';
> - lenp++;
> - }
> - memcpy(str+lenp, name, lenn+1);
> - return str;
> -}
> +int phandle_format = PHANDLE_BOTH; /* Use linux,phandle or phandle properties */
>
> static void fill_fullpaths(struct node *tree, const char *prefix)
> {
> @@ -104,8 +81,15 @@ static void __attribute__ ((noreturn)) usage(void)
> fprintf(stderr, "\t\tSet the physical boot cpu\n");
> fprintf(stderr, "\t-f\n");
> fprintf(stderr, "\t\tForce - try to produce output even if the input tree has errors\n");
> + fprintf(stderr, "\t-s\n");
> + fprintf(stderr, "\t\tSort nodes and properties before outputting (only useful for\n\t\tcomparing trees)\n");
> fprintf(stderr, "\t-v\n");
> fprintf(stderr, "\t\tPrint DTC version and exit\n");
> + fprintf(stderr, "\t-H <phandle format>\n");
> + fprintf(stderr, "\t\tphandle formats are:\n");
> + fprintf(stderr, "\t\t\tlegacy - \"linux,phandle\" properties only\n");
> + fprintf(stderr, "\t\t\tepapr - \"phandle\" properties only\n");
> + fprintf(stderr, "\t\t\tboth - Both \"linux,phandle\" and \"phandle\" properties\n");
> exit(3);
> }
>
> @@ -115,7 +99,7 @@ int main(int argc, char *argv[])
> const char *inform = "dts";
> const char *outform = "dts";
> const char *outname = "-";
> - int force = 0, check = 0;
> + int force = 0, check = 0, sort = 0;
> const char *arg;
> int opt;
> FILE *outf = NULL;
> @@ -127,7 +111,7 @@ int main(int argc, char *argv[])
> minsize = 0;
> padsize = 0;
>
> - while ((opt = getopt(argc, argv, "hI:O:o:V:R:S:p:fcqb:v")) != EOF) {
> + while ((opt = getopt(argc, argv, "hI:O:o:V:R:S:p:fcqb:vH:s")) != EOF) {
> switch (opt) {
> case 'I':
> inform = optarg;
> @@ -165,6 +149,22 @@ int main(int argc, char *argv[])
> case 'v':
> printf("Version: %s\n", DTC_VERSION);
> exit(0);
> + case 'H':
> + if (streq(optarg, "legacy"))
> + phandle_format = PHANDLE_LEGACY;
> + else if (streq(optarg, "epapr"))
> + phandle_format = PHANDLE_EPAPR;
> + else if (streq(optarg, "both"))
> + phandle_format = PHANDLE_BOTH;
> + else
> + die("Invalid argument \"%s\" to -H option\n",
> + optarg);
> + break;
> +
> + case 's':
> + sort = 1;
> + break;
> +
> case 'h':
> default:
> usage();
> @@ -182,6 +182,9 @@ int main(int argc, char *argv[])
> if (minsize && padsize)
> die("Can't set both -p and -S\n");
>
> + if (minsize)
> + fprintf(stderr, "DTC: Use of \"-S\" is deprecated; it will be removed soon, use \"-p\" instead\n");
> +
> fprintf(stderr, "DTC: %s->%s on file \"%s\"\n",
> inform, outform, arg);
>
> @@ -200,6 +203,8 @@ int main(int argc, char *argv[])
> fill_fullpaths(bi->dt, "");
> process_checks(force, bi);
>
> + if (sort)
> + sort_tree(bi);
>
> if (streq(outname, "-")) {
> outf = stdout;
> diff --git a/scripts/dtc/dtc.h b/scripts/dtc/dtc.h
> index 08d54c8..f37c97e 100644
> --- a/scripts/dtc/dtc.h
> +++ b/scripts/dtc/dtc.h
> @@ -34,7 +34,17 @@
> #include <libfdt_env.h>
> #include <fdt.h>
>
> +#include "util.h"
> +
> +#ifdef DEBUG
> +#define debug(fmt,args...) printf(fmt, ##args)
> +#else
> +#define debug(fmt,args...)
> +#endif
> +
> +
> #define DEFAULT_FDT_VERSION 17
> +
> /*
> * Command line options
> */
> @@ -42,36 +52,11 @@ extern int quiet; /* Level of quietness */
> extern int reservenum; /* Number of memory reservation slots */
> extern int minsize; /* Minimum blob size */
> extern int padsize; /* Additional padding to blob */
> +extern int phandle_format; /* Use linux,phandle or phandle properties */
>
> -static inline void __attribute__((noreturn)) die(char * str, ...)
> -{
> - va_list ap;
> -
> - va_start(ap, str);
> - fprintf(stderr, "FATAL ERROR: ");
> - vfprintf(stderr, str, ap);
> - exit(1);
> -}
> -
> -static inline void *xmalloc(size_t len)
> -{
> - void *new = malloc(len);
> -
> - if (! new)
> - die("malloc() failed\n");
> -
> - return new;
> -}
> -
> -static inline void *xrealloc(void *p, size_t len)
> -{
> - void *new = realloc(p, len);
> -
> - if (! new)
> - die("realloc() failed (len=%d)\n", len);
> -
> - return new;
> -}
> +#define PHANDLE_LEGACY 0x1
> +#define PHANDLE_EPAPR 0x2
> +#define PHANDLE_BOTH 0x3
>
> typedef uint32_t cell_t;
>
> @@ -140,13 +125,18 @@ int data_is_one_string(struct data d);
> #define MAX_NODENAME_LEN 31
>
> /* Live trees */
> +struct label {
> + char *label;
> + struct label *next;
> +};
> +
> struct property {
> char *name;
> struct data val;
>
> struct property *next;
>
> - char *label;
> + struct label *labels;
> };
>
> struct node {
> @@ -163,22 +153,28 @@ struct node {
> cell_t phandle;
> int addr_cells, size_cells;
>
> - char *label;
> + struct label *labels;
> };
>
> +#define for_each_label(l0, l) \
> + for ((l) = (l0); (l); (l) = (l)->next)
> +
> #define for_each_property(n, p) \
> for ((p) = (n)->proplist; (p); (p) = (p)->next)
>
> #define for_each_child(n, c) \
> for ((c) = (n)->children; (c); (c) = (c)->next_sibling)
>
> -struct property *build_property(char *name, struct data val, char *label);
> +void add_label(struct label **labels, char *label);
> +
> +struct property *build_property(char *name, struct data val);
> struct property *chain_property(struct property *first, struct property *list);
> struct property *reverse_properties(struct property *first);
>
> struct node *build_node(struct property *proplist, struct node *children);
> -struct node *name_node(struct node *node, char *name, char *label);
> +struct node *name_node(struct node *node, char *name);
> struct node *chain_node(struct node *first, struct node *list);
> +struct node *merge_nodes(struct node *old_node, struct node *new_node);
>
> void add_property(struct node *node, struct property *prop);
> void add_child(struct node *parent, struct node *child);
> @@ -186,6 +182,10 @@ void add_child(struct node *parent, struct node *child);
> const char *get_unitname(struct node *node);
> struct property *get_property(struct node *node, const char *propname);
> cell_t propval_cell(struct property *prop);
> +struct property *get_property_by_label(struct node *tree, const char *label,
> + struct node **node);
> +struct marker *get_marker_label(struct node *tree, const char *label,
> + struct node **node, struct property **prop);
> struct node *get_subnode(struct node *node, const char *nodename);
> struct node *get_node_by_path(struct node *tree, const char *path);
> struct node *get_node_by_label(struct node *tree, const char *label);
> @@ -193,6 +193,8 @@ struct node *get_node_by_phandle(struct node *tree, cell_t phandle);
> struct node *get_node_by_ref(struct node *tree, const char *ref);
> cell_t get_node_phandle(struct node *root, struct node *node);
>
> +uint32_t guess_boot_cpuid(struct node *tree);
> +
> /* Boot info (tree plus memreserve information */
>
> struct reserve_info {
> @@ -200,10 +202,10 @@ struct reserve_info {
>
> struct reserve_info *next;
>
> - char *label;
> + struct label *labels;
> };
>
> -struct reserve_info *build_reserve_entry(uint64_t start, uint64_t len, char *label);
> +struct reserve_info *build_reserve_entry(uint64_t start, uint64_t len);
> struct reserve_info *chain_reserve_entry(struct reserve_info *first,
> struct reserve_info *list);
> struct reserve_info *add_reserve_entry(struct reserve_info *list,
> @@ -218,6 +220,7 @@ struct boot_info {
>
> struct boot_info *build_boot_info(struct reserve_info *reservelist,
> struct node *tree, uint32_t boot_cpuid_phys);
> +void sort_tree(struct boot_info *bi);
>
> /* Checks */
>
> @@ -239,8 +242,4 @@ struct boot_info *dt_from_source(const char *f);
>
> struct boot_info *dt_from_fs(const char *dirname);
>
> -/* misc */
> -
> -char *join_path(const char *path, const char *name);
> -
> #endif /* _DTC_H */
> diff --git a/scripts/dtc/flattree.c b/scripts/dtc/flattree.c
> index 76acd28..ead0332 100644
> --- a/scripts/dtc/flattree.c
> +++ b/scripts/dtc/flattree.c
> @@ -52,9 +52,9 @@ struct emitter {
> void (*string)(void *, char *, int);
> void (*align)(void *, int);
> void (*data)(void *, struct data);
> - void (*beginnode)(void *, const char *);
> - void (*endnode)(void *, const char *);
> - void (*property)(void *, const char *);
> + void (*beginnode)(void *, struct label *labels);
> + void (*endnode)(void *, struct label *labels);
> + void (*property)(void *, struct label *labels);
> };
>
> static void bin_emit_cell(void *e, cell_t val)
> @@ -89,17 +89,17 @@ static void bin_emit_data(void *e, struct data d)
> *dtbuf = data_append_data(*dtbuf, d.val, d.len);
> }
>
> -static void bin_emit_beginnode(void *e, const char *label)
> +static void bin_emit_beginnode(void *e, struct label *labels)
> {
> bin_emit_cell(e, FDT_BEGIN_NODE);
> }
>
> -static void bin_emit_endnode(void *e, const char *label)
> +static void bin_emit_endnode(void *e, struct label *labels)
> {
> bin_emit_cell(e, FDT_END_NODE);
> }
>
> -static void bin_emit_property(void *e, const char *label)
> +static void bin_emit_property(void *e, struct label *labels)
> {
> bin_emit_cell(e, FDT_PROP);
> }
> @@ -127,11 +127,21 @@ static void emit_offset_label(FILE *f, const char *label, int offset)
> fprintf(f, "%s\t= . + %d\n", label, offset);
> }
>
> +#define ASM_EMIT_BELONG(f, fmt, ...) \
> + { \
> + fprintf((f), "\t.byte\t((" fmt ") >> 24) & 0xff\n", __VA_ARGS__); \
> + fprintf((f), "\t.byte\t((" fmt ") >> 16) & 0xff\n", __VA_ARGS__); \
> + fprintf((f), "\t.byte\t((" fmt ") >> 8) & 0xff\n", __VA_ARGS__); \
> + fprintf((f), "\t.byte\t(" fmt ") & 0xff\n", __VA_ARGS__); \
> + }
> +
> static void asm_emit_cell(void *e, cell_t val)
> {
> FILE *f = e;
>
> - fprintf(f, "\t.long\t0x%x\n", val);
> + fprintf(f, "\t.byte 0x%02x; .byte 0x%02x; .byte 0x%02x; .byte 0x%02x\n",
> + (val >> 24) & 0xff, (val >> 16) & 0xff,
> + (val >> 8) & 0xff, val & 0xff);
> }
>
> static void asm_emit_string(void *e, char *str, int len)
> @@ -156,7 +166,7 @@ static void asm_emit_align(void *e, int a)
> {
> FILE *f = e;
>
> - fprintf(f, "\t.balign\t%d\n", a);
> + fprintf(f, "\t.balign\t%d, 0\n", a);
> }
>
> static void asm_emit_data(void *e, struct data d)
> @@ -169,8 +179,7 @@ static void asm_emit_data(void *e, struct data d)
> emit_offset_label(f, m->ref, m->offset);
>
> while ((d.len - off) >= sizeof(uint32_t)) {
> - fprintf(f, "\t.long\t0x%x\n",
> - fdt32_to_cpu(*((uint32_t *)(d.val+off))));
> + asm_emit_cell(e, fdt32_to_cpu(*((uint32_t *)(d.val+off))));
> off += sizeof(uint32_t);
> }
>
> @@ -182,37 +191,43 @@ static void asm_emit_data(void *e, struct data d)
> assert(off == d.len);
> }
>
> -static void asm_emit_beginnode(void *e, const char *label)
> +static void asm_emit_beginnode(void *e, struct label *labels)
> {
> FILE *f = e;
> + struct label *l;
>
> - if (label) {
> - fprintf(f, "\t.globl\t%s\n", label);
> - fprintf(f, "%s:\n", label);
> + for_each_label(labels, l) {
> + fprintf(f, "\t.globl\t%s\n", l->label);
> + fprintf(f, "%s:\n", l->label);
> }
> - fprintf(f, "\t.long\tFDT_BEGIN_NODE\n");
> + fprintf(f, "\t/* FDT_BEGIN_NODE */\n");
> + asm_emit_cell(e, FDT_BEGIN_NODE);
> }
>
> -static void asm_emit_endnode(void *e, const char *label)
> +static void asm_emit_endnode(void *e, struct label *labels)
> {
> FILE *f = e;
> + struct label *l;
>
> - fprintf(f, "\t.long\tFDT_END_NODE\n");
> - if (label) {
> - fprintf(f, "\t.globl\t%s_end\n", label);
> - fprintf(f, "%s_end:\n", label);
> + fprintf(f, "\t/* FDT_END_NODE */\n");
> + asm_emit_cell(e, FDT_END_NODE);
> + for_each_label(labels, l) {
> + fprintf(f, "\t.globl\t%s_end\n", l->label);
> + fprintf(f, "%s_end:\n", l->label);
> }
> }
>
> -static void asm_emit_property(void *e, const char *label)
> +static void asm_emit_property(void *e, struct label *labels)
> {
> FILE *f = e;
> + struct label *l;
>
> - if (label) {
> - fprintf(f, "\t.globl\t%s\n", label);
> - fprintf(f, "%s:\n", label);
> + for_each_label(labels, l) {
> + fprintf(f, "\t.globl\t%s\n", l->label);
> + fprintf(f, "%s:\n", l->label);
> }
> - fprintf(f, "\t.long\tFDT_PROP\n");
> + fprintf(f, "\t/* FDT_PROP */\n");
> + asm_emit_cell(e, FDT_PROP);
> }
>
> static struct emitter asm_emitter = {
> @@ -248,7 +263,7 @@ static void flatten_tree(struct node *tree, struct emitter *emit,
> struct node *child;
> int seen_name_prop = 0;
>
> - emit->beginnode(etarget, tree->label);
> + emit->beginnode(etarget, tree->labels);
>
> if (vi->flags & FTF_FULLPATH)
> emit->string(etarget, tree->fullpath, 0);
> @@ -265,7 +280,7 @@ static void flatten_tree(struct node *tree, struct emitter *emit,
>
> nameoff = stringtable_insert(strbuf, prop->name);
>
> - emit->property(etarget, prop->label);
> + emit->property(etarget, prop->labels);
> emit->cell(etarget, prop->val.len);
> emit->cell(etarget, nameoff);
>
> @@ -292,7 +307,7 @@ static void flatten_tree(struct node *tree, struct emitter *emit,
> flatten_tree(child, emit, etarget, strbuf, vi);
> }
>
> - emit->endnode(etarget, tree->label);
> + emit->endnode(etarget, tree->labels);
> }
>
> static struct data flatten_reserve_list(struct reserve_info *reservelist,
> @@ -413,10 +428,13 @@ void dt_to_blob(FILE *f, struct boot_info *bi, int version)
> if (padlen > 0)
> blob = data_append_zeroes(blob, padlen);
>
> - fwrite(blob.val, blob.len, 1, f);
> -
> - if (ferror(f))
> - die("Error writing device tree blob: %s\n", strerror(errno));
> + if (fwrite(blob.val, blob.len, 1, f) != 1) {
> + if (ferror(f))
> + die("Error writing device tree blob: %s\n",
> + strerror(errno));
> + else
> + die("Short write on device tree blob\n");
> + }
>
> /*
> * data_merge() frees the right-hand element so only the blob
> @@ -455,39 +473,44 @@ void dt_to_asm(FILE *f, struct boot_info *bi, int version)
> die("Unknown device tree blob version %d\n", version);
>
> fprintf(f, "/* autogenerated by dtc, do not edit */\n\n");
> - fprintf(f, "#define FDT_MAGIC 0x%x\n", FDT_MAGIC);
> - fprintf(f, "#define FDT_BEGIN_NODE 0x%x\n", FDT_BEGIN_NODE);
> - fprintf(f, "#define FDT_END_NODE 0x%x\n", FDT_END_NODE);
> - fprintf(f, "#define FDT_PROP 0x%x\n", FDT_PROP);
> - fprintf(f, "#define FDT_END 0x%x\n", FDT_END);
> - fprintf(f, "\n");
>
> emit_label(f, symprefix, "blob_start");
> emit_label(f, symprefix, "header");
> - fprintf(f, "\t.long\tFDT_MAGIC\t\t\t\t/* magic */\n");
> - fprintf(f, "\t.long\t_%s_blob_abs_end - _%s_blob_start\t/* totalsize */\n",
> - symprefix, symprefix);
> - fprintf(f, "\t.long\t_%s_struct_start - _%s_blob_start\t/* off_dt_struct */\n",
> + fprintf(f, "\t/* magic */\n");
> + asm_emit_cell(f, FDT_MAGIC);
> + fprintf(f, "\t/* totalsize */\n");
> + ASM_EMIT_BELONG(f, "_%s_blob_abs_end - _%s_blob_start",
> + symprefix, symprefix);
> + fprintf(f, "\t/* off_dt_struct */\n");
> + ASM_EMIT_BELONG(f, "_%s_struct_start - _%s_blob_start",
> symprefix, symprefix);
> - fprintf(f, "\t.long\t_%s_strings_start - _%s_blob_start\t/* off_dt_strings */\n",
> + fprintf(f, "\t/* off_dt_strings */\n");
> + ASM_EMIT_BELONG(f, "_%s_strings_start - _%s_blob_start",
> symprefix, symprefix);
> - fprintf(f, "\t.long\t_%s_reserve_map - _%s_blob_start\t/* off_dt_strings */\n",
> + fprintf(f, "\t/* off_mem_rsvmap */\n");
> + ASM_EMIT_BELONG(f, "_%s_reserve_map - _%s_blob_start",
> symprefix, symprefix);
> - fprintf(f, "\t.long\t%d\t\t\t\t\t/* version */\n", vi->version);
> - fprintf(f, "\t.long\t%d\t\t\t\t\t/* last_comp_version */\n",
> - vi->last_comp_version);
> -
> - if (vi->flags & FTF_BOOTCPUID)
> - fprintf(f, "\t.long\t%i\t\t\t\t\t/* boot_cpuid_phys */\n",
> - bi->boot_cpuid_phys);
> + fprintf(f, "\t/* version */\n");
> + asm_emit_cell(f, vi->version);
> + fprintf(f, "\t/* last_comp_version */\n");
> + asm_emit_cell(f, vi->last_comp_version);
> +
> + if (vi->flags & FTF_BOOTCPUID) {
> + fprintf(f, "\t/* boot_cpuid_phys */\n");
> + asm_emit_cell(f, bi->boot_cpuid_phys);
> + }
>
> - if (vi->flags & FTF_STRTABSIZE)
> - fprintf(f, "\t.long\t_%s_strings_end - _%s_strings_start\t/* size_dt_strings */\n",
> - symprefix, symprefix);
> + if (vi->flags & FTF_STRTABSIZE) {
> + fprintf(f, "\t/* size_dt_strings */\n");
> + ASM_EMIT_BELONG(f, "_%s_strings_end - _%s_strings_start",
> + symprefix, symprefix);
> + }
>
> - if (vi->flags & FTF_STRUCTSIZE)
> - fprintf(f, "\t.long\t_%s_struct_end - _%s_struct_start\t/* size_dt_struct */\n",
> + if (vi->flags & FTF_STRUCTSIZE) {
> + fprintf(f, "\t/* size_dt_struct */\n");
> + ASM_EMIT_BELONG(f, "_%s_struct_end - _%s_struct_start",
> symprefix, symprefix);
> + }
>
> /*
> * Reserve map entries.
> @@ -505,16 +528,17 @@ void dt_to_asm(FILE *f, struct boot_info *bi, int version)
> * as it appears .quad isn't available in some assemblers.
> */
> for (re = bi->reservelist; re; re = re->next) {
> - if (re->label) {
> - fprintf(f, "\t.globl\t%s\n", re->label);
> - fprintf(f, "%s:\n", re->label);
> + struct label *l;
> +
> + for_each_label(re->labels, l) {
> + fprintf(f, "\t.globl\t%s\n", l->label);
> + fprintf(f, "%s:\n", l->label);
> }
> - fprintf(f, "\t.long\t0x%08x, 0x%08x\n",
> - (unsigned int)(re->re.address >> 32),
> - (unsigned int)(re->re.address & 0xffffffff));
> - fprintf(f, "\t.long\t0x%08x, 0x%08x\n",
> - (unsigned int)(re->re.size >> 32),
> - (unsigned int)(re->re.size & 0xffffffff));
> + ASM_EMIT_BELONG(f, "0x%08x", (unsigned int)(re->re.address >> 32));
> + ASM_EMIT_BELONG(f, "0x%08x",
> + (unsigned int)(re->re.address & 0xffffffff));
> + ASM_EMIT_BELONG(f, "0x%08x", (unsigned int)(re->re.size >> 32));
> + ASM_EMIT_BELONG(f, "0x%08x", (unsigned int)(re->re.size & 0xffffffff));
> }
> for (i = 0; i < reservenum; i++) {
> fprintf(f, "\t.long\t0, 0\n\t.long\t0, 0\n");
> @@ -524,7 +548,9 @@ void dt_to_asm(FILE *f, struct boot_info *bi, int version)
>
> emit_label(f, symprefix, "struct_start");
> flatten_tree(bi->dt, &asm_emitter, f, &strbuf, vi);
> - fprintf(f, "\t.long\tFDT_END\n");
> +
> + fprintf(f, "\t/* FDT_END */\n");
> + asm_emit_cell(f, FDT_END);
> emit_label(f, symprefix, "struct_end");
>
> emit_label(f, symprefix, "strings_start");
> @@ -601,7 +627,7 @@ static char *flat_read_string(struct inbuf *inb)
> len++;
> } while ((*p++) != '\0');
>
> - str = strdup(inb->ptr);
> + str = xstrdup(inb->ptr);
>
> inb->ptr += len;
>
> @@ -643,7 +669,7 @@ static char *flat_read_stringtable(struct inbuf *inb, int offset)
> p++;
> }
>
> - return strdup(inb->base + offset);
> + return xstrdup(inb->base + offset);
> }
>
> static struct property *flat_read_property(struct inbuf *dtbuf,
> @@ -663,7 +689,7 @@ static struct property *flat_read_property(struct inbuf *dtbuf,
>
> val = flat_read_data(dtbuf, proplen);
>
> - return build_property(name, val, NULL);
> + return build_property(name, val);
> }
>
>
> @@ -688,7 +714,7 @@ static struct reserve_info *flat_read_mem_reserve(struct inbuf *inb)
> if (re.size == 0)
> break;
>
> - new = build_reserve_entry(re.address, re.size, NULL);
> + new = build_reserve_entry(re.address, re.size);
> reservelist = add_reserve_entry(reservelist, new);
> }
>
> @@ -710,7 +736,7 @@ static char *nodename_from_path(const char *ppath, const char *cpath)
> if (!streq(ppath, "/"))
> plen++;
>
> - return strdup(cpath + plen);
> + return xstrdup(cpath + plen);
> }
>
> static struct node *unflatten_tree(struct inbuf *dtbuf,
> @@ -776,7 +802,7 @@ static struct node *unflatten_tree(struct inbuf *dtbuf,
>
> struct boot_info *dt_from_blob(const char *fname)
> {
> - struct dtc_file *dtcf;
> + FILE *f;
> uint32_t magic, totalsize, version, size_dt, boot_cpuid_phys;
> uint32_t off_dt, off_str, off_mem_rsvmap;
> int rc;
> @@ -791,14 +817,14 @@ struct boot_info *dt_from_blob(const char *fname)
> uint32_t val;
> int flags = 0;
>
> - dtcf = dtc_open_file(fname, NULL);
> + f = srcfile_relative_open(fname, NULL);
>
> - rc = fread(&magic, sizeof(magic), 1, dtcf->file);
> - if (ferror(dtcf->file))
> + rc = fread(&magic, sizeof(magic), 1, f);
> + if (ferror(f))
> die("Error reading DT blob magic number: %s\n",
> strerror(errno));
> if (rc < 1) {
> - if (feof(dtcf->file))
> + if (feof(f))
> die("EOF reading DT blob magic number\n");
> else
> die("Mysterious short read reading magic number\n");
> @@ -808,11 +834,11 @@ struct boot_info *dt_from_blob(const char *fname)
> if (magic != FDT_MAGIC)
> die("Blob has incorrect magic number\n");
>
> - rc = fread(&totalsize, sizeof(totalsize), 1, dtcf->file);
> - if (ferror(dtcf->file))
> + rc = fread(&totalsize, sizeof(totalsize), 1, f);
> + if (ferror(f))
> die("Error reading DT blob size: %s\n", strerror(errno));
> if (rc < 1) {
> - if (feof(dtcf->file))
> + if (feof(f))
> die("EOF reading DT blob size\n");
> else
> die("Mysterious short read reading blob size\n");
> @@ -832,12 +858,12 @@ struct boot_info *dt_from_blob(const char *fname)
> p = blob + sizeof(magic) + sizeof(totalsize);
>
> while (sizeleft) {
> - if (feof(dtcf->file))
> + if (feof(f))
> die("EOF before reading %d bytes of DT blob\n",
> totalsize);
>
> - rc = fread(p, 1, sizeleft, dtcf->file);
> - if (ferror(dtcf->file))
> + rc = fread(p, 1, sizeleft, f);
> + if (ferror(f))
> die("Error reading DT blob: %s\n",
> strerror(errno));
>
> @@ -900,7 +926,7 @@ struct boot_info *dt_from_blob(const char *fname)
>
> free(blob);
>
> - dtc_close_file(dtcf);
> + fclose(f);
>
> return build_boot_info(reservelist, tree, boot_cpuid_phys);
> }
> diff --git a/scripts/dtc/fstree.c b/scripts/dtc/fstree.c
> index 8fe1bdf..f377453 100644
> --- a/scripts/dtc/fstree.c
> +++ b/scripts/dtc/fstree.c
> @@ -58,10 +58,9 @@ static struct node *read_fstree(const char *dirname)
> "WARNING: Cannot open %s: %s\n",
> tmpnam, strerror(errno));
> } else {
> - prop = build_property(strdup(de->d_name),
> + prop = build_property(xstrdup(de->d_name),
> data_copy_file(pfile,
> - st.st_size),
> - NULL);
> + st.st_size));
> add_property(tree, prop);
> fclose(pfile);
> }
> @@ -69,8 +68,7 @@ static struct node *read_fstree(const char *dirname)
> struct node *newchild;
>
> newchild = read_fstree(tmpnam);
> - newchild = name_node(newchild, strdup(de->d_name),
> - NULL);
> + newchild = name_node(newchild, xstrdup(de->d_name));
> add_child(tree, newchild);
> }
>
> @@ -86,8 +84,8 @@ struct boot_info *dt_from_fs(const char *dirname)
> struct node *tree;
>
> tree = read_fstree(dirname);
> - tree = name_node(tree, "", NULL);
> + tree = name_node(tree, "");
>
> - return build_boot_info(NULL, tree, 0);
> + return build_boot_info(NULL, tree, guess_boot_cpuid(tree));
> }
>
> diff --git a/scripts/dtc/livetree.c b/scripts/dtc/livetree.c
> index 0ca3de5..c9209d5 100644
> --- a/scripts/dtc/livetree.c
> +++ b/scripts/dtc/livetree.c
> @@ -24,17 +24,30 @@
> * Tree building functions
> */
>
> -struct property *build_property(char *name, struct data val, char *label)
> +void add_label(struct label **labels, char *label)
> +{
> + struct label *new;
> +
> + /* Make sure the label isn't already there */
> + for_each_label(*labels, new)
> + if (streq(new->label, label))
> + return;
> +
> + new = xmalloc(sizeof(*new));
> + new->label = label;
> + new->next = *labels;
> + *labels = new;
> +}
> +
> +struct property *build_property(char *name, struct data val)
> {
> struct property *new = xmalloc(sizeof(*new));
>
> + memset(new, 0, sizeof(*new));
> +
> new->name = name;
> new->val = val;
>
> - new->next = NULL;
> -
> - new->label = label;
> -
> return new;
> }
>
> @@ -78,17 +91,82 @@ struct node *build_node(struct property *proplist, struct node *children)
> return new;
> }
>
> -struct node *name_node(struct node *node, char *name, char * label)
> +struct node *name_node(struct node *node, char *name)
> {
> assert(node->name == NULL);
>
> node->name = name;
>
> - node->label = label;
> -
> return node;
> }
>
> +struct node *merge_nodes(struct node *old_node, struct node *new_node)
> +{
> + struct property *new_prop, *old_prop;
> + struct node *new_child, *old_child;
> + struct label *l;
> +
> + /* Add new node labels to old node */
> + for_each_label(new_node->labels, l)
> + add_label(&old_node->labels, l->label);
> +
> + /* Move properties from the new node to the old node. If there
> + * is a collision, replace the old value with the new */
> + while (new_node->proplist) {
> + /* Pop the property off the list */
> + new_prop = new_node->proplist;
> + new_node->proplist = new_prop->next;
> + new_prop->next = NULL;
> +
> + /* Look for a collision, set new value if there is */
> + for_each_property(old_node, old_prop) {
> + if (streq(old_prop->name, new_prop->name)) {
> + /* Add new labels to old property */
> + for_each_label(new_prop->labels, l)
> + add_label(&old_prop->labels, l->label);
> +
> + old_prop->val = new_prop->val;
> + free(new_prop);
> + new_prop = NULL;
> + break;
> + }
> + }
> +
> + /* if no collision occurred, add property to the old node. */
> + if (new_prop)
> + add_property(old_node, new_prop);
> + }
> +
> + /* Move the override child nodes into the primary node. If
> + * there is a collision, then merge the nodes. */
> + while (new_node->children) {
> + /* Pop the child node off the list */
> + new_child = new_node->children;
> + new_node->children = new_child->next_sibling;
> + new_child->parent = NULL;
> + new_child->next_sibling = NULL;
> +
> + /* Search for a collision. Merge if there is */
> + for_each_child(old_node, old_child) {
> + if (streq(old_child->name, new_child->name)) {
> + merge_nodes(old_child, new_child);
> + new_child = NULL;
> + break;
> + }
> + }
> +
> + /* if no collision occured, add child to the old node. */
> + if (new_child)
> + add_child(old_node, new_child);
> + }
> +
> + /* The new node contents are now merged into the old node. Free
> + * the new node. */
> + free(new_node);
> +
> + return old_node;
> +}
> +
> struct node *chain_node(struct node *first, struct node *list)
> {
> assert(first->next_sibling == NULL);
> @@ -124,18 +202,15 @@ void add_child(struct node *parent, struct node *child)
> *p = child;
> }
>
> -struct reserve_info *build_reserve_entry(uint64_t address, uint64_t size,
> - char *label)
> +struct reserve_info *build_reserve_entry(uint64_t address, uint64_t size)
> {
> struct reserve_info *new = xmalloc(sizeof(*new));
>
> + memset(new, 0, sizeof(*new));
> +
> new->re.address = address;
> new->re.size = size;
>
> - new->next = NULL;
> -
> - new->label = label;
> -
> return new;
> }
>
> @@ -208,6 +283,60 @@ cell_t propval_cell(struct property *prop)
> return fdt32_to_cpu(*((cell_t *)prop->val.val));
> }
>
> +struct property *get_property_by_label(struct node *tree, const char *label,
> + struct node **node)
> +{
> + struct property *prop;
> + struct node *c;
> +
> + *node = tree;
> +
> + for_each_property(tree, prop) {
> + struct label *l;
> +
> + for_each_label(prop->labels, l)
> + if (streq(l->label, label))
> + return prop;
> + }
> +
> + for_each_child(tree, c) {
> + prop = get_property_by_label(c, label, node);
> + if (prop)
> + return prop;
> + }
> +
> + *node = NULL;
> + return NULL;
> +}
> +
> +struct marker *get_marker_label(struct node *tree, const char *label,
> + struct node **node, struct property **prop)
> +{
> + struct marker *m;
> + struct property *p;
> + struct node *c;
> +
> + *node = tree;
> +
> + for_each_property(tree, p) {
> + *prop = p;
> + m = p->val.markers;
> + for_each_marker_of_type(m, LABEL)
> + if (streq(m->ref, label))
> + return m;
> + }
> +
> + for_each_child(tree, c) {
> + m = get_marker_label(c, label, node, prop);
> + if (m)
> + return m;
> + }
> +
> + *prop = NULL;
> + *node = NULL;
> + return NULL;
> +}
> +
> struct node *get_subnode(struct node *node, const char *nodename)
> {
> struct node *child;
> @@ -245,11 +374,13 @@ struct node *get_node_by_path(struct node *tree, const char *path)
> struct node *get_node_by_label(struct node *tree, const char *label)
> {
> struct node *child, *node;
> + struct label *l;
>
> assert(label && (strlen(label) > 0));
>
> - if (tree->label && streq(tree->label, label))
> - return tree;
> + for_each_label(tree->labels, l)
> + if (streq(l->label, label))
> + return tree;
>
> for_each_child(tree, child) {
> node = get_node_by_label(child, label);
> @@ -293,16 +424,186 @@ cell_t get_node_phandle(struct node *root, struct node *node)
> if ((node->phandle != 0) && (node->phandle != -1))
> return node->phandle;
>
> - assert(! get_property(node, "linux,phandle"));
> -
> while (get_node_by_phandle(root, phandle))
> phandle++;
>
> node->phandle = phandle;
> - add_property(node,
> - build_property("linux,phandle",
> - data_append_cell(empty_data, phandle),
> - NULL));
> +
> + if (!get_property(node, "linux,phandle")
> + && (phandle_format & PHANDLE_LEGACY))
> + add_property(node,
> + build_property("linux,phandle",
> + data_append_cell(empty_data, phandle)));
> +
> + if (!get_property(node, "phandle")
> + && (phandle_format & PHANDLE_EPAPR))
> + add_property(node,
> + build_property("phandle",
> + data_append_cell(empty_data, phandle)));
> +
> + /* If the node *does* have a phandle property, we must
> + * be dealing with a self-referencing phandle, which will be
> + * fixed up momentarily in the caller */
>
> return node->phandle;
> }
> +
> +uint32_t guess_boot_cpuid(struct node *tree)
> +{
> + struct node *cpus, *bootcpu;
> + struct property *reg;
> +
> + cpus = get_node_by_path(tree, "/cpus");
> + if (!cpus)
> + return 0;
> +
> +
> + bootcpu = cpus->children;
> + if (!bootcpu)
> + return 0;
> +
> + reg = get_property(bootcpu, "reg");
> + if (!reg || (reg->val.len != sizeof(uint32_t)))
> + return 0;
> +
> + /* FIXME: Sanity check node? */
> +
> + return propval_cell(reg);
> +}
> +
> +static int cmp_reserve_info(const void *ax, const void *bx)
> +{
> + const struct reserve_info *a, *b;
> +
> + a = *((const struct reserve_info * const *)ax);
> + b = *((const struct reserve_info * const *)bx);
> +
> + if (a->re.address < b->re.address)
> + return -1;
> + else if (a->re.address > b->re.address)
> + return 1;
> + else if (a->re.size < b->re.size)
> + return -1;
> + else if (a->re.size > b->re.size)
> + return 1;
> + else
> + return 0;
> +}
> +
> +static void sort_reserve_entries(struct boot_info *bi)
> +{
> + struct reserve_info *ri, **tbl;
> + int n = 0, i = 0;
> +
> + for (ri = bi->reservelist;
> + ri;
> + ri = ri->next)
> + n++;
> +
> + if (n == 0)
> + return;
> +
> + tbl = xmalloc(n * sizeof(*tbl));
> +
> + for (ri = bi->reservelist;
> + ri;
> + ri = ri->next)
> + tbl[i++] = ri;
> +
> + qsort(tbl, n, sizeof(*tbl), cmp_reserve_info);
> +
> + bi->reservelist = tbl[0];
> + for (i = 0; i < (n-1); i++)
> + tbl[i]->next = tbl[i+1];
> + tbl[n-1]->next = NULL;
> +
> + free(tbl);
> +}
> +
> +static int cmp_prop(const void *ax, const void *bx)
> +{
> + const struct property *a, *b;
> +
> + a = *((const struct property * const *)ax);
> + b = *((const struct property * const *)bx);
> +
> + return strcmp(a->name, b->name);
> +}
> +
> +static void sort_properties(struct node *node)
> +{
> + int n = 0, i = 0;
> + struct property *prop, **tbl;
> +
> + for_each_property(node, prop)
> + n++;
> +
> + if (n == 0)
> + return;
> +
> + tbl = xmalloc(n * sizeof(*tbl));
> +
> + for_each_property(node, prop)
> + tbl[i++] = prop;
> +
> + qsort(tbl, n, sizeof(*tbl), cmp_prop);
> +
> + node->proplist = tbl[0];
> + for (i = 0; i < (n-1); i++)
> + tbl[i]->next = tbl[i+1];
> + tbl[n-1]->next = NULL;
> +
> + free(tbl);
> +}
> +
> +static int cmp_subnode(const void *ax, const void *bx)
> +{
> + const struct node *a, *b;
> +
> + a = *((const struct node * const *)ax);
> + b = *((const struct node * const *)bx);
> +
> + return strcmp(a->name, b->name);
> +}
> +
> +static void sort_subnodes(struct node *node)
> +{
> + int n = 0, i = 0;
> + struct node *subnode, **tbl;
> +
> + for_each_child(node, subnode)
> + n++;
> +
> + if (n == 0)
> + return;
> +
> + tbl = xmalloc(n * sizeof(*tbl));
> +
> + for_each_child(node, subnode)
> + tbl[i++] = subnode;
> +
> + qsort(tbl, n, sizeof(*tbl), cmp_subnode);
> +
> + node->children = tbl[0];
> + for (i = 0; i < (n-1); i++)
> + tbl[i]->next_sibling = tbl[i+1];
> + tbl[n-1]->next_sibling = NULL;
> +
> + free(tbl);
> +}
> +
> +static void sort_node(struct node *node)
> +{
> + struct node *c;
> +
> + sort_properties(node);
> + sort_subnodes(node);
> + for_each_child(node, c)
> + sort_node(c);
> +}
> +
> +void sort_tree(struct boot_info *bi)
> +{
> + sort_reserve_entries(bi);
> + sort_node(bi->dt);
> +}
> diff --git a/scripts/dtc/srcpos.c b/scripts/dtc/srcpos.c
> index 9641b76..2dbc874 100644
> --- a/scripts/dtc/srcpos.c
> +++ b/scripts/dtc/srcpos.c
> @@ -17,100 +17,232 @@
> * USA
> */
>
> +#define _GNU_SOURCE
> +
> +#include <stdio.h>
> +
> #include "dtc.h"
> #include "srcpos.h"
>
> -/*
> - * Like yylineno, this is the current open file pos.
> - */
>
> -struct dtc_file *srcpos_file;
> +static char *dirname(const char *path)
> +{
> + const char *slash = strrchr(path, '/');
> +
> + if (slash) {
> + int len = slash - path;
> + char *dir = xmalloc(len + 1);
> +
> + memcpy(dir, path, len);
> + dir[len] = '\0';
> + return dir;
> + }
> + return NULL;
> +}
> +
> +struct srcfile_state *current_srcfile; /* = NULL */
>
> -static int dtc_open_one(struct dtc_file *file,
> - const char *search,
> - const char *fname)
> +/* Detect infinite include recursion. */
> +#define MAX_SRCFILE_DEPTH (100)
> +static int srcfile_depth; /* = 0 */
> +
> +FILE *srcfile_relative_open(const char *fname, char **fullnamep)
> {
> + FILE *f;
> char *fullname;
>
> - if (search) {
> - fullname = xmalloc(strlen(search) + strlen(fname) + 2);
> -
> - strcpy(fullname, search);
> - strcat(fullname, "/");
> - strcat(fullname, fname);
> + if (streq(fname, "-")) {
> + f = stdin;
> + fullname = xstrdup("<stdin>");
> } else {
> - fullname = strdup(fname);
> + if (!current_srcfile || !current_srcfile->dir
> + || (fname[0] == '/'))
> + fullname = xstrdup(fname);
> + else
> + fullname = join_path(current_srcfile->dir, fname);
> +
> + f = fopen(fullname, "r");
> + if (!f)
> + die("Couldn't open \"%s\": %s\n", fname,
> + strerror(errno));
> }
>
> - file->file = fopen(fullname, "r");
> - if (!file->file) {
> + if (fullnamep)
> + *fullnamep = fullname;
> + else
> free(fullname);
> - return 0;
> - }
>
> - file->name = fullname;
> - return 1;
> + return f;
> }
>
> +void srcfile_push(const char *fname)
> +{
> + struct srcfile_state *srcfile;
> +
> + if (srcfile_depth++ >= MAX_SRCFILE_DEPTH)
> + die("Includes nested too deeply");
> +
> + srcfile = xmalloc(sizeof(*srcfile));
> +
> + srcfile->f = srcfile_relative_open(fname, &srcfile->name);
> + srcfile->dir = dirname(srcfile->name);
> + srcfile->prev = current_srcfile;
> +
> + srcfile->lineno = 1;
> + srcfile->colno = 1;
> +
> + current_srcfile = srcfile;
> +}
>
> -struct dtc_file *dtc_open_file(const char *fname,
> - const struct search_path *search)
> +int srcfile_pop(void)
> {
> - static const struct search_path default_search = { NULL, NULL, NULL };
> + struct srcfile_state *srcfile = current_srcfile;
>
> - struct dtc_file *file;
> - const char *slash;
> + assert(srcfile);
>
> - file = xmalloc(sizeof(struct dtc_file));
> + current_srcfile = srcfile->prev;
>
> - slash = strrchr(fname, '/');
> - if (slash) {
> - char *dir = xmalloc(slash - fname + 1);
> + if (fclose(srcfile->f))
> + die("Error closing \"%s\": %s\n", srcfile->name,
> + strerror(errno));
>
> - memcpy(dir, fname, slash - fname);
> - dir[slash - fname] = 0;
> - file->dir = dir;
> - } else {
> - file->dir = NULL;
> - }
> + /* FIXME: We allow the srcfile_state structure to leak,
> + * because it could still be referenced from a location
> + * variable being carried through the parser somewhere. To
> + * fix this we could either allocate all the files from a
> + * table, or use a pool allocator. */
>
> - if (streq(fname, "-")) {
> - file->name = "stdin";
> - file->file = stdin;
> - return file;
> - }
> + return current_srcfile ? 1 : 0;
> +}
>
> - if (fname[0] == '/') {
> - file->file = fopen(fname, "r");
> - if (!file->file)
> - goto fail;
> +/*
> + * The empty source position.
> + */
>
> - file->name = strdup(fname);
> - return file;
> - }
> +struct srcpos srcpos_empty = {
> + .first_line = 0,
> + .first_column = 0,
> + .last_line = 0,
> + .last_column = 0,
> + .file = NULL,
> +};
>
> - if (!search)
> - search = &default_search;
> +#define TAB_SIZE 8
>
> - while (search) {
> - if (dtc_open_one(file, search->dir, fname))
> - return file;
> +void srcpos_update(struct srcpos *pos, const char *text, int len)
> +{
> + int i;
> +
> + pos->file = current_srcfile;
> +
> + pos->first_line = current_srcfile->lineno;
> + pos->first_column = current_srcfile->colno;
> +
> + for (i = 0; i < len; i++)
> + if (text[i] == '\n') {
> + current_srcfile->lineno++;
> + current_srcfile->colno = 1;
> + } else if (text[i] == '\t') {
> + current_srcfile->colno =
> + ALIGN(current_srcfile->colno, TAB_SIZE);
> + } else {
> + current_srcfile->colno++;
> + }
> +
> + pos->last_line = current_srcfile->lineno;
> + pos->last_column = current_srcfile->colno;
> +}
>
> - if (errno != ENOENT)
> - goto fail;
> +struct srcpos *
> +srcpos_copy(struct srcpos *pos)
> +{
> + struct srcpos *pos_new;
>
> - search = search->next;
> - }
> + pos_new = xmalloc(sizeof(struct srcpos));
> + memcpy(pos_new, pos, sizeof(struct srcpos));
> +
> + return pos_new;
> +}
> +
> +
> +
> +void
> +srcpos_dump(struct srcpos *pos)
> +{
> + printf("file : \"%s\"\n",
> + pos->file ? (char *) pos->file : "<no file>");
> + printf("first_line : %d\n", pos->first_line);
> + printf("first_column: %d\n", pos->first_column);
> + printf("last_line : %d\n", pos->last_line);
> + printf("last_column : %d\n", pos->last_column);
> + printf("file : %s\n", pos->file->name);
> +}
>
> -fail:
> - die("Couldn't open \"%s\": %s\n", fname, strerror(errno));
> +
> +char *
> +srcpos_string(struct srcpos *pos)
> +{
> + const char *fname = "<no-file>";
> + char *pos_str;
> + int rc;
> +
> + if (pos)
> + fname = pos->file->name;
> +
> +
> + if (pos->first_line != pos->last_line)
> + rc = asprintf(&pos_str, "%s:%d.%d-%d.%d", fname,
> + pos->first_line, pos->first_column,
> + pos->last_line, pos->last_column);
> + else if (pos->first_column != pos->last_column)
> + rc = asprintf(&pos_str, "%s:%d.%d-%d", fname,
> + pos->first_line, pos->first_column,
> + pos->last_column);
> + else
> + rc = asprintf(&pos_str, "%s:%d.%d", fname,
> + pos->first_line, pos->first_column);
> +
> + if (rc == -1)
> + die("Couldn't allocate in srcpos string");
> +
> + return pos_str;
> +}
> +
> +void
> +srcpos_verror(struct srcpos *pos, char const *fmt, va_list va)
> +{
> + const char *srcstr;
> +
> + srcstr = srcpos_string(pos);
> +
> + fprintf(stdout, "Error: %s ", srcstr);
> + vfprintf(stdout, fmt, va);
> + fprintf(stdout, "\n");
> }
>
> -void dtc_close_file(struct dtc_file *file)
> +void
> +srcpos_error(struct srcpos *pos, char const *fmt, ...)
> {
> - if (fclose(file->file))
> - die("Error closing \"%s\": %s\n", file->name, strerror(errno));
> + va_list va;
> +
> + va_start(va, fmt);
> + srcpos_verror(pos, fmt, va);
> + va_end(va);
> +}
> +
> +
> +void
> +srcpos_warn(struct srcpos *pos, char const *fmt, ...)
> +{
> + const char *srcstr;
> + va_list va;
> + va_start(va, fmt);
> +
> + srcstr = srcpos_string(pos);
> +
> + fprintf(stderr, "Warning: %s ", srcstr);
> + vfprintf(stderr, fmt, va);
> + fprintf(stderr, "\n");
>
> - free(file->dir);
> - free(file);
> + va_end(va);
> }
> diff --git a/scripts/dtc/srcpos.h b/scripts/dtc/srcpos.h
> index e17c7c0..bd7966e 100644
> --- a/scripts/dtc/srcpos.h
> +++ b/scripts/dtc/srcpos.h
> @@ -17,69 +17,70 @@
> * USA
> */
>
> -/*
> - * Augment the standard YYLTYPE with a filenum index into an
> - * array of all opened filenames.
> - */
> +#ifndef _SRCPOS_H_
> +#define _SRCPOS_H_
>
> #include <stdio.h>
>
> -struct dtc_file {
> +struct srcfile_state {
> + FILE *f;
> + char *name;
> char *dir;
> - const char *name;
> - FILE *file;
> + int lineno, colno;
> + struct srcfile_state *prev;
> };
>
> -#if ! defined(YYLTYPE) && ! defined(YYLTYPE_IS_DECLARED)
> -typedef struct YYLTYPE {
> +extern struct srcfile_state *current_srcfile; /* = NULL */
> +
> +FILE *srcfile_relative_open(const char *fname, char **fullnamep);
> +void srcfile_push(const char *fname);
> +int srcfile_pop(void);
> +
> +struct srcpos {
> int first_line;
> int first_column;
> int last_line;
> int last_column;
> - struct dtc_file *file;
> -} YYLTYPE;
> -
> -#define YYLTYPE_IS_DECLARED 1
> -#define YYLTYPE_IS_TRIVIAL 1
> -#endif
> -
> -/* Cater to old parser templates. */
> -#ifndef YYID
> -#define YYID(n) (n)
> -#endif
> + struct srcfile_state *file;
> +};
>
> -#define YYLLOC_DEFAULT(Current, Rhs, N) \
> - do \
> - if (YYID (N)) \
> - { \
> - (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
> - (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \
> - (Current).last_line = YYRHSLOC (Rhs, N).last_line; \
> - (Current).last_column = YYRHSLOC (Rhs, N).last_column; \
> - (Current).file = YYRHSLOC (Rhs, N).file; \
> - } \
> - else \
> - { \
> - (Current).first_line = (Current).last_line = \
> - YYRHSLOC (Rhs, 0).last_line; \
> - (Current).first_column = (Current).last_column = \
> - YYRHSLOC (Rhs, 0).last_column; \
> - (Current).file = YYRHSLOC (Rhs, 0).file; \
> - } \
> - while (YYID (0))
> +#define YYLTYPE struct srcpos
>
> +#define YYLLOC_DEFAULT(Current, Rhs, N) \
> + do { \
> + if (N) { \
> + (Current).first_line = YYRHSLOC(Rhs, 1).first_line; \
> + (Current).first_column = YYRHSLOC(Rhs, 1).first_column; \
> + (Current).last_line = YYRHSLOC(Rhs, N).last_line; \
> + (Current).last_column = YYRHSLOC (Rhs, N).last_column; \
> + (Current).file = YYRHSLOC(Rhs, N).file; \
> + } else { \
> + (Current).first_line = (Current).last_line = \
> + YYRHSLOC(Rhs, 0).last_line; \
> + (Current).first_column = (Current).last_column = \
> + YYRHSLOC(Rhs, 0).last_column; \
> + (Current).file = YYRHSLOC (Rhs, 0).file; \
> + } \
> + } while (0)
>
>
> -extern void yyerror(char const *);
> -extern void yyerrorf(char const *, ...) __attribute__((format(printf, 1, 2)));
> +/*
> + * Fictional source position used for IR nodes that are
> + * created without otherwise knowing a true source position.
> + * For example,constant definitions from the command line.
> + */
> +extern struct srcpos srcpos_empty;
>
> -extern struct dtc_file *srcpos_file;
> +extern void srcpos_update(struct srcpos *pos, const char *text, int len);
> +extern struct srcpos *srcpos_copy(struct srcpos *pos);
> +extern char *srcpos_string(struct srcpos *pos);
> +extern void srcpos_dump(struct srcpos *pos);
>
> -struct search_path {
> - const char *dir; /* NULL for current directory */
> - struct search_path *prev, *next;
> -};
> +extern void srcpos_verror(struct srcpos *pos, char const *, va_list va)
> + __attribute__((format(printf, 2, 0)));
> +extern void srcpos_error(struct srcpos *pos, char const *, ...)
> + __attribute__((format(printf, 2, 3)));
> +extern void srcpos_warn(struct srcpos *pos, char const *, ...)
> + __attribute__((format(printf, 2, 3)));
>
> -extern struct dtc_file *dtc_open_file(const char *fname,
> - const struct search_path *search);
> -extern void dtc_close_file(struct dtc_file *file);
> +#endif /* _SRCPOS_H_ */
> diff --git a/scripts/dtc/treesource.c b/scripts/dtc/treesource.c
> index 1521ff1..c09aafa 100644
> --- a/scripts/dtc/treesource.c
> +++ b/scripts/dtc/treesource.c
> @@ -32,8 +32,8 @@ struct boot_info *dt_from_source(const char *fname)
> the_boot_info = NULL;
> treesource_error = 0;
>
> - srcpos_file = dtc_open_file(fname, NULL);
> - yyin = srcpos_file->file;
> + srcfile_push(fname);
> + yyin = current_srcfile->f;
>
> if (yyparse() != 0)
> die("Unable to parse input tree\n");
> @@ -63,26 +63,20 @@ static void write_propval_string(FILE *f, struct data val)
> {
> const char *str = val.val;
> int i;
> - int newchunk = 1;
> struct marker *m = val.markers;
>
> assert(str[val.len-1] == '\0');
>
> + while (m && (m->offset == 0)) {
> + if (m->type == LABEL)
> + fprintf(f, "%s: ", m->ref);
> + m = m->next;
> + }
> + fprintf(f, "\"");
> +
> for (i = 0; i < (val.len-1); i++) {
> char c = str[i];
>
> - if (newchunk) {
> - while (m && (m->offset <= i)) {
> - if (m->type == LABEL) {
> - assert(m->offset == i);
> - fprintf(f, "%s: ", m->ref);
> - }
> - m = m->next;
> - }
> - fprintf(f, "\"");
> - newchunk = 0;
> - }
> -
> switch (c) {
> case '\a':
> fprintf(f, "\\a");
> @@ -113,7 +107,14 @@ static void write_propval_string(FILE *f, struct data val)
> break;
> case '\0':
> fprintf(f, "\", ");
> - newchunk = 1;
> + while (m && (m->offset < i)) {
> + if (m->type == LABEL) {
> + assert(m->offset == (i+1));
> + fprintf(f, "%s: ", m->ref);
> + }
> + m = m->next;
> + }
> + fprintf(f, "\"");
> break;
> default:
> if (isprint(c))
> @@ -234,10 +235,11 @@ static void write_tree_source_node(FILE *f, struct node *tree, int level)
> {
> struct property *prop;
> struct node *child;
> + struct label *l;
>
> write_prefix(f, level);
> - if (tree->label)
> - fprintf(f, "%s: ", tree->label);
> + for_each_label(tree->labels, l)
> + fprintf(f, "%s: ", l->label);
> if (tree->name && (*tree->name))
> fprintf(f, "%s {\n", tree->name);
> else
> @@ -245,8 +247,8 @@ static void write_tree_source_node(FILE *f, struct node *tree, int level)
>
> for_each_property(tree, prop) {
> write_prefix(f, level+1);
> - if (prop->label)
> - fprintf(f, "%s: ", prop->label);
> + for_each_label(prop->labels, l)
> + fprintf(f, "%s: ", l->label);
> fprintf(f, "%s", prop->name);
> write_propval(f, prop);
> }
> @@ -266,8 +268,10 @@ void dt_to_source(FILE *f, struct boot_info *bi)
> fprintf(f, "/dts-v1/;\n\n");
>
> for (re = bi->reservelist; re; re = re->next) {
> - if (re->label)
> - fprintf(f, "%s: ", re->label);
> + struct label *l;
> +
> + for_each_label(re->labels, l)
> + fprintf(f, "%s: ", l->label);
> fprintf(f, "/memreserve/\t0x%016llx 0x%016llx;\n",
> (unsigned long long)re->re.address,
> (unsigned long long)re->re.size);
> diff --git a/scripts/dtc/version_gen.h b/scripts/dtc/version_gen.h
> index 658ff42..0c35fb2 100644
> --- a/scripts/dtc/version_gen.h
> +++ b/scripts/dtc/version_gen.h
> @@ -1 +1 @@
> -#define DTC_VERSION "DTC 1.2.0"
> +#define DTC_VERSION "DTC 1.2.0-g211e80d4"
>
More information about the devicetree-discuss
mailing list