Skip to content

Commit ac9a678

Browse files
Add format.ps1, format with Clang.
1 parent be22d32 commit ac9a678

35 files changed

Lines changed: 15628 additions & 10571 deletions

ext/std/networking.c

Lines changed: 1391 additions & 1107 deletions
Large diffs are not rendered by default.

ext/std/win32.c

Lines changed: 580 additions & 341 deletions
Large diffs are not rendered by default.

format.ps1

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
<#
2+
format.ps1
3+
Formats and lint-fixes the Prefix C codebase with Clang tools.
4+
5+
Usage (from Prefix folder):
6+
powershell -ExecutionPolicy Bypass -File .\format.ps1
7+
#>
8+
9+
$ErrorActionPreference = 'Stop'
10+
11+
$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Definition
12+
$srcDir = Join-Path $scriptDir "src"
13+
14+
if (-not (Test-Path $srcDir)) {
15+
Write-Error "Could not locate src directory at: $srcDir"
16+
exit 1
17+
}
18+
19+
$clang = Get-Command clang.exe -ErrorAction SilentlyContinue
20+
$clangFormat = Get-Command clang-format.exe -ErrorAction SilentlyContinue
21+
$clangTidy = Get-Command clang-tidy.exe -ErrorAction SilentlyContinue
22+
23+
if (-not $clang) {
24+
Write-Error "clang.exe not found on PATH."
25+
exit 1
26+
}
27+
if (-not $clangFormat) {
28+
Write-Error "clang-format.exe not found on PATH."
29+
exit 1
30+
}
31+
if (-not $clangTidy) {
32+
Write-Error "clang-tidy.exe not found on PATH."
33+
exit 1
34+
}
35+
36+
# Determine clang-tidy checks to use. Priority:
37+
# 1) CLANG_TIDY_CHECKS env var
38+
# 2) repo .clang-tidy file (let clang-tidy find it)
39+
# 3) fix-oriented default checks that stay quiet unless they can rewrite code
40+
$repoTidyFile = Join-Path $scriptDir ".clang-tidy"
41+
$clangTidyChecks = $env:CLANG_TIDY_CHECKS
42+
if (-not $clangTidyChecks) {
43+
if (-not (Test-Path $repoTidyFile)) {
44+
# Default to checks that usually provide mechanical fixes instead of
45+
# flooding the run with non-actionable audit diagnostics.
46+
$clangTidyChecks = "readability-braces-around-statements,readability-isolate-declaration,readability-redundant-control-flow"
47+
} else {
48+
$clangTidyChecks = ""
49+
}
50+
}
51+
$repoClangFormat = Join-Path $scriptDir ".clang-format"
52+
# If repo provides a .clang-format, prefer it; otherwise use an inline
53+
# style that enforces four-space indents and no tabs.
54+
if (Test-Path $repoClangFormat) {
55+
$clangFormatStyle = "file"
56+
$clangTidyFormatArg = "-format-style=file"
57+
} else {
58+
$clangFormatStyle = "{BasedOnStyle: LLVM, IndentWidth: 4, UseTab: Never, ColumnLimit: 120}"
59+
$clangTidyFormatArg = "-format-style=$clangFormatStyle"
60+
}
61+
$roots = @(
62+
(Join-Path $scriptDir "src"),
63+
(Join-Path $scriptDir "ext"),
64+
(Join-Path $scriptDir "lib"),
65+
(Join-Path $scriptDir "tests\helpers")
66+
)
67+
68+
$allC = @()
69+
$allH = @()
70+
71+
foreach ($root in $roots) {
72+
if (-not (Test-Path $root)) {
73+
continue
74+
}
75+
$allC += Get-ChildItem -Path $root -Recurse -File -Filter *.c | ForEach-Object { $_.FullName }
76+
$allH += Get-ChildItem -Path $root -Recurse -File -Filter *.h | ForEach-Object { $_.FullName }
77+
}
78+
79+
$sourceFiles = @($allC | Sort-Object -Unique)
80+
$headerFiles = @($allH | Sort-Object -Unique)
81+
$formatFiles = @($sourceFiles + $headerFiles | Sort-Object -Unique)
82+
83+
if ($sourceFiles.Count -eq 0) {
84+
Write-Error "No C source files found under src/, ext/, lib/, or tests/helpers/."
85+
exit 1
86+
}
87+
88+
if ($formatFiles.Count -eq 0) {
89+
Write-Error "No C/C header files found to format."
90+
exit 1
91+
}
92+
93+
Write-Host "Formatting $($formatFiles.Count) C/C header file(s) with clang-format (IndentWidth=$($clangFormatStyle -replace '^\{|\}$',''))..."
94+
foreach ($file in $formatFiles) {
95+
& $clangFormat.Path "-style=$clangFormatStyle" -i $file
96+
if ($LASTEXITCODE -ne 0) {
97+
Write-Error "clang-format failed for: $file"
98+
exit 1
99+
}
100+
}
101+
102+
$stamp = Get-Date -Format "yyyyMMdd-HHmmss"
103+
$tidyDbDir = Join-Path $env:TEMP ("prefix-clang-tidy-" + $stamp)
104+
New-Item -ItemType Directory -Path $tidyDbDir -Force | Out-Null
105+
106+
try {
107+
$compileDbPath = Join-Path $tidyDbDir "compile_commands.json"
108+
$compileDb = @()
109+
110+
foreach ($file in $sourceFiles) {
111+
$command = ('"{0}" --driver-mode=cl /std:c17 /I"{1}" /I"{2}" /D_CRT_SECURE_NO_WARNINGS "{3}"' -f $clang.Path, $srcDir, $scriptDir, $file)
112+
$compileDb += [ordered]@{
113+
directory = $scriptDir
114+
file = $file
115+
command = $command
116+
}
117+
}
118+
119+
$compileDb | ConvertTo-Json -Depth 4 | Set-Content -Path $compileDbPath -Encoding UTF8
120+
121+
Write-Host "Lint-fixing $($sourceFiles.Count) C source file(s) with clang-tidy..."
122+
$lintFixFailures = @()
123+
foreach ($file in $sourceFiles) {
124+
$tidyArgs = @('-p', $tidyDbDir)
125+
if ($clangTidyChecks -ne "") { $tidyArgs += "--checks=$clangTidyChecks" }
126+
# Narrow header filter to just project files (src/, ext/, lib/, tests/) to avoid analyzing system headers
127+
$headerFilter = "(src|ext|lib|tests)/"
128+
$tidyArgs += @('-quiet', '-fix', '-fix-errors', '-fix-notes', $clangTidyFormatArg, "-header-filter=$headerFilter", $file)
129+
$tidyOutput = & $clangTidy.Path @tidyArgs 2>&1
130+
131+
if ($LASTEXITCODE -ne 0) {
132+
$lintFixFailures += [pscustomobject]@{
133+
File = $file
134+
Output = (($tidyOutput | ForEach-Object { $_.ToString() }) -join [Environment]::NewLine)
135+
}
136+
}
137+
}
138+
139+
if ($lintFixFailures.Count -gt 0) {
140+
Write-Host "clang-tidy auto-fix failed for $($lintFixFailures.Count) file(s):" -ForegroundColor Red
141+
foreach ($failure in $lintFixFailures) {
142+
Write-Host "--- $($failure.File) ---" -ForegroundColor Red
143+
if ($failure.Output) {
144+
Write-Host $failure.Output -ForegroundColor Red
145+
}
146+
}
147+
Write-Error "clang-tidy auto-fix failed."
148+
exit 1
149+
}
150+
151+
Write-Host "Re-formatting after clang-tidy fixes..."
152+
foreach ($file in $formatFiles) {
153+
& $clangFormat.Path "-style=$clangFormatStyle" -i $file
154+
if ($LASTEXITCODE -ne 0) {
155+
Write-Error "clang-format post-lint failed for: $file"
156+
exit 1
157+
}
158+
}
159+
160+
Write-Host "Formatting and lint auto-fix completed successfully." -ForegroundColor Green
161+
exit 0
162+
} finally {
163+
if (Test-Path $tidyDbDir) {
164+
Remove-Item -Recurse -Force $tidyDbDir -ErrorAction SilentlyContinue
165+
}
166+
}

0 commit comments

Comments
 (0)