A fork of https://github.com/crosspoint-reader/crosspoint-reader
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

chore: Add powershell script for clang-formatting (#1472)

## Summary

* **What is the goal of this PR?** Add a windows equivalent for the
linux clang-format-fix script
* **What changes are included?**

## Additional Context
```
.SYNOPSIS
Runs clang-format -i on project *.cpp and *.h files.

.DESCRIPTION
Formats all C/C++ source and header files in the repository, excluding
generated, vendored, and build directories (open-x4-sdk, builtinFonts,
hyphenation tries, uzlib, .pio, *.generated.h).

The clang-format binary path is resolved once and cached in
.local/clang-format-fix.local. On first run it checks a default path,
then PATH, then common install locations. Edit the .local file to
override manually.

.PARAMETER g
Format only git-modified files (git diff --name-only HEAD) instead of
the full tree.

.PARAMETER h
Show this help text.
```
---

### AI Usage

While CrossPoint doesn't have restrictions on AI tools in contributing,
please be transparent about their usage as it
helps set the right context for reviewers.

Did you use AI tools to help write this code? _**< YES >**_

authored by

jpirnay and committed by
GitHub
02459721 0cbfaa00

+154
+154
bin/clang-format-fix.ps1
··· 1 + <# 2 + .SYNOPSIS 3 + Runs clang-format -i on project *.cpp and *.h files. 4 + 5 + .DESCRIPTION 6 + Formats all C/C++ source and header files in the repository, excluding 7 + generated, vendored, and build directories (open-x4-sdk, builtinFonts, 8 + hyphenation tries, uzlib, .pio, *.generated.h). 9 + 10 + The clang-format binary path is resolved once and cached in 11 + bin/clang-format-fix.local. On first run it checks a default path, 12 + then PATH, then common install locations. Edit the .local file to 13 + override manually. 14 + 15 + .PARAMETER g 16 + Format only git-modified files (git diff --name-only HEAD) instead of 17 + the full tree. 18 + 19 + .PARAMETER h 20 + Show this help text. 21 + 22 + .EXAMPLE 23 + .\clang-format-fix.ps1 24 + Format all files. 25 + 26 + .EXAMPLE 27 + .\clang-format-fix.ps1 -g 28 + Format only git-modified files. 29 + #> 30 + 31 + param( 32 + [switch]$g, 33 + [switch]$h 34 + ) 35 + 36 + if ($h) { 37 + Get-Help $PSCommandPath -Detailed 38 + return 39 + } 40 + 41 + $repoRoot = (Resolve-Path "$PSScriptRoot\..").Path 42 + $configFile = Join-Path $PSScriptRoot 'clang-format-fix.local' 43 + $defaultPath = 'C:\Program Files\LLVM\bin\clang-format.exe' 44 + 45 + $candidatePaths = @( 46 + 'C:\Program Files\LLVM\bin\clang-format.exe' 47 + 'C:\Program Files (x86)\LLVM\bin\clang-format.exe' 48 + 'C:\msys64\ucrt64\bin\clang-format.exe' 49 + 'C:\msys64\mingw64\bin\clang-format.exe' 50 + "$env:LOCALAPPDATA\LLVM\bin\clang-format.exe" 51 + ) 52 + 53 + function Find-ClangFormat { 54 + # Try PATH first 55 + $inPath = Get-Command clang-format -ErrorAction SilentlyContinue 56 + if ($inPath) { return $inPath.Source } 57 + 58 + # Try candidate paths 59 + foreach ($p in $candidatePaths) { 60 + if (Test-Path $p) { return $p } 61 + } 62 + return $null 63 + } 64 + 65 + function Resolve-ClangFormat { 66 + # 1. Read from config if present 67 + if (Test-Path $configFile) { 68 + $saved = (Get-Content $configFile -Raw).Trim() 69 + if ($saved -and (Test-Path $saved)) { return $saved } 70 + Write-Host "Configured path no longer valid: $saved" 71 + } 72 + 73 + # 2. Check default 74 + if (Test-Path $defaultPath) { 75 + $defaultPath | Set-Content $configFile 76 + Write-Host "Saved clang-format path to $configFile" 77 + return $defaultPath 78 + } 79 + 80 + # 3. Search PATH and candidate locations 81 + $found = Find-ClangFormat 82 + if ($found) { 83 + $found | Set-Content $configFile 84 + Write-Host "Found clang-format at $found - saved to $configFile" 85 + return $found 86 + } 87 + 88 + Write-Error "clang-format not found. Install LLVM or add clang-format to PATH." 89 + exit 1 90 + } 91 + 92 + $clangFormat = Resolve-ClangFormat 93 + 94 + $exclude = @( 95 + 'open-x4-sdk' 96 + 'lib\EpdFont\builtinFonts' 97 + 'lib\Epub\Epub\hyphenation\generated' 98 + 'lib\uzlib' 99 + '.pio' 100 + ) 101 + 102 + function Test-Excluded($fullPath) { 103 + foreach ($ex in $exclude) { 104 + if ($fullPath -like "*\$ex\*") { return $true } 105 + } 106 + if ($fullPath -like '*.generated.h') { return $true } 107 + return $false 108 + } 109 + 110 + if ($g) { 111 + # Only git-modified *.cpp / *.h files 112 + # Covers both staged and unstaged changes 113 + $files = @(git -C $repoRoot diff --name-only HEAD) + 114 + @(git -C $repoRoot diff --name-only --cached) | 115 + Sort-Object -Unique | 116 + Where-Object { $_ -match '\.(cpp|h)$' } | 117 + ForEach-Object { Get-Item (Join-Path $repoRoot $_) -ErrorAction SilentlyContinue } | 118 + Where-Object { $_ -and -not (Test-Excluded $_.FullName) } 119 + } else { 120 + $files = Get-ChildItem -Path $repoRoot -Recurse -Include *.cpp, *.h -File | 121 + Where-Object { -not (Test-Excluded $_.FullName) } 122 + } 123 + 124 + $files = @($files) 125 + 126 + if ($files.Count -eq 0) { 127 + Write-Host 'No files to format.' 128 + return 129 + } 130 + 131 + Write-Host "Formatting $($files.Count) files..." 132 + $i = 0 133 + $changed = 0 134 + $failures = 0 135 + foreach ($f in $files) { 136 + $i++ 137 + $rel = $f.FullName.Substring($repoRoot.Length + 1) 138 + $hashBefore = (Get-FileHash $f.FullName -Algorithm MD5).Hash 139 + & $clangFormat -i $f.FullName 140 + if ($LASTEXITCODE -ne 0) { 141 + $failures++ 142 + Write-Host " [$i/$($files.Count)] $rel (FAILED, exit code $LASTEXITCODE)" 143 + continue 144 + } 145 + $hashAfter = (Get-FileHash $f.FullName -Algorithm MD5).Hash 146 + if ($hashBefore -ne $hashAfter) { 147 + $changed++ 148 + Write-Host " [$i/$($files.Count)] $rel (changed)" 149 + } else { 150 + Write-Host " [$i/$($files.Count)] $rel" 151 + } 152 + } 153 + Write-Host "Done. $changed/$($files.Count) files changed, $failures failed." 154 + if ($failures -gt 0) { exit 1 }