[PATCH v3 3/4] dtc: Add /./

Ayush Singh <[email protected]>
Newsgroups org.kernel.vger.devicetree-compiler
Message-ID <[email protected]>
Allow constructing new values for a property using old property values.
Can be used to append, pre-append, duplicate, etc.

In practice, it looks as follows:

/dts-v1/;

/ {
	str-prop = "0";
	int-prop = <0>;
};

/ {
	str-prop = /./, "1", /./;
	int-prop = /./, <1>, /./;
};

dts to source output with -T -T also works as expected:

/dts-v1/;

/ { /* temp/a.dts:3:3-6:3, temp/a.dts:8:3-11:3 */
	str-prop = "0", "1", "0"; /* temp/a.dts:4:5-4:20, temp/a.dts:9:5-9:30 */
	int-prop = <0x00>, <0x01>, <0x00>; /* temp/a.dts:5:5-5:20, temp/a.dts:10:5-10:30 */
}; /* temp/a.dts:3:3-6:3, temp/a.dts:8:3-11:3 */

Signed-off-by: Ayush Singh <[email protected]>
---
 dtc-lexer.l  |  5 +++++
 dtc-parser.y |  5 +++++
 dtc.h        |  1 +
 livetree.c   | 23 +++++++++++++++++++++--
 4 files changed, 32 insertions(+), 2 deletions(-)

diff --git a/dtc-lexer.l b/dtc-lexer.l
index de60a70b6bdbcb5ae4336ea4171ad6f645e91b36..7ad98b3c5d1fa24dda04731a64d18ecc6ec1e448 100644
--- a/dtc-lexer.l
+++ b/dtc-lexer.l
@@ -144,6 +144,11 @@ static void PRINTF(1, 2) lexical_error(const char *fmt, ...);
 			return DT_OMIT_NO_REF;
 		}
 
+<*>"/./" {
+			DPRINT("Keyword: /./\n");
+			return DT_PREV_VALUE;
+		}
+
 <*>{LABEL}:	{
 			DPRINT("Label: %s\n", yytext);
 			yylval.labelref = xstrdup(yytext);
diff --git a/dtc-parser.y b/dtc-parser.y
index 4d5eece526243460203157464e3cd75f781e50e7..0b7932d4172f30f1c45a9f521dc43a2fae1692b8 100644
--- a/dtc-parser.y
+++ b/dtc-parser.y
@@ -57,6 +57,7 @@ static bool is_ref_relative(const char *ref)
 %token DT_LSHIFT DT_RSHIFT DT_LE DT_GE DT_EQ DT_NE DT_AND DT_OR
 %token DT_BITS
 %token DT_DEL_PROP
+%token DT_PREV_VALUE
 %token DT_DEL_NODE
 %token DT_OMIT_NO_REF
 %token <propnodename> DT_PROPNODENAME
@@ -308,6 +309,10 @@ propdata:
 		{
 			$$ = data_merge($1, $2);
 		}
+        | propdataprefix DT_PREV_VALUE
+                {
+                        $$ = data_add_marker($1, PREV_VALUE, NULL);
+                }
 	| propdataprefix arrayprefix '>'
 		{
 			$$ = data_merge($1, $2.data);
diff --git a/dtc.h b/dtc.h
index 3a220b9afc99f92ea57d50d348eb0872bc779818..f9bdf1d117f8a70d168243129db8f8d940de8064 100644
--- a/dtc.h
+++ b/dtc.h
@@ -110,6 +110,7 @@ enum markertype {
 	REF_PHANDLE,
 	REF_PATH,
 	LABEL,
+	PREV_VALUE,
 	TYPE_UINT8,
 	TYPE_UINT16,
 	TYPE_UINT32,
diff --git a/livetree.c b/livetree.c
index d51d05830b181476ddbab878ef8b556230b58e2b..11c40724c7a8c8b429230f211455f7bcbdc050ec 100644
--- a/livetree.c
+++ b/livetree.c
@@ -143,6 +143,7 @@ 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 marker *marker;
 	struct label *l;
 
 	old_node->deleted = 0;
@@ -154,6 +155,8 @@ struct node *merge_nodes(struct node *old_node, struct node *new_node)
 	/* 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) {
+		bool prev_value_used = false;
+
 		/* Pop the property off the list */
 		new_prop = new_node->proplist;
 		new_node->proplist = new_prop->next;
@@ -172,10 +175,26 @@ struct node *merge_nodes(struct node *old_node, struct node *new_node)
 				for_each_label_withdel(new_prop->labels, l)
 					add_label(&old_prop->labels, l->label);
 
+				marker = new_prop->val.markers;
+				for_each_marker_of_type(marker, PREV_VALUE) {
+					new_prop->val = data_insert_data(
+						new_prop->val, marker,
+						old_prop->val);
+					prev_value_used = true;
+				}
+
 				old_prop->val = new_prop->val;
 				old_prop->deleted = 0;
-				srcpos_free(old_prop->srcpos);
-				old_prop->srcpos = new_prop->srcpos;
+
+				if (prev_value_used) {
+					old_prop->srcpos =
+						srcpos_extend(old_prop->srcpos,
+							      new_prop->srcpos);
+				} else {
+					srcpos_free(old_prop->srcpos);
+					old_prop->srcpos = new_prop->srcpos;
+				}
+
 				free(new_prop);
 				new_prop = NULL;
 				break;

-- 
2.49.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.