2 # Copyright © 2019 Intel Corporation
3 # SPDX-License-Identifier: MIT
5 from collections
import OrderedDict
9 import xml
.etree
.ElementTree
as et
11 def get_filename(element
):
12 return element
.attrib
['filename']
14 def get_name(element
):
15 return element
.attrib
['name']
17 def get_value(element
):
18 return int(element
.attrib
['value'], 0)
20 def get_start(element
):
21 return int(element
.attrib
['start'], 0)
33 ufixed_pattern
= re
.compile(r
"u(\d+)\.(\d+)")
34 sfixed_pattern
= re
.compile(r
"s(\d+)\.(\d+)")
36 def is_base_type(name
):
37 return name
in base_types
or sfixed_pattern
.match(name
) or ufixed_pattern
.match(name
)
39 def add_struct_refs(items
, node
):
40 if node
.tag
== 'field':
41 if 'type' in node
.attrib
and not is_base_type(node
.attrib
['type']):
42 t
= node
.attrib
['type']
45 if node
.tag
!= 'struct' and node
.tag
!= 'group':
48 add_struct_refs(items
, c
)
52 def __init__(self
, xml
):
54 self
.name
= xml
.attrib
['name']
55 self
.deps
= OrderedDict()
57 def find_deps(self
, struct_dict
, enum_dict
):
59 add_struct_refs(deps
, self
.xml
)
62 self
.deps
[d
] = struct_dict
[d
]
64 assert(d
in enum_dict
)
66 def add_xml(self
, items
):
67 for d
in self
.deps
.values():
69 items
[self
.name
] = self
.xml
72 # ordering of the various tag attributes
74 'genxml' : [ 'name', 'gen', ],
75 'enum' : [ 'name', 'value', 'prefix', ],
76 'struct' : [ 'name', 'length', ],
77 'field' : [ 'name', 'start', 'end', 'type', 'default', 'prefix', ],
78 'instruction' : [ 'name', 'bias', 'length', 'engine', ],
79 'value' : [ 'name', 'value', ],
80 'group' : [ 'count', 'start', 'size', ],
81 'register' : [ 'name', 'length', 'num', ],
86 def print_node(f
, offset
, node
):
87 if node
.tag
in [ 'enum', 'struct', 'instruction', 'register' ]:
89 spaces
= ''.rjust(offset
* space_delta
)
90 f
.write('{0}<{1}'.format(spaces
, node
.tag
))
91 attribs
= genxml_desc
[node
.tag
]
96 f
.write(' {0}="{1}"'.format(a
, node
.attrib
[a
]))
101 print_node(f
, offset
+ 1, c
)
102 f
.write('{0}</{1}>\n'.format(spaces
, node
.tag
))
107 def process(filename
):
108 xml
= et
.parse(filename
)
109 genxml
= xml
.getroot()
111 enums
= sorted(genxml
.findall('enum'), key
=get_name
)
114 values
= e
.findall('./value')
115 e
[:] = sorted(e
, key
=get_value
)
116 enum_dict
[e
.attrib
['name']] = e
118 # Structs are a bit annoying because they can refer to each other. We sort
119 # them alphabetically and then build a graph of depedencies. Finally we go
120 # through the alphabetically sorted list and print out dependencies first.
121 structs
= sorted(xml
.findall('./struct'), key
=get_name
)
122 wrapped_struct_dict
= {}
124 s
[:] = sorted(s
, key
=get_start
)
126 wrapped_struct_dict
[ws
.name
] = ws
128 for s
in wrapped_struct_dict
:
129 wrapped_struct_dict
[s
].find_deps(wrapped_struct_dict
, enum_dict
)
131 sorted_structs
= OrderedDict()
133 s
= wrapped_struct_dict
[_s
.attrib
['name']]
134 s
.add_xml(sorted_structs
)
136 instructions
= sorted(xml
.findall('./instruction'), key
=get_name
)
137 for i
in instructions
:
138 i
[:] = sorted(i
, key
=get_start
)
140 registers
= sorted(xml
.findall('./register'), key
=get_name
)
142 r
[:] = sorted(r
, key
=get_start
)
144 genxml
[:] = enums
+ list(sorted_structs
.values()) + instructions
+ registers
146 with
open(filename
, 'w') as f
:
147 f
.write('<?xml version="1.0" ?>\n')
148 print_node(f
, 0, genxml
)
151 if __name__
== '__main__':
152 folder
= pathlib
.Path('.')
153 for f
in folder
.glob('*.xml'):
154 print('Processing {}... '.format(f
), end
='', flush
=True)