Author SHA1 Message Date
billow 8618b4051a Add binding for RzAnnotatedCode and RzCodeAnnotation headers 2025-10-01 03:01:38 +08:00
22 changed files with 130 additions and 310 deletions

No files matched your search

-7
View File
@@ -1,7 +0,0 @@
version: 2
updates:
- package-ecosystem: github-actions
directory: "/"
schedule:
interval: "weekly"
+16 -20
View File
@@ -1,11 +1,6 @@
name: build
on:
push:
branches:
- dev
- stable
- 'ci-*'
pull_request:
workflow_dispatch:
workflow_call:
inputs:
@@ -26,7 +21,7 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [ubuntu-24.04, windows-2022, macos-14]
os: [ubuntu-24.04, windows-2019, macos-14]
steps:
- name: Install SWIG with Homebrew
@@ -34,12 +29,12 @@ jobs:
run: brew install swig
- name: Checkout rz-bindgen
uses: actions/checkout@v6
uses: actions/checkout@v4
# runned only from workflow_call
- name: Checkout rizin
if: ${{ inputs.external_call }}
uses: actions/checkout@v6
uses: actions/checkout@v4
with:
repository: rizinorg/rizin
path: rizin
@@ -47,7 +42,7 @@ jobs:
- name: Checkout rizin (stable)
if: ${{ !inputs.external_call && ((github.ref_name == 'stable') || (github.base_ref == 'stable')) }}
uses: actions/checkout@v6
uses: actions/checkout@v4
with:
repository: rizinorg/rizin
path: rizin
@@ -55,23 +50,23 @@ jobs:
- name: Checkout rizin (dev)
if: ${{ !inputs.external_call && ((github.ref_name != 'stable') && (github.base_ref != 'stable')) }}
uses: actions/checkout@v6
uses: actions/checkout@v4
with:
repository: rizinorg/rizin
path: rizin
ref: dev
- name: Build rz-bindgen
uses: pypa/cibuildwheel@v3.4.1
uses: pypa/cibuildwheel@v2.22.0
- name: Upload sdist
uses: actions/upload-artifact@v7
uses: actions/upload-artifact@v4
with:
name: sdist-${{ matrix.os }}
path: dist/*.tar.gz
- name: Upload wheels
uses: actions/upload-artifact@v7
uses: actions/upload-artifact@v4
with:
name: wheels-${{ matrix.os }}
path: wheelhouse/*.whl
@@ -81,14 +76,14 @@ jobs:
steps:
- name: Checkout rz-bindgen
uses: actions/checkout@v6
uses: actions/checkout@v4
with:
path: rz-bindgen
# runned only from workflow_call
- name: Checkout rizin
if: ${{ inputs.external_call }}
uses: actions/checkout@v6
uses: actions/checkout@v4
with:
repository: rizinorg/rizin
path: rizin
@@ -96,7 +91,7 @@ jobs:
- name: Checkout rizin (stable)
if: ${{ !inputs.external_call && ((github.ref_name == 'stable') || (github.base_ref == 'stable')) }}
uses: actions/checkout@v6
uses: actions/checkout@v4
with:
repository: rizinorg/rizin
path: rizin
@@ -104,7 +99,7 @@ jobs:
- name: Checkout rizin (dev)
if: ${{ !inputs.external_call && ((github.ref_name != 'stable') && (github.base_ref != 'stable')) }}
uses: actions/checkout@v6
uses: actions/checkout@v4
with:
repository: rizinorg/rizin
path: rizin
@@ -132,6 +127,7 @@ jobs:
- name: Test python lang plugin
run: rizin -qc "Ll" | grep "Python SWIG"
- name: Run rz-test
run: rz-test -L tests/
working-directory: rz-bindgen
- name: Test rizin.py
run: |
echo "import rizin" > testimport.py
python3 testimport.py
+7 -13
View File
@@ -1,25 +1,19 @@
name: lint
on:
push:
branches:
- dev
- stable
- 'ci-*'
pull_request:
on: push
jobs:
licenses:
runs-on: ubuntu-24.04
steps:
- name: Checkout rz-bindgen
uses: actions/checkout@v6
uses: actions/checkout@v3
- name: REUSE compliance check
uses: fsfe/reuse-action@v6
uses: fsfe/reuse-action@v1
python:
runs-on: ubuntu-24.04
steps:
- name: Checkout rz-bindgen
uses: actions/checkout@v6
uses: actions/checkout@v3
- name: Install tools
run: |
pip install mypy pyflakes pylint black
@@ -46,10 +40,10 @@ jobs:
security-events: write
steps:
- name: Checkout rz-bindgen
uses: actions/checkout@v6
uses: actions/checkout@v3
- name: Initialize CodeQL
uses: github/codeql-action/init@v4
uses: github/codeql-action/init@v2
with:
languages: python
- name: Run CodeQL
uses: github/codeql-action/analyze@v4
uses: github/codeql-action/analyze@v2
+3 -3
View File
@@ -25,16 +25,16 @@ jobs:
needs: [build]
steps:
- name: Download artifacts
uses: actions/download-artifact@v8
uses: actions/download-artifact@v3
with:
name: wheels
path: dist
- name: Download sdist
uses: actions/download-artifact@v8
uses: actions/download-artifact@v3
with:
name: sdist
path: dist
- name: Publish wheels
uses: pypa/gh-action-pypi-publish@v1.14.0
uses: pypa/gh-action-pypi-publish@v1.5.1
with:
password: ${{ secrets.PYPI_TOKEN }}
+32
View File
@@ -0,0 +1,32 @@
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: rz-bindgen
Upstream-Contact: wingdeans <[email protected]>
Source: https://github.com/rizinorg/rz-bindgen/
Files: src/clang/__init__.py src/clang/cindex.py src/clang/enumerations.py
Copyright: 2022 The LLVM Project
License: Apache-2.0 WITH LLVM-exception
Files: src/snippets_swig/*
Copyright: 2022 wingdeans <[email protected]>
License: LGPL-3.0-only
Files: .github/workflows/* .gitignore README.md src/README.md
Copyright: 2022 wingdeans <[email protected]>
License: LGPL-3.0-only
Files: meson.build plugin/meson.build meson_options.txt
Copyright: 2022 wingdeans <[email protected]>
License: LGPL-3.0-only
Files: pyproject.toml mypy.ini pylintrc
Copyright: 2022 wingdeans <[email protected]>
License: LGPL-3.0-only
Files: cutter/PythonConsole.ui cutter/CMakeLists.txt .clang-format
Copyright: 2022 wingdeans <[email protected]>
License: LGPL-3.0-only
Files: doc/*.md
Copyright: 2022 wingdeans <[email protected]>
License: LGPL-3.0-only
-58
View File
@@ -1,58 +0,0 @@
version = 1
SPDX-PackageName = "rz-bindgen"
SPDX-PackageSupplier = "wingdeans <[email protected]>"
SPDX-PackageDownloadLocation = "https://github.com/rizinorg/rz-bindgen/"
[[annotations]]
path = ["src/clang/__init__.py", "src/clang/cindex.py", "src/clang/enumerations.py"]
precedence = "aggregate"
SPDX-FileCopyrightText = "2022 The LLVM Project"
SPDX-License-Identifier = "Apache-2.0 WITH LLVM-exception"
[[annotations]]
path = "src/snippets_swig/**"
precedence = "aggregate"
SPDX-FileCopyrightText = "2022 wingdeans <[email protected]>"
SPDX-License-Identifier = "LGPL-3.0-only"
[[annotations]]
path = [".github/workflows/**", ".gitignore", "README.md", "src/README.md"]
precedence = "aggregate"
SPDX-FileCopyrightText = "2022 wingdeans <[email protected]>"
SPDX-License-Identifier = "LGPL-3.0-only"
[[annotations]]
path = ["meson.build", "plugin/meson.build", "meson_options.txt"]
precedence = "aggregate"
SPDX-FileCopyrightText = "2022 wingdeans <[email protected]>"
SPDX-License-Identifier = "LGPL-3.0-only"
[[annotations]]
path = ["pyproject.toml", "mypy.ini", "pylintrc"]
precedence = "aggregate"
SPDX-FileCopyrightText = "2022 wingdeans <[email protected]>"
SPDX-License-Identifier = "LGPL-3.0-only"
[[annotations]]
path = ["cutter/PythonConsole.ui", "cutter/CMakeLists.txt", ".clang-format"]
precedence = "aggregate"
SPDX-FileCopyrightText = "2022 wingdeans <[email protected]>"
SPDX-License-Identifier = "LGPL-3.0-only"
[[annotations]]
path = "doc/**.md"
precedence = "aggregate"
SPDX-FileCopyrightText = "2022 wingdeans <[email protected]>"
SPDX-License-Identifier = "LGPL-3.0-only"
[[annotations]]
path = "tests/**"
precedence = "aggregate"
SPDX-FileCopyrightText = "2026 RizinOrg <[email protected]>"
SPDX-License-Identifier = "LGPL-3.0-only"
[[annotations]]
path = ".github/**"
precedence = "aggregate"
SPDX-FileCopyrightText = "2026 RizinOrg <[email protected]>"
SPDX-License-Identifier = "LGPL-3.0-only"
+1 -1
View File
@@ -43,7 +43,7 @@ else
export CFLAGS="-include linux/limits.h"
fi
meson setup --buildtype=release --libdir=lib build
sudo PATH="$PATH" bash -c "meson install -C build"
sudo meson install -C build
fi
popd
+3 -5
View File
@@ -50,7 +50,6 @@ In the SWIG bindings, these functions are mapped to methods of RzCore.
```py
import rizin
from rizin import RZ_CORE_CMD_EXIT as CMD_EXIT
from sys import argv
filename = argv[1]
@@ -67,8 +66,8 @@ for i, corefile in enumerate(core.files):
for binfile in corefile.binfiles:
print(f" * {binfile.file}")
while core.flush(input("rizin> ")) != CMD_EXIT:
pass
while True:
core.flush(input("rizin> "))
```
Here's an example session:
@@ -87,11 +86,10 @@ rizin> aaa
[x] Applied 0 FLIRT signatures via sigdb
[x] Propagate noreturn information
[x] Use -AA or aaaa to perform additional experimental analysis.
rizin> afl
> afl
0x0040233e 1 6 entry0
0x00402051 3 49 -> 16 sym.HelloWorld::Main
0x0040205f 99 24482 -> 31854 sym.HelloWorld::.ctor
rizin> q
```
### Plugins
+2 -3
View File
@@ -4,7 +4,6 @@ SPDX-License-Identifier: LGPL-3.0-only
"""
import rizin
from rizin import RZ_CORE_CMD_EXIT as CMD_EXIT
from sys import argv
filename = argv[1]
@@ -21,5 +20,5 @@ for i, corefile in enumerate(core.files):
for binfile in corefile.binfiles:
print(f" * {binfile.file}")
while core.flush(input("rizin> ")) != CMD_EXIT:
pass
while True:
core.flush(input("rizin> "))
+4 -4
View File
@@ -8,10 +8,11 @@ SPDX-License-Identifier: LGPL-3.0-only
# things, see `2b-rz_bin_plugin.py`
import rizin
from rizin import RZ_CORE_CMD_EXIT as CMD_EXIT
import sys
import rizin
class CustomBinPlugin(rizin.RzBinPluginDirector):
def __init__(self):
super().__init__()
@@ -22,7 +23,6 @@ class CustomBinPlugin(rizin.RzBinPluginDirector):
print("size: ", bf.size)
return True
# Construct the director
builder = rizin.RzBinPluginBuilder()
builder.name = "SWIGCustom"
@@ -36,5 +36,5 @@ core.bin.plugins.append(plugin)
core.bin.force_plugin(plugin.name)
core.file_open_load(sys.argv[1])
while core.flush(input("rizin> ")) != CMD_EXIT:
pass
while True:
core.flush(input("> "))
+2 -3
View File
@@ -4,7 +4,6 @@ SPDX-License-Identifier: LGPL-3.0-only
"""
import rizin
from rizin import RZ_CORE_CMD_EXIT as CMD_EXIT
import sys
@@ -27,5 +26,5 @@ core.bin.plugins.append(plugin_struct)
core.bin.force_plugin(plugin.name)
core.file_open_load(sys.argv[1])
while core.flush(input("rizin> ")) != CMD_EXIT:
pass
while True:
core.flush(input("> "))
-5
View File
@@ -89,11 +89,6 @@ if target_swig or target_sphinx
'src/lint.py',
'src/main.py',
'src/writer.py',
'src/snippets_swig/cmd_director.i',
'src/snippets_swig/iterators.py',
'src/snippets_swig/prologue.i',
'src/snippets_swig/register_command.py',
'src/snippets_swig/register_swig_command.cpp',
)
bindgen_outputs = custom_target(
+1 -9
View File
@@ -29,7 +29,6 @@ class Generic:
specializations: Set[str]
c_methods: OrderedDict[str, List[str]]
python_methods: OrderedDict[str, List[str]]
specialization_extensions: DefaultDict[str, List[str]]
@@ -50,7 +49,6 @@ class Generic:
self.methods = OrderedDict()
self.specializations = set()
self.c_methods = OrderedDict()
self.python_methods = OrderedDict()
self.specialization_extensions = DefaultDict(list)
@@ -133,15 +131,9 @@ class Generic:
return specialization
def add_c_method(self, name: str, *lines: str) -> None:
"""
Add C method for name
"""
self.c_methods[name] = list(lines)
def add_python_method(self, decl: str, *lines: str) -> None:
"""
Add python method with decl
Add python function with decl
"""
self.python_methods[decl] = [f"def {decl}:"] + [f" {line}" for line in lines]
+3 -11
View File
@@ -42,19 +42,11 @@ def gen_ctype_specializations(cursors: List[Cursor], ctype: CType) -> None:
# eg. typedef RzVector /*<ut64>*/ (*func)(void)
gen_ctype_specializations(cursors + [ctype.cursor], ctype.canonical)
elif isinstance(ctype, CFunctionType):
cursor_children = list(cursors[-1].get_children())
# Handle typedef of typedef of a function pointer
while (
len(cursor_children) == 1 and cursor_children[0].kind == CursorKind.TYPE_REF
):
cursor_children = list(
cursor_children[0].referenced.get_children() # type: ignore[attr-defined]
)
gen_ctype_specializations(cursors, ctype.result)
cursor_args = [
cursor for cursor in cursor_children if cursor.kind == CursorKind.PARM_DECL
cursor
for cursor in cursors[-1].get_children()
if cursor.kind == CursorKind.PARM_DECL
]
assert len(cursor_args) == len(ctype.args)
+32 -23
View File
@@ -63,15 +63,15 @@ def bind_list(list_h: Header) -> None:
"""
### RzListIter ###
rz_list_iter = Generic(list_h, "RzListIter", pointer=True)
rz_list_iter.add_method("rz_list_next", rename="next", generic_ret=True)
rz_list_iter.add_method("rz_list_val", rename="data", generic_ret=True)
rz_list_iter.add_method("rz_list_iter_get_next", rename="next", generic_ret=True)
rz_list_iter.add_method("rz_list_iter_get_data", rename="data", generic_ret=True)
### RzList ###
rz_list = Generic(list_h, "RzList", dependencies=[rz_list_iter], pointer=True)
rz_list.add_method("rz_list_length", rename="length")
rz_list.add_method("rz_list_first_val", rename="first", generic_ret=True)
rz_list.add_method("rz_list_last_val", rename="last", generic_ret=True)
rz_list.add_method("rz_list_first", rename="first", generic_ret=True)
rz_list.add_method("rz_list_last", rename="last", generic_ret=True)
rz_list.add_method("rz_list_iterator", rename="iterator", generic_ret=True)
rz_list.add_method(
@@ -150,7 +150,8 @@ def bind_analysis(analysis_h: Header) -> None:
rz_analysis = Class(
analysis_h,
typedef="RzAnalysis",
struct="rz_analysis_t",
ignore_fields={"leaddrs"},
rename_fields={},
)
rz_analysis_function = Class(analysis_h, typedef="RzAnalysisFunction")
@@ -158,10 +159,12 @@ def bind_analysis(analysis_h: Header) -> None:
rz_analysis_function.add_prefixed_methods("rz_analysis_function_")
rz_analysis.add_method("rz_analysis_reflines_get", rename="get_reflines")
rz_analysis.add_constructor("rz_analysis_new")
rz_analysis.add_destructor("rz_analysis_free")
rz_analysis.add_prefixed_methods("rz_analysis_")
rz_analysis.add_prefixed_funcs("rz_analysis_")
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")
Class(
@@ -177,13 +180,7 @@ def bind_asm(asm_h: Header) -> None:
"""
RzAsm
"""
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="RzAsm") # TODO: Add functions
Class(asm_h, typedef="RzAsmPlugin")
@@ -330,17 +327,29 @@ def bind_core(core_h: Header) -> None:
Class(core_h, typedef="RzCoreFile")
MacroEnum(core_h, prefix="RZ_CORE_CMD_")
@threaded_header("rz_esil/rz_esil.h")
def bind_esil(esil_h: Header) -> None:
@threaded_header("rz_util/rz_annotated_code.h")
def bind_annotated_code(annotated_code_h: Header) -> None:
"""
RzAnalysisEsil
RzAnnotatedCode
"""
Class(esil_h, typedef="RzAnalysisEsil")
Class(esil_h, typedef="RzAnalysisEsilInterState")
rz_code_annotation = Class(
annotated_code_h,
typedef="RzCodeAnnotation",
struct="rz_code_annotation_t",
)
rz_code_annotation.add_prefixed_methods("rz_annotation_")
rz_code_annotation.add_prefixed_funcs("rz_annotation_")
rz_annotated_code = Class(
annotated_code_h,
typedef="RzAnnotatedCode",
struct="rz_annotated_code_t",
)
rz_annotated_code.add_constructor("rz_annotated_code_new")
rz_annotated_code.add_destructor("rz_annotated_code_free")
rz_annotated_code.add_prefixed_methods("rz_annotated_code_")
rz_annotated_code.add_prefixed_funcs("rz_annotated_code_")
@threaded_header("rz_flag.h")
def bind_flag(flag_h: Header) -> None:
+14 -14
View File
@@ -110,23 +110,23 @@ class Token:
extent: SourceRange
class CursorKind(Enum):
INCLUSION_DIRECTIVE: CursorKind
MACRO_INSTANTIATION: CursorKind
INCLUSION_DIRECTIVE: TypeKind
MACRO_INSTANTIATION: TypeKind
ENUM_DECL: CursorKind
MACRO_DEFINITION: CursorKind
STRUCT_DECL: CursorKind
TYPEDEF_DECL: CursorKind
FUNCTION_DECL: CursorKind
ENUM_DECL: TypeKind
MACRO_DEFINITION: TypeKind
STRUCT_DECL: TypeKind
TYPEDEF_DECL: TypeKind
FUNCTION_DECL: TypeKind
FIELD_DECL: CursorKind
UNION_DECL: CursorKind
PARM_DECL: CursorKind
ENUM_CONSTANT_DECL: CursorKind
FIELD_DECL: TypeKind
UNION_DECL: TypeKind
PARM_DECL: TypeKind
ENUM_CONSTANT_DECL: TypeKind
ANNOTATE_ATTR: CursorKind
TYPE_REF: CursorKind
PACKED_ATTR: CursorKind
ANNOTATE_ATTR: TypeKind
TYPE_REF: TypeKind
PACKED_ATTR: TypeKind
class Cursor:
kind: CursorKind
+1 -1
View File
@@ -76,7 +76,7 @@ class CFunc(AttrCursor):
### Configuration ###
rizin_include_path: Optional[str] = None # pylint: disable=invalid-name
rizin_include_path: Optional[str] = None
clang_args: List[str] = []
### Headers ###
+1 -1
View File
@@ -39,7 +39,7 @@ from binding_func import Func
from writer import Writer
doxygen_path: Optional[str] = None # pylint: disable=invalid-name
doxygen_path: Optional[str] = None
DoxygenElements = Dict[str, Element]
-3
View File
@@ -114,9 +114,6 @@ def write_generic(writer: Writer, generic: Generic) -> None:
for name, method in generic.methods.items():
write_func(writer, method, name, FuncKind.GENERIC)
for c_lines in generic.c_methods.values():
writer.line(*c_lines)
for python_lines in generic.python_methods.values():
writer.line("%pythoncode %{")
with writer.indent():
+4 -103
View File
@@ -30,11 +30,9 @@ import os
import sys
import json
import shlex
import re
from argparse import ArgumentParser
from dataclasses import dataclass
from itertools import zip_longest
from pathlib import Path
from clang.cindex import (
Config,
@@ -46,30 +44,6 @@ from clang.cindex import (
SourceLocation,
)
# Detect /** ... */ or /*! ... */ style Doxygen block comments
_DOXY_BLOCK_RE = re.compile(r"/\*[*!][\s\S]*?\*/")
# Detect consecutive /// or //! style Doxygen line comments
_DOXY_LINE_RE = re.compile(r"(?:(?:\/\/[\/!])[^\n]*\n?)+")
# Match any @-prefixed Doxygen command with word boundary
_DOXY_COMMAND_RE = re.compile(r"@(\w+)\b")
# Map of @-prefixed commands to their correct backslash equivalents
_DOXY_COMMANDS = {
"param": "\\param",
"return": "\\return",
"brief": "\\brief",
"ref": "\\ref",
"p": "\\p",
"see": "\\see",
"file": "\\file",
"ingroup": "\\ingroup",
"post": "\\post",
"sa": "\\sa",
"test": "\\test",
}
warnings = set()
@@ -83,14 +57,6 @@ 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
@@ -110,8 +76,7 @@ def cursor_get_annotations(cursor: Cursor) -> List[str]:
]
generic_types = {"RzList", "RzListIter", "RzPVector", "RzVector", "RzGraph", "HtPP"}
skip_files = {"ht_inc.c", "ht_inc.h", "rz_th_ht.h", "thread_hash_table.c"}
generic_types = {"RzList", "RzListIter", "RzPVector", "RzVector", "RzGraph"}
def cursor_get_comment(cursor: Cursor, *, packed: bool = False) -> Optional[str]:
@@ -171,10 +136,7 @@ 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
and location_get_filename(cursor.location) not in skip_files
):
if typeref_spelling in generic_types:
warn(
f"Missing type comment at {stringify_location(cursor.location)} "
"(token is not a comment)"
@@ -190,7 +152,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"}:
if typeref_spelling in {"RzList", "RzListIter", "RzPVector", "RzGraph"}:
if comment[-2] != "*":
warn(f"Type comment at {stringify_location(cursor.location)} lacks pointer")
elif comment[-3] != " ":
@@ -202,21 +164,8 @@ 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",
@@ -316,51 +265,6 @@ class Function:
)
def check_doxygen_syntax(file_path: str, rizin_path: str) -> None:
"""
Check for incorrect Doxygen syntax in a file.
Rizin uses backslash syntax (\\param, \\return, etc.)
instead of at-sign syntax (@param, @return, etc.).
This function scans Doxygen comment blocks and reports any @-prefixed command usage.
"""
if not (file_path.endswith(".c") or file_path.endswith(".h")):
return
try:
with open(file_path, "r", encoding="utf-8", errors="ignore") as f:
content = f.read()
except (OSError, IOError):
return
relpath = os.path.relpath(os.path.abspath(file_path), rizin_path)
comment_matches = list(_DOXY_BLOCK_RE.finditer(content)) + list(
_DOXY_LINE_RE.finditer(content)
)
comment_matches.sort(key=lambda m: m.start())
for match in comment_matches:
block_text = match.group(0)
block_start_pos = match.start()
line_offset = content[:block_start_pos].count("\n")
lines = block_text.splitlines()
for line_idx, line in enumerate(lines):
for cmd_match in _DOXY_COMMAND_RE.finditer(line):
command = cmd_match.group(1).lower()
if command in _DOXY_COMMANDS:
line_num = line_offset + line_idx + 1
column = cmd_match.start() + 1
correct_syntax = _DOXY_COMMANDS[command]
warn(
f"<{relpath}:{line_num}:{column}> "
f"Found @{command}, should use {correct_syntax}"
)
def check_translation_unit(
translation_unit: TranslationUnit, *, skipped_paths: Set[str], rizin_path: str
) -> None:
@@ -405,7 +309,6 @@ def check_translation_unit(
CursorKind.STRUCT_DECL,
CursorKind.UNION_DECL,
CursorKind.ENUM_DECL,
CursorKind.ALIGNED_ATTR,
]:
warn(f"Unknown field cursor kind: {field.kind}")
@@ -482,8 +385,6 @@ def main() -> int:
for include in includes
]
check_doxygen_syntax(abspath, rizin_path)
try:
check_translation_unit(
TranslationUnit.from_source(abspath, clang_args),
+4 -8
View File
@@ -9,20 +9,16 @@ bool rizin_warn_deprecate_instructions = true;
%{
void rizin_try_warn_deprecate(const char *name, const char *c_name) {
if (rizin_warn_deprecate) {
fprintf(stderr, "Warning: `%s` calls deprecated function `%s`\n", name, c_name);
printf("Warning: `%s` calls deprecated function `%s`\n", name, c_name);
if (rizin_warn_deprecate_instructions) {
fprintf(stderr,
"To disable this warning, set rizin_warn_deprecate to false\n"
"The way to do this depends on the SWIG language being used\n"
"For python, do `rizin.cvar.rizin_warn_deprecate = False`\n");
puts("To disable this warning, set rizin_warn_deprecate to false");
puts("The way to do this depends on the SWIG language being used");
puts("For python, do `rizin.cvar.rizin_warn_deprecate = False`");
}
}
}
%}
// uint64_t, int64_t etc
%include <stdint.i>
// Buffer typemaps
%include <pybuffer.i>
%pybuffer_mutable_binary(unsigned char *buf, unsigned long long len);
-15
View File
@@ -1,15 +0,0 @@
NAME=1-rz_core.py =
FILE=--
CMDS=<<EOF
!echo q | python3 examples/1-rz_core.py =
echo
EOF
EXPECT=<<EOF
Loaded 1 file(s)
Corefile #1 has 1 binfile(s)
* malloc://512
rizin>
EOF
EXPECT_ERR=<<EOF
EOF
RUN