`scripts/reindent.sh` and `scripts/hooks/pre-commit` each carried their own copy of the directory list, and neither included `tools` or `examples`. Both hold ordinary hand-written C, so `--check` reported a clean tree without having looked at them and the hook let them through unformatted -- which defeats the one thing that keeps this tree a fixed point of `indent-region`. The comment in `reindent.sh` already said the scope is "directories whose C sources are hand-maintained", so this is the list catching up with the stated intent rather than a new policy. The two copies are now marked as being two copies of one decision, because they have already disagreed once and nothing detects it when they do. `scripts/reindent.sh --check` is clean with the wider scope. Co-Authored-By: Claude Code <noreply@anthropic.com> Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
108 lines
3.4 KiB
Bash
Executable File
108 lines
3.4 KiB
Bash
Executable File
#!/bin/sh
|
|
#
|
|
# Reindent C sources to the project's canonical style (cc-mode "stroustrup",
|
|
# 4-column offset, 8-column tabs). See AGENTS.md -> "Coding Style".
|
|
#
|
|
# scripts/reindent.sh reindent every tracked C source in place
|
|
# scripts/reindent.sh FILE... reindent only the named files
|
|
# scripts/reindent.sh --check ... report non-conforming files, change nothing
|
|
#
|
|
# Exit status: 0 if everything already conforms (or was reindented), 1 if
|
|
# --check found a file that needs reindenting, 2 on a usage or environment
|
|
# error.
|
|
|
|
set -eu
|
|
|
|
root=$(git rev-parse --show-toplevel)
|
|
elisp="$root/scripts/reindent.el"
|
|
|
|
# Directories whose C sources are hand-maintained. Anything outside these is
|
|
# vendored (deps/) or generated (include/akgl/SDL_GameControllerDB.h) and is
|
|
# left alone.
|
|
#
|
|
# `tools` and `examples` joined the list with the documentation harness. Both
|
|
# hold ordinary hand-written C -- the doc-example validators and the two
|
|
# tutorial games -- and while they were outside the scope neither `--check` nor
|
|
# the pre-commit hook could see them, so the one thing that keeps this tree a
|
|
# fixed point of `indent-region` was not being applied to its newest sources.
|
|
SCOPE='src include tests util tools examples'
|
|
GENERATED='include/akgl/SDL_GameControllerDB.h'
|
|
|
|
check=0
|
|
if [ "${1:-}" = "--check" ]; then
|
|
check=1
|
|
shift
|
|
fi
|
|
|
|
if ! command -v emacs >/dev/null 2>&1; then
|
|
echo "reindent: emacs not found; cannot verify or apply the canonical style" >&2
|
|
exit 2
|
|
fi
|
|
if [ ! -f "$elisp" ]; then
|
|
echo "reindent: missing $elisp" >&2
|
|
exit 2
|
|
fi
|
|
|
|
# Build the file list: explicit arguments, or every tracked C source in scope.
|
|
if [ "$#" -gt 0 ]; then
|
|
files=$(for f in "$@"; do printf '%s\n' "$f"; done)
|
|
else
|
|
files=$(cd "$root" && git ls-files $SCOPE | grep -E '\.[ch]$' || true)
|
|
fi
|
|
|
|
# Drop generated files and anything that no longer exists on disk.
|
|
files=$(printf '%s\n' "$files" | grep -v -x -F "$GENERATED" || true)
|
|
files=$(cd "$root" && for f in $files; do [ -f "$f" ] && printf '%s\n' "$f"; done)
|
|
|
|
if [ -z "$files" ]; then
|
|
exit 0
|
|
fi
|
|
|
|
if [ "$check" -eq 0 ]; then
|
|
# Reindent in place. A non-zero status here is a real failure -- never
|
|
# swallow it, or a broken Emacs would look like "everything already conforms".
|
|
# shellcheck disable=SC2086
|
|
(cd "$root" && emacs --batch -Q -l "$elisp" -- $files) || {
|
|
echo "reindent: emacs failed; no files were reindented" >&2
|
|
exit 2
|
|
}
|
|
exit 0
|
|
fi
|
|
|
|
# --check: reindent throwaway copies and report which originals differ. The
|
|
# copies keep their extension so cc-mode still selects the right major mode.
|
|
tmp=$(mktemp -d)
|
|
trap 'rm -rf "$tmp"' EXIT INT TERM
|
|
|
|
# Accept both repo-relative and absolute paths: the default file list is
|
|
# relative, but callers (including the pre-commit hook) pass absolute ones.
|
|
abspath() {
|
|
case "$1" in
|
|
/*) printf '%s' "$1" ;;
|
|
*) printf '%s/%s' "$root" "$1" ;;
|
|
esac
|
|
}
|
|
|
|
copies=''
|
|
for f in $files; do
|
|
dest="$tmp/$(printf '%s' "$f" | tr '/' '_')"
|
|
cp "$(abspath "$f")" "$dest"
|
|
copies="$copies $dest"
|
|
done
|
|
|
|
# shellcheck disable=SC2086
|
|
emacs --batch -Q -l "$elisp" -- $copies >/dev/null || {
|
|
echo "reindent: emacs failed; cannot determine whether sources conform" >&2
|
|
exit 2
|
|
}
|
|
|
|
status=0
|
|
for f in $files; do
|
|
dest="$tmp/$(printf '%s' "$f" | tr '/' '_')"
|
|
if ! cmp -s "$(abspath "$f")" "$dest"; then
|
|
echo "$f"
|
|
status=1
|
|
fi
|
|
done
|
|
exit $status
|