Skip to content
Open
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
7 changes: 7 additions & 0 deletions .clang-tidy
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Checks: >
-*,
modernize-use-nullptr,
WarningsAsErrors: "*"
HeaderFilterRegex: "^(src|tests|tools)/"
FormatStyle: none
SystemHeaders: false
24 changes: 16 additions & 8 deletions .github/workflows/01-ci-pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,42 +42,50 @@ jobs:
!contains(github.event.pull_request.title, 'wip'))
uses: ./.github/workflows/02-lint-check.yml

# Static analysis: clang-tidy on changed C/C++ files
clang-tidy:
if: >-
github.event_name != 'pull_request' ||
(!github.event.pull_request.draft &&
!contains(github.event.pull_request.title, 'wip'))
uses: ./.github/workflows/clang_tidy.yml

# Main build and test matrix
build-and-test-macos-arm64:
name: Build & Test (macos-arm64)
needs: lint
needs: [lint, clang-tidy]
uses: ./.github/workflows/03-macos-linux-build.yml
with:
platform: macos-arm64
os: macos-15

build-and-test-macos-26-arm64:
name: Build & Test (macos-26-arm64)
needs: lint
needs: [lint, clang-tidy]
uses: ./.github/workflows/03-macos-linux-build.yml
with:
platform: macos-arm64
os: macos-26

build-and-test-linux-arm64:
name: Build & Test (linux-arm64)
needs: lint
needs: [lint, clang-tidy]
uses: ./.github/workflows/03-macos-linux-build.yml
with:
platform: linux-arm64
os: ubuntu-24.04-arm

build-and-test-linux-x64:
name: Build & Test (linux-x64)
needs: lint
needs: [lint, clang-tidy]
uses: ./.github/workflows/03-macos-linux-build.yml
with:
platform: linux-x64
os: ubuntu-24.04

build-and-test-linux-x64-clang:
name: Build & Test (linux-x64-clang)
needs: lint
needs: [lint, clang-tidy]
uses: ./.github/workflows/03-macos-linux-build.yml
with:
platform: linux-x64-clang
Expand All @@ -86,15 +94,15 @@ jobs:

build-android:
name: Build & Test (android)
needs: lint
needs: [lint, clang-tidy]
uses: ./.github/workflows/04-android-build.yml

build-and-test-on-windows:
name: Build & Test (Windows)
needs: lint
needs: [lint, clang-tidy]
uses: ./.github/workflows/05-windows-build.yml

build-ios:
name: Build & Test (iOS)
needs: lint
needs: [lint, clang-tidy]
uses: ./.github/workflows/06-ios-build.yml
156 changes: 156 additions & 0 deletions .github/workflows/clang_tidy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
name: Clang-Tidy

on:
workflow_call:
workflow_dispatch:

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

permissions:
contents: read

jobs:
clang_tidy:
name: Clang-Tidy Checks
runs-on: ubuntu-24.04
steps:
- name: Checkout code
uses: actions/checkout@v6
with:
submodules: recursive
# fetch-depth: 0 is required for tj-actions/changed-files to correctly
# compute the diff against the base branch on pull_request events.
fetch-depth: 0

- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y clang-tidy=1:18.0-59~exp2 cmake ninja-build

- name: Configure CMake and export compile commands
run: |
cmake -S . -B build -G Ninja \
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON \
-DBUILD_TOOLS=ON

- name: Collect changed C/C++ files
id: changed_files
uses: tj-actions/changed-files@v47
with:
files: |
**/*.c
**/*.cc
**/*.cpp
**/*.cxx
files_ignore: |
thirdparty/**
build/**

- name: Filter changed files against compile_commands.json
id: tidy_files
if: steps.changed_files.outputs.any_changed == 'true'
run: |
python3 - <<'PY'
import json
import os
from pathlib import Path

# all_changed_files is space-separated when output_format is not set;
# tj-actions v46 defaults to space-separated for the env var form.
# We read from the file written by the action instead via GITHUB_OUTPUT,
# but the safest approach is to use the JSON output format.
raw = os.environ.get("ALL_CHANGED_FILES", "")
changed = [f for f in raw.split() if f]

compile_db_path = Path("build/compile_commands.json")
with compile_db_path.open("r", encoding="utf-8") as fh:
compile_db = json.load(fh)

# Build a set of absolute, normalised paths from compile_commands.json.
compile_entries = set()
for entry in compile_db:
file_field = entry.get("file", "")
if file_field:
compile_entries.add(os.path.normpath(file_field))

cwd = Path.cwd().resolve()
selected = []
skipped = []

for rel_path in changed:
abs_path = os.path.normpath(str((cwd / rel_path).resolve()))
if abs_path in compile_entries:
selected.append(rel_path)
elif not Path(rel_path).is_file():
skipped.append(f"{rel_path} (file not found)")
else:
skipped.append(f"{rel_path} (not in compile_commands.json)")

github_output = os.environ["GITHUB_OUTPUT"]
with open(github_output, "a", encoding="utf-8") as out:
out.write(f"any_tidy_files={'true' if selected else 'false'}\n")
out.write("all_tidy_files<<TIDY_EOF\n")
out.write("\n".join(selected) + "\n")
out.write("TIDY_EOF\n")
out.write("skipped_files<<SKIP_EOF\n")
out.write("\n".join(skipped) + "\n")
out.write("SKIP_EOF\n")
PY
env:
ALL_CHANGED_FILES: ${{ steps.changed_files.outputs.all_changed_files }}

- name: Show skipped files
if: steps.changed_files.outputs.any_changed == 'true' && steps.tidy_files.outputs.skipped_files != ''
run: |
echo "=== Files skipped by clang-tidy ==="
printf '%s\n' "${{ steps.tidy_files.outputs.skipped_files }}"

- name: Compute submodule commits hash
id: submodule_hash
run: |
# Collect each submodule's current commit SHA, sort for a stable order,
# then SHA-256 the result so the cache key stays a fixed length.
hash=$(git submodule status --recursive | awk '{print $1}' | sort | sha256sum | awk '{print $1}')
echo "value=${hash}" >> "$GITHUB_OUTPUT"

- name: Cache third-party build artifacts
id: cache_thirdparty
uses: actions/cache@v5
with:
path: build/external
# Cache key combines:
# - thirdparty CMakeLists / cmake / patch file contents
# - all submodule commit SHAs (upgrading a submodule busts the cache)
key: thirdparty-${{ runner.os }}-${{ hashFiles('thirdparty/**/*.cmake', 'thirdparty/**/CMakeLists.txt', 'thirdparty/**/*.patch') }}-${{ steps.submodule_hash.outputs.value }}

