annotations: add positions
Extend the parser to record positions, in build_node, build_node_delete, and build_property. srcpos structures are added to the property and node types, and to the parameter lists of the above functions that construct these types. Nodes and properties that are created by the compiler rather than from parsing source code have NULL as the srcpos value. merge_nodes, defined in livetree.c, uses srcpos_extend to combine multiple positions, resulting in a list of positions. srcpos_extend is defined in srcpos.c. New elements are added at the end. This requires the srcpos type, define in srcpos.h, to be a list structure with a next field. This next field is initialized to NULL in srcpos.h, in the macro YYLLOC_DEFAULT invoked implicitly by the generated parser code. Another change to srcpos.c is to make srcpos_copy always do a full copy, including a copy of the file substructure. This is required because when dtc is used on the output of cpp, the successive detected file names overwrite the file name in the file structure. The next field does not need to be deep copied, because it is always NULL when srcpos_copy is called; an assert checks for this. File names are only updated in uncopied position structures. Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
This commit is contained in:
parent
ca930e20bb
commit
8e20ccf52f
7 changed files with 68 additions and 23 deletions
13
dtc-parser.y
13
dtc-parser.y
|
@ -180,7 +180,10 @@ devicetree:
|
||||||
*/
|
*/
|
||||||
if (!($<flags>-1 & DTSF_PLUGIN))
|
if (!($<flags>-1 & DTSF_PLUGIN))
|
||||||
ERROR(&@2, "Label or path %s not found", $1);
|
ERROR(&@2, "Label or path %s not found", $1);
|
||||||
$$ = add_orphan_node(name_node(build_node(NULL, NULL), ""), $2, $1);
|
$$ = add_orphan_node(
|
||||||
|
name_node(build_node(NULL, NULL, NULL),
|
||||||
|
""),
|
||||||
|
$2, $1);
|
||||||
}
|
}
|
||||||
| devicetree DT_LABEL dt_ref nodedef
|
| devicetree DT_LABEL dt_ref nodedef
|
||||||
{
|
{
|
||||||
|
@ -260,7 +263,7 @@ devicetree:
|
||||||
nodedef:
|
nodedef:
|
||||||
'{' proplist subnodes '}' ';'
|
'{' proplist subnodes '}' ';'
|
||||||
{
|
{
|
||||||
$$ = build_node($2, $3);
|
$$ = build_node($2, $3, &@$);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -278,11 +281,11 @@ proplist:
|
||||||
propdef:
|
propdef:
|
||||||
DT_PROPNODENAME '=' propdata ';'
|
DT_PROPNODENAME '=' propdata ';'
|
||||||
{
|
{
|
||||||
$$ = build_property($1, $3);
|
$$ = build_property($1, $3, &@$);
|
||||||
}
|
}
|
||||||
| DT_PROPNODENAME ';'
|
| DT_PROPNODENAME ';'
|
||||||
{
|
{
|
||||||
$$ = build_property($1, empty_data);
|
$$ = build_property($1, empty_data, &@$);
|
||||||
}
|
}
|
||||||
| DT_DEL_PROP DT_PROPNODENAME ';'
|
| DT_DEL_PROP DT_PROPNODENAME ';'
|
||||||
{
|
{
|
||||||
|
@ -563,7 +566,7 @@ subnode:
|
||||||
}
|
}
|
||||||
| DT_DEL_NODE DT_PROPNODENAME ';'
|
| DT_DEL_NODE DT_PROPNODENAME ';'
|
||||||
{
|
{
|
||||||
$$ = name_node(build_node_delete(), $2);
|
$$ = name_node(build_node_delete(&@$), $2);
|
||||||
}
|
}
|
||||||
| DT_OMIT_NO_REF subnode
|
| DT_OMIT_NO_REF subnode
|
||||||
{
|
{
|
||||||
|
|
10
dtc.h
10
dtc.h
|
@ -158,6 +158,7 @@ struct property {
|
||||||
struct property *next;
|
struct property *next;
|
||||||
|
|
||||||
struct label *labels;
|
struct label *labels;
|
||||||
|
struct srcpos *srcpos;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct node {
|
struct node {
|
||||||
|
@ -177,6 +178,7 @@ struct node {
|
||||||
|
|
||||||
struct label *labels;
|
struct label *labels;
|
||||||
const struct bus_type *bus;
|
const struct bus_type *bus;
|
||||||
|
struct srcpos *srcpos;
|
||||||
|
|
||||||
bool omit_if_unused, is_referenced;
|
bool omit_if_unused, is_referenced;
|
||||||
};
|
};
|
||||||
|
@ -205,13 +207,15 @@ struct node {
|
||||||
void add_label(struct label **labels, char *label);
|
void add_label(struct label **labels, char *label);
|
||||||
void delete_labels(struct label **labels);
|
void delete_labels(struct label **labels);
|
||||||
|
|
||||||
struct property *build_property(char *name, struct data val);
|
struct property *build_property(char *name, struct data val,
|
||||||
|
struct srcpos *srcpos);
|
||||||
struct property *build_property_delete(char *name);
|
struct property *build_property_delete(char *name);
|
||||||
struct property *chain_property(struct property *first, struct property *list);
|
struct property *chain_property(struct property *first, struct property *list);
|
||||||
struct property *reverse_properties(struct property *first);
|
struct property *reverse_properties(struct property *first);
|
||||||
|
|
||||||
struct node *build_node(struct property *proplist, struct node *children);
|
struct node *build_node(struct property *proplist, struct node *children,
|
||||||
struct node *build_node_delete(void);
|
struct srcpos *srcpos);
|
||||||
|
struct node *build_node_delete(struct srcpos *srcpos);
|
||||||
struct node *name_node(struct node *node, char *name);
|
struct node *name_node(struct node *node, char *name);
|
||||||
struct node *omit_node_if_unused(struct node *node);
|
struct node *omit_node_if_unused(struct node *node);
|
||||||
struct node *reference_node(struct node *node);
|
struct node *reference_node(struct node *node);
|
||||||
|
|
|
@ -692,7 +692,7 @@ static struct property *flat_read_property(struct inbuf *dtbuf,
|
||||||
|
|
||||||
val = flat_read_data(dtbuf, proplen);
|
val = flat_read_data(dtbuf, proplen);
|
||||||
|
|
||||||
return build_property(name, val);
|
return build_property(name, val, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -750,7 +750,7 @@ static struct node *unflatten_tree(struct inbuf *dtbuf,
|
||||||
char *flatname;
|
char *flatname;
|
||||||
uint32_t val;
|
uint32_t val;
|
||||||
|
|
||||||
node = build_node(NULL, NULL);
|
node = build_node(NULL, NULL, NULL);
|
||||||
|
|
||||||
flatname = flat_read_string(dtbuf);
|
flatname = flat_read_string(dtbuf);
|
||||||
|
|
||||||
|
|
5
fstree.c
5
fstree.c
|
@ -34,7 +34,7 @@ static struct node *read_fstree(const char *dirname)
|
||||||
if (!d)
|
if (!d)
|
||||||
die("Couldn't opendir() \"%s\": %s\n", dirname, strerror(errno));
|
die("Couldn't opendir() \"%s\": %s\n", dirname, strerror(errno));
|
||||||
|
|
||||||
tree = build_node(NULL, NULL);
|
tree = build_node(NULL, NULL, NULL);
|
||||||
|
|
||||||
while ((de = readdir(d)) != NULL) {
|
while ((de = readdir(d)) != NULL) {
|
||||||
char *tmpname;
|
char *tmpname;
|
||||||
|
@ -60,7 +60,8 @@ static struct node *read_fstree(const char *dirname)
|
||||||
} else {
|
} else {
|
||||||
prop = build_property(xstrdup(de->d_name),
|
prop = build_property(xstrdup(de->d_name),
|
||||||
data_copy_file(pfile,
|
data_copy_file(pfile,
|
||||||
st.st_size));
|
st.st_size),
|
||||||
|
NULL);
|
||||||
add_property(tree, prop);
|
add_property(tree, prop);
|
||||||
fclose(pfile);
|
fclose(pfile);
|
||||||
}
|
}
|
||||||
|
|
33
livetree.c
33
livetree.c
|
@ -19,6 +19,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "dtc.h"
|
#include "dtc.h"
|
||||||
|
#include "srcpos.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Tree building functions
|
* Tree building functions
|
||||||
|
@ -50,7 +51,8 @@ void delete_labels(struct label **labels)
|
||||||
label->deleted = 1;
|
label->deleted = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct property *build_property(char *name, struct data val)
|
struct property *build_property(char *name, struct data val,
|
||||||
|
struct srcpos *srcpos)
|
||||||
{
|
{
|
||||||
struct property *new = xmalloc(sizeof(*new));
|
struct property *new = xmalloc(sizeof(*new));
|
||||||
|
|
||||||
|
@ -58,6 +60,7 @@ struct property *build_property(char *name, struct data val)
|
||||||
|
|
||||||
new->name = name;
|
new->name = name;
|
||||||
new->val = val;
|
new->val = val;
|
||||||
|
new->srcpos = srcpos_copy(srcpos);
|
||||||
|
|
||||||
return new;
|
return new;
|
||||||
}
|
}
|
||||||
|
@ -97,7 +100,8 @@ struct property *reverse_properties(struct property *first)
|
||||||
return head;
|
return head;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct node *build_node(struct property *proplist, struct node *children)
|
struct node *build_node(struct property *proplist, struct node *children,
|
||||||
|
struct srcpos *srcpos)
|
||||||
{
|
{
|
||||||
struct node *new = xmalloc(sizeof(*new));
|
struct node *new = xmalloc(sizeof(*new));
|
||||||
struct node *child;
|
struct node *child;
|
||||||
|
@ -106,6 +110,7 @@ struct node *build_node(struct property *proplist, struct node *children)
|
||||||
|
|
||||||
new->proplist = reverse_properties(proplist);
|
new->proplist = reverse_properties(proplist);
|
||||||
new->children = children;
|
new->children = children;
|
||||||
|
new->srcpos = srcpos_copy(srcpos);
|
||||||
|
|
||||||
for_each_child(new, child) {
|
for_each_child(new, child) {
|
||||||
child->parent = new;
|
child->parent = new;
|
||||||
|
@ -114,13 +119,14 @@ struct node *build_node(struct property *proplist, struct node *children)
|
||||||
return new;
|
return new;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct node *build_node_delete(void)
|
struct node *build_node_delete(struct srcpos *srcpos)
|
||||||
{
|
{
|
||||||
struct node *new = xmalloc(sizeof(*new));
|
struct node *new = xmalloc(sizeof(*new));
|
||||||
|
|
||||||
memset(new, 0, sizeof(*new));
|
memset(new, 0, sizeof(*new));
|
||||||
|
|
||||||
new->deleted = 1;
|
new->deleted = 1;
|
||||||
|
new->srcpos = srcpos_copy(srcpos);
|
||||||
|
|
||||||
return new;
|
return new;
|
||||||
}
|
}
|
||||||
|
@ -183,6 +189,8 @@ struct node *merge_nodes(struct node *old_node, struct node *new_node)
|
||||||
|
|
||||||
old_prop->val = new_prop->val;
|
old_prop->val = new_prop->val;
|
||||||
old_prop->deleted = 0;
|
old_prop->deleted = 0;
|
||||||
|
free(old_prop->srcpos);
|
||||||
|
old_prop->srcpos = new_prop->srcpos;
|
||||||
free(new_prop);
|
free(new_prop);
|
||||||
new_prop = NULL;
|
new_prop = NULL;
|
||||||
break;
|
break;
|
||||||
|
@ -223,6 +231,8 @@ struct node *merge_nodes(struct node *old_node, struct node *new_node)
|
||||||
add_child(old_node, new_child);
|
add_child(old_node, new_child);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
old_node->srcpos = srcpos_extend(old_node->srcpos, new_node->srcpos);
|
||||||
|
|
||||||
/* The new node contents are now merged into the old node. Free
|
/* The new node contents are now merged into the old node. Free
|
||||||
* the new node. */
|
* the new node. */
|
||||||
free(new_node);
|
free(new_node);
|
||||||
|
@ -241,18 +251,18 @@ struct node * add_orphan_node(struct node *dt, struct node *new_node, char *ref)
|
||||||
if (ref[0] == '/') {
|
if (ref[0] == '/') {
|
||||||
d = data_append_data(d, ref, strlen(ref) + 1);
|
d = data_append_data(d, ref, strlen(ref) + 1);
|
||||||
|
|
||||||
p = build_property("target-path", d);
|
p = build_property("target-path", d, NULL);
|
||||||
} else {
|
} else {
|
||||||
d = data_add_marker(d, REF_PHANDLE, ref);
|
d = data_add_marker(d, REF_PHANDLE, ref);
|
||||||
d = data_append_integer(d, 0xffffffff, 32);
|
d = data_append_integer(d, 0xffffffff, 32);
|
||||||
|
|
||||||
p = build_property("target", d);
|
p = build_property("target", d, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
xasprintf(&name, "fragment@%u",
|
xasprintf(&name, "fragment@%u",
|
||||||
next_orphan_fragment++);
|
next_orphan_fragment++);
|
||||||
name_node(new_node, "__overlay__");
|
name_node(new_node, "__overlay__");
|
||||||
node = build_node(p, new_node);
|
node = build_node(p, new_node, NULL);
|
||||||
name_node(node, name);
|
name_node(node, name);
|
||||||
|
|
||||||
add_child(dt, node);
|
add_child(dt, node);
|
||||||
|
@ -351,7 +361,7 @@ void append_to_property(struct node *node,
|
||||||
p->val = d;
|
p->val = d;
|
||||||
} else {
|
} else {
|
||||||
d = data_append_data(empty_data, data, len);
|
d = data_append_data(empty_data, data, len);
|
||||||
p = build_property(name, d);
|
p = build_property(name, d, NULL);
|
||||||
add_property(node, p);
|
add_property(node, p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -609,11 +619,11 @@ cell_t get_node_phandle(struct node *root, struct node *node)
|
||||||
|
|
||||||
if (!get_property(node, "linux,phandle")
|
if (!get_property(node, "linux,phandle")
|
||||||
&& (phandle_format & PHANDLE_LEGACY))
|
&& (phandle_format & PHANDLE_LEGACY))
|
||||||
add_property(node, build_property("linux,phandle", d));
|
add_property(node, build_property("linux,phandle", d, NULL));
|
||||||
|
|
||||||
if (!get_property(node, "phandle")
|
if (!get_property(node, "phandle")
|
||||||
&& (phandle_format & PHANDLE_EPAPR))
|
&& (phandle_format & PHANDLE_EPAPR))
|
||||||
add_property(node, build_property("phandle", d));
|
add_property(node, build_property("phandle", d, NULL));
|
||||||
|
|
||||||
/* If the node *does* have a phandle property, we must
|
/* If the node *does* have a phandle property, we must
|
||||||
* be dealing with a self-referencing phandle, which will be
|
* be dealing with a self-referencing phandle, which will be
|
||||||
|
@ -787,7 +797,7 @@ static struct node *build_and_name_child_node(struct node *parent, char *name)
|
||||||
{
|
{
|
||||||
struct node *node;
|
struct node *node;
|
||||||
|
|
||||||
node = build_node(NULL, NULL);
|
node = build_node(NULL, NULL, NULL);
|
||||||
name_node(node, xstrdup(name));
|
name_node(node, xstrdup(name));
|
||||||
add_child(parent, node);
|
add_child(parent, node);
|
||||||
|
|
||||||
|
@ -849,7 +859,8 @@ static void generate_label_tree_internal(struct dt_info *dti,
|
||||||
/* insert it */
|
/* insert it */
|
||||||
p = build_property(l->label,
|
p = build_property(l->label,
|
||||||
data_copy_mem(node->fullpath,
|
data_copy_mem(node->fullpath,
|
||||||
strlen(node->fullpath) + 1));
|
strlen(node->fullpath) + 1),
|
||||||
|
NULL);
|
||||||
add_property(an, p);
|
add_property(an, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
22
srcpos.c
22
srcpos.c
|
@ -222,13 +222,35 @@ struct srcpos *
|
||||||
srcpos_copy(struct srcpos *pos)
|
srcpos_copy(struct srcpos *pos)
|
||||||
{
|
{
|
||||||
struct srcpos *pos_new;
|
struct srcpos *pos_new;
|
||||||
|
struct srcfile_state *srcfile_state;
|
||||||
|
|
||||||
|
if (!pos)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
pos_new = xmalloc(sizeof(struct srcpos));
|
pos_new = xmalloc(sizeof(struct srcpos));
|
||||||
|
assert(pos->next == NULL);
|
||||||
memcpy(pos_new, pos, sizeof(struct srcpos));
|
memcpy(pos_new, pos, sizeof(struct srcpos));
|
||||||
|
|
||||||
|
/* allocate without free */
|
||||||
|
srcfile_state = xmalloc(sizeof(struct srcfile_state));
|
||||||
|
memcpy(srcfile_state, pos->file, sizeof(struct srcfile_state));
|
||||||
|
pos_new->file = srcfile_state;
|
||||||
|
|
||||||
return pos_new;
|
return pos_new;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct srcpos *srcpos_extend(struct srcpos *pos, struct srcpos *newtail)
|
||||||
|
{
|
||||||
|
struct srcpos *p;
|
||||||
|
|
||||||
|
if (!pos)
|
||||||
|
return newtail;
|
||||||
|
|
||||||
|
for (p = pos; p->next != NULL; p = p->next);
|
||||||
|
p->next = newtail;
|
||||||
|
return pos;
|
||||||
|
}
|
||||||
|
|
||||||
char *
|
char *
|
||||||
srcpos_string(struct srcpos *pos)
|
srcpos_string(struct srcpos *pos)
|
||||||
{
|
{
|
||||||
|
|
4
srcpos.h
4
srcpos.h
|
@ -74,6 +74,7 @@ struct srcpos {
|
||||||
int last_line;
|
int last_line;
|
||||||
int last_column;
|
int last_column;
|
||||||
struct srcfile_state *file;
|
struct srcfile_state *file;
|
||||||
|
struct srcpos *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define YYLTYPE struct srcpos
|
#define YYLTYPE struct srcpos
|
||||||
|
@ -93,11 +94,14 @@ struct srcpos {
|
||||||
YYRHSLOC(Rhs, 0).last_column; \
|
YYRHSLOC(Rhs, 0).last_column; \
|
||||||
(Current).file = YYRHSLOC (Rhs, 0).file; \
|
(Current).file = YYRHSLOC (Rhs, 0).file; \
|
||||||
} \
|
} \
|
||||||
|
(Current).next = NULL; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
|
||||||
extern void srcpos_update(struct srcpos *pos, const char *text, int len);
|
extern void srcpos_update(struct srcpos *pos, const char *text, int len);
|
||||||
extern struct srcpos *srcpos_copy(struct srcpos *pos);
|
extern struct srcpos *srcpos_copy(struct srcpos *pos);
|
||||||
|
extern struct srcpos *srcpos_extend(struct srcpos *new_srcpos,
|
||||||
|
struct srcpos *old_srcpos);
|
||||||
extern char *srcpos_string(struct srcpos *pos);
|
extern char *srcpos_string(struct srcpos *pos);
|
||||||
|
|
||||||
extern void PRINTF(3, 0) srcpos_verror(struct srcpos *pos, const char *prefix,
|
extern void PRINTF(3, 0) srcpos_verror(struct srcpos *pos, const char *prefix,
|
||||||
|
|
Loading…
Reference in a new issue