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

2 messages, 1 author, 2007-11-06 · open the first message on its own page

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

From: David Gibson <hidden>
Date: 2007-11-06 23:21:20

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.

Signed-off-by: David Gibson <redacted>

---
 treesource.c |   97 +++++++++++++++++++++++------------------------------------
 1 file changed, 38 insertions(+), 59 deletions(-)

Index: dtc/treesource.c
===================================================================
--- dtc.orig/treesource.c	2007-11-07 09:55:03.000000000 +1100
+++ dtc/treesource.c	2007-11-07 10:19:13.000000000 +1100
@@ -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");
-- 
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

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

From: David Gibson <hidden>
Date: 2007-11-06 23:22:25

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.

Signed-off-by: David Gibson <redacted>

---
 tests/label01.dts |    7 +++--
 treesource.c      |   66 +++++++++++++++++++++++++++++++++++++++++++++++++-----
 2 files changed, 65 insertions(+), 8 deletions(-)

Index: dtc/treesource.c
===================================================================
--- dtc.orig/treesource.c	2007-11-07 10:19:13.000000000 +1100
+++ dtc/treesource.c	2007-11-07 10:19:42.000000000 +1100
@@ -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");
 }
 
Index: dtc/tests/label01.dts
===================================================================
--- dtc.orig/tests/label01.dts	2007-11-07 09:55:03.000000000 +1100
+++ dtc/tests/label01.dts	2007-11-07 10:19:42.000000000 +1100
@@ -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 */
-- 
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
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help