2 # Copyright 2017 Advanced Micro Devices, Inc.
4 # Permission is hereby granted, free of charge, to any person obtaining a
5 # copy of this software and associated documentation files (the "Software"),
6 # to deal in the Software without restriction, including without limitation
7 # on the rights to use, copy, modify, merge, publish, distribute, sub
8 # license, and/or sell copies of the Software, and to permit persons to whom
9 # the Software is furnished to do so, subject to the following conditions:
11 # The above copyright notice and this permission notice (including the next
12 # paragraph) shall be included in all copies or substantial portions of the
15 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 # FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18 # THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
19 # DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20 # OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21 # USE OR OTHER DEALINGS IN THE SOFTWARE.
24 usage: merge_driinfo.py <list of input files>
26 Generates a source file which contains the DRI_CONF_xxx macros for generating
27 the driinfo XML that describes the available DriConf options for a driver and
28 its supported state trackers, based on the merged information from the input
32 from __future__ import print_function
39 # Some regexps used during input parsing
40 RE_section_begin = re.compile(r'DRI_CONF_SECTION_(.*)')
41 RE_option = re.compile(r'DRI_CONF_(.*)\((.*)\)')
46 Represent a config option as:
47 * name: the xxx part of the DRI_CONF_xxx macro
48 * defaults: the defaults parameters that are passed into the macro
50 def __init__(self, name, defaults):
52 self.defaults = defaults
55 class Section(object):
57 Represent a config section description as:
58 * name: the xxx part of the DRI_CONF_SECTION_xxx macro
59 * options: list of options
61 def __init__(self, name):
66 def parse_inputs(input_filenames):
70 for input_filename in input_filenames:
71 with open(input_filename, 'r') as infile:
73 sections_lists.append(sections)
84 if line.startswith('//'):
87 if line == 'DRI_CONF_SECTION_END':
89 print('{}:{}: no open section'
90 .format(input_filename, linenum))
96 m = RE_section_begin.match(line)
98 if section is not None:
99 print('{}:{}: nested sections are not supported'
100 .format(input_filename, linenum))
104 print('{}:{}: missing DRIINFO line'
105 .format(input_filename, linenum))
107 break # parsing the rest really makes no sense
108 section = Section(m.group(1))
109 sections.append(section)
112 m = RE_option.match(line)
115 print('{}:{}: no open section'
116 .format(input_filename, linenum))
119 section.options.append(Option(m.group(1), m.group(2)))
122 print('{}:{}: do not understand this line'
123 .format(input_filename, linenum))
126 if section is not None:
127 print('{}:end-of-file: missing end of section'
128 .format(input_filename))
132 return sections_lists
136 def merge_sections(section_list):
138 section_list: list of Section objects to be merged, all of the same name
139 Return a merged Section object (everything is deeply copied)
141 merged_section = Section(section_list[0].name)
143 for section in section_list:
144 assert section.name == merged_section.name
146 for orig_option in section.options:
147 for merged_option in merged_section.options:
148 if orig_option.name == merged_option.name:
149 merged_option.defaults = orig_option.defaults
152 merged_section.options.append(Option(orig_option.name, orig_option.defaults))
154 return merged_section
157 def merge_sections_lists(sections_lists):
159 sections_lists: list of lists of Section objects to be merged
160 Return a merged list of merged Section objects; everything is deeply copied.
161 Default values for options in later lists override earlier default values.
165 for idx,sections in enumerate(sections_lists):
166 for base_section in sections:
167 original_sections = [base_section]
168 for next_sections in sections_lists[idx+1:]:
169 for j,section in enumerate(next_sections):
170 if section.name == base_section.name:
171 original_sections.append(section)
175 merged_section = merge_sections(original_sections)
177 merged_sections.append(merged_section)
179 return merged_sections
182 def main(input_filenames):
183 sections_lists = parse_inputs(input_filenames)
184 if sections_lists is None:
187 merged_sections_list = merge_sections_lists(sections_lists)
189 driinfo_h_template = mako.template.Template("""\
190 // DO NOT EDIT - this file is automatically generated by merge_driinfo.py
197 static const char driinfo_xml[] =
203 % for section in sections:
204 DRI_CONF_SECTION_${section.name}
205 % for option in section.options:
206 DRI_CONF_${option.name}(${option.defaults})
212 print(driinfo_h_template.render(sections=merged_sections_list))
216 if __name__ == '__main__':
217 if len(sys.argv) <= 1:
218 print('Missing arguments')
221 if not main(sys.argv[1:]):