Browse Source

tie all fuctionality together in the package

master
heck 5 years ago
parent
commit
6e1cc1794a
  1. 55
      gen/gen_cid/__init__.py
  2. 48
      gen/gen_cid/ast_2_cid.py
  3. 2
      gen/gen_cid/c_2_ast.py
  4. 2
      gen/gen_cid/utils.py

55
gen/gen_cid/__init__.py

@ -1,3 +1,56 @@
# -*- coding: utf-8 -*-
from . import generate_cid
from . import c_2_ast
from . import ast_2_cid
from . import cid_2_yml
from . import utils
import os
class CIDTools:
def __init__(self, libclang_path, header_filename, out_dir=None):
self.header = self._create_header(header_filename, out_dir)
self.c2ast = c_2_ast.C2AST(libclang_path)
# out-dir is in-dir if not specified
def _create_header(self, path, out_dir=None):
header = {"path": "",
"dir": "",
"filename": "",
"out_dir": "",
"sourcecode": "",
"ast": "",
"cid": "",
"yml": ""}
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"] = utils.read_file(path)
return header
def extract(self, var_names, func_names, debug_ast=False, debug_cid=False, debug_yml=False):
# ast
self.header["ast"] = self.c2ast.parse(self.header["path"], follow_includes=True)
if debug_ast:
utils.write_json(self.header["ast"], self.header["out_dir"] + "/" + self.header["filename"] + ".ast.json")
# cid
self.header["cid"] = ast_2_cid.extract_cid_selectively(self.header["ast"], var_names, func_names)
if debug_cid:
utils.write_json(self.header["cid"], self.header["out_dir"] + "/" + self.header["filename"] + ".cid.json")
# yml
self.header["yml"] = cid_2_yml.generate_yml(self.header["cid"])
if debug_yml:
utils.write_string(self.header["yml"], self.header["out_dir"] + "/" + self.header["filename"] + ".cid.yml")
return self.header

48
gen/gen_cid/generate_cid.py → gen/gen_cid/ast_2_cid.py

@ -1,30 +1,9 @@
# -*- coding: utf-8 -*-
import os
from . import ast_parser
from . import utils
# 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"] = utils.read_file(path)
return header
def extract_forward_declarations(data):
def filter(item):
if (item["is_definition"] == False
@ -207,7 +186,7 @@ def extract_typedef_decl(ast, name):
return ret
# TODO: move to tests
def find_dup_types(data):
def filter(item):
if (item["kind"] == "CursorKind.STRUCT_DECL"
@ -238,35 +217,29 @@ def remove_typedefs_of_primitive(types):
return types_struct_enum
def parse(libclang_path, header_filename, function_names, var_names, debug_ast=False):
astp = ast_parser.ASTParser(libclang_path)
# header = create_header("/Users/heck/local-default/include/pEp/pEpEngine.h", out_dir="./")
header = create_header(header_filename)
header["ast"] = astp.parse(header["path"], follow_includes=True)
if debug_ast:
utils.write_json(header["ast"], header["out_dir"] + "/" + header["filename"] + ".ast.json")
def extract_cid_selectively(ast, var_names, function_names):
# CDL
cid = {"functions": "",
"vars": "",
"types": ""}
# stage 1: extract functions and vars
(cid["functions"], cid["functions_notfound"]) = extract_functions_named(header["ast"], function_names)
(cid["vars"], cid["vars_notfound"]) = extract_vars_named(header["ast"], var_names)
(cid["functions"], cid["functions_notfound"]) = extract_functions_named(ast, function_names)
(cid["vars"], cid["vars_notfound"]) = extract_vars_named(ast, var_names)
# stage 2: collect type refs
cid["types"] = []
typerefs_unresolved = []
cid["typerefs_resolved"] = []
cid["typerefs_notfound"] = []
while True:
typerefs_unresolved = collect_all_typerefs(cid) # only list of typenames
typerefs_unresolved = list(set(typerefs_unresolved) - (set(cid["typerefs_resolved"]).union(set(cid["typerefs_notfound"]))))
if (len(typerefs_unresolved) <= 0):
break
(types, typerefs_resolved, notfound) = resolve_typerefs(header["ast"], typerefs_unresolved)
(types, typerefs_resolved, notfound) = resolve_typerefs(ast, typerefs_unresolved)
cid["types"] += types
cid["typerefs_resolved"] += typerefs_resolved
cid["typerefs_notfound"] += notfound
@ -274,8 +247,13 @@ def parse(libclang_path, header_filename, function_names, var_names, debug_ast=F
cid["types"] = remove_typedefs_of_primitive(cid["types"])
cid["type_names"] = extract_type_names(cid["types"])
header["cid"] = cid
return header
return cid
def extract_cid_all(ast, function_names, var_names):
pass
# generates simple-ast for each header specified in spec out dir.
# def main_old():

2
gen/gen_cid/ast_parser.py → gen/gen_cid/c_2_ast.py

@ -3,7 +3,7 @@ import clang.cindex
from clang.cindex import CursorKind
class ASTParser:
class C2AST:
def __init__(self, library_file):
if not clang.cindex.Config.loaded:
print("Using libclang from: %s", library_file)

2
gen/gen_cid/utils.py

@ -15,7 +15,7 @@ def read_file(path):
file_content = f.read()
return file_content
def write_file(path, data):
def write_string(data, path):
with open(path, "w+") as f:
f.write(data)

Loading…
Cancel
Save