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 <[EMAIL PROTECTED]>

Index: dtc/treesource.c
===================================================================
--- dtc.orig/treesource.c       2007-10-17 10:27:35.000000000 +1000
+++ dtc/treesource.c    2007-10-17 11:43:18.000000000 +1000
@@ -56,22 +56,31 @@
        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 @@
                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 @@
                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 @@
                        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;
                }
        }
Index: dtc/tests/escapes.dts
===================================================================
--- dtc.orig/tests/escapes.dts  2007-10-17 11:36:37.000000000 +1000
+++ dtc/tests/escapes.dts       2007-10-17 12:32:27.000000000 +1000
@@ -1,4 +1,5 @@
 / {
        compatible = "test_string_escapes";
-       escape-str = "nastystring: \a\b\t\n\v\f\r\\\"\xff";
+       escape-str = "nastystring: \a\b\t\n\v\f\r\\\"";
+       escape-str-2 = "\xde\xad\xbe\xef";
 };
Index: dtc/tests/string_escapes.c
===================================================================
--- dtc.orig/tests/string_escapes.c     2007-10-17 12:31:56.000000000 +1000
+++ dtc/tests/string_escapes.c  2007-10-17 12:32:04.000000000 +1000
@@ -37,6 +37,8 @@
 
        check_getprop(fdt, 0, "escape-str",
                      strlen(TEST_STRING_2)+1, TEST_STRING_2);
+       check_getprop(fdt, 0, "escape-str-2",
+                     strlen(TEST_STRING_3)+1, TEST_STRING_3);
 
        PASS();
 }
Index: dtc/tests/testdata.h
===================================================================
--- dtc.orig/tests/testdata.h   2007-10-17 12:28:50.000000000 +1000
+++ dtc/tests/testdata.h        2007-10-17 12:31:45.000000000 +1000
@@ -24,7 +24,8 @@
 #define TEST_VALUE_2   cell_to_fdt(0xabcd1234)
 
 #define TEST_STRING_1  "hello world"
-#define TEST_STRING_2  "nastystring: \a\b\t\n\v\f\r\\\"\xff"
+#define TEST_STRING_2  "nastystring: \a\b\t\n\v\f\r\\\""
+#define TEST_STRING_3  "\xde\xad\xbe\xef"
 
 #ifndef __ASSEMBLY__
 extern struct fdt_header _test_tree1;

-- 
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
_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev

Reply via email to