- name: Build
if: steps.tidy_files.outputs.any_tidy_files == 'true'
run: |
# build so that clang-tidy can find the headers
ninja -C build zvec_db

- name: Run clang-tidy on changed files
if: steps.tidy_files.outputs.any_tidy_files == 'true'
run: |
# Read the newline-delimited file list into an array.
mapfile -t files_to_check <<'TIDY_EOF'
${{ steps.tidy_files.outputs.all_tidy_files }}
TIDY_EOF

failed=0
for file in "${files_to_check[@]}"; do
# Skip blank lines that mapfile may produce.
[[ -z "${file// }" ]] && continue
if [ -f "$file" ]; then
echo "=== clang-tidy: $file ==="
clang-tidy -p build --warnings-as-errors='*' "$file" || failed=1
fi
done

exit $failed

- name: No C/C++ files changed
if: steps.changed_files.outputs.any_changed != 'true' || steps.tidy_files.outputs.any_tidy_files != 'true'
run: echo "No changed source files with compile_commands entries to analyse."
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ tests/de_integration/log
tests/de_integration/*.log
!.git*
!.clang-format
!.clang-tidy
!.circleci
!.drone.yml
sdk/python/dist/
Expand Down
20 changes: 10 additions & 10 deletions src/ailego/container/bitmap.cc
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ void Bitmap::copy(const Bitmap &rhs) {

for (std::vector<Bucket *>::const_iterator iter = rhs.array_.begin();
iter != rhs.array_.end(); ++iter) {
Bucket *bucket = NULL;
Bucket *bucket = nullptr;
if (*iter) {
bucket = new Bucket(*(*iter));
}
Expand All @@ -106,14 +106,14 @@ void Bitmap::shrink_to_fit(void) {
break;
}
delete (*iter);
*iter = NULL;
*iter = nullptr;
}
++shrink_count;
}
for (; iter != array_.rend(); ++iter) {
if ((*iter) && (*iter)->test_none()) {
delete (*iter);
*iter = NULL;
*iter = nullptr;
}
}
if (shrink_count != 0) {
Expand All @@ -139,7 +139,7 @@ void Bitmap::set(size_t num) {
// High 16 bits
size_t offset = num >> 16;
if (offset >= array_.size()) {
array_.resize(offset + 1, NULL);
array_.resize(offset + 1, nullptr);
}

Bucket *&bucket = array_[offset];
Expand All @@ -154,7 +154,7 @@ void Bitmap::reset(size_t num) {
// High 16 bits
size_t offset = num >> 16;
if (offset >= array_.size()) {
array_.resize(offset + 1, NULL);
array_.resize(offset + 1, nullptr);
}

if (offset < array_.size()) {
Expand All @@ -170,7 +170,7 @@ void Bitmap::flip(size_t num) {
// High 16 bits
uint16_t offset = (uint16_t)(num >> 16);
if (offset >= array_.size()) {
array_.resize(offset + 1, NULL);
array_.resize(offset + 1, nullptr);
}

Bucket *&bucket = array_[offset];
Expand All @@ -193,14 +193,14 @@ void Bitmap::bitwise_and(const Bitmap &rhs) {
dst->bitwise_and(*src);
} else {
delete dst;
dst = NULL;
dst = nullptr;
}
}
}
for (size_t i = overlap; i < array_.size(); ++i) {
Bucket *&dst = array_[i];
delete dst;
dst = NULL;
dst = nullptr;
}
}

Expand Down Expand Up @@ -237,7 +237,7 @@ void Bitmap::bitwise_or(const Bitmap &rhs) {
}
for (size_t i = overlap; i < rhs.array_.size(); ++i) {
const Bucket *src = rhs.array_[i];
Bucket *bucket = NULL;
Bucket *bucket = nullptr;

if (src) {
bucket = new Bucket(*src);
Expand All @@ -264,7 +264,7 @@ void Bitmap::bitwise_xor(const Bitmap &rhs) {
}
for (size_t i = overlap; i < rhs.array_.size(); ++i) {
const Bucket *src = rhs.array_[i];
Bucket *bucket = NULL;
Bucket *bucket = nullptr;

if (src) {
bucket = new Bucket(*src);
Expand Down
2 changes: 1 addition & 1 deletion src/ailego/internal/cpu_features.cc
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ CpuFeatures::CpuFlags::CpuFlags(void)
L1_ECX = ecx;
L1_EDX = edx;
}
if (__get_cpuid_max(0, NULL) >= 7) {
if (__get_cpuid_max(0, nullptr) >= 7) {
__cpuid_count(7, 0, eax, ebx, ecx, edx);
L7_EBX = ebx;
L7_ECX = ecx;
Expand Down
Loading
Loading