summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tests/escapes.dts3
-rw-r--r--tests/string_escapes.c2
-rw-r--r--tests/testdata.h3
-rw-r--r--treesource.c124
4 files changed, 103 insertions, 29 deletions
diff --git a/tests/escapes.dts b/tests/escapes.dts
index 236fe13..f1b8dbc 100644
--- a/tests/escapes.dts
+++ b/tests/escapes.dts
@@ -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";
};
diff --git a/tests/string_escapes.c b/tests/string_escapes.c
index 0238502..30eb6a8 100644
--- a/tests/string_escapes.c
+++ b/tests/string_escapes.c
@@ -37,6 +37,8 @@ int main(int argc, char *argv[])
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();
}
diff --git a/tests/testdata.h b/tests/testdata.h
index 525177f..94f3dee 100644
--- a/tests/testdata.h
+++ b/tests/testdata.h
@@ -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;
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;
}
}