--- /dev/null
+#!/bin/bash
+#
+# Checks source code and data for potential problems.
+# Meant to be executed before submitting/committing.
+
+
+SELF=${0/#*\/}
+
+# optional apps
+RLE=$(which rle &>/dev/null) # http://members.aon.at/mfranz/rle.tar.gz (depends on Qt lib)
+AC3D_SCAN=$(which ac3d-scan 2>/dev/null) # http://members.aon.at/mfranz/ac3d-scan
+
+
+function ERROR { echo -e "\e[31;1m$*\e[m"; }
+function LOG { echo -e "\e[35m$*\e[m"; }
+function RESULT { echo -e "\t$*"; }
+
+
+TMP=$(mktemp -d -t $SELF.XXX) || (echo "$0: can't create temporary dir"; exit 1)
+trap "rm -rf $TMP" 0 1 2 3 13 15
+
+
+LOG "checking for spaces in filenames ..."
+find .|grep " "|while read i; do RESULT "$i"; done
+
+
+LOG "checking for upper-case extensions ..." # except *.TXT
+find .|while read i; do
+ case "$i" in .|..|CVS/*|*/CVS/*|*.Opt|*.README|*.Po) continue ;; esac
+ base=${i/#.*\/}
+ ext=${base/#*./}
+ [ "$base" == "$ext" ] && continue # has no extension
+ ext=$(echo $ext|sed -e 's,[^A-Za-z],,'g)
+ [ -z "$ext" ] && continue # only non-letters
+ lcext=$(echo $ext|sed -e 's,\(.*\),\L\1,')
+ [ "$ext" != "$lcext" -a "$lcext" != "txt" ] && RESULT "$i"
+done
+
+
+LOG "checking for DOS line endings ..."
+find . -type f|while read i; do
+ desc=$(file -b "$i")
+ case "$desc" in *text*)
+ grep "\r$" "$i" >/dev/null && RESULT "$i"
+ ;;
+ esac
+done
+
+
+LOG "checking for uncompressed textures ..."
+find . -iname \*.rgb -o -iname \*.rgba|while read i; do
+ if file "$i"|grep -v RLE >/dev/null; then
+ new=$TMP/sgi.rgb
+ convert "$i" -compress RLE sgi:$new
+ [ "$RLE" ] && $RLE $new 2>/dev/null
+ perl -e '
+ my $file = shift;
+ my $old = -s $file;
+ my $new = -s shift;
+ if ($new < $old) {
+ printf "\t$file: could be %0.02f%% of current size (%d bytes less)\n",
+ 100 * $new / $old, $old - $new;
+ }
+ ' "$i" $new
+ fi
+done
+
+
+if [ "$AC3D_SCAN" ]; then
+ LOG "checking for AC3D sanity ..."
+ find . -iname \*.ac|while read i; do
+ case "$i" in configure.ac|*/configure.ac) continue ;; esac
+ result=$($AC3D_SCAN <$i 2>&1)
+ [ "$result" ] && echo -e "$result\n\t... in file \e[36m$i\e[m";
+ done
+fi
+
+
+LOG "checking for XML syntax ..."
+find . -name \*.xml|while read i; do
+ xmllint $i >/dev/null || RESULT "... min file \e[36m$i\e[m"
+done
+
+
+LOG "checking for 'if (foo) delete foo;' ..."
+find . -iregex ".*\.\([ch]\(xx\|pp\)\|cc\|h\)$"|while read i; do perl -e '
+ my $i = 0;
+ my $name = $ARGV[0];
+ undef $/;
+ $_ = <>;
+ s/(if\s*\(([^\)]+)\)\s*delete(?:\s+|\s*\[\]\s*)\2\s*;)/print "$1\n" and $i++/ges;
+ print "\t... \033[36min file $name\033[m\n" if $i;
+' "$i"; done
+
+
# $ fg-submit # generates foo.tar.bz2 and foo.diff
#
# The archive contains a copy of the diff, so the extra diff file
-# shouldn't be sumitted. It's only left for convenience.
+# shouldn't be submitted. It's only left for (in?)convenience.
-SELF=$(basename $0)
-AIRCRAFT=$(basename $PWD)
+SELF=${0/#*\/}
+AIRCRAFT=${PWD/#*\/}
CVS=/usr/bin/cvs
ARCHIVE=$AIRCRAFT.tar.bz2
DIFF=$AIRCRAFT.diff
+CDIFF=$DIFF.bz2
-function ERROR { echo -e "\e[31;1m$*\e[m"; }
-function LOG { echo -e "\e[35m$*\e[m"; }
-function ADD { echo -e "\e[32m\t+ $*\e[m"; }
-function REJECT { echo -e "\e[31m\t- $*\e[m"; }
+function ERROR { echo -e "\e[31;1m$*\e[m"; }
+function LOG { echo -e "\e[35m$*\e[m"; }
+function NEW { echo -e "\e[32m\t+ $*\e[m"; }
+function CHANGED { echo -e "\e[36m\t+ $*\e[m"; }
+function REJECT { echo -e "\e[31m\t- $*\e[m"; }
function diffstat {
# output diff statistics, similar to the "diffstat" utility
awk '
+ function line(a, r, c, f) {
+ print "\t\033[32m"a"\033[m\t\033[31m"r"\033[m\t\033[34m"c"\033[m\t"f
+ }
function dofile() {
if (!file) {
- return;
+ return
}
if (bin) {
- print "\t\tbinary\t\t"file;
+ line("\033[m. . . .", "\033[mbinary", "\033[m. . . .", file)
} else {
- print "\t+"a"\t-"r"\t!"c"\t"file
+ line(a, r, c, file)
at += a; rt += r; ct += c;
}
- a = r = c = 0;
+ a = r = c = 0
}
BEGIN {
- print "\tadded___removed_changed___________________________________";
- a = r = c = at = rt = ct = n = bin = 0;
+ print "\tadded---removed-changed----------------------------------------"
+ a = r = c = at = rt = ct = n = bin = 0
}
/^Index: / { dofile(); scan = bin = 0; file = $2; n += 1; next }
/^@@/ { scan = 1; next }
/^-/ { if (scan) { r += 1 } next }
/^!/ { if (scan) { c += 1 } next }
END {
- dofile();
- print "\t-----------------------------------total------------------";
- print "\t+"at"\t-"rt"\t!"ct"\tin "n" files"
+ dofile()
+ print "\t----------------------------------------total------------------"
+ line(at, rt, ct, "\033[min "n" files")
}
- ' < $1
+ ' <$1
}
trap "rm -rf $TMP" 0 1 2 3 13 15
-# move older archive or diff file out of the way
+# move older archive or diff files out of the way
[ -f $DIFF ] && mv $DIFF $(mktemp $DIFF.X)
+[ -f $CDIFF ] && mv $CDIFF $(mktemp $CDIFF.X)
[ -f $ARCHIVE ] && mv $ARCHIVE $(mktemp $ARCHIVE.X)
-LOG "updating and checking for changed and new files ..."
+LOG "updating and checking for new files ..."
$CVS -q up -dP >$TMP/up
if ! $CVS -q diff -up >$DIFF; then
LOG "diff statistics:"
diffstat $DIFF
+ echo
# add diff file itself
- echo $DIFF >>$TMP/include
+ echo $DIFF >>$TMP/files
# add changed binary files
awk '
- /^Index: / { scan = 1; file = $2 }
- /^@@/ { scan = 0 }
+ /^Index: / { scan = 1; file = $2; next }
+ /^@@/ { scan = 0; next }
/^Binary/ { if (scan) { print file } }
- ' <$DIFF >>$TMP/include
+ ' <$DIFF >>$TMP/files
else
rm -f $DIFF
fi
-# write list of all files to add
-LOG "adding to archive ..."
-if [ -f $TMP/include ]; then
- cat $TMP/include|while read i; do
- ADD "$i"
- echo $i >>$TMP/files
+LOG "checking for files to submit ..."
+if [ -f $TMP/files ]; then
+ cat $TMP/files|while read i; do
+ CHANGED "$i"
done
fi
grep "^? " $TMP/up|while read i; do
- find ${i#? } -type f >>$TMP/files
+ find ${i#? } -type f >>$TMP/check
done
# classify and filter files
-if [ -f $TMP/files ]; then
- for i in $(cat $TMP/files); do
+if [ -f $TMP/check ]; then
+ for i in $(cat $TMP/check); do
case "$i" in
$ARCHIVE*|$DIFF*) # don't add files generated by the script
;;
REJECT "$i\t\t(graphics file)"
;;
*)
- ADD "$i"
- echo "$i" >>$TMP/include
+ NEW "$i"
+ echo "$i" >>$TMP/files
;;
esac
done
fi
-if [ -f $TMP/include ]; then
- LOG "creating archive $ARCHIVE"
- tar -cjf $ARCHIVE --files-from $TMP/include
+if ! [ -f $TMP/files ]; then
+ LOG "no changed or new files found"
+ exit 0
+fi
+
+echo
+numfiles=$(awk '//{n+=1}END{print n}' <$TMP/files)
+if [ -f $DIFF -a $numfiles == 1 ]; then
+ LOG "only changed non-binary files found"
+ LOG "creating compressed diff \e[1;37;40m$CDIFF\e[m\e[35m ..."
+ bzip2 -k $DIFF
else
- LOG "no changed or new files detected"
+ LOG "changed and/or new files found"
+ LOG "creating archive \e[1;37;40m$ARCHIVE\e[m\e[35m ..."
+ tar -cjf $ARCHIVE --files-from $TMP/files
fi
exit 0