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