You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
143 lines
3.7 KiB
143 lines
3.7 KiB
#!/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()
|
|
|