#!/bin/sh

# tree-diff --- recursive diff with options I typically use
# Author: Noah Friedman <friedman@splode.com>
# Public domain.

# $Id: tree-diff,v 1.9 2013/02/22 21:44:07 friedman Exp $

exclude_pats=${EXCLUDE_PATS-'
    CVS
    RCS
    {arch}
    .git
    .hg
    .svn
    _MTN

    .arch-ids
    .arch-inventory
    .cvsignore
    .gitignore
    .hgignore

    *~
    #*#
    .#*

    TAGS

    core
    core.[0-9]*
    *.core

    *.[ao]
    *.obj
    *.so
    lib*.so.*
    *.dll
    *.dylib
    *.elc
    *.class
    *.dvi

    autom4te.cache
    config.log
    config.status

'}${EXCLUDE_AC+'

    ChangeLog*
    Makefile
    Makefile.*
    config.guess
    config.sub
    configure
    configure.in
    config.h.in
    install-sh
    ltmain.sh
    *.m4
'}

set -o noglob

if diff --version 2>&1 | grep 'GNU' > /dev/null; then
  case $1 in
    --no-missing ) shift ;;
    * ) set fnord --new-file ${1+"$@"}; shift ;;
  esac

  for pat in $exclude_pats ; do
    set fnord --exclude "$pat" ${1+"$@"}
    shift
  done

  exec diff --ignore-blank-lines \
            --ignore-space-change \
            --recursive \
            --show-c-function \
            --unified \
         ${1+"$@"}
else
  echo "tree-diff: warning: not using GNU diff" 1>&2

  n=$#
  m=`expr $# - 1`
  eval "d1=\"\$$m\" d2=\"\$$n\""

  set fnord
  shift
  for pat in $exclude_pats ; do
    set fnord -o -name "$pat" ${1+"$@"}
    shift
  done
  shift # get rid of leading '-o'

  for dir in "$d1" "$d2"; do
    (cd "$dir" && find . \( ${1+"$@"} \) -prune -o -type f -print)
  done \
   | sort -u \
   | sed -e 's=^\./==' \
   | while read file ; do
       if [ -f "$d1/$file" ] && [ -f "$d2/$file" ]; then
         # Do all non-gnu versions of diff support -b?
         # solaris, irix, osf1, and hpux do.
         diff -b -c "$d1/$file" "$d2/$file"
       fi
     done
fi

# eof
