diff options
author | David Gibson <dgibson@sneetch.(none)> | 2005-06-08 17:18:34 +1000 |
---|---|---|
committer | David Gibson <dgibson@sneetch.(none)> | 2005-06-08 17:18:34 +1000 |
commit | fc14dad7692d84d5f0f547fd0456b3f98526b6cc (patch) | |
tree | 9fba031b6dfd273fcb78d23e9ff6e869cce9df97 /treesource.c | |
download | dtc-fc14dad7692d84d5f0f547fd0456b3f98526b6cc.tar.gz |
Initial commit
Diffstat (limited to 'treesource.c')
-rw-r--r-- | treesource.c | 140 |
1 files changed, 140 insertions, 0 deletions
diff --git a/treesource.c b/treesource.c new file mode 100644 index 0000000..6b0c974 --- /dev/null +++ b/treesource.c @@ -0,0 +1,140 @@ +/* + * (C) Copyright David Gibson <dwg@au1.ibm.com>, IBM Corporation. 2005. + * + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + */ + +#include "dtc.h" + +struct node *device_tree; + +extern FILE *yyin; +extern int yyparse(void); + +struct node *dt_from_source(FILE *f) +{ + yyin = f; + if (yyparse() != 0) + return NULL; + + fill_fullpaths(device_tree, ""); + + return device_tree; +} + +static void write_prefix(FILE *f, int level) +{ + int i; + + for (i = 0; i < level; i++) + fputc('\t', f); +} + +enum proptype { + PROP_EMPTY, + PROP_STRING, + PROP_CELLS, + PROP_BYTES, +}; + +static enum proptype guess_type(struct property *prop) +{ + int len = prop->val.len; + char *p = prop->val.val; + int nnoprint = 0; + int i; + + if (len == 0) + return PROP_EMPTY; + + for (i = 0; i < len; i++) { + if (! isprint(p[i])) + nnoprint++; + } + + if ((nnoprint == 1) && (p[len-1] == '\0')) + return PROP_STRING; + else if ((len % sizeof(cell_t)) == 0) + return PROP_CELLS; + else + return PROP_BYTES; + +} + +void write_tree_source(FILE *f, struct node *tree, int level) +{ + struct property *prop; + struct node *child; + + write_prefix(f, level); + if (tree->name && (*tree->name)) + fprintf(f, "%s {\n", tree->name); + else + 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: + fprintf(f, ";\n"); + break; + + case PROP_STRING: + fprintf(f, " = \"%s\";\n", (char *)prop->val.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"); + 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"); + break; + } + } + for_each_child(tree, child) { + fprintf(f, "\n"); + write_tree_source(f, child, level+1); + } + write_prefix(f, level); + fprintf(f, "};\n"); +} |