4 # Copyright © 2019 Intel Corporation
6 # Permission is hereby granted, free of charge, to any person obtaining a
7 # copy of this software and associated documentation files (the "Software"),
8 # to deal in the Software without restriction, including without limitation
9 # the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 # and/or sell copies of the Software, and to permit persons to whom the
11 # Software is furnished to do so, subject to the following conditions:
13 # The above copyright notice and this permission notice (including the next
14 # paragraph) shall be included in all copies or substantial portions of the
17 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22 # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
26 from __future__
import print_function
27 from collections
import OrderedDict
31 import xml
.etree
.cElementTree
as et
33 def get_filename(element
):
34 return element
.attrib
['filename']
36 def get_name(element
):
37 return element
.attrib
['name']
39 def get_value(element
):
40 return int(element
.attrib
['value'], 0)
42 def get_start(element
):
43 return int(element
.attrib
['start'], 0)
55 ufixed_pattern
= re
.compile(r
"u(\d+)\.(\d+)")
56 sfixed_pattern
= re
.compile(r
"s(\d+)\.(\d+)")
58 def is_base_type(name
):
59 return name
in base_types
or sfixed_pattern
.match(name
) or ufixed_pattern
.match(name
)
61 def add_struct_refs(items
, node
):
62 if node
.tag
== 'field':
63 if 'type' in node
.attrib
and not is_base_type(node
.attrib
['type']):
64 t
= node
.attrib
['type']
67 if node
.tag
!= 'struct' and node
.tag
!= 'group':
69 for c
in node
.getchildren():
70 add_struct_refs(items
, c
)
74 def __init__(self
, xml
):
76 self
.name
= xml
.attrib
['name']
77 self
.deps
= OrderedDict()
79 def find_deps(self
, struct_dict
, enum_dict
):
81 add_struct_refs(deps
, self
.xml
)
84 self
.deps
[d
] = struct_dict
[d
]
86 assert(d
in enum_dict
)
88 def add_xml(self
, items
):
89 for d
in self
.deps
.values():
91 items
[self
.name
] = self
.xml
94 # ordering of the various tag attributes
96 'genxml' : [ 'name', 'gen', ],
97 'enum' : [ 'name', 'value', 'prefix', ],
98 'struct' : [ 'name', 'length', ],
99 'field' : [ 'name', 'start', 'end', 'type', 'default', 'prefix', ],
100 'instruction' : [ 'name', 'bias', 'length', 'engine', ],
101 'value' : [ 'name', 'value', ],
102 'group' : [ 'count', 'start', 'size', ],
103 'register' : [ 'name', 'length', 'num', ],
108 def print_node(f
, offset
, node
):
109 if node
.tag
in [ 'enum', 'struct', 'instruction', 'register' ]:
111 spaces
= ''.rjust(offset
* space_delta
)
112 f
.write('{0}<{1}'.format(spaces
, node
.tag
))
113 attribs
= genxml_desc
[node
.tag
]
114 for a
in node
.attrib
:
118 f
.write(' {0}="{1}"'.format(a
, node
.attrib
[a
]))
119 children
= node
.getchildren()
120 if len(children
) > 0:
123 print_node(f
, offset
+ 1, c
)
124 f
.write('{0}</{1}>\n'.format(spaces
, node
.tag
))
129 def process(filename
):
130 xml
= et
.parse(filename
)
131 genxml
= xml
.getroot()
133 enums
= sorted(genxml
.findall('enum'), key
=get_name
)
136 values
= e
.findall('./value')
137 e
[:] = sorted(e
.getchildren(), key
=get_value
)
138 enum_dict
[e
.attrib
['name']] = e
140 # Structs are a bit annoying because they can refer to each other. We sort
141 # them alphabetically and then build a graph of depedencies. Finally we go
142 # through the alphabetically sorted list and print out dependencies first.
143 structs
= sorted(xml
.findall('./struct'), key
=get_name
)
144 wrapped_struct_dict
= {}
146 s
[:] = sorted(s
.getchildren(), key
=get_start
)
148 wrapped_struct_dict
[ws
.name
] = ws
150 for s
in wrapped_struct_dict
:
151 wrapped_struct_dict
[s
].find_deps(wrapped_struct_dict
, enum_dict
)
153 sorted_structs
= OrderedDict()
155 s
= wrapped_struct_dict
[_s
.attrib
['name']]
156 s
.add_xml(sorted_structs
)
158 instructions
= sorted(xml
.findall('./instruction'), key
=get_name
)
159 for i
in instructions
:
160 i
[:] = sorted(i
.getchildren(), key
=get_start
)
162 registers
= sorted(xml
.findall('./register'), key
=get_name
)
164 r
[:] = sorted(r
.getchildren(), key
=get_start
)
166 genxml
[:] = enums
+ sorted_structs
.values() + instructions
+ registers
168 with
open(filename
, 'w') as f
:
169 f
.write('<?xml version="1.0" ?>\n')
170 print_node(f
, 0, genxml
)
173 if __name__
== '__main__':
174 folder
= pathlib
.Path('.')
175 for f
in folder
.glob('*.xml'):
176 print('Processing {}... '.format(f
), end
='', flush
=True)