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>
diff --git a/dtc-parser.y b/dtc-parser.y
index deda663..2ec981e 100644
--- a/dtc-parser.y
+++ b/dtc-parser.y
@@ -180,7 +180,10 @@
*/
if (!($<flags>-1 & DTSF_PLUGIN))
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
{
@@ -260,7 +263,7 @@
nodedef:
'{' proplist subnodes '}' ';'
{
- $$ = build_node($2, $3);
+ $$ = build_node($2, $3, &@$);
}
;
@@ -278,11 +281,11 @@
propdef:
DT_PROPNODENAME '=' propdata ';'
{
- $$ = build_property($1, $3);
+ $$ = build_property($1, $3, &@$);
}
| DT_PROPNODENAME ';'
{
- $$ = build_property($1, empty_data);
+ $$ = build_property($1, empty_data, &@$);
}
| DT_DEL_PROP DT_PROPNODENAME ';'
{
@@ -563,7 +566,7 @@
}
| DT_DEL_NODE DT_PROPNODENAME ';'
{
- $$ = name_node(build_node_delete(), $2);
+ $$ = name_node(build_node_delete(&@$), $2);
}
| DT_OMIT_NO_REF subnode
{
diff --git a/dtc.h b/dtc.h
index cbe5415..8722cbc 100644
--- a/dtc.h
+++ b/dtc.h
@@ -158,6 +158,7 @@
struct property *next;
struct label *labels;
+ struct srcpos *srcpos;
};
struct node {
@@ -177,6 +178,7 @@
struct label *labels;
const struct bus_type *bus;
+ struct srcpos *srcpos;
bool omit_if_unused, is_referenced;
};
@@ -205,13 +207,15 @@
void add_label(struct label **labels, char *label);
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 *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 *build_node_delete(void);
+struct node *build_node(struct property *proplist, struct node *children,
+ struct srcpos *srcpos);
+struct node *build_node_delete(struct srcpos *srcpos);
struct node *name_node(struct node *node, char *name);
struct node *omit_node_if_unused(struct node *node);
struct node *reference_node(struct node *node);
diff --git a/flattree.c b/flattree.c
index 851ea87..acf04c3 100644
--- a/flattree.c
+++ b/flattree.c
@@ -692,7 +692,7 @@
val = flat_read_data(dtbuf, proplen);
- return build_property(name, val);
+ return build_property(name, val, NULL);
}
@@ -750,7 +750,7 @@
char *flatname;
uint32_t val;
- node = build_node(NULL, NULL);
+ node = build_node(NULL, NULL, NULL);
flatname = flat_read_string(dtbuf);
diff --git a/fstree.c b/fstree.c
index ae7d06c..1e7eeba 100644
--- a/fstree.c
+++ b/fstree.c
@@ -34,7 +34,7 @@
if (!d)
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) {
char *tmpname;
@@ -60,7 +60,8 @@
} else {
prop = build_property(xstrdup(de->d_name),
data_copy_file(pfile,
- st.st_size));
+ st.st_size),
+ NULL);
add_property(tree, prop);
fclose(pfile);
}
diff --git a/livetree.c b/livetree.c
index 4ff0679..7a2e644 100644
--- a/livetree.c
+++ b/livetree.c
@@ -19,6 +19,7 @@
*/
#include "dtc.h"
+#include "srcpos.h"
/*
* Tree building functions
@@ -50,7 +51,8 @@
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));
@@ -58,6 +60,7 @@
new->name = name;
new->val = val;
+ new->srcpos = srcpos_copy(srcpos);
return new;
}
@@ -97,7 +100,8 @@
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 *child;
@@ -106,6 +110,7 @@
new->proplist = reverse_properties(proplist);
new->children = children;
+ new->srcpos = srcpos_copy(srcpos);
for_each_child(new, child) {
child->parent = new;
@@ -114,13 +119,14 @@
return new;
}
-struct node *build_node_delete(void)
+struct node *build_node_delete(struct srcpos *srcpos)
{
struct node *new = xmalloc(sizeof(*new));
memset(new, 0, sizeof(*new));
new->deleted = 1;
+ new->srcpos = srcpos_copy(srcpos);
return new;
}
@@ -183,6 +189,8 @@
old_prop->val = new_prop->val;
old_prop->deleted = 0;
+ free(old_prop->srcpos);
+ old_prop->srcpos = new_prop->srcpos;
free(new_prop);
new_prop = NULL;
break;
@@ -223,6 +231,8 @@
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. */
free(new_node);
@@ -241,18 +251,18 @@
if (ref[0] == '/') {
d = data_append_data(d, ref, strlen(ref) + 1);
- p = build_property("target-path", d);
+ p = build_property("target-path", d, NULL);
} else {
d = data_add_marker(d, REF_PHANDLE, ref);
d = data_append_integer(d, 0xffffffff, 32);
- p = build_property("target", d);
+ p = build_property("target", d, NULL);
}
xasprintf(&name, "fragment@%u",
next_orphan_fragment++);
name_node(new_node, "__overlay__");
- node = build_node(p, new_node);
+ node = build_node(p, new_node, NULL);
name_node(node, name);
add_child(dt, node);
@@ -351,7 +361,7 @@
p->val = d;
} else {
d = data_append_data(empty_data, data, len);
- p = build_property(name, d);
+ p = build_property(name, d, NULL);
add_property(node, p);
}
}
@@ -609,11 +619,11 @@
if (!get_property(node, "linux,phandle")
&& (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")
&& (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
* be dealing with a self-referencing phandle, which will be
@@ -787,7 +797,7 @@
{
struct node *node;
- node = build_node(NULL, NULL);
+ node = build_node(NULL, NULL, NULL);
name_node(node, xstrdup(name));
add_child(parent, node);
@@ -849,7 +859,8 @@
/* insert it */
p = build_property(l->label,
data_copy_mem(node->fullpath,
- strlen(node->fullpath) + 1));
+ strlen(node->fullpath) + 1),
+ NULL);
add_property(an, p);
}
diff --git a/srcpos.c b/srcpos.c
index ea82d88..77b50c9 100644
--- a/srcpos.c
+++ b/srcpos.c
@@ -222,13 +222,35 @@
srcpos_copy(struct srcpos *pos)
{
struct srcpos *pos_new;
+ struct srcfile_state *srcfile_state;
+
+ if (!pos)
+ return NULL;
pos_new = xmalloc(sizeof(struct srcpos));
+ assert(pos->next == NULL);
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;
}
+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 *
srcpos_string(struct srcpos *pos)
{
diff --git a/srcpos.h b/srcpos.h
index 1c74efd..8dc118f 100644
--- a/srcpos.h
+++ b/srcpos.h
@@ -74,6 +74,7 @@
int last_line;
int last_column;
struct srcfile_state *file;
+ struct srcpos *next;
};
#define YYLTYPE struct srcpos
@@ -93,11 +94,14 @@
YYRHSLOC(Rhs, 0).last_column; \
(Current).file = YYRHSLOC (Rhs, 0).file; \
} \
+ (Current).next = NULL; \
} while (0)
extern void srcpos_update(struct srcpos *pos, const char *text, int len);
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 void PRINTF(3, 0) srcpos_verror(struct srcpos *pos, const char *prefix,