summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dtc.h44
-rw-r--r--tests/delete_reinstate_multilabel.dts37
-rw-r--r--tests/delete_reinstate_multilabel_ref.dts9
-rwxr-xr-xtests/run_tests.sh3
4 files changed, 59 insertions, 34 deletions
diff --git a/dtc.h b/dtc.h
index d501c86..3e42a07 100644
--- a/dtc.h
+++ b/dtc.h
@@ -161,51 +161,27 @@ struct node {
struct label *labels;
};
-static inline struct label *for_each_label_next(struct label *l)
-{
- do {
- l = l->next;
- } while (l && l->deleted);
-
- return l;
-}
-
-#define for_each_label(l0, l) \
- for ((l) = (l0); (l); (l) = for_each_label_next(l))
-
#define for_each_label_withdel(l0, l) \
for ((l) = (l0); (l); (l) = (l)->next)
-static inline struct property *for_each_property_next(struct property *p)
-{
- do {
- p = p->next;
- } while (p && p->deleted);
-
- return p;
-}
-
-#define for_each_property(n, p) \
- for ((p) = (n)->proplist; (p); (p) = for_each_property_next(p))
+#define for_each_label(l0, l) \
+ for_each_label_withdel(l0, l) \
+ if (!(l)->deleted)
#define for_each_property_withdel(n, p) \
for ((p) = (n)->proplist; (p); (p) = (p)->next)
-static inline struct node *for_each_child_next(struct node *c)
-{
- do {
- c = c->next_sibling;
- } while (c && c->deleted);
-
- return c;
-}
-
-#define for_each_child(n, c) \
- for ((c) = (n)->children; (c); (c) = for_each_child_next(c))
+#define for_each_property(n, p) \
+ for_each_property_withdel(n, p) \
+ if (!(p)->deleted)
#define for_each_child_withdel(n, c) \
for ((c) = (n)->children; (c); (c) = (c)->next_sibling)
+#define for_each_child(n, c) \
+ for_each_child_withdel(n, c) \
+ if (!(c)->deleted)
+
void add_label(struct label **labels, char *label);
void delete_labels(struct label **labels);
diff --git a/tests/delete_reinstate_multilabel.dts b/tests/delete_reinstate_multilabel.dts
new file mode 100644
index 0000000..281a6b2
--- /dev/null
+++ b/tests/delete_reinstate_multilabel.dts
@@ -0,0 +1,37 @@
+/dts-v1/;
+
+/* Create some nodes and properties with multiple labels */
+
+/ {
+ label1: label2: prop = "value";
+
+ label3: label4: node {
+ label5: label6: prop = "value";
+ };
+};
+
+/* Delete them, and everything that's part of them, i.e. the labels */
+
+/ {
+ /delete-property/ prop;
+ /delete-node/ node;
+};
+
+/*
+ * Re-instate them. None of the old labels should come back
+ *
+ * Note: Do not add any new/extra labels here. As of the time of writing,
+ * when dtc adds labels to an object, they are added to the head of the list
+ * of labels, and this test is specifically about ensuring the correct
+ * handling of lists of labels where the first label in the list is marked as
+ * deleted. Failure to observe this note may result in the test passing when
+ * it should not.
+ */
+
+/ {
+ prop = "value";
+
+ node {
+ prop = "value";
+ };
+};
diff --git a/tests/delete_reinstate_multilabel_ref.dts b/tests/delete_reinstate_multilabel_ref.dts
new file mode 100644
index 0000000..28fa117
--- /dev/null
+++ b/tests/delete_reinstate_multilabel_ref.dts
@@ -0,0 +1,9 @@
+/dts-v1/;
+
+/ {
+ prop = "value";
+
+ node {
+ prop = "value";
+ };
+};
diff --git a/tests/run_tests.sh b/tests/run_tests.sh
index 9ca45c9..dd7f217 100755
--- a/tests/run_tests.sh
+++ b/tests/run_tests.sh
@@ -376,6 +376,9 @@ dtc_tests () {
run_dtc_test -I dts -O dtb -o dtc_tree1_delete.test.dtb test_tree1_delete.dts
tree1_tests dtc_tree1_delete.test.dtb
+ run_dtc_test -I dts -O dts -o delete_reinstate_multilabel.dts.test.dts delete_reinstate_multilabel.dts
+ run_wrap_test cmp delete_reinstate_multilabel.dts.test.dts delete_reinstate_multilabel_ref.dts
+
# Check some checks
check_tests dup-nodename.dts duplicate_node_names
check_tests dup-propname.dts duplicate_property_names