[PATCH v2] Fix dts output of string lists with dtb and fs input

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]



Commit 32b9c6130762 ("Preserve datatype markers when emitting dts format")
fails to split string lists into multiple strings and instead just outputs
a "\0" between strings. This is broken when the input is dtb or fs tree.

This could be fixed in the dts output where the problem was introduced,
but fix it by adding markers on the input side instead. This will allow
for any possible future uses of type markers.

Reported-by: Stewart Smith <stewart@xxxxxxxxxxxxx>
Signed-off-by: Rob Herring <robh@xxxxxxxxxx>
---
 treesource.c | 63 +++++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 50 insertions(+), 13 deletions(-)

diff --git a/treesource.c b/treesource.c
index 93fd8ac1c513..09f0512060a9 100644
--- a/treesource.c
+++ b/treesource.c
@@ -175,7 +175,43 @@ static const char *delim_end[] = {
 	[TYPE_STRING] = "",
 };
 
-static enum markertype guess_value_type(struct property *prop)
+
+static struct marker *add_int_marker(struct property *prop, enum markertype type)
+{
+	struct marker *m;
+
+	m = xmalloc(sizeof(*m));
+	m->offset = 0;
+	m->type = type;
+	m->ref = NULL;
+	m->next = NULL;
+
+	return m;
+}
+
+static struct marker *add_string_markers(struct property *prop)
+{
+	int i;
+	int len = prop->val.len;
+	const char *p = prop->val.val;
+	struct marker *m = NULL, *prev_m = NULL;
+
+	for (i = len - 1; i >= 0; i--) {
+		if (i && !(p[i] && p[i - 1] == '\0'))
+			continue;
+
+		m = xmalloc(sizeof(*m));
+		m->offset = i;
+		m->type = TYPE_STRING;
+		m->ref = NULL;
+		m->next = prev_m;
+
+		prev_m = m;
+	}
+	return m;
+}
+
+static struct marker *gen_missing_markers(struct property *prop)
 {
 	int len = prop->val.len;
 	const char *p = prop->val.val;
@@ -200,20 +236,20 @@ static enum markertype guess_value_type(struct property *prop)
 
 	if ((p[len-1] == '\0') && (nnotstring == 0) && (nnul < (len-nnul))
 	    && (nnotstringlbl == 0)) {
-		return TYPE_STRING;
+		return add_string_markers(prop);
 	} else if (((len % sizeof(cell_t)) == 0) && (nnotcelllbl == 0)) {
-		return TYPE_UINT32;
+		return add_int_marker(prop, TYPE_UINT32);
 	}
 
-	return TYPE_UINT8;
+	return add_int_marker(prop, TYPE_UINT8);
 }
 
 static void write_propval(FILE *f, struct property *prop)
 {
 	size_t len = prop->val.len;
 	struct marker *m = prop->val.markers;
-	struct marker dummy_marker;
 	enum markertype emit_type = TYPE_NONE;
+	struct marker *dummy_markers = NULL;
 
 	if (len == 0) {
 		fprintf(f, ";\n");
@@ -222,14 +258,9 @@ static void write_propval(FILE *f, struct property *prop)
 
 	fprintf(f, " =");
 
-	if (!next_type_marker(m)) {
-		/* data type information missing, need to guess */
-		dummy_marker.type = guess_value_type(prop);
-		dummy_marker.next = prop->val.markers;
-		dummy_marker.offset = 0;
-		dummy_marker.ref = NULL;
-		m = &dummy_marker;
-	}
+	/* If data type information is missing, need to guess */
+	if (!next_type_marker(m))
+		m = dummy_markers = gen_missing_markers(prop);
 
 	for_each_marker(m) {
 		size_t chunk_len = (m->next ? m->next->offset : len) - m->offset;
@@ -274,6 +305,12 @@ static void write_propval(FILE *f, struct property *prop)
 		}
 	}
 	fprintf(f, ";\n");
+
+	while (dummy_markers) {
+		m = dummy_markers;
+		dummy_markers = dummy_markers->next;
+		free(m);
+	}
 }
 
 static void write_tree_source_node(FILE *f, struct node *tree, int level)
-- 
2.17.1




[Index of Archives]     [Device Tree]     [Device Tree Spec]     [Linux Driver Backports]     [Video for Linux]     [Linux USB Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]

  Powered by Linux