1#! /usr/bin/env tcsh
2
3set prog = `basename $0`
4
5set exit_on_missing = 1
6set list_missing = 1
7set longlist = 0
8set showfiles = 1
9set showdiffs = 0
10set savediffs = 0
11set xxdiff = 0
12set diffprog = ''       # can pass any, like xxdiff
13set diffopts = ()
14set verb = 1
15
16if ( $#argv < 2 ) then
17    goto SHOW_HELP
18endif
19
20set ac = 1
21while ( $ac < $#argv )
22    if ( "$argv[$ac]" == '-save' ) then
23        set savediffs = 1
24        @ ac ++
25    else if ( "$argv[$ac]" == '-ignore_missing' || "$argv[$ac]" == '-im' ) then
26        set exit_on_missing = 0
27        @ ac ++
28    else if ( "$argv[$ac]" == '-ll' || "$argv[$ac]" == '-longlist' ) then
29        set longlist = 1
30        @ ac ++
31    else if ( "$argv[$ac]" == '-show' ) then
32        set showdiffs = 1
33        set showfiles = 0
34        @ ac ++
35    else if ( "$argv[$ac]" == '-xxdiff' ) then
36        set xxdiff = 1
37        if ( "$diffprog" != "" ) then
38           echo "** only specify one of -xxdiff -diffprog"
39           exit 1
40        endif
41        # no longer call xxdiff explicitly
42        set diffprog = xxdiff
43        @ ac ++
44    else if ( "$argv[$ac]" == '-diff_opts' ) then
45        @ ac ++
46        set diffopts = ( $diffopts $argv[$ac] )
47        @ ac ++
48    else if ( "$argv[$ac]" == '-diff_prog' ) then
49        @ ac ++
50        set diffprog = "$argv[$ac]"
51        if ( $xxdiff ) then
52           echo "** only specify one of -xxdiff -diffprog"
53           exit 1
54        endif
55        @ ac ++
56    else if ( "$argv[$ac]" == '-X' ) then
57        set xxdiff = 1
58        set diffprog = xxdiff
59        set exit_on_missing = 0
60        @ ac ++
61    else if ( "$argv[$ac]" == '-verb' ) then
62        @ ac ++
63        set verb = "$argv[$ac]"
64        @ ac ++
65        if ( $verb > 2 ) then
66           set echo
67        endif
68    else
69        break
70    endif
71end
72
73if ( $verb > 1 ) then
74   set list_missing = 1
75endif
76
77# if a diffprog is requested, make sure it exists...
78if ( $diffprog != "" ) then
79   which $diffprog >& /dev/null
80   if ( $status ) then
81      echo "** $prog : missing Unix program $diffprog (please install)"
82      exit
83   endif
84endif
85
86# default to pdf output, but use ps if ps2pdf is not there
87# (** temporary change to ps output - ps2pdf is crashing **)
88set useps = 0
89which ps2pdf >& /dev/null
90if ( $status ) then
91    set useps = 1
92endif
93
94@ last = $#argv - 1
95
96set odir = $argv[$#argv]
97@ nfiles = $#argv - $ac
98
99set files = ( $argv[$ac-$last] )
100
101if ( ! -d $odir ) then
102    echo missing comparison directory: $odir
103    exit
104endif
105
106# see if all of the files exist
107set missA = 0
108set missB = 0
109foreach file ( $files )
110    if ( ! -e $file ) then
111        echo missing A: $file
112        @ missA ++
113    endif
114end
115foreach file ( $files )
116    if ( ! -e $odir/$file ) then
117        echo missing B: $odir/$file
118        @ missB ++
119    endif
120end
121
122if ( $missA || $missB ) then
123   if ( $exit_on_missing ) exit
124
125   # ls missing files
126   if ( $list_missing ) then
127      echo "==== missing files ($missA and $missB) ===="
128      foreach file ( $files )
129          if ( -e $file && ! -e $odir/$file ) then
130              ls -ld $file
131          endif
132      end
133      foreach file ( $files )
134          if ( ! -e $file && -e $odir/$file ) then
135              ls -ld $odir/$file
136          endif
137      end
138   echo ""
139   echo "   ... done with missing, on to diffs ..."
140
141   endif
142
143   echo ""
144
145endif
146
147# remove directories and missing files
148set newfiles = ()
149foreach file ( $files )
150    if ( -f $file && -f $odir/$file ) then
151        set newfiles = ( $newfiles $file )
152    endif
153end
154
155set files = ( $newfiles )
156
157
158# prepare diffs directory
159if ( $savediffs ) then
160    if ( -d diffs ) then
161        echo removing old diff files...
162        \rm -f diffs/* >& /dev/null
163    else
164        mkdir diffs
165        if ( $status ) then
166            echo failed to make diffs dir, exiting...
167            exit
168        endif
169    endif
170endif
171
172# check for diffs
173set count = 0
174foreach file ( $files )
175    cmp -s $file $odir/$file
176    set result = $status
177    if ( $result ) then
178        if ( $showdiffs ) then
179            echo --------------------- $file ---------------------
180            diff $diffopts $file $odir/$file
181        endif
182
183        if ( $longlist ) then
184           ls -l $file $odir/$file
185           echo ""
186        else if ( $showfiles ) then
187           if ( $verb > 1 ) then
188              echo "    diff: $file"
189           else
190              echo "    $file"
191           endif
192        endif
193        @ count ++
194
195        if ( $diffprog != "" ) then
196           $diffprog $file $odir/$file
197        endif
198
199        if ( $savediffs ) then
200            set dfile = `echo $file | sed 's/\//./g'`
201            diff $diffopts $file $odir/$file > diffs/$dfile.txt
202            if ( $useps ) then
203                diff -bB $odir/$file $file | diffpp $odir/$file \
204                         | enscript -Ge -p diffs/$dfile.ps
205            else
206                diff -bB $odir/$file $file | diffpp $odir/$file \
207                         | enscript -Ge -p - | ps2pdf - diffs/$dfile.pdf
208            endif
209        endif
210    else if ( $verb > 1 ) then
211       echo "    no diff: $file"
212    endif
213end
214
215if ( $count > 0 ) then
216    echo ""
217    echo $count diffs found
218endif
219
220exit
221SHOW_HELP:
222
223cat << EOF
224
225   ----------------------------------------------------------------------
226   $prog - show file differences (between "these" files and "those" files)
227
228      Given:
229         - a list of files
230         - a directory name
231
232      Show files that differ (and/or their differences) between each file
233      in the given list and its corresponding file in the other directory.
234
235      This is similar to @diff.tree, except that one main input is a list
236      of files.
237
238   ----------------------------------------------------------------------
239   usage: $prog [options] file1 file2 ... old_dir
240
241   ----------------------------------------------------------------------
242   options:
243      -diff_opts 'OPTS'  : add options to diff command
244                           e.g. -diff_opts -w
245      -diff_prog DPROG   : display diffs using DPROG (probably graphical)
246                           e.g. -diff_opts meld
247                           e.g. -diff_opts xxdiff    [same as -xxdiff]
248                           Consider also: kdiff3, tkdiff.
249      -ignore_missing    : continue even if files are missing
250                           alt: -im
251      -longlist          : instead of listing file, run 'ls -l' on both
252                           alt: -ll
253      -save              : create pdfs of diffs
254      -show              : show diffs using 'diff'
255      -xxdiff            : show diffs using 'xxdiff'
256      -X                 : implies -xxdiff and -ignore_missing'
257      -verb LEVEL        : be more chatty at 2 (set echo at 3)
258
259   ----------------------------------------------------------------------
260   examples:
261
262      $prog file1             some/other/directory
263      $prog file1 file2 file3 some/other/directory
264      $prog *                 some/other/directory
265
266      $prog -im *             some/other/directory
267      $prog -X  *             some/other/directory
268
269   ----------------------------------------------------------------------
270   R Reynolds    written ages ago, but added 10 Jun, 2015
271   ----------------------------------------
272
273EOF
274