Maybe I miss something, but still didn't find such a setting. Formally speaking clang-format
doesn't produce proper UNIX text files, since last lines always lack EOL-character.
Asked
Active
Viewed 2,311 times
19

ababo
- 1,490
- 1
- 10
- 24
-
Well, it doesn't remove the EOL at the end of the file if it's already there. But would be nice if it added EOL if it isn't there. Three years later, this still seems to be missing from clang-format. – Eric Backus Aug 07 '20 at 21:03
-
Yep, that's pretty sad. At least, IDEs allow to enforce that on save, for example CLion/Android Studio: `File->Settings->Editor->General` and toggle `Ensure an empty line at the end of a file on Save` – Antonio Jun 09 '21 at 09:28
-
1Not sure if this might be related: https://reviews.llvm.org/rG978419bf37546da788a7042d8de4044196c1d515 – Antonio Jun 09 '21 at 09:35
-
Not quite the answer to the question, but adding a .editorconfig file to the root of the repository will at least make modern editors add EOL and EOF. VisualStudio supports it. So while you couldn't reformat all files with clang-format, at least new files would be saved in the right format. – Hajo Kirchhoff Jun 16 '21 at 06:03
1 Answers
3
Option 1:
Found and outside ref. which could help you, "You can recursively add an EOL-character / sanitize the files from here..."
git ls-files -z "*.cpp" "*.hpp" | while IFS= read -rd '' f; do tail -c1 < "$f" | read -r _ || echo >> "$f"; done
Explanation:
git ls-files -z "*.cpp" "*.hpp" //lists files in the repository matching the listed patterns. You can add more patterns, but they need the quotes so that the * is not substituted by the shell but interpreted by git. As an alternative, you could use find -print0 ... or similar programs to list affected files - just make sure it emits NUL-delimited entries.
while IFS= read -rd '' f; do ... done //iterates through the entries, safely handling filenames that include whitespace and/or newlines.
tail -c1 < "$f" reads the last char from a file.
read -r _ exits with a nonzero exit status if a trailing newline is missing.
|| echo >> "$f" appends a newline to the file if the exit status of the previous command was nonzero.
Option 2 from Clang format script:
#!/bin/bash
set -e
function append_newline {
if [[ -z "$(tail -c 1 "$1")" ]]; then
:
else
echo >> "$1"
fi
}
if [ -z "$1" ]; then
TARGET_DIR="."
else
TARGET_DIR=$1
fi
pushd ${TARGET_DIR} >> /dev/null
# Find all source files using Git to automatically respect .gitignore
FILES=$(git ls-files "*.h" "*.cpp" "*.c")
# Run clang-format
clang-format-10 -i ${FILES}
# Check newlines
for f in ${FILES}; do
append_newline $f
done
popd >> /dev/null

Antonio
- 19,451
- 13
- 99
- 197

Transformer
- 6,963
- 2
- 26
- 52
-
1Option 1 is great, thanks! Especially combined with the right settings of your editor, so that afterwards no new files missing the EOL at EOF are introduced. I wouldn't know exactly how Option 2 should be used in practice. – Antonio Jun 16 '21 at 12:43
-
1Option 2 could be used for scripts such as git pre-commit hooks, and is more readable. – Gamrix Sep 07 '21 at 19:12