On 13/09/2018 13:34, Łukasz Dobrowolski wrote:
When there is a label inside of sequence of ints the assertion is hit.
To reproduce run: "dtc -O dts tests/label01.dts". The problematic node
is /randomnode/blob.
Oh, ick. That was a big miss. Thanks for finding it and suggesting a
fix. Comment below.
Fixes: 32b9c6130762 ("Preserve datatype markers when emitting dts
format")
Signed-off-by: Łukasz Dobrowolski <lukasz.dobrowolski@xxxxxxxxx>
---
treesource.c | 37 +++++++++++++++++++++++++++++--------
1 file changed, 29 insertions(+), 8 deletions(-)
diff --git a/treesource.c b/treesource.c
index f2874f1d1465..7007c7314c92 100644
--- a/treesource.c
+++ b/treesource.c
@@ -61,11 +61,17 @@ static bool isstring(char c)
|| strchr("\a\b\t\n\v\f\r", c));
}
-static void write_propval_string(FILE *f, const char *s, size_t len)
+static void write_propval_string(FILE *f, const char *s, size_t len,
+ struct marker *m_label, size_t m_offset)
{
const char *end = s + len - 1;
assert(*end == '\0');
+ for_each_marker_of_type(m_label, LABEL) {
+ if (m_label->offset == m_offset)
+ fprintf(f, "%s: ", m_label->ref);
+ }
+
I tried really hard when I refactored the code to keep label emission
out of the write_propval_* functions, so I'm not fond of this approach.
It is better to refactor the main loop to emit the labels correctly, and
simplify the code at the same time.
I've written a patch to do it that way. I'll post in a few minutes.
Cheers,
g.
fprintf(f, "\"");
while (s < end) {
char c = *s++;
@@ -110,12 +116,21 @@ static void write_propval_string(FILE *f, const char *s, size_t len)
fprintf(f, "\"");
}
-static void write_propval_int(FILE *f, const char *p, size_t len, size_t width)
+static void write_propval_int(FILE *f, const char *p, size_t len, size_t width,
+ struct marker *m_label, size_t m_offset)
{
const char *end = p + len;
assert(len % width == 0);
for (; p < end; p += width) {
+ struct marker *m = m_label;
+
+ for_each_marker_of_type(m, LABEL) {
+ if (m->offset == m_offset)
+ fprintf(f, " %s:", m->ref);
+ }
+ m_offset += width;
+
switch (width) {
case 1:
fprintf(f, " %02"PRIx8, *(const uint8_t*)p);
@@ -254,25 +269,31 @@ static void write_propval(FILE *f, struct property *prop)
switch(emit_type) {
case TYPE_UINT16:
- write_propval_int(f, p, chunk_len, 2);
+ write_propval_int(f, p, chunk_len, 2, m_label,
+ m->offset);
break;
case TYPE_UINT32:
- write_propval_int(f, p, chunk_len, 4);
+ write_propval_int(f, p, chunk_len, 4, m_label,
+ m->offset);
break;
case TYPE_UINT64:
- write_propval_int(f, p, chunk_len, 8);
+ write_propval_int(f, p, chunk_len, 8, m_label,
+ m->offset);
break;
case TYPE_STRING:
- write_propval_string(f, p, chunk_len);
+ write_propval_string(f, p, chunk_len, m_label,
+ m->offset);
break;
default:
- write_propval_int(f, p, chunk_len, 1);
+ write_propval_int(f, p, chunk_len, 1, m_label,
+ m->offset);
}
}
/* Wrap up any labels at the end of the value */
for_each_marker_of_type(m_label, LABEL) {
- assert (m_label->offset == len);
+ if (m_label->offset != len)
+ continue;
fprintf(f, " %s:", m_label->ref);
}