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:]):