ff993923c5802087851ed351770c0911325978ca
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 gallium frontends, 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 Verbatim(object):
57 Represent a chunk of code that is copied into the result file verbatim.
63 class Section(object):
65 Represent a config section description as:
66 * name: the xxx part of the DRI_CONF_SECTION_xxx macro
67 * options: list of options
69 def __init__(self
, name
):
74 def parse_inputs(input_filenames
):
78 for input_filename
in input_filenames
:
79 with
open(input_filename
, 'r') as infile
:
81 sections_lists
.append(sections
)
90 if line
.startswith('//= BEGIN VERBATIM'):
91 if verbatim
is not None:
92 print('{}:{}: nested verbatim'
93 .format(input_filename
, linenum
))
98 if verbatim
is not None:
99 verbatim
.string
+= line
101 if line
.startswith('//= END VERBATIM'):
103 sections
.append(verbatim
)
105 section
.options
.append(verbatim
)
113 if line
.startswith('//'):
116 if line
== 'DRI_CONF_SECTION_END':
118 print('{}:{}: no open section'
119 .format(input_filename
, linenum
))
125 m
= RE_section_begin
.match(line
)
127 if section
is not None:
128 print('{}:{}: nested sections are not supported'
129 .format(input_filename
, linenum
))
133 print('{}:{}: missing DRIINFO line'
134 .format(input_filename
, linenum
))
136 break # parsing the rest really makes no sense
137 section
= Section(m
.group(1))
138 sections
.append(section
)
141 m
= RE_option
.match(line
)
144 print('{}:{}: no open section'
145 .format(input_filename
, linenum
))
148 section
.options
.append(Option(m
.group(1), m
.group(2)))
151 print('{}:{}: do not understand this line'
152 .format(input_filename
, linenum
))
155 if section
is not None:
156 print('{}:end-of-file: missing end of section'
157 .format(input_filename
))
161 return sections_lists
165 def merge_sections(section_list
):
167 section_list: list of Section objects to be merged, all of the same name
168 Return a merged Section object (everything is deeply copied)
170 merged_section
= Section(section_list
[0].name
)
172 for section
in section_list
:
173 assert section
.name
== merged_section
.name
175 for orig_option
in section
.options
:
176 if isinstance(orig_option
, Option
):
177 for merged_option
in merged_section
.options
:
178 if not isinstance(merged_option
, Option
):
180 if orig_option
.name
== merged_option
.name
:
181 merged_option
.defaults
= orig_option
.defaults
184 merged_section
.options
.append(Option(orig_option
.name
, orig_option
.defaults
))
186 merged_section
.options
.append(orig_option
)
188 return merged_section
191 def merge_sections_lists(sections_lists
):
193 sections_lists: list of lists of Section objects to be merged
194 Return a merged list of merged Section objects; everything is deeply copied.
195 Default values for options in later lists override earlier default values.
199 for idx
,sections
in enumerate(sections_lists
):
200 for base_section
in sections
:
201 if not isinstance(base_section
, Section
):
202 merged_sections
.append(base_section
)
205 original_sections
= [base_section
]
206 for next_sections
in sections_lists
[idx
+1:]:
207 for j
,section
in enumerate(next_sections
):
208 if section
.name
== base_section
.name
:
209 original_sections
.append(section
)
213 merged_section
= merge_sections(original_sections
)
215 merged_sections
.append(merged_section
)
217 return merged_sections
220 def main(input_filenames
):
221 sections_lists
= parse_inputs(input_filenames
)
222 if sections_lists
is None:
225 merged_sections_list
= merge_sections_lists(sections_lists
)
227 driinfo_h_template
= mako
.template
.Template("""\
228 // DO NOT EDIT - this file is automatically generated by merge_driinfo.py
235 static const char driinfo_xml[] =
241 % for section in sections:
242 % if isinstance(section, Section):
243 DRI_CONF_SECTION_${section.name}
244 % for option in section.options:
245 % if isinstance(option, Option):
246 DRI_CONF_${option.name}(${option.defaults})
258 print(driinfo_h_template
.render(sections
=merged_sections_list
, Section
=Section
, Option
=Option
))
262 if __name__
== '__main__':
263 if len(sys
.argv
) <= 1:
264 print('Missing arguments')
267 if not main(sys
.argv
[1:]):