1# Copyright 2019 Google LLC 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# https://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14"""SAPI interface header generator. 15 16Parses headers to extract type information from functions and generate a SAPI 17interface wrapper. 18""" 19import os # pylint: disable=unused-import 20import sys 21 22from absl import app 23from absl import flags 24from absl import logging 25 26sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..', '..')) 27from sandboxed_api.tools.python_generator import code 28 29FLAGS = flags.FLAGS 30 31flags.DEFINE_string('sapi_name', None, 'library name') 32flags.DEFINE_string('sapi_out', '', 'output header file') 33flags.DEFINE_string('sapi_ns', '', 'namespace') 34flags.DEFINE_string('sapi_isystem', '', 'system includes') 35flags.DEFINE_list('sapi_functions', [], 'function list to analyze') 36flags.DEFINE_list('sapi_in', None, 'input files to analyze') 37flags.DEFINE_string('sapi_embed_dir', '', 'directory with embed includes') 38flags.DEFINE_string('sapi_embed_name', '', 'name of the embed object') 39flags.DEFINE_bool( 40 'sapi_limit_scan_depth', False, 41 'scan only functions from top level file in compilation unit') 42 43def extract_includes(path, array): 44 try: 45 with open(path, 'r') as f: 46 for line in f: 47 array.append('-isystem') 48 array.append(line.strip()) 49 except IOError: 50 pass 51 return array 52 53 54def main(c_flags): 55 # remove path to current binary 56 c_flags.pop(0) 57 logging.debug(FLAGS.sapi_functions) 58 extract_includes(FLAGS.sapi_isystem, c_flags) 59 tus = code.Analyzer.process_files( 60 FLAGS.sapi_in, c_flags, FLAGS.sapi_limit_scan_depth, FLAGS.sapi_functions 61 ) 62 generator = code.Generator(tus) 63 result = generator.generate( 64 FLAGS.sapi_name, 65 FLAGS.sapi_ns, 66 FLAGS.sapi_out, 67 FLAGS.sapi_embed_dir, 68 FLAGS.sapi_embed_name, 69 ) 70 71 if FLAGS.sapi_out: 72 with open(FLAGS.sapi_out, 'w') as out_file: 73 out_file.write(result) 74 else: 75 sys.stdout.write(result) 76 77 78if __name__ == '__main__': 79 flags.mark_flags_as_required(['sapi_name', 'sapi_in']) 80 app.run(main) 81