Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 12 additions & 6 deletions src/bindings.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,19 +150,19 @@ def bind_analysis(analysis_h: Header) -> None:
rz_analysis = Class(
analysis_h,
typedef="RzAnalysis",
ignore_fields={"leaddrs"},
rename_fields={},
struct="rz_analysis_t",
)

rz_analysis_function = Class(analysis_h, typedef="RzAnalysisFunction")
rz_analysis_function.add_method("rz_analysis_function_delete", rename="delete_self")
rz_analysis_function.add_prefixed_methods("rz_analysis_function_")

rz_analysis.add_method("rz_analysis_reflines_get", rename="get_reflines")
rz_analysis.add_prefixed_methods("rz_analysis_")
rz_analysis.add_prefixed_funcs("rz_analysis_")
rz_analysis.add_constructor("rz_analysis_new")
rz_analysis.add_destructor("rz_analysis_free")

Class(analysis_h, typedef="RzAnalysisBlock", struct="rz_analysis_bb_t")

Class(analysis_h, typedef="RzAnalysisBlock")
Class(analysis_h, typedef="RzAnalysisEsil")
Class(analysis_h, typedef="RzAnalysisEsilInterState")
Class(analysis_h, typedef="RzAnalysisPlugin")
Expand All @@ -180,7 +180,13 @@ def bind_asm(asm_h: Header) -> None:
"""
RzAsm
"""
Class(asm_h, typedef="RzAsm") # TODO: Add functions

rz_asm = Class(asm_h, typedef="RzAsm", struct="rz_asm_t") # TODO: Add functions
rz_asm.add_constructor("rz_asm_new")
rz_asm.add_destructor("rz_asm_free")
rz_asm.add_prefixed_methods("rz_asm_")
rz_asm.add_prefixed_funcs("rz_asm_")

Class(asm_h, typedef="RzAsmPlugin")


Expand Down
34 changes: 17 additions & 17 deletions src/clang/cindex.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -110,23 +110,23 @@ class Token:
extent: SourceRange

class CursorKind(Enum):
INCLUSION_DIRECTIVE: TypeKind
MACRO_INSTANTIATION: TypeKind

ENUM_DECL: TypeKind
MACRO_DEFINITION: TypeKind
STRUCT_DECL: TypeKind
TYPEDEF_DECL: TypeKind
FUNCTION_DECL: TypeKind

FIELD_DECL: TypeKind
UNION_DECL: TypeKind
PARM_DECL: TypeKind
ENUM_CONSTANT_DECL: TypeKind

ANNOTATE_ATTR: TypeKind
TYPE_REF: TypeKind
PACKED_ATTR: TypeKind
INCLUSION_DIRECTIVE: CursorKind
MACRO_INSTANTIATION: CursorKind

ENUM_DECL: CursorKind
MACRO_DEFINITION: CursorKind
STRUCT_DECL: CursorKind
TYPEDEF_DECL: CursorKind
FUNCTION_DECL: CursorKind

FIELD_DECL: CursorKind
UNION_DECL: CursorKind
PARM_DECL: CursorKind
ENUM_CONSTANT_DECL: CursorKind

ANNOTATE_ATTR: CursorKind
TYPE_REF: CursorKind
PACKED_ATTR: CursorKind

class Cursor:
kind: CursorKind
Expand Down
34 changes: 30 additions & 4 deletions src/lint.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
from argparse import ArgumentParser
from dataclasses import dataclass
from itertools import zip_longest
from pathlib import Path

from clang.cindex import (
Config,
Expand Down Expand Up @@ -82,6 +83,14 @@ def warn(warning: str) -> None:
warnings.add(warning)


def location_get_filename(location: SourceLocation) -> str:
"""
Get filename for a SourceLocation
"""
path = Path(os.path.abspath(location.file.name))
return path.name


def stringify_location(location: SourceLocation) -> str:
"""
Get <relpath:filename:line> for a SourceLocation
Expand All @@ -101,7 +110,8 @@ def cursor_get_annotations(cursor: Cursor) -> List[str]:
]


generic_types = {"RzList", "RzListIter", "RzPVector", "RzVector", "RzGraph"}
generic_types = {"RzList", "RzListIter", "RzPVector", "RzVector", "RzGraph", "HtPP"}
skip_files = {"ht_inc.c", "ht_inc.h", "rz_th_ht.h", "thread_hash_table.c"}


def cursor_get_comment(cursor: Cursor, *, packed: bool = False) -> Optional[str]:
Expand Down Expand Up @@ -161,7 +171,10 @@ def cursor_get_comment(cursor: Cursor, *, packed: bool = False) -> Optional[str]
# Filter out other tokens
comment = token.spelling
if not comment.startswith("/*") or not comment.endswith("*/"):
if typeref_spelling in generic_types:
if (
typeref_spelling in generic_types
and location_get_filename(cursor.location) not in skip_files
):
warn(
f"Missing type comment at {stringify_location(cursor.location)} "
"(token is not a comment)"
Expand All @@ -177,7 +190,7 @@ def cursor_get_comment(cursor: Cursor, *, packed: bool = False) -> Optional[str]
return comment

# Check pointer (or lack of) and space between pointer
if typeref_spelling in {"RzList", "RzListIter", "RzPVector", "RzGraph"}:
if typeref_spelling in {"RzList", "RzListIter", "RzPVector"}:
if comment[-2] != "*":
warn(f"Type comment at {stringify_location(cursor.location)} lacks pointer")
elif comment[-3] != " ":
Expand All @@ -189,8 +202,21 @@ def cursor_get_comment(cursor: Cursor, *, packed: bool = False) -> Optional[str]
warn(
f"Type comment at {stringify_location(cursor.location)} should not have pointer"
)
elif typeref_spelling in {"RzGraph", "HtPP"}:
if not re.match(
r"<(struct )?[A-Za-z0-9_]+ \*, (struct )?[A-Za-z0-9_]+ \*>", comment
):
if typeref_spelling == "RzGraph":
warn(
f"Type comment at {stringify_location(cursor.location)} must "
f"follow exactly the pattern '/*<NodeType *, EdgeType *>*/'. Is: '{comment}'"
)
elif typeref_spelling == "HtPP":
warn(
f"Type comment at {stringify_location(cursor.location)} must "
f"follow exactly the pattern '/*<KeyType *, ValueType *>*/'. Is: '{comment}'"
)
elif typeref_spelling in {
"HtPP",
"HtUP",
"HtUU",
"HtPU",
Expand Down
Loading