The controls namespace isn't documenting, making it impossible to reference the variables it contains. Furthermore, within the documentation page for the control_ids.h file, links from overview to detailed variable documentation are broken for the same reason. Both issues can be fixed by documenting the controls namespace. Unfortunately doxygen then fails to parse the initialisers for the controls global variables correctly and considers them as functions. To work around this, modify the control_ids.cpp generation script to hide the variables from doxygen, but still expose their documentation. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org> Tested-by: Niklas Söderlund <niklas.soderlund@ragnatech.se> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
121 lines
3.1 KiB
Python
Executable File
121 lines
3.1 KiB
Python
Executable File
#!/usr/bin/python3
|
|
# SPDX-License-Identifier: GPL-2.0-or-later
|
|
# Copyright (C) 2019, Google Inc.
|
|
#
|
|
# Author: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
|
|
#
|
|
# gen-controls.py - Generate control definitions from YAML
|
|
|
|
import argparse
|
|
import string
|
|
import sys
|
|
import yaml
|
|
|
|
|
|
def snake_case(s):
|
|
return ''.join([c.isupper() and ('_' + c) or c for c in s]).strip('_')
|
|
|
|
|
|
def generate_cpp(controls):
|
|
doc_template = string.Template('''/**
|
|
* \\var extern const Control<${type}> ${name}
|
|
${description}
|
|
*/''')
|
|
def_template = string.Template('extern const Control<${type}> ${name}(${id_name}, "${name}");')
|
|
|
|
ctrls_doc = []
|
|
ctrls_def = []
|
|
|
|
for ctrl in controls:
|
|
name, ctrl = ctrl.popitem()
|
|
id_name = snake_case(name).upper()
|
|
|
|
description = ctrl['description'].strip('\n').split('\n')
|
|
description[0] = '\\brief ' + description[0]
|
|
description = '\n'.join([(line and ' * ' or ' *') + line for line in description])
|
|
|
|
info = {
|
|
'name': name,
|
|
'type': ctrl['type'],
|
|
'description': description,
|
|
'id_name': id_name,
|
|
}
|
|
|
|
ctrls_doc.append(doc_template.substitute(info))
|
|
ctrls_def.append(def_template.substitute(info))
|
|
|
|
return {
|
|
'controls_doc': '\n\n'.join(ctrls_doc),
|
|
'controls_def': '\n'.join(ctrls_def),
|
|
}
|
|
|
|
|
|
def generate_h(controls):
|
|
template = string.Template('''extern const Control<${type}> ${name};''')
|
|
|
|
ctrls = []
|
|
ids = []
|
|
id_value = 1
|
|
|
|
for ctrl in controls:
|
|
name, ctrl = ctrl.popitem()
|
|
id_name = snake_case(name).upper()
|
|
|
|
ids.append('\t' + id_name + ' = ' + str(id_value) + ',')
|
|
|
|
info = {
|
|
'name': name,
|
|
'type': ctrl['type'],
|
|
}
|
|
|
|
ctrls.append(template.substitute(info))
|
|
id_value += 1
|
|
|
|
return {'ids': '\n'.join(ids), 'controls': '\n'.join(ctrls)}
|
|
|
|
|
|
def fill_template(template, data):
|
|
|
|
template = open(template, 'rb').read()
|
|
template = template.decode('utf-8')
|
|
template = string.Template(template)
|
|
return template.substitute(data)
|
|
|
|
|
|
def main(argv):
|
|
|
|
# Parse command line arguments
|
|
parser = argparse.ArgumentParser()
|
|
parser.add_argument('-o', dest='output', metavar='file', type=str,
|
|
help='Output file name. Defaults to standard output if not specified.')
|
|
parser.add_argument('input', type=str,
|
|
help='Input file name.')
|
|
parser.add_argument('template', type=str,
|
|
help='Template file name.')
|
|
args = parser.parse_args(argv[1:])
|
|
|
|
data = open(args.input, 'rb').read()
|
|
controls = yaml.safe_load(data)['controls']
|
|
|
|
if args.template.endswith('.cpp.in'):
|
|
data = generate_cpp(controls)
|
|
elif args.template.endswith('.h.in'):
|
|
data = generate_h(controls)
|
|
else:
|
|
raise RuntimeError('Unknown template type')
|
|
|
|
data = fill_template(args.template, data)
|
|
|
|
if args.output:
|
|
output = open(args.output, 'wb')
|
|
output.write(data.encode('utf-8'))
|
|
output.close()
|
|
else:
|
|
sys.stdout.write(data)
|
|
|
|
return 0
|
|
|
|
|
|
if __name__ == '__main__':
|
|
sys.exit(main(sys.argv))
|