summaryrefslogtreecommitdiff
path: root/treesource.c
diff options
context:
space:
mode:
authorDavid Gibson <david@gibson.dropbear.id.au>2007-10-17 12:39:10 +1000
committerJon Loeliger <jdl@freescale.com>2007-10-17 07:14:38 -0500
commit5a98ddd10af0113d80e08946f9ba5dbc99174402 (patch)
tree8ac2b7b8df05ec751e1e95b53fb4362c0c951cca /treesource.c
parent32b6bd349087019d2915f350e9f3f0e64ec69e73 (diff)
downloaddtc-5a98ddd10af0113d80e08946f9ba5dbc99174402.tar.gz
dtc: Improve -Odts output
This patch makes improvements to the way properties are printed when in dtc is producing dts output. - Characters which need escaping are now properly handled when printing properties as strings - The heuristics for what format to use for a property are improved so that 'compatible' properties will be displayed as expected. - escapes.dts is altered to better demonstrate the changes, and the string_escapes testcase is adjusted accordingly. Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Diffstat (limited to 'treesource.c')
-rw-r--r--treesource.c124
1 files changed, 97 insertions, 27 deletions
diff --git a/treesource.c b/treesource.c
index a04c173..f62041f 100644
--- a/treesource.c
+++ b/treesource.c
@@ -56,22 +56,31 @@ enum proptype {
PROP_BYTES,
};
+int isstring(char c)
+{
+ return (isprint(c)
+ || (c == '\0')
+ || 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 nnoprint = 0;
+ int nnotstring = 0, nnul = 0;
int i;
if (len == 0)
return PROP_EMPTY;
for (i = 0; i < len; i++) {
- if (! isprint(p[i]))
- nnoprint++;
+ if (! isstring(p[i]))
+ nnotstring++;
+ if (p[i] == '\0')
+ nnul++;
}
- if ((nnoprint == 1) && (p[len-1] == '\0'))
+ if ((p[len-1] == '\0') && (nnotstring == 0) && (nnul < (len-nnul)))
return PROP_STRING;
else if ((len % sizeof(cell_t)) == 0)
return PROP_CELLS;
@@ -79,6 +88,87 @@ static enum proptype guess_type(struct property *prop)
return PROP_BYTES;
}
+static void write_propval_string(FILE *f, struct data val)
+{
+ char *str = val.val;
+ int i;
+
+ assert(str[val.len-1] == '\0');
+
+ fprintf(f, " = \"");
+ for (i = 0; i < (val.len-1); i++) {
+ char c = str[i];
+
+ switch (c) {
+ case '\a':
+ fprintf(f, "\\a");
+ break;
+ case '\b':
+ fprintf(f, "\\b");
+ break;
+ case '\t':
+ fprintf(f, "\\t");
+ break;
+ case '\n':
+ fprintf(f, "\\n");
+ break;
+ case '\v':
+ fprintf(f, "\\v");
+ break;
+ case '\f':
+ fprintf(f, "\\f");
+ break;
+ case '\r':
+ fprintf(f, "\\r");
+ break;
+ case '\\':
+ fprintf(f, "\\\\");
+ break;
+ case '\"':
+ fprintf(f, "\\\"");
+ break;
+ case '\0':
+ fprintf(f, "\", \"");
+ break;
+ default:
+ if (isprint(c))
+ fprintf(f, "%c", c);
+ else
+ fprintf(f, "\\x%02hhx", c);
+ }
+ }
+ fprintf(f, "\";\n");
+}
+
+static void write_propval_cells(FILE *f, struct data val)
+{
+ void *propend = val.val + val.len;
+ cell_t *cp = (cell_t *)val.val;
+
+ fprintf(f, " = <");
+ for (;;) {
+ fprintf(f, "%x", be32_to_cpu(*cp++));
+ if ((void *)cp >= propend)
+ break;
+ fprintf(f, " ");
+ }
+ fprintf(f, ">;\n");
+}
+
+static void write_propval_bytes(FILE *f, struct data val)
+{
+ void *propend = val.val + val.len;
+ char *bp = val.val;
+
+ fprintf(f, " = [");
+ for (;;) {
+ fprintf(f, "%02hhx", *bp++);
+ if ((void *)bp >= propend)
+ break;
+ fprintf(f, " ");
+ }
+ fprintf(f, "];\n");
+}
static void write_tree_source_node(FILE *f, struct node *tree, int level)
{
@@ -92,15 +182,11 @@ static void write_tree_source_node(FILE *f, struct node *tree, int level)
fprintf(f, "/ {\n");
for_each_property(tree, prop) {
- cell_t *cp;
- char *bp;
- void *propend;
enum proptype type;
write_prefix(f, level);
fprintf(f, "\t%s", prop->name);
type = guess_type(prop);
- propend = prop->val.val + prop->val.len;
switch (type) {
case PROP_EMPTY:
@@ -108,31 +194,15 @@ static void write_tree_source_node(FILE *f, struct node *tree, int level)
break;
case PROP_STRING:
- fprintf(f, " = \"%s\";\n", (char *)prop->val.val);
+ write_propval_string(f, prop->val);
break;
case PROP_CELLS:
- fprintf(f, " = <");
- cp = (cell_t *)prop->val.val;
- for (;;) {
- fprintf(f, "%x", be32_to_cpu(*cp++));
- if ((void *)cp >= propend)
- break;
- fprintf(f, " ");
- }
- fprintf(f, ">;\n");
+ write_propval_cells(f, prop->val);
break;
case PROP_BYTES:
- fprintf(f, " = [");
- bp = prop->val.val;
- for (;;) {
- fprintf(f, "%02hhx", *bp++);
- if ((void *)bp >= propend)
- break;
- fprintf(f, " ");
- }
- fprintf(f, "];\n");
+ write_propval_bytes(f, prop->val);
break;
}
}