diff options
author | David Gibson <david@gibson.dropbear.id.au> | 2007-10-17 12:39:10 +1000 |
---|---|---|
committer | Jon Loeliger <jdl@freescale.com> | 2007-10-17 07:14:38 -0500 |
commit | 5a98ddd10af0113d80e08946f9ba5dbc99174402 (patch) | |
tree | 8ac2b7b8df05ec751e1e95b53fb4362c0c951cca /treesource.c | |
parent | 32b6bd349087019d2915f350e9f3f0e64ec69e73 (diff) | |
download | dtc-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.c | 124 |
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; } } |