#!/usr/bin/env python3 # -*- coding: utf-8 -*- import os import json from ast_parser import ASTParser from simple_ast import SimpleAST def join_dir_and_filenames(dirname, filenames): paths = [] for basename in filenames: path = dirname + basename paths.append(path) return paths def read_file(path): with open(path) as f: file_content = f.read() return file_content # out-dir is in-dir if not specified def create_header(path, out_dir=None): header = {"path": "", "dir": "", "filename": "", "out_dir": "", "sourcecode": ""} header["path"] = path header["dir"] = os.path.dirname(path) header["filename"] = os.path.basename(path) header["out_dir"] = header["dir"] if out_dir: header["out_dir"] = out_dir header["sourcecode"] = read_file(path) return header def write_json(content, outpath): # create path if not existing out_dir = os.path.dirname(outpath) if not os.path.isdir(out_dir): os.makedirs(out_dir) # write with open(outpath, "w+") as f: json.dump(content, f, indent=4) # generates simple-ast for each header specified in spec out dir. def main_old(): parser = ASTParser("/opt/local/libexec/llvm-9.0/lib/libclang.dylib") in_dir = r"/Users/heck/local-default/include/pEp/" filenames = ["pEpEngine.h", "keymanagement.h", "message_api.h", "message.h", "sync_api.h", "key_reset.h", "Identity.h", "Rating.h"] out_dir = "data/output" paths = join_dir_and_filenames(in_dir, filenames) headers = [] for path in paths: headers.append(create_header(path, out_dir)) for header in headers: print("processing path: " + header["path"] + "...") header["ast"] = parser.parse(header["path"], header["sourcecode"]) write_json(header["ast"], header["out_dir"] + "/" + header["filename"] + ".ast.json") simpleAst = SimpleAST() header["simple_ast"] = simpleAst.create_simple_ast(header["ast"]) write_json(header["simple_ast"], header["out_dir"] + "/" + header["filename"] + ".simple_ast.json") def recursive_query(data, filter, transform=lambda x: x): resultset = [] # decorator just handling exceptions def filter_decorator(data): try: return filter(data) except KeyError: pass # filter current data if filter_decorator(data): # transform result xformed = transform(data) if xformed: resultset.append(xformed) # recurse if "children" in data: for item in data["children"]: childres = recursive_query(item, filter, transform) if childres: resultset += childres return resultset def main_new(): parser = ASTParser("/opt/local/libexec/llvm-9.0/lib/libclang.dylib") # header = create_header("/Users/heck/local-default/include/pEp/pEpEngine.h", out_dir="./") header = create_header("data/input/test_data/main_include.h") header["ast"] = parser.parse(header["path"], follow_includes=True) write_json(header["ast"], header["out_dir"] + "/" + header["filename"] + ".ast.json") # query def filter_xzy(item): if (item["is_definition"] == False and item["kind"] == "CursorKind.STRUCT_DECL" ): return True def xform(item): return item matches = recursive_query(header["ast"], filter_xzy, xform) # matches = list(set(matches)) write_json(matches, header["out_dir"] + "/" + header["filename"] + ".matches.json") def main(): main_old() # main_new() if __name__ == "__main__": main()