blob: 4550cb172925b8739094a4a081c2ae7dd2c5a3ec [file] [log] [blame]
#!/usr/bin/env python3.8
# Copyright 2019 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import json
import textwrap
import sys
def usage():
print('Usage:\n'
' magma.h.gen.py INPUT OUTPUT\n'
' INPUT json file containing the magma interface definition\n'
' OUTPUT destination path for the magma header file to generate\n'
' Example: ./magma.h.gen.py ./magma.json ./magma.h\n'
' Generates the magma header based on a provided json definition.\n'
' Description fields are generated in the Doxygen format.')
# Generate a string for a comment with a Doxygen tag, wrapping text as necessary.
def format_comment(type, comment):
wrap = 100
prefix_first = '/// \\' + type + ' '
prefix_len = len(prefix_first)
prefix_rest = '///'.ljust(prefix_len)
lines = textwrap.wrap(comment, wrap - prefix_len)
formatted = [f'{prefix_first}{lines[0]}']
formatted.extend(f'{prefix_rest}{line}' for line in lines[1:])
return '\n'.join(formatted)
# Generate a string for a magma export object, including its comment block.
def format_export(export):
# Leading comment
lines = [f'///\n{format_comment("brief", export["description"])}']
lines.extend(format_comment('param', f'{arg["name"]} {arg["description"]}')
for arg in export['arguments'])
lines.append('///')
# Function signature
lines.append(f'{export["type"]} {export["name"]}(')
lines.append(',\n'.join(f' {arg["type"]} {arg["name"]}'
for arg in export['arguments']))
lines[-1] = f'{lines[-1]});'
lines.append('')
return '\n'.join(lines)
# License string for the top of the file.
def license():
return ('// Copyright 2016 The Fuchsia Authors. All rights reserved.\n'
'// Use of this source code is governed by a BSD-style license that can be\n'
'// found in the LICENSE file.\n')
# Guard macro that goes at the beginning/end of the header (after license).
def guards(begin):
macro = 'SRC_GRAPHICS_LIB_MAGMA_INCLUDE_MAGMA_ABI_MAGMA_H_'
if begin:
return f'#ifndef {macro}\n#define {macro}\n'
return f'#endif // {macro}'
# Begin/end C linkage scope.
def externs(begin):
if begin:
return '#if defined(__cplusplus)\nextern "C" {\n#endif\n'
return '#if defined(__cplusplus)\n}\n#endif\n'
# Includes list.
def includes():
return ('#include "magma_common_defs.h"\n'
'#include <stdint.h>\n')
# Warning comment about auto-generation.
def genwarning():
return ('// NOTE: DO NOT EDIT THIS FILE!\n'
'// It is automatically generated by //src/graphics/lib/magma/include/magma_abi/magma.h.gen.py\n')
def genformatoff():
return '// clang-format off\n'
def main():
if (len(sys.argv) != 3):
usage()
exit(-1)
try:
with open(sys.argv[1], 'r') as file:
with open(sys.argv[2], 'w') as dest:
magma = json.load(file)['magma-interface']
lines = [license(),
genwarning(),
genformatoff(),
guards(True),
includes(),
externs(True)]
lines.extend(format_export(e) for e in magma['exports'])
lines.append(externs(False))
lines.append(guards(False))
lines.append('')
dest.write('\n'.join(lines))
except Exception as e:
print(f'Error accessing files: {e}')
usage()
exit(-2)
if __name__ == '__main__':
sys.exit(main())