Skip to content

Instantly share code, notes, and snippets.

@azat
Last active February 17, 2016 10:04
Show Gist options
  • Save azat/9577db04cb9de5c2c018 to your computer and use it in GitHub Desktop.
Save azat/9577db04cb9de5c2c018 to your computer and use it in GitHub Desktop.
#!/usr/bin/env bash
# uncrustify git commits, IOW not the whole files, but only parts of them
# XXX: not 100% correct
function uncrustify_frag()
{ command uncrustify -l C --frag "$@"; }
function indent_off() { echo '/* *INDENT-OFF* */'; }
function indent_on() { echo '/* *INDENT-ON* */'; }
function hunk()
{
local ref=$1 f=$2
shift 2
git cat-file -p $ref:$f
}
function indent_hunk()
{
local start=$1 end=$2
shift 2
# Will be beatier with tee(1), but doh bash async substitution
{ indent_off; hunk "$@" | head -n$((start - 1)); }
{ indent_on; hunk "$@" | head -n$((end - 1)) | tail -n+$start; }
{ indent_off; hunk "$@" | tail -n+$((end + 1)); }
}
function strip()
{
local start=$1 end=$2
shift 2
# seek indent_{on,off}()
let start+=2
head -n$end | tail -n+$start
}
function uncrustify_git()
{
local ref=$1 r f start end length
shift
local files=( $(git diff --name-only $ref^..$ref | egrep "\.(c|h)$") )
for f in "${files[@]}"; do
local ranges=( $(git diff -W $ref^..$ref -- $f | egrep -o '^@@ -[0-9]+(,[0-9]+|) \+[0-9]+(,[0-9]+|) @@' | cut -d' ' -f3) )
for r in "${ranges[@]}"; do
[[ ! "$r" =~ ^\+([0-9]+)(,([0-9]+)|)$ ]] && continue
start=${BASH_REMATCH[1]}
[ -n "${BASH_REMATCH[3]}" ] && \
length=${BASH_REMATCH[3]} || \
length=1
end=$((start + length))
echo "Range: $start:$end ($length)" >&2
diff -u \
<(indent_hunk $start $end $ref $f | strip $start $end) \
<(indent_hunk $start $end $ref $f | uncrustify_frag | strip $start $end) \
| sed \
-e "s#^--- /dev/fd.*\$#--- a/$f#" \
-e "s#^+++ /dev/fd.*\$#+++ b/$f#"
done
done
}
uncrustify_git "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment