* [PATCH v3 1/4] srcpos: Define srcpos_free
2025-06-05 10:48 [PATCH v3 0/4] Add capability to create property from old property Ayush Singh
@ 2025-06-05 10:48 ` Ayush Singh
2025-06-09 12:39 ` David Gibson
2025-06-05 10:48 ` [PATCH v3 2/4] dtc: Add data_insert_data function Ayush Singh
` (2 subsequent siblings)
3 siblings, 1 reply; 7+ messages in thread
From: Ayush Singh @ 2025-06-05 10:48 UTC (permalink / raw)
To: David Gibson, Andreas Gnau, d-gole, lorforlinux, jkridner,
robertcnelson, Andrew Davis, Geert Uytterhoeven, Simon Glass
Cc: devicetree-compiler, Ayush Singh
srcpos can be chained together using srcpos_extend. However, in such
cases, we need to free all the chained nodes.
srcpos_free is a helper to recursively free all the linked srcpos.
Signed-off-by: Ayush Singh <ayush@beagleboard.org>
---
livetree.c | 2 +-
srcpos.c | 11 +++++++++++
srcpos.h | 1 +
3 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/livetree.c b/livetree.c
index 93c77d95a320ec05aa355e12920cef9e1c91c26a..d51d05830b181476ddbab878ef8b556230b58e2b 100644
--- a/livetree.c
+++ b/livetree.c
@@ -174,7 +174,7 @@ struct node *merge_nodes(struct node *old_node, struct node *new_node)
old_prop->val = new_prop->val;
old_prop->deleted = 0;
- free(old_prop->srcpos);
+ srcpos_free(old_prop->srcpos);
old_prop->srcpos = new_prop->srcpos;
free(new_prop);
new_prop = NULL;
diff --git a/srcpos.c b/srcpos.c
index 5e2f7dd299184ff86b00b280dc31498cb9830e28..5bb57bf6856c6ff6b8eb993aff5d216c63bf5ecb 100644
--- a/srcpos.c
+++ b/srcpos.c
@@ -287,6 +287,17 @@ struct srcpos *srcpos_extend(struct srcpos *pos, struct srcpos *newtail)
return pos;
}
+void srcpos_free(struct srcpos *pos)
+{
+ struct srcpos *p_next;
+
+ while (pos) {
+ p_next = pos->next;
+ free(pos);
+ pos = p_next;
+ }
+}
+
char *
srcpos_string(struct srcpos *pos)
{
diff --git a/srcpos.h b/srcpos.h
index 4318d7ad34d91d2ada1a5d7f92d2c84148fec366..4d60b50e31197c2da6a7fa8851c5e5a6717d78a6 100644
--- a/srcpos.h
+++ b/srcpos.h
@@ -88,6 +88,7 @@ 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 void srcpos_free(struct srcpos *pos);
extern char *srcpos_string(struct srcpos *pos);
extern char *srcpos_string_first(struct srcpos *pos, int level);
extern char *srcpos_string_last(struct srcpos *pos, int level);
--
2.49.0
^ permalink raw reply related [flat|nested] 7+ messages in thread* Re: [PATCH v3 1/4] srcpos: Define srcpos_free
2025-06-05 10:48 ` [PATCH v3 1/4] srcpos: Define srcpos_free Ayush Singh
@ 2025-06-09 12:39 ` David Gibson
0 siblings, 0 replies; 7+ messages in thread
From: David Gibson @ 2025-06-09 12:39 UTC (permalink / raw)
To: Ayush Singh
Cc: Andreas Gnau, d-gole, lorforlinux, jkridner, robertcnelson,
Andrew Davis, Geert Uytterhoeven, Simon Glass,
devicetree-compiler
[-- Attachment #1: Type: text/plain, Size: 2393 bytes --]
On Thu, Jun 05, 2025 at 04:18:06PM +0530, Ayush Singh wrote:
> srcpos can be chained together using srcpos_extend. However, in such
> cases, we need to free all the chained nodes.
>
> srcpos_free is a helper to recursively free all the linked srcpos.
>
> Signed-off-by: Ayush Singh <ayush@beagleboard.org>
Merged, thanks.
> ---
> livetree.c | 2 +-
> srcpos.c | 11 +++++++++++
> srcpos.h | 1 +
> 3 files changed, 13 insertions(+), 1 deletion(-)
>
> diff --git a/livetree.c b/livetree.c
> index 93c77d95a320ec05aa355e12920cef9e1c91c26a..d51d05830b181476ddbab878ef8b556230b58e2b 100644
> --- a/livetree.c
> +++ b/livetree.c
> @@ -174,7 +174,7 @@ struct node *merge_nodes(struct node *old_node, struct node *new_node)
>
> old_prop->val = new_prop->val;
> old_prop->deleted = 0;
> - free(old_prop->srcpos);
> + srcpos_free(old_prop->srcpos);
> old_prop->srcpos = new_prop->srcpos;
> free(new_prop);
> new_prop = NULL;
> diff --git a/srcpos.c b/srcpos.c
> index 5e2f7dd299184ff86b00b280dc31498cb9830e28..5bb57bf6856c6ff6b8eb993aff5d216c63bf5ecb 100644
> --- a/srcpos.c
> +++ b/srcpos.c
> @@ -287,6 +287,17 @@ struct srcpos *srcpos_extend(struct srcpos *pos, struct srcpos *newtail)
> return pos;
> }
>
> +void srcpos_free(struct srcpos *pos)
> +{
> + struct srcpos *p_next;
> +
> + while (pos) {
> + p_next = pos->next;
> + free(pos);
> + pos = p_next;
> + }
> +}
> +
> char *
> srcpos_string(struct srcpos *pos)
> {
> diff --git a/srcpos.h b/srcpos.h
> index 4318d7ad34d91d2ada1a5d7f92d2c84148fec366..4d60b50e31197c2da6a7fa8851c5e5a6717d78a6 100644
> --- a/srcpos.h
> +++ b/srcpos.h
> @@ -88,6 +88,7 @@ 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 void srcpos_free(struct srcpos *pos);
> extern char *srcpos_string(struct srcpos *pos);
> extern char *srcpos_string_first(struct srcpos *pos, int level);
> extern char *srcpos_string_last(struct srcpos *pos, int level);
>
--
David Gibson (he or they) | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you, not the other way
| around.
http://www.ozlabs.org/~dgibson
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v3 2/4] dtc: Add data_insert_data function
2025-06-05 10:48 [PATCH v3 0/4] Add capability to create property from old property Ayush Singh
2025-06-05 10:48 ` [PATCH v3 1/4] srcpos: Define srcpos_free Ayush Singh
@ 2025-06-05 10:48 ` Ayush Singh
2025-06-12 10:56 ` David Gibson
2025-06-05 10:48 ` [PATCH v3 3/4] dtc: Add /./ Ayush Singh
2025-06-05 10:48 ` [PATCH v3 4/4] tests: Add test for /./ Ayush Singh
3 siblings, 1 reply; 7+ messages in thread
From: Ayush Singh @ 2025-06-05 10:48 UTC (permalink / raw)
To: David Gibson, Andreas Gnau, d-gole, lorforlinux, jkridner,
robertcnelson, Andrew Davis, Geert Uytterhoeven, Simon Glass
Cc: devicetree-compiler, Ayush Singh
Add helper function to insert a data struct into another.
Signed-off-by: Ayush Singh <ayush@beagleboard.org>
---
data.c | 27 +++++++++++++++++++++++++++
dtc.h | 1 +
2 files changed, 28 insertions(+)
diff --git a/data.c b/data.c
index 913796f2e664d07cdc48e0cbf2ab5d6fe9978072..5b25aa060416134be430aebe33c9cce49515297f 100644
--- a/data.c
+++ b/data.c
@@ -251,6 +251,33 @@ bool data_is_one_string(struct data d)
return true;
}
+struct data data_insert_data(struct data d, struct marker *m, struct data old)
+{
+ unsigned int offset = m->offset;
+ struct marker *next = m->next;
+ struct marker *marker;
+ struct data new_data;
+ char *ref;
+
+ new_data = data_insert_at_marker(d, m, old.val, old.len);
+
+ /* Copy all markers from old value */
+ marker = old.markers;
+ for_each_marker(marker) {
+ ref = NULL;
+
+ if (marker->ref)
+ ref = xstrdup(marker->ref);
+
+ m->next = alloc_marker(marker->offset + offset, marker->type,
+ ref);
+ m = m->next;
+ }
+ m->next = next;
+
+ return new_data;
+}
+
struct marker *alloc_marker(unsigned int offset, enum markertype type,
char *ref)
{
diff --git a/dtc.h b/dtc.h
index bd803397449a4b71ff89944ea125cefb96c4dd21..3a220b9afc99f92ea57d50d348eb0872bc779818 100644
--- a/dtc.h
+++ b/dtc.h
@@ -182,6 +182,7 @@ struct data data_append_addr(struct data d, uint64_t addr);
struct data data_append_byte(struct data d, uint8_t byte);
struct data data_append_zeroes(struct data d, int len);
struct data data_append_align(struct data d, int align);
+struct data data_insert_data(struct data d, struct marker *m, struct data old);
struct marker *alloc_marker(unsigned int offset, enum markertype type,
char *ref);
--
2.49.0
^ permalink raw reply related [flat|nested] 7+ messages in thread* Re: [PATCH v3 2/4] dtc: Add data_insert_data function
2025-06-05 10:48 ` [PATCH v3 2/4] dtc: Add data_insert_data function Ayush Singh
@ 2025-06-12 10:56 ` David Gibson
0 siblings, 0 replies; 7+ messages in thread
From: David Gibson @ 2025-06-12 10:56 UTC (permalink / raw)
To: Ayush Singh
Cc: Andreas Gnau, d-gole, lorforlinux, jkridner, robertcnelson,
Andrew Davis, Geert Uytterhoeven, Simon Glass,
devicetree-compiler
[-- Attachment #1: Type: text/plain, Size: 2155 bytes --]
On Thu, Jun 05, 2025 at 04:18:07PM +0530, Ayush Singh wrote:
> Add helper function to insert a data struct into another.
Applied, thanks.
>
> Signed-off-by: Ayush Singh <ayush@beagleboard.org>
> ---
> data.c | 27 +++++++++++++++++++++++++++
> dtc.h | 1 +
> 2 files changed, 28 insertions(+)
>
> diff --git a/data.c b/data.c
> index 913796f2e664d07cdc48e0cbf2ab5d6fe9978072..5b25aa060416134be430aebe33c9cce49515297f 100644
> --- a/data.c
> +++ b/data.c
> @@ -251,6 +251,33 @@ bool data_is_one_string(struct data d)
> return true;
> }
>
> +struct data data_insert_data(struct data d, struct marker *m, struct data old)
> +{
> + unsigned int offset = m->offset;
> + struct marker *next = m->next;
> + struct marker *marker;
> + struct data new_data;
> + char *ref;
> +
> + new_data = data_insert_at_marker(d, m, old.val, old.len);
> +
> + /* Copy all markers from old value */
> + marker = old.markers;
> + for_each_marker(marker) {
> + ref = NULL;
> +
> + if (marker->ref)
> + ref = xstrdup(marker->ref);
> +
> + m->next = alloc_marker(marker->offset + offset, marker->type,
> + ref);
> + m = m->next;
> + }
> + m->next = next;
> +
> + return new_data;
> +}
> +
> struct marker *alloc_marker(unsigned int offset, enum markertype type,
> char *ref)
> {
> diff --git a/dtc.h b/dtc.h
> index bd803397449a4b71ff89944ea125cefb96c4dd21..3a220b9afc99f92ea57d50d348eb0872bc779818 100644
> --- a/dtc.h
> +++ b/dtc.h
> @@ -182,6 +182,7 @@ struct data data_append_addr(struct data d, uint64_t addr);
> struct data data_append_byte(struct data d, uint8_t byte);
> struct data data_append_zeroes(struct data d, int len);
> struct data data_append_align(struct data d, int align);
> +struct data data_insert_data(struct data d, struct marker *m, struct data old);
>
> struct marker *alloc_marker(unsigned int offset, enum markertype type,
> char *ref);
>
--
David Gibson (he or they) | I'll have my music baroque, and my code
david AT gibson.dropbear.id.au | minimalist, thank you, not the other way
| around.
http://www.ozlabs.org/~dgibson
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v3 3/4] dtc: Add /./
2025-06-05 10:48 [PATCH v3 0/4] Add capability to create property from old property Ayush Singh
2025-06-05 10:48 ` [PATCH v3 1/4] srcpos: Define srcpos_free Ayush Singh
2025-06-05 10:48 ` [PATCH v3 2/4] dtc: Add data_insert_data function Ayush Singh
@ 2025-06-05 10:48 ` Ayush Singh
2025-06-05 10:48 ` [PATCH v3 4/4] tests: Add test for /./ Ayush Singh
3 siblings, 0 replies; 7+ messages in thread
From: Ayush Singh @ 2025-06-05 10:48 UTC (permalink / raw)
To: David Gibson, Andreas Gnau, d-gole, lorforlinux, jkridner,
robertcnelson, Andrew Davis, Geert Uytterhoeven, Simon Glass
Cc: devicetree-compiler, Ayush Singh
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 <ayush@beagleboard.org>
---
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
^ permalink raw reply related [flat|nested] 7+ messages in thread* [PATCH v3 4/4] tests: Add test for /./
2025-06-05 10:48 [PATCH v3 0/4] Add capability to create property from old property Ayush Singh
` (2 preceding siblings ...)
2025-06-05 10:48 ` [PATCH v3 3/4] dtc: Add /./ Ayush Singh
@ 2025-06-05 10:48 ` Ayush Singh
3 siblings, 0 replies; 7+ messages in thread
From: Ayush Singh @ 2025-06-05 10:48 UTC (permalink / raw)
To: David Gibson, Andreas Gnau, d-gole, lorforlinux, jkridner,
robertcnelson, Andrew Davis, Geert Uytterhoeven, Simon Glass
Cc: devicetree-compiler, Ayush Singh
- Test /./ on a string and int array.
- Also test on subnode property.
Signed-off-by: Ayush Singh <ayush@beagleboard.org>
---
tests/prev_prop.dts | 25 +++++++++++++++++++++++++
tests/prev_prop_expected.dts | 13 +++++++++++++
tests/run_tests.sh | 5 +++++
3 files changed, 43 insertions(+)
diff --git a/tests/prev_prop.dts b/tests/prev_prop.dts
new file mode 100644
index 0000000000000000000000000000000000000000..27b5395628999b0a06ccd0c160d4e928bd6396ea
--- /dev/null
+++ b/tests/prev_prop.dts
@@ -0,0 +1,25 @@
+/dts-v1/;
+
+/ {
+ str-prop = "1", "2";
+ int-prop = <1 2>;
+
+ mixed-prop = "1", <0>;
+
+ subnode {
+ str-prop = "1", "2";
+ int-prop = <1 2>;
+ };
+};
+
+/ {
+ str-prop = /./, "3", "4", /./, "6";
+ int-prop = /./, <3 4>, /./, <6>;
+
+ mixed-prop = <1>, /./, "0";
+
+ subnode {
+ str-prop = /./, "3", "4", /./;
+ int-prop = /./, <3 4>, /./;
+ };
+};
diff --git a/tests/prev_prop_expected.dts b/tests/prev_prop_expected.dts
new file mode 100644
index 0000000000000000000000000000000000000000..59e6573674e55c3d7cf8b0f236324ec0f8585915
--- /dev/null
+++ b/tests/prev_prop_expected.dts
@@ -0,0 +1,13 @@
+/dts-v1/;
+
+/ {
+ str-prop = "1", "2", "3", "4", "1", "2", "6";
+ int-prop = <1 2 3 4 1 2 6>;
+
+ mixed-prop = <1>, "1", <0>, "0";
+
+ subnode {
+ str-prop = "1", "2", "3", "4", "1", "2";
+ int-prop = <1 2 3 4 1 2>;
+ };
+};
diff --git a/tests/run_tests.sh b/tests/run_tests.sh
index fecfe7cc09b3517acd264e5dead378730671fbca..476554c2138192277ef8266c476b1cc45067f407 100755
--- a/tests/run_tests.sh
+++ b/tests/run_tests.sh
@@ -708,6 +708,11 @@ dtc_tests () {
run_dtc_test -I dts -O dtb -o dtc_tree1_delete.test.dtb "$SRCDIR/test_tree1_delete.dts"
tree1_tests dtc_tree1_delete.test.dtb
+ # Check previous property functionality
+ run_dtc_test -I dts -O dtb -o prev_prop.test.dtb "$SRCDIR/prev_prop.dts"
+ run_dtc_test -I dts -O dtb -o prev_prop_expected.test.dtb "$SRCDIR/prev_prop_expected.dts"
+ run_test dtbs_equal_ordered prev_prop.test.dtb prev_prop_expected.test.dtb
+
# Check omit-if-no-ref functionality
run_dtc_test -I dts -O dtb -o omit-no-ref.test.dtb "$SRCDIR/omit-no-ref.dts"
run_test check_path omit-no-ref.test.dtb not-exists "/node1"
--
2.49.0
^ permalink raw reply related [flat|nested] 7+ messages in thread