Skip to contentSkip to conversation

dtc: Refactor printing of property values in -Odts mode

PATCH Applied David Gibson 2 participants 4 messages Nov 6, 2007 – Nov 8, 2007

lore
Share & tools
lore
#0 lore raw

PATCH 1/2 dtc: Refactor printing of property values in -Odts mode

Currently the main recursive tree printing function, write_tree_source_node(), calls guess_type() to apply heuristics to see how to print a property value, then calls the appropriate write_propval_*() function to print it.

However, future heuristics for handling internal labels and the like don't work well this way. Therefore, this patch refactors things to have write_tree_source_node() call a new write_propval() function, which incorporates the heurstic logic from guess_type() and also calls the right function to do the actual printing.

No behavioural change.

---
 treesource.c |   97 +++++++++++++++++++++++------------------------------------
 1 file changed, 38 insertions(+), 59 deletions(-)
treesource.c +38 -59
Index: dtc/treesource.c
===================================================================
@@ -49,13 +49,6 @@
 		fputc('\t', f);
 }
 
-enum proptype {
-	PROP_EMPTY,
-	PROP_STRING,
-	PROP_CELLS,
-	PROP_BYTES,
-};
-
 int isstring(char c)
 {
 	return (isprint(c)
@@ -63,31 +56,6 @@
 		|| strchr("\a\b\t\n\v\f\r", c));
 }
 
-static enum proptype guess_type(struct property *prop)
-{
-	int len = prop->val.len;
-	char *p = prop->val.val;
-	int nnotstring = 0, nnul = 0;
-	int i;
-
-	if (len == 0)
-		return PROP_EMPTY;
-
-	for (i = 0; i < len; i++) {
-		if (! isstring(p[i]))
-			nnotstring++;
-		if (p[i] == '\0')
-			nnul++;
-	}
-
-	if ((p[len-1] == '\0') && (nnotstring == 0) && (nnul < (len-nnul)))
-		return PROP_STRING;
-	else if ((len % sizeof(cell_t)) == 0)
-		return PROP_CELLS;
-	else
-		return PROP_BYTES;
-}
-
 static void write_propval_string(FILE *f, struct data val)
 {
 	char *str = val.val;
@@ -95,7 +63,7 @@
 
 	assert(str[val.len-1] == '\0');
 
-	fprintf(f, " = \"");
+	fprintf(f, "\"");
 	for (i = 0; i < (val.len-1); i++) {
 		char c = str[i];
 
@@ -137,7 +105,7 @@
 				fprintf(f, "\\x%02hhx", c);
 		}
 	}
-	fprintf(f, "\";\n");
+	fprintf(f, "\"");
 }
 
 static void write_propval_cells(FILE *f, struct data val)
@@ -145,14 +113,14 @@
 	void *propend = val.val + val.len;
 	cell_t *cp = (cell_t *)val.val;
 
-	fprintf(f, " = <");
+	fprintf(f, "<");
 	for (;;) {
 		fprintf(f, "%x", be32_to_cpu(*cp++));
 		if ((void *)cp >= propend)
 			break;
 		fprintf(f, " ");
 	}
-	fprintf(f, ">;\n");
+	fprintf(f, ">");
 }
 
 static void write_propval_bytes(FILE *f, struct data val)
@@ -160,14 +128,45 @@
 	void *propend = val.val + val.len;
 	char *bp = val.val;
 
-	fprintf(f, " = [");
+	fprintf(f, "[");
 	for (;;) {
 		fprintf(f, "%02hhx", *bp++);
 		if ((void *)bp >= propend)
 			break;
 		fprintf(f, " ");
 	}
-	fprintf(f, "];\n");
+	fprintf(f, "]");
+}
+
+static void write_propval(FILE *f, struct property *prop)
+{
+	int len = prop->val.len;
+	char *p = prop->val.val;
+	int nnotstring = 0, nnul = 0;
+	int i;
+
+	if (len == 0) {
+		fprintf(f, ";\n");
+		return;
+	}
+
+	for (i = 0; i < len; i++) {
+		if (! isstring(p[i]))
+			nnotstring++;
+		if (p[i] == '\0')
+			nnul++;
+	}
+
+	fprintf(f, " = ");
+
+	if ((p[len-1] == '\0') && (nnotstring == 0) && (nnul < (len-nnul))) {
+		write_propval_string(f, prop->val);
+	} else if (((len % sizeof(cell_t)) == 0)) {
+		write_propval_cells(f, prop->val);
+	} else {
+		write_propval_bytes(f, prop->val);
+	}
+	fprintf(f, ";\n");
 }
 
 static void write_tree_source_node(FILE *f, struct node *tree, int level)
