1*61046927SAndroid Build Coastguard Worker# 2*61046927SAndroid Build Coastguard Worker# Copyright (C) 2021 Google, Inc. 3*61046927SAndroid Build Coastguard Worker# 4*61046927SAndroid Build Coastguard Worker# Permission is hereby granted, free of charge, to any person obtaining a 5*61046927SAndroid Build Coastguard Worker# copy of this software and associated documentation files (the "Software"), 6*61046927SAndroid Build Coastguard Worker# to deal in the Software without restriction, including without limitation 7*61046927SAndroid Build Coastguard Worker# the rights to use, copy, modify, merge, publish, distribute, sublicense, 8*61046927SAndroid Build Coastguard Worker# and/or sell copies of the Software, and to permit persons to whom the 9*61046927SAndroid Build Coastguard Worker# Software is furnished to do so, subject to the following conditions: 10*61046927SAndroid Build Coastguard Worker# 11*61046927SAndroid Build Coastguard Worker# The above copyright notice and this permission notice (including the next 12*61046927SAndroid Build Coastguard Worker# paragraph) shall be included in all copies or substantial portions of the 13*61046927SAndroid Build Coastguard Worker# Software. 14*61046927SAndroid Build Coastguard Worker# 15*61046927SAndroid Build Coastguard Worker# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16*61046927SAndroid Build Coastguard Worker# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17*61046927SAndroid Build Coastguard Worker# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18*61046927SAndroid Build Coastguard Worker# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19*61046927SAndroid Build Coastguard Worker# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20*61046927SAndroid Build Coastguard Worker# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21*61046927SAndroid Build Coastguard Worker# IN THE SOFTWARE. 22*61046927SAndroid Build Coastguard Worker 23*61046927SAndroid Build Coastguard Workerfrom mako.template import Template 24*61046927SAndroid Build Coastguard Workerfrom xml.etree import ElementTree 25*61046927SAndroid Build Coastguard Workerimport argparse 26*61046927SAndroid Build Coastguard Workerimport os 27*61046927SAndroid Build Coastguard Worker 28*61046927SAndroid Build Coastguard Workerdef dbg(str): 29*61046927SAndroid Build Coastguard Worker if False: 30*61046927SAndroid Build Coastguard Worker print(str) 31*61046927SAndroid Build Coastguard Worker 32*61046927SAndroid Build Coastguard Workercnt = 0 33*61046927SAndroid Build Coastguard Workerdef cname(name): 34*61046927SAndroid Build Coastguard Worker global cnt 35*61046927SAndroid Build Coastguard Worker cnt = cnt + 1 36*61046927SAndroid Build Coastguard Worker return name + '_' + str(cnt) 37*61046927SAndroid Build Coastguard Worker 38*61046927SAndroid Build Coastguard Workerclass Option(object): 39*61046927SAndroid Build Coastguard Worker def __init__(self, xml): 40*61046927SAndroid Build Coastguard Worker self.cname = cname('option') 41*61046927SAndroid Build Coastguard Worker self.name = xml.attrib['name'] 42*61046927SAndroid Build Coastguard Worker self.value = xml.attrib['value'] 43*61046927SAndroid Build Coastguard Worker 44*61046927SAndroid Build Coastguard Workerclass Application(object): 45*61046927SAndroid Build Coastguard Worker def __init__(self, xml): 46*61046927SAndroid Build Coastguard Worker self.cname = cname('application') 47*61046927SAndroid Build Coastguard Worker self.name = xml.attrib['name'] 48*61046927SAndroid Build Coastguard Worker self.executable = xml.attrib.get('executable', None) 49*61046927SAndroid Build Coastguard Worker self.executable_regexp = xml.attrib.get('executable_regexp', None) 50*61046927SAndroid Build Coastguard Worker self.sha1 = xml.attrib.get('sha1', None) 51*61046927SAndroid Build Coastguard Worker self.application_name_match = xml.attrib.get('application_name_match', None) 52*61046927SAndroid Build Coastguard Worker self.application_versions = xml.attrib.get('application_versions', None) 53*61046927SAndroid Build Coastguard Worker self.options = [] 54*61046927SAndroid Build Coastguard Worker 55*61046927SAndroid Build Coastguard Worker for option in xml.findall('option'): 56*61046927SAndroid Build Coastguard Worker self.options.append(Option(option)) 57*61046927SAndroid Build Coastguard Worker 58*61046927SAndroid Build Coastguard Workerclass Engine(object): 59*61046927SAndroid Build Coastguard Worker def __init__(self, xml): 60*61046927SAndroid Build Coastguard Worker self.cname = cname('engine') 61*61046927SAndroid Build Coastguard Worker self.engine_name_match = xml.attrib['engine_name_match'] 62*61046927SAndroid Build Coastguard Worker self.engine_versions = xml.attrib.get('engine_versions', None) 63*61046927SAndroid Build Coastguard Worker self.options = [] 64*61046927SAndroid Build Coastguard Worker 65*61046927SAndroid Build Coastguard Worker for option in xml.findall('option'): 66*61046927SAndroid Build Coastguard Worker self.options.append(Option(option)) 67*61046927SAndroid Build Coastguard Worker 68*61046927SAndroid Build Coastguard Workerclass Device(object): 69*61046927SAndroid Build Coastguard Worker def __init__(self, xml): 70*61046927SAndroid Build Coastguard Worker self.cname = cname('device') 71*61046927SAndroid Build Coastguard Worker self.driver = xml.attrib.get('driver', None) 72*61046927SAndroid Build Coastguard Worker self.device = xml.attrib.get('device', None) 73*61046927SAndroid Build Coastguard Worker self.applications = [] 74*61046927SAndroid Build Coastguard Worker self.engines = [] 75*61046927SAndroid Build Coastguard Worker 76*61046927SAndroid Build Coastguard Worker for application in xml.findall('application'): 77*61046927SAndroid Build Coastguard Worker self.applications.append(Application(application)) 78*61046927SAndroid Build Coastguard Worker 79*61046927SAndroid Build Coastguard Worker for engine in xml.findall('engine'): 80*61046927SAndroid Build Coastguard Worker self.engines.append(Engine(engine)) 81*61046927SAndroid Build Coastguard Worker 82*61046927SAndroid Build Coastguard Workerclass DriConf(object): 83*61046927SAndroid Build Coastguard Worker def __init__(self, xmlpaths): 84*61046927SAndroid Build Coastguard Worker self.devices = [] 85*61046927SAndroid Build Coastguard Worker for xmlpath in xmlpaths: 86*61046927SAndroid Build Coastguard Worker root = ElementTree.parse(xmlpath).getroot() 87*61046927SAndroid Build Coastguard Worker 88*61046927SAndroid Build Coastguard Worker for device in root.findall('device'): 89*61046927SAndroid Build Coastguard Worker self.devices.append(Device(device)) 90*61046927SAndroid Build Coastguard Worker 91*61046927SAndroid Build Coastguard Worker 92*61046927SAndroid Build Coastguard Workertemplate = """\ 93*61046927SAndroid Build Coastguard Worker/* Copyright (C) 2021 Google, Inc. 94*61046927SAndroid Build Coastguard Worker * 95*61046927SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a 96*61046927SAndroid Build Coastguard Worker * copy of this software and associated documentation files (the "Software"), 97*61046927SAndroid Build Coastguard Worker * to deal in the Software without restriction, including without limitation 98*61046927SAndroid Build Coastguard Worker * the rights to use, copy, modify, merge, publish, distribute, sublicense, 99*61046927SAndroid Build Coastguard Worker * and/or sell copies of the Software, and to permit persons to whom the 100*61046927SAndroid Build Coastguard Worker * Software is furnished to do so, subject to the following conditions: 101*61046927SAndroid Build Coastguard Worker * 102*61046927SAndroid Build Coastguard Worker * The above copyright notice and this permission notice (including the next 103*61046927SAndroid Build Coastguard Worker * paragraph) shall be included in all copies or substantial portions of the 104*61046927SAndroid Build Coastguard Worker * Software. 105*61046927SAndroid Build Coastguard Worker * 106*61046927SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 107*61046927SAndroid Build Coastguard Worker * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 108*61046927SAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 109*61046927SAndroid Build Coastguard Worker * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 110*61046927SAndroid Build Coastguard Worker * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 111*61046927SAndroid Build Coastguard Worker * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 112*61046927SAndroid Build Coastguard Worker * IN THE SOFTWARE. 113*61046927SAndroid Build Coastguard Worker */ 114*61046927SAndroid Build Coastguard Worker 115*61046927SAndroid Build Coastguard Workerstruct driconf_option { 116*61046927SAndroid Build Coastguard Worker const char *name; 117*61046927SAndroid Build Coastguard Worker const char *value; 118*61046927SAndroid Build Coastguard Worker}; 119*61046927SAndroid Build Coastguard Worker 120*61046927SAndroid Build Coastguard Workerstruct driconf_application { 121*61046927SAndroid Build Coastguard Worker const char *name; 122*61046927SAndroid Build Coastguard Worker const char *executable; 123*61046927SAndroid Build Coastguard Worker const char *executable_regexp; 124*61046927SAndroid Build Coastguard Worker const char *sha1; 125*61046927SAndroid Build Coastguard Worker const char *application_name_match; 126*61046927SAndroid Build Coastguard Worker const char *application_versions; 127*61046927SAndroid Build Coastguard Worker unsigned num_options; 128*61046927SAndroid Build Coastguard Worker const struct driconf_option *options; 129*61046927SAndroid Build Coastguard Worker}; 130*61046927SAndroid Build Coastguard Worker 131*61046927SAndroid Build Coastguard Workerstruct driconf_engine { 132*61046927SAndroid Build Coastguard Worker const char *engine_name_match; 133*61046927SAndroid Build Coastguard Worker const char *engine_versions; 134*61046927SAndroid Build Coastguard Worker unsigned num_options; 135*61046927SAndroid Build Coastguard Worker const struct driconf_option *options; 136*61046927SAndroid Build Coastguard Worker}; 137*61046927SAndroid Build Coastguard Worker 138*61046927SAndroid Build Coastguard Workerstruct driconf_device { 139*61046927SAndroid Build Coastguard Worker const char *driver; 140*61046927SAndroid Build Coastguard Worker const char *device; 141*61046927SAndroid Build Coastguard Worker unsigned num_engines; 142*61046927SAndroid Build Coastguard Worker const struct driconf_engine *engines; 143*61046927SAndroid Build Coastguard Worker unsigned num_applications; 144*61046927SAndroid Build Coastguard Worker const struct driconf_application *applications; 145*61046927SAndroid Build Coastguard Worker}; 146*61046927SAndroid Build Coastguard Worker 147*61046927SAndroid Build Coastguard Worker<%def name="render_options(cname, options)"> 148*61046927SAndroid Build Coastguard Workerstatic const struct driconf_option ${cname}[] = { 149*61046927SAndroid Build Coastguard Worker% for option in options: 150*61046927SAndroid Build Coastguard Worker { .name = "${option.name}", .value = "${option.value}" }, 151*61046927SAndroid Build Coastguard Worker% endfor 152*61046927SAndroid Build Coastguard Worker}; 153*61046927SAndroid Build Coastguard Worker</%def> 154*61046927SAndroid Build Coastguard Worker 155*61046927SAndroid Build Coastguard Worker%for device in driconf.devices: 156*61046927SAndroid Build Coastguard Worker% for engine in device.engines: 157*61046927SAndroid Build Coastguard Worker ${render_options(engine.cname + '_options', engine.options)} 158*61046927SAndroid Build Coastguard Worker% endfor 159*61046927SAndroid Build Coastguard Worker 160*61046927SAndroid Build Coastguard Worker%if len(device.engines) > 0: 161*61046927SAndroid Build Coastguard Workerstatic const struct driconf_engine ${device.cname}_engines[] = { 162*61046927SAndroid Build Coastguard Worker% for engine in device.engines: 163*61046927SAndroid Build Coastguard Worker { .engine_name_match = "${engine.engine_name_match}", 164*61046927SAndroid Build Coastguard Worker% if engine.engine_versions: 165*61046927SAndroid Build Coastguard Worker .engine_versions = "${engine.engine_versions}", 166*61046927SAndroid Build Coastguard Worker% endif 167*61046927SAndroid Build Coastguard Worker .num_options = ${len(engine.options)}, 168*61046927SAndroid Build Coastguard Worker .options = ${engine.cname + '_options'}, 169*61046927SAndroid Build Coastguard Worker }, 170*61046927SAndroid Build Coastguard Worker% endfor 171*61046927SAndroid Build Coastguard Worker}; 172*61046927SAndroid Build Coastguard Worker%endif 173*61046927SAndroid Build Coastguard Worker 174*61046927SAndroid Build Coastguard Worker% for application in device.applications: 175*61046927SAndroid Build Coastguard Worker ${render_options(application.cname + '_options', application.options)} 176*61046927SAndroid Build Coastguard Worker% endfor 177*61046927SAndroid Build Coastguard Worker 178*61046927SAndroid Build Coastguard Worker%if len(device.applications) > 0: 179*61046927SAndroid Build Coastguard Workerstatic const struct driconf_application ${device.cname}_applications[] = { 180*61046927SAndroid Build Coastguard Worker% for application in device.applications: 181*61046927SAndroid Build Coastguard Worker { .name = "${application.name}", 182*61046927SAndroid Build Coastguard Worker% if application.executable: 183*61046927SAndroid Build Coastguard Worker .executable = "${application.executable}", 184*61046927SAndroid Build Coastguard Worker% endif 185*61046927SAndroid Build Coastguard Worker% if application.executable_regexp: 186*61046927SAndroid Build Coastguard Worker .executable_regexp = "${application.executable_regexp}", 187*61046927SAndroid Build Coastguard Worker% endif 188*61046927SAndroid Build Coastguard Worker% if application.sha1: 189*61046927SAndroid Build Coastguard Worker .sha1 = "${application.sha1}", 190*61046927SAndroid Build Coastguard Worker% endif 191*61046927SAndroid Build Coastguard Worker% if application.application_name_match: 192*61046927SAndroid Build Coastguard Worker .application_name_match = "${application.application_name_match}", 193*61046927SAndroid Build Coastguard Worker% endif 194*61046927SAndroid Build Coastguard Worker% if application.application_versions: 195*61046927SAndroid Build Coastguard Worker .application_versions = "${application.application_versions}", 196*61046927SAndroid Build Coastguard Worker% endif 197*61046927SAndroid Build Coastguard Worker .num_options = ${len(application.options)}, 198*61046927SAndroid Build Coastguard Worker .options = ${application.cname + '_options'}, 199*61046927SAndroid Build Coastguard Worker }, 200*61046927SAndroid Build Coastguard Worker% endfor 201*61046927SAndroid Build Coastguard Worker}; 202*61046927SAndroid Build Coastguard Worker%endif 203*61046927SAndroid Build Coastguard Worker 204*61046927SAndroid Build Coastguard Workerstatic const struct driconf_device ${device.cname} = { 205*61046927SAndroid Build Coastguard Worker% if device.driver: 206*61046927SAndroid Build Coastguard Worker .driver = "${device.driver}", 207*61046927SAndroid Build Coastguard Worker% endif 208*61046927SAndroid Build Coastguard Worker% if device.device: 209*61046927SAndroid Build Coastguard Worker .device = "${device.device}", 210*61046927SAndroid Build Coastguard Worker% endif 211*61046927SAndroid Build Coastguard Worker .num_engines = ${len(device.engines)}, 212*61046927SAndroid Build Coastguard Worker% if len(device.engines) > 0: 213*61046927SAndroid Build Coastguard Worker .engines = ${device.cname}_engines, 214*61046927SAndroid Build Coastguard Worker% endif 215*61046927SAndroid Build Coastguard Worker .num_applications = ${len(device.applications)}, 216*61046927SAndroid Build Coastguard Worker% if len(device.applications) > 0: 217*61046927SAndroid Build Coastguard Worker .applications = ${device.cname}_applications, 218*61046927SAndroid Build Coastguard Worker% endif 219*61046927SAndroid Build Coastguard Worker}; 220*61046927SAndroid Build Coastguard Worker%endfor 221*61046927SAndroid Build Coastguard Worker 222*61046927SAndroid Build Coastguard Workerstatic const struct driconf_device *driconf[] = { 223*61046927SAndroid Build Coastguard Worker%for device in driconf.devices: 224*61046927SAndroid Build Coastguard Worker &${device.cname}, 225*61046927SAndroid Build Coastguard Worker%endfor 226*61046927SAndroid Build Coastguard Worker}; 227*61046927SAndroid Build Coastguard Worker""" 228*61046927SAndroid Build Coastguard Worker 229*61046927SAndroid Build Coastguard Workerparser = argparse.ArgumentParser() 230*61046927SAndroid Build Coastguard Workerparser.add_argument('drirc', 231*61046927SAndroid Build Coastguard Worker nargs=argparse.ONE_OR_MORE, 232*61046927SAndroid Build Coastguard Worker help='drirc *.conf file(s) to statically include') 233*61046927SAndroid Build Coastguard Workerparser.add_argument('header', 234*61046927SAndroid Build Coastguard Worker help='C header file to output the static configuration to') 235*61046927SAndroid Build Coastguard Workerargs = parser.parse_args() 236*61046927SAndroid Build Coastguard Worker 237*61046927SAndroid Build Coastguard Workerxml = args.drirc 238*61046927SAndroid Build Coastguard Workerdst = args.header 239*61046927SAndroid Build Coastguard Worker 240*61046927SAndroid Build Coastguard Workerwith open(dst, 'w', encoding='utf-8') as f: 241*61046927SAndroid Build Coastguard Worker f.write(Template(template).render(driconf=DriConf(xml))) 242*61046927SAndroid Build Coastguard Worker 243