1#!/usr/bin/env python3 2# Copyright 2023 The Fuchsia Authors. All rights reserved. 3# Use of this source code is governed by a BSD-style license that can be 4# found in the LICENSE file. 5 6import json 7import sys 8 9def usage(): 10 print( 11 'Usage:\n' 12 ' regen.py INPUT OUT.in OUT.attrib\n' 13 ' INPUT json file containing the magma interface definition\n' 14 ' OUT.in destination path for the magma interface file to generate\n' 15 ' OUT.attrib destination path for the magma interface file to generate\n' 16 ' Example: ./regen.py ./magma.json ./magma.in ./magma.attrib\n' 17 ' Generates magma interface and attrib files based on a provided json definition.') 18 19# returns a string that will block presubmit 20def dnsstr(): 21 return ( 22 'DO ' 23 'NOT ' 24 'SUBMIT' 25 ) 26 27def format_export(export): 28 args = [f'{arg["type"]} {arg["name"]}' for arg in export["arguments"]] 29 return f'MAGMA({export["type"]}, {export["name"]}, {", ".join(args)})' 30 31def if_header(): 32 return ( 33 f'# !!!! {dnsstr()} !!!!\n' 34 '# This interface file was generated using the magma\n' 35 '# definition file. Some methods with nested structs must\n' 36 '# be manually serialized/deserialized and so modifications\n' 37 '# must be made to those method signatures prior to running\n' 38 '# emugen!\n' 39 f'# !!!! {dnsstr()} !!!!\n' 40 '\n' 41 ) 42 43def attrib_header(): 44 return ( 45 f'# !!!! {dnsstr()} !!!!\n' 46 '# This attrib file was generated using HEURISTICS based on\n' 47 '# the magma definition file. It must be manually verified\n' 48 '# prior to submission!\n' 49 f'# !!!! {dnsstr()} !!!!\n' 50 '\n' 51 '# For documentation on the .attrib file format, see:\n' 52 '# android/android-emugl/host/tools/emugen/README\n' 53 '\n' 54 'GLOBAL\n' 55 '\tbase_opcode 100000\n' 56 '\tencoder_headers <stdint.h>\n' 57 ) 58 59def format_attribs(export): 60 out_args = [arg for arg in export["arguments"] if arg["name"].endswith('_out')] 61 if len(out_args) == 0: 62 return None 63 ret = f'{export["name"]}\n' 64 for arg in out_args: 65 ret += f'\tdir {arg["name"]} out\n' 66 ret += f'\tlen {arg["name"]} sizeof({arg["type"][:-1]})\n' 67 return ret 68 69def main(): 70 if (len(sys.argv) != 4): 71 usage() 72 return 2 73 try: 74 with open(sys.argv[1], 'r') as file: 75 with open(sys.argv[2], 'w') as dest_in: 76 with open(sys.argv[3], 'w') as dest_attrib: 77 magma = json.load(file)['magma-interface'] 78 lines = [format_export(e) for e in magma['exports']] 79 dest_in.write(if_header()) 80 dest_in.write('\n'.join(lines)) 81 dest_attrib.write(attrib_header()) 82 for export in magma['exports']: 83 attribs = format_attribs(export) 84 if (attribs): 85 dest_attrib.write('\n' + attribs) 86 87 except Exception as e: 88 print(f'Error accessing files: {e}') 89 usage() 90 return 1 91 92if __name__ == '__main__': 93 sys.exit(main()) 94