diff options
Diffstat (limited to 'tools/xml2h.py')
-rw-r--r-- | tools/xml2h.py | 191 |
1 files changed, 191 insertions, 0 deletions
diff --git a/tools/xml2h.py b/tools/xml2h.py new file mode 100644 index 0000000000..d259c5ba3c --- /dev/null +++ b/tools/xml2h.py | |||
@@ -0,0 +1,191 @@ | |||
1 | #!/usr/bin/python | ||
2 | # __________ __ ___. | ||
3 | # Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | # Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | # Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | # Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | # \/ \/ \/ \/ \/ | ||
8 | # $Id$ | ||
9 | # | ||
10 | # Copyright (C) 2007 Catalin Patulea <cat@vv.carleton.ca> | ||
11 | # | ||
12 | # All files in this archive are subject to the GNU General Public License. | ||
13 | # See the file COPYING in the source tree root for full license agreement. | ||
14 | # | ||
15 | # This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
16 | # KIND, either express or implied. | ||
17 | # | ||
18 | import sys, os.path, array, re | ||
19 | from xml.dom import Node | ||
20 | from xml.dom.minidom import parse | ||
21 | |||
22 | |||
23 | C_IDENT_RE = re.compile('^[0-9a-zA-Z_]+$') | ||
24 | |||
25 | |||
26 | def getText(nodelist): | ||
27 | rc = "" | ||
28 | for node in nodelist: | ||
29 | if node.nodeType == node.TEXT_NODE: | ||
30 | rc = rc + node.data | ||
31 | return rc | ||
32 | |||
33 | |||
34 | def descendAll(root, tagname): | ||
35 | for child in root.childNodes: | ||
36 | if child.nodeType == Node.ELEMENT_NODE and child.tagName == tagname: | ||
37 | yield child | ||
38 | |||
39 | |||
40 | def descend(root, tagname): | ||
41 | return descendAll(root, tagname).next() | ||
42 | |||
43 | |||
44 | def getTagText(root, tagname): | ||
45 | try: | ||
46 | tag = descend(root, tagname) | ||
47 | except StopIteration: | ||
48 | return None | ||
49 | return getText(tag.childNodes) | ||
50 | |||
51 | |||
52 | def main(): | ||
53 | dom = parse(sys.stdin) | ||
54 | |||
55 | ofd = descend(dom, "ofd") | ||
56 | object_file = descend(ofd, "object_file") | ||
57 | object_file_name = descend(object_file, "name") | ||
58 | |||
59 | out_filepath = getText(object_file_name.childNodes) | ||
60 | sys.stderr.write("*.out filename (input): %s\n" % out_filepath) | ||
61 | |||
62 | out_file = open(out_filepath, "rb") | ||
63 | h_file = sys.stdout | ||
64 | |||
65 | h_file.write("""#ifndef DSP_IMAGE | ||
66 | #define DSP_IMAGE | ||
67 | /* | ||
68 | * Automatically generated by xml2h.py from %s. | ||
69 | * | ||
70 | * This program is free software; you can redistribute it and/or | ||
71 | * modify it under the terms of the GNU General Public License as | ||
72 | * published by the Free Software Foundation; either version 2 of | ||
73 | * the License, or (at your option) any later version. | ||
74 | * | ||
75 | * This program is distributed in the hope that it will be useful, | ||
76 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
77 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
78 | * GNU General Public License for more details. | ||
79 | * | ||
80 | * You should have received a copy of the GNU General Public License | ||
81 | * along with this program; if not, write to the Free Software | ||
82 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | ||
83 | * MA 02111-1307 USA | ||
84 | * | ||
85 | */ | ||
86 | """ % out_filepath) | ||
87 | |||
88 | # Section data and directory. | ||
89 | h_directory = [""" | ||
90 | static const struct dsp_section dsp_image[] = {"""] | ||
91 | |||
92 | ti_coff = descend(object_file, "ti_coff") | ||
93 | for section in descendAll(ti_coff, "section"): | ||
94 | page = int(getTagText(section, "page") or "0", 16) | ||
95 | name = getTagText(section, "name") | ||
96 | physical_addr = int(getTagText(section, "physical_addr"), 16) | ||
97 | raw_data_size = int(getTagText(section, "raw_data_size"), 16) | ||
98 | copy = getTagText(section, "copy") | ||
99 | data = getTagText(section, "data") | ||
100 | regular = getTagText(section, "regular") | ||
101 | text = getTagText(section, "text") | ||
102 | bss = getTagText(section, "bss") | ||
103 | |||
104 | file_offsets = descend(section, "file_offsets") | ||
105 | raw_data_ptr = int(getTagText(file_offsets, "raw_data_ptr"), 16) | ||
106 | |||
107 | if copy: | ||
108 | # Empirically, .debug* sections have this attribute set. | ||
109 | sys.stderr.write( | ||
110 | "%s: didn't copy debug section ('copy' attribute set)\n" % | ||
111 | name) | ||
112 | continue | ||
113 | |||
114 | if raw_data_size == 0: | ||
115 | sys.stderr.write("%s: not copying empty section\n" % name) | ||
116 | continue | ||
117 | |||
118 | if raw_data_size % 2 != 0: | ||
119 | sys.stderr.write("%s: error, raw_data_size 0x%04x not a multiple " | ||
120 | "of word size (2 bytes)\n" % (name, raw_data_size)) | ||
121 | break | ||
122 | |||
123 | if data or regular or text: | ||
124 | sys.stderr.write("%s: placing 0x%04x words at 0x%04x from offset " | ||
125 | "0x%08x\n" % ( | ||
126 | name, raw_data_size >> 1, physical_addr, raw_data_ptr)) | ||
127 | |||
128 | sanitized_name = name.replace(".", "_") | ||
129 | h_file.write(("static const unsigned short _section%s[] = {\n" % | ||
130 | sanitized_name)) | ||
131 | |||
132 | out_file.seek(raw_data_ptr) | ||
133 | data = array.array('H') | ||
134 | data.fromfile(out_file, raw_data_size >> 1) | ||
135 | h_file.write("\t") | ||
136 | for word in data: | ||
137 | h_file.write("0x%04x, " % word) | ||
138 | h_file.write(""" | ||
139 | }; | ||
140 | """) | ||
141 | |||
142 | h_directory.append("\t{_section%s, 0x%04x, 0x%04x}," % ( | ||
143 | sanitized_name, physical_addr, raw_data_size >> 1)) | ||
144 | |||
145 | continue | ||
146 | |||
147 | if bss: | ||
148 | sys.stderr.write("%s: bss section, 0x%04x words at 0x%04x\n" % ( | ||
149 | name, raw_data_size >> 1, physical_addr)) | ||
150 | |||
151 | h_directory.append("\t{NULL /* %s */, 0x%04x, 0x%04x}," % ( | ||
152 | name, physical_addr, raw_data_size >> 1)) | ||
153 | continue | ||
154 | |||
155 | sys.stderr.write("%s: error, unprocessed section\n" % name) | ||
156 | |||
157 | h_file.write("\n") | ||
158 | |||
159 | h_directory.append("\t{NULL, 0, 0}") | ||
160 | h_directory.append("};") | ||
161 | |||
162 | h_file.write("\n".join(h_directory)) | ||
163 | h_file.write("\n") | ||
164 | |||
165 | # Symbols. | ||
166 | symbol_table = descend(ti_coff, "symbol_table") | ||
167 | h_file.write(""" | ||
168 | /* Symbol table, usable with the DSP_() macro (see dsp-target.h). */ | ||
169 | """) | ||
170 | for symbol in descendAll(symbol_table, "symbol"): | ||
171 | name = getTagText(symbol, "name") | ||
172 | kind = getTagText(symbol, "kind") | ||
173 | value = int(getTagText(symbol, "value"), 16) | ||
174 | |||
175 | if kind != "defined": | ||
176 | continue | ||
177 | |||
178 | if not C_IDENT_RE.match(name): | ||
179 | continue | ||
180 | |||
181 | h_file.write("#define %s 0x%04x\n" % (name, value)) | ||
182 | |||
183 | h_file.write("\n#endif\n") | ||
184 | h_file.close() | ||
185 | out_file.close() | ||
186 | |||
187 | dom.unlink() | ||
188 | |||
189 | |||
190 | if __name__ == "__main__": | ||
191 | main() | ||