@@ -184,31 +183,11 @@
 		fprintf(f, "/ {\n");
 
 	for_each_property(tree, prop) {
-		enum proptype type;
-
 		write_prefix(f, level+1);
 		if (prop->label)
 			fprintf(f, "%s: ", prop->label);
 		fprintf(f, "%s", prop->name);
-		type = guess_type(prop);
-
-		switch (type) {
-		case PROP_EMPTY:
-			fprintf(f, ";\n");
-			break;
-
-		case PROP_STRING:
-			write_propval_string(f, prop->val);
-			break;
-
-		case PROP_CELLS:
-			write_propval_cells(f, prop->val);
-			break;
-
-		case PROP_BYTES:
-			write_propval_bytes(f, prop->val);
-			break;
-		}
+		write_propval(f, prop);
 	}
 	for_each_child(tree, child) {
 		fprintf(f, "\n");
Signature · 4 lines
David Gibson			| 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
#1 lore raw

PATCH 2/2 dtc: Make -Idts -Odts preserve property-internal labels

This patch changes -Odts mode output so that labels within property values in the input are preserved in the output. Applied on top of the earlier patch to preserve node and property labels in -Odts mode, this means that dtc in -Idts -Odts mode will transfer all labels in the input to the output.

---
 tests/label01.dts |    7 +++--
 treesource.c      |   66 +++++++++++++++++++++++++++++++++++++++++++++++++-----
 2 files changed, 65 insertions(+), 8 deletions(-)
treesource.c +61 -5
Index: dtc/treesource.c
===================================================================
@@ -60,13 +60,24 @@
 {
 	char *str = val.val;
 	int i;
+	int newchunk = 1;
+	struct fixup *l = val.labels;
 
 	assert(str[val.len-1] == '\0');
 
-	fprintf(f, "\"");
 	for (i = 0; i < (val.len-1); i++) {
 		char c = str[i];
 
+		if (newchunk) {
+			while (l && (l->offset <= i)) {
+				assert(l->offset == i);
+				fprintf(f, "%s: ", l->ref);
+				l = l->next;
+			}
+			fprintf(f, "\"");
+			newchunk = 0;
+		}
+
 		switch (c) {
 		case '\a':
 			fprintf(f, "\\a");
@@ -96,7 +107,8 @@
 			fprintf(f, "\\\"");
 			break;
 		case '\0':
-			fprintf(f, "\", \"");
+			fprintf(f, "\", ");
+			newchunk = 1;
 			break;
 		default:
 			if (isprint(c))
@@ -106,20 +118,41 @@
 		}
 	}
 	fprintf(f, "\"");
+
+	/* Wrap up any labels at the end of the value */
+	while (l) {
+		assert (l->offset == val.len);
+		fprintf(f, " %s:", l->ref);
+		l = l->next;
+	}
 }
 
 static void write_propval_cells(FILE *f, struct data val)
 {
 	void *propend = val.val + val.len;
 	cell_t *cp = (cell_t *)val.val;
+	struct fixup *l = val.labels;
 
 	fprintf(f, "<");
 	for (;;) {
+		while (l && (l->offset <= ((char *)cp - val.val))) {
+			assert(l->offset == ((char *)cp - val.val));
+			fprintf(f, "%s: ", l->ref);
+			l = l->next;
+		}
+
 		fprintf(f, "%x", be32_to_cpu(*cp++));
 		if ((void *)cp >= propend)
 			break;
 		fprintf(f, " ");
 	}
+
+	/* Wrap up any labels at the end of the value */
+	while (l) {
+		assert (l->offset == val.len);
+		fprintf(f, " %s:", l->ref);
+		l = l->next;
+	}
 	fprintf(f, ">");
 }
 
@@ -127,14 +160,27 @@
 {
 	void *propend = val.val + val.len;
 	char *bp = val.val;
+	struct fixup *l = val.labels;
 
 	fprintf(f, "[");
 	for (;;) {
+		while (l && (l->offset == (bp-val.val))) {
+			fprintf(f, "%s: ", l->ref);
+			l = l->next;
+		}
+
 		fprintf(f, "%02hhx", *bp++);
 		if ((void *)bp >= propend)
 			break;
 		fprintf(f, " ");
 	}
+
+	/* Wrap up any labels at the end of the value */
+	while (l) {
+		assert (l->offset == val.len);
+		fprintf(f, " %s:", l->ref);
+		l = l->next;
+	}
 	fprintf(f, "]");
 }
 
@@ -142,7 +188,9 @@
 {
 	int len = prop->val.len;
 	char *p = prop->val.val;
+	struct fixup *l;
 	int nnotstring = 0, nnul = 0;
+	int nnotstringlbl = 0, nnotcelllbl = 0;
 	int i;
 
 	if (len == 0) {
@@ -157,15 +205,23 @@
 			nnul++;
 	}
 
-	fprintf(f, " = ");
+	for (l = prop->val.labels; l; l = l->next) {
+		if ((l->offset > 0) && (prop->val.val[l->offset - 1] != '\0'))
+			nnotstringlbl++;
+		if ((l->offset % sizeof(cell_t)) != 0)
+			nnotcelllbl++;
+	}
 
-	if ((p[len-1] == '\0') && (nnotstring == 0) && (nnul < (len-nnul))) {
+	fprintf(f, " = ");
+	if ((p[len-1] == '\0') && (nnotstring == 0) && (nnul < (len-nnul))
+	    && (nnotstringlbl == 0)) {
 		write_propval_string(f, prop->val);
-	} else if (((len % sizeof(cell_t)) == 0)) {
+	} else if (((len % sizeof(cell_t)) == 0) && (nnotcelllbl == 0)) {
 		write_propval_cells(f, prop->val);
 	} else {
 		write_propval_bytes(f, prop->val);
 	}
+
 	fprintf(f, ";\n");
 }
 
tests/label01.dts +4 -3
Index: dtc/tests/label01.dts
===================================================================
@@ -36,10 +36,11 @@
 	};
 
 	node: randomnode {
-		prop: string = data: "\xff\0stuffstuff\t\t\t\n\n\n" data_end: ;
-		blob = [byte: 0a 0b 0c 0d de ea ad be ef byte_end: ];
-		ref = < cell: &/memory@0 cell_end: >;
+		prop: string = str: "foo", str_mid: "stuffstuff\t\t\t\n\n\n" str_end: ;
+		blob = [byte: 0a 0b 0c 0d byte_mid: de ea ad be ef byte_end: ];
+		ref = < cell: &/memory@0 0 cell_mid: ffffffff cell_end: >;
 		mixed = "abc", pre: [1234] post: , gap: < aligned: a b c>;
+		tricky1 = [61 lt1: 62 63 00];
 		subnode: child {
 		};
 		/* subnode_end: is auto-generated by node emit */
Signature · 4 lines
David Gibson			| 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
Applied
#2 lore raw

Re: [2/2] dtc: Make -Idts -Odts preserve property-internal labels

So, like, the other day David Gibson mumbled:

Quoted 7 lines

This patch changes -Odts mode output so that labels within property values in the input are preserved in the output. Applied on top of the earlier patch to preserve node and property labels in -Odts mode, this means that dtc in -Idts -Odts mode will transfer all labels in the input to the output.

Applied.

jdl

Applied
#3 lore raw
In reply to David Gibson

So, like, the other day David Gibson mumbled:

Quoted 11 lines

Currently the main recursive tree printing function, write_tree_source_node(), calls guess_type() to apply heuristics to see how to print a property value, then calls the appropriate write_propval_*() function to print it.

However, future heuristics for handling internal labels and the like don't work well this way. Therefore, this patch refactors things to have write_tree_source_node() call a new write_propval() function, which incorporates the heurstic logic from guess_type() and also calls the right function to do the actual printing.

Quoted 3 lines

No behavioural change.

Applied.

jdl