diff options
author | Lionel Landwerlin <[email protected]> | 2019-04-07 16:52:55 +0100 |
---|---|---|
committer | Lionel Landwerlin <[email protected]> | 2019-04-09 18:23:34 +0100 |
commit | 903e142f0d35bc550ffde321987a5b6fca1095eb (patch) | |
tree | cd44e2d150a1be6967bbc3ccd14f5dcf5965c4dc /src/intel/genxml | |
parent | eb699c15750f6e927e666bdd0ef2b6d6aff8a1b9 (diff) |
genxml: add a sorting script
Signed-off-by: Lionel Landwerlin <[email protected]>
Reviewed-by: Kenneth Graunke <[email protected]>
Diffstat (limited to 'src/intel/genxml')
-rw-r--r-- | src/intel/genxml/README | 18 | ||||
-rw-r--r-- | src/intel/genxml/gen_sort_tags.py | 177 | ||||
-rwxr-xr-x | src/intel/genxml/sort_xml.sh | 8 |
3 files changed, 203 insertions, 0 deletions
diff --git a/src/intel/genxml/README b/src/intel/genxml/README index bc518c60bad..11ac17ada3a 100644 --- a/src/intel/genxml/README +++ b/src/intel/genxml/README @@ -58,3 +58,21 @@ in memory: have to call a function to do this, but with the pack function we generate code in the pack function to do this for us. That's a lot less error prone and less work. + +Keeping genxml files tidy : + + In order to spot differences easily between generations, we keep genxml files sorted. + You can trigger the sort by running : + + $ cd src/intel/genxml; ./sort_xml.sh + + gen_sort_tags.py is the script that sorts genxml files using with + the following rules : + + 1) Tags are grouped in the following order <enum>, <struct>, + <instruction>, <register> + + 2) <field> tags are sorted through the value of their start attribute + + 3) Sort <struct> tags by dependency so that other scripts have + everything properly ordered. diff --git a/src/intel/genxml/gen_sort_tags.py b/src/intel/genxml/gen_sort_tags.py new file mode 100644 index 00000000000..94c5ff26e03 --- /dev/null +++ b/src/intel/genxml/gen_sort_tags.py @@ -0,0 +1,177 @@ +#encoding=utf-8 +# +# Copyright © 2019 Intel Corporation +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice (including the next +# paragraph) shall be included in all copies or substantial portions of the +# Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +# IN THE SOFTWARE. +# + +from __future__ import print_function +from collections import OrderedDict +import os +import re +import sys +import xml.etree.cElementTree as et + +def get_filename(element): + return element.attrib['filename'] + +def get_name(element): + return element.attrib['name'] + +def get_value(element): + return int(element.attrib['value']) + +def get_start(element): + return int(element.attrib['start']) + + +base_types = [ + 'address', + 'offset', + 'int', + 'uint', + 'bool', + 'float', +] + +ufixed_pattern = re.compile(r"u(\d+)\.(\d+)") +sfixed_pattern = re.compile(r"s(\d+)\.(\d+)") + +def is_base_type(name): + return name in base_types or sfixed_pattern.match(name) or ufixed_pattern.match(name) + +def add_struct_refs(items, node): + if node.tag == 'field': + if 'type' in node.attrib and not is_base_type(node.attrib['type']): + t = node.attrib['type'] + items[t] = True + return + if node.tag != 'struct' and node.tag != 'group': + return + for c in node.getchildren(): + add_struct_refs(items, c) + + +class Struct(object): + def __init__(self, xml): + self.xml = xml + self.name = xml.attrib['name'] + self.deps = OrderedDict() + + def find_deps(self, struct_dict, enum_dict): + deps = OrderedDict() + add_struct_refs(deps, self.xml) + for d in deps.keys(): + if d in struct_dict: + self.deps[d] = struct_dict[d] + else: + assert(d in enum_dict) + + def add_xml(self, items): + for d in self.deps.values(): + d.add_xml(items) + items[self.name] = self.xml + + +# ordering of the various tag attributes +genxml_desc = { + 'genxml' : [ 'name', 'gen', ], + 'enum' : [ 'name', 'value', 'prefix', ], + 'struct' : [ 'name', 'length', ], + 'field' : [ 'name', 'start', 'end', 'type', 'default', 'prefix', ], + 'instruction' : [ 'name', 'bias', 'length', 'engine', ], + 'value' : [ 'name', 'value', ], + 'group' : [ 'count', 'start', 'size', ], + 'register' : [ 'name', 'length', 'num', ], +} + +space_delta = 2 + +def print_node(f, offset, node): + if node.tag in [ 'enum', 'struct', 'instruction', 'register' ]: + f.write('\n') + spaces = ''.rjust(offset * space_delta) + f.write('{0}<{1}'.format(spaces, node.tag)) + attribs = genxml_desc[node.tag] + for a in node.attrib: + assert(a in attribs) + for a in attribs: + if a in node.attrib: + f.write(' {0}="{1}"'.format(a, node.attrib[a])) + children = node.getchildren() + if len(children) > 0: + f.write('>\n') + for c in children: + print_node(f, offset + 1, c) + f.write('{0}</{1}>\n'.format(spaces, node.tag)) + else: + f.write('/>\n') + + +def main(): + if len(sys.argv) < 2: + print("No input xml file specified") + sys.exit(1) + + filename = sys.argv[1] + xml = et.parse(filename) + genxml = xml.getroot() + + enums = sorted(genxml.findall('enum'), key=get_name) + enum_dict = {} + for e in enums: + values = e.findall('./value') + e[:] = sorted(e.getchildren(), key=get_value) + enum_dict[e.attrib['name']] = e + + # Structs are a bit annoying because they can refer to each other. We sort + # them alphabetically and then build a graph of depedencies. Finally we go + # through the alphabetically sorted list and print out dependencies first. + structs = sorted(xml.findall('./struct'), key=get_name) + wrapped_struct_dict = {} + for s in structs: + s[:] = sorted(s.getchildren(), key=get_start) + ws = Struct(s) + wrapped_struct_dict[ws.name] = ws + + for s in wrapped_struct_dict: + wrapped_struct_dict[s].find_deps(wrapped_struct_dict, enum_dict) + + sorted_structs = OrderedDict() + for _s in structs: + s = wrapped_struct_dict[_s.attrib['name']] + s.add_xml(sorted_structs) + + instructions = sorted(xml.findall('./instruction'), key=get_name) + for i in instructions: + i[:] = sorted(i.getchildren(), key=get_start) + + registers = sorted(xml.findall('./register'), key=get_name) + for r in registers: + r[:] = sorted(r.getchildren(), key=get_start) + + genxml[:] = enums + sorted_structs.values() + instructions + registers + + print('<?xml version="1.0" ?>') + print_node(sys.stdout, 0, genxml) + + +if __name__ == '__main__': + main() diff --git a/src/intel/genxml/sort_xml.sh b/src/intel/genxml/sort_xml.sh new file mode 100755 index 00000000000..48362743b63 --- /dev/null +++ b/src/intel/genxml/sort_xml.sh @@ -0,0 +1,8 @@ +#!/bin/sh + +for i in ./*.xml; do + echo -n "Processing $i... " + python ./gen_sort_tags.py $i > $i.tmp + mv $i.tmp $i + echo "done." +done |