This commit adds an output format, which produces python
code. When run, the python produces a data structure that
can then be inspected in order to do various things.

Signed-off-by: Michael Ellerman <[EMAIL PROTECTED]>
---

I'm not sure if this is generally useful (or sane) but it was for me so
I thought I'd post it.

I have a dts that I want to use to configure a simulator, and this
seemed like the nicest way to get there. dtc spits out the pythonised
device tree, and then I have a 10 line python script that does the
configuring.

cheers


 Makefile.dtc |    1 +
 dtc.c        |    3 +
 dtc.h        |    1 +
 python.c     |  129 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 134 insertions(+), 0 deletions(-)
 create mode 100644 python.c

diff --git a/Makefile.dtc b/Makefile.dtc
index bece49b..92164de 100644
--- a/Makefile.dtc
+++ b/Makefile.dtc
@@ -12,6 +12,7 @@ DTC_SRCS = \
        livetree.c \
        srcpos.c \
        treesource.c \
+       python.c \
        util.c
 
 DTC_GEN_SRCS = dtc-lexer.lex.c dtc-parser.tab.c
diff --git a/dtc.c b/dtc.c
index 84bee2d..496aebf 100644
--- a/dtc.c
+++ b/dtc.c
@@ -92,6 +92,7 @@ static void  __attribute__ ((noreturn)) usage(void)
        fprintf(stderr, "\t\t\tdts - device tree source text\n");
        fprintf(stderr, "\t\t\tdtb - device tree blob\n");
        fprintf(stderr, "\t\t\tasm - assembler source\n");
+       fprintf(stderr, "\t\t\tpy  - python source\n");
        fprintf(stderr, "\t-V <output version>\n");
        fprintf(stderr, "\t\tBlob version to produce, defaults to %d (relevant 
for dtb\n\t\tand asm output only)\n", DEFAULT_FDT_VERSION);
        fprintf(stderr, "\t-R <number>\n");
@@ -219,6 +220,8 @@ int main(int argc, char *argv[])
                dt_to_blob(outf, bi, outversion);
        } else if (streq(outform, "asm")) {
                dt_to_asm(outf, bi, outversion);
+       } else if (streq(outform, "py")) {
+               dt_to_python(outf, bi, outversion);
        } else if (streq(outform, "null")) {
                /* do nothing */
        } else {
diff --git a/dtc.h b/dtc.h
index 5cb9f58..45252fe 100644
--- a/dtc.h
+++ b/dtc.h
@@ -237,6 +237,7 @@ void process_checks(int force, struct boot_info *bi);
 
 void dt_to_blob(FILE *f, struct boot_info *bi, int version);
 void dt_to_asm(FILE *f, struct boot_info *bi, int version);
+void dt_to_python(FILE *f, struct boot_info *bi, int version);
 
 struct boot_info *dt_from_blob(const char *fname);
 
diff --git a/python.c b/python.c
new file mode 100644
index 0000000..8ad0433
--- /dev/null
+++ b/python.c
@@ -0,0 +1,129 @@
+/*
+ * (C) Copyright David Gibson <[EMAIL PROTECTED]>, IBM Corporation.  2005.
+ * (C) Copyright Michael Ellerman, IBM Corporation.  2008.
+ *
+ *
+ * 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"
+#include "srcpos.h"
+
+
+static void write_propval_cells(FILE *f, struct property *prop)
+{
+       cell_t *cp = (cell_t *)prop->val.val;
+       int i;
+
+       fprintf(f, "    p = Property('%s', [", prop->name);
+
+       for (i = 0; i < prop->val.len / sizeof(cell_t); i++)
+               fprintf(f, "0x%x, ", fdt32_to_cpu(cp[i]));
+
+       fprintf(f, "])\n");
+}
+
+static int isstring(char c)
+{
+       return (isprint(c)
+               || (c == '\0')
+               || strchr("\a\b\t\n\v\f\r", c));
+}
+
+static void write_property(FILE *f, struct property *prop)
+{
+       const char *p = prop->val.val;
+       int i, strtype, len = prop->val.len;
+
+       if (len == 0) {
+               fprintf(f, "    p = Property('%s', None)\n", prop->name);
+               goto out;
+       }
+
+       strtype = 1;
+       for (i = 0; i < len; i++) {
+               if (!isstring(p[i])) {
+                       strtype = 0;
+                       break;
+               }
+       }
+
+       if (strtype)
+               fprintf(f, "    p = Property('%s', '%s')\n", prop->name,
+                       prop->val.val);
+       else if (len == 4)
+               fprintf(f, "    p = Property('%s', 0x%x)\n", prop->name,
+                       fdt32_to_cpu(*(const cell_t *)p));
+       else
+               write_propval_cells(f, prop);
+       
+out:
+       fprintf(f, "    n.properties.append(p)\n");
+}
+
+static void write_tree_source_node(FILE *f, struct node *tree, int level)
+{
+       char name[MAX_NODENAME_LEN + 1] = "root";
+       struct property *prop;
+       struct node *child;
+
+       if (tree->name && (*tree->name))
+               strncpy(name, tree->name, MAX_NODENAME_LEN);
+
+       fprintf(f, "    n = Node('%s', parents[-1])\n", name);
+
+       if (level > 0)
+               fprintf(f, "    parents[-1].children.append(n)\n");
+       else
+               fprintf(f, "    root = n\n");
+
+       for_each_property(tree, prop)
+               write_property(f, prop);
+
+       fprintf(f, "    parents.append(n)\n");
+
+       for_each_child(tree, child) {
+               write_tree_source_node(f, child, level + 1);
+       }
+
+       fprintf(f, "    parents.pop()\n");
+}
+
+
+static char *header = "#!/usr/bin/python\n\
+\n\
+class Node(object):\n\
+    def __init__(self, name, parent, unitaddr=None):\n\
+        self.__dict__.update(locals())\n\
+        self.children = []\n\
+        self.properties = []\n\
+\n\
+class Property(object):\n\
+    def __init__(self, name, value):\n\
+        self.__dict__.update(locals())\n\
+";
+
+void dt_to_python(FILE *f, struct boot_info *bi, int version)
+{
+       fprintf(f, "%s\n", header);
+       fprintf(f, "def generate_tree():\n");
+       fprintf(f, "    parents = [None]\n");
+
+       write_tree_source_node(f, bi->dt, 0);
+
+       fprintf(f, "    root.version = %d\n", version);
+       fprintf(f, "    return root\n");
+}
-- 
1.5.6



_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev

Reply via email to