| #!/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()) |