diff options
Diffstat (limited to 'diff/diff-daemon.sh')
-rw-r--r-- | diff/diff-daemon.sh | 156 |
1 files changed, 156 insertions, 0 deletions
diff --git a/diff/diff-daemon.sh b/diff/diff-daemon.sh new file mode 100644 index 0000000..daa258d --- /dev/null +++ b/diff/diff-daemon.sh @@ -0,0 +1,156 @@ +#!/bin/sh +name='diff-daemon' +ver=1.1 +# Copyright (C) 2009 Luke Shumaker +# +# This file is part of diff-daemon. +# +# diff-daemon is free software; you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2, or (at your option) any later version. +# +# diff-daemon is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with diff-daemon; see the file COPYING. +# If not, write to the Free Software Foundation, +# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +# count the number of times the char "$1" occurs in string "$2" +# note that the string can't contain any newlines. +chCount() { + char=$1 + string="$2" + echo "$string" | tr ':' '\n' | wc -l + # this returns the correct answer+1 + # this is OK for now, because it is only used for inequality +} + +l_common() { + # If they're the same, just echo one of them + if [ "$1" = "$2" ]; then + str="$1" + else + # it will be faster if the string with fewer #s is first + if [ "`chCount ':' "$1"`" -lt "`chCount ':' "$2"`" ]; then + a0="$1" + a1="$2" + else + a0="$2" + a1="$1" + fi + str='' + #for int in ${a0//:/: }; do # bash optimized version + for int in `echo "$a0" | tr ':' ' '`; do + str="$str`echo ":$a1" | sed -n "s/.*:\($int:\).*/\1/p"`" + done + fi + echo "$str" +} + +l_add() { + str='' + #for int in ${1//:/: }; do # bash optimized version + for int in `echo "$1" | tr ':' ' '`; do + str="$str`expr "$int" + "$2"`:" + done + echo "$str" +} + +# add a new line with contents $1 +print_new() { + echo "n$1" +} + +# insert $1 blank lines +# if $1 is not defined, default to 1 +print_blank() { + echo "b${1-1}" +} + +print_copy() { + if [ -n "$m1" ]; then + m1="`echo "$m1" | sed 's/:.*//'`" + if [ "$mi" = '0' ]; then + mp="${m1}" + else + m0="`expr $m1 - $mi`" + mp="$m0,$m1" + fi + if [ -z "`sed -n "$mp p" "$file0"`" ]; then + print_blank "`expr 1 + $m1 - $m0`" + else + echo "c$mp" + fi + fi +} + +print_uniq() { + if [ -n "$line" ]; then + print_new "$line" + else + print_blank + fi +} + +matches() { + grep -n "^$line$" "$file0" | cut -d ':' -f 1 | tr '\n' ':' +} + +# main loop + +file0="$1" +file1="$2" + +i='1' +c=`wc -l "$file1" | cut -d ' ' -f 1` +while [ "$i" -le "$c" ]; do + line="`sed -n "$i p" "$file1"`" + + # it should be simpler to count the `:'s in $m1 + ms="`echo "$m1" | sed 's/:.*//'`" + #echo "ms=$ms" + if [ -n "$m1" ] && [ "$m1" = "$ms:" ]; then + #echo "yay $ms" + ret1="`expr $ms + 1`" + if [ "$line" = "`sed -n "$ret1 p" "$file0"`" ]; then + m1="$ret1:" + mi=`expr "$mi" + 1` + else + print_copy + m1="`matches`" + if [ -n "$m1" ]; then + # start new trend + mi='0' + else + print_uniq + fi + fi + else + matches="`matches`" + if [ -n "$matches" ]; then + ret1=`l_common "$matches" "$(l_add "$m1" '1')"` + if [ -n "$ret1" ]; then + # continue trend + m1="$ret1" + mi=`expr "$mi" + 1` + else + # start new trend + print_copy + m1="$matches" + mi='0' + fi + else + print_copy + m1='' + print_uniq + fi + fi + + i=`expr $i + 1` +done +print_copy + |