xref: /dragonfly/contrib/xz/src/scripts/xzdiff.in (revision c69bf40f)
1#!@POSIX_SHELL@
2
3# Copyright (C) 1998, 2002, 2006, 2007 Free Software Foundation
4# Copyright (C) 1993 Jean-loup Gailly
5
6# Modified for XZ Utils by Andrew Dudman and Lasse Collin.
7
8# This program is free software; you can redistribute it and/or modify
9# it under the terms of the GNU General Public License as published by
10# the Free Software Foundation; either version 2 of the License, or
11# (at your option) any later version.
12
13# This program is distributed in the hope that it will be useful,
14# but WITHOUT ANY WARRANTY; without even the implied warranty of
15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16# GNU General Public License for more details.
17
18#SET_PATH - This line is a placeholder to ease patching this script.
19
20# Instead of unsetting XZ_OPT, just make sure that xz will use file format
21# autodetection. This way memory usage limit and thread limit can be
22# specified via XZ_OPT. With gzip, bzip2, and lzop it's OK to just unset the
23# environment variables.
24xz='@xz@ --format=auto'
25unset GZIP BZIP BZIP2 LZOP
26
27case ${0##*/} in
28  *cmp*) prog=xzcmp; cmp=${CMP:-cmp};;
29  *)     prog=xzdiff; cmp=${DIFF:-diff};;
30esac
31
32version="$prog (@PACKAGE_NAME@) @VERSION@"
33
34usage="Usage: ${0##*/} [OPTION]... FILE1 [FILE2]
35Compare FILE1 to FILE2, using their uncompressed contents if they are
36compressed.  If FILE2 is omitted, then the files compared are FILE1 and
37FILE1 from which the compression format suffix has been stripped.
38
39Do comparisons like '$cmp' does.  OPTIONs are the same as for '$cmp'.
40
41Report bugs to <@PACKAGE_BUGREPORT@>."
42
43# sed script to escape all ' for the shell, and then (to handle trailing
44# newlines correctly) turn trailing X on last line into '.
45escape='
46  s/'\''/'\''\\'\'''\''/g
47  $s/X$/'\''/
48'
49
50while :; do
51  case $1 in
52    --h*) printf '%s\n' "$usage" || exit 2; exit;;
53    --v*) echo "$version" || exit 2; exit;;
54    --) shift; break;;
55    -*\'*) cmp="$cmp '"`printf '%sX\n' "$1" | sed "$escape"`;;
56    -?*) cmp="$cmp '$1'";;
57    *) break;;
58  esac
59  shift
60done
61cmp="$cmp --"
62
63for file; do
64  test "X$file" = X- || <"$file" || exit 2
65done
66
67xz1=$xz
68xz2=$xz
69xz_status=0
70exec 3>&1
71
72if test $# -eq 1; then
73  case $1 in
74    *[-.]xz | *[-.]lzma | *.t[lx]z)
75      ;;
76    *[-.]bz2 | *.tbz | *.tbz2)
77      xz1=bzip2;;
78    *[-.][zZ] | *_z | *[-.]gz | *.t[ag]z)
79      xz1=gzip;;
80    *[-.]lzo | *.tzo)
81      xz1=lzop;;
82    *)
83      echo >&2 "$0: $1: Unknown compressed file name suffix"
84      exit 2;;
85  esac
86  case $1 in
87    *[-.][zZ] | *_z | *[-.][gx]z | *[-.]bz2 | *[-.]lzma | *[-.]lzo)
88      FILE=`expr "X$1" : 'X\(.*\)[-.][abglmoxzZ2]*$'`;;
89    *.t[abglx]z)
90      FILE=`expr "X$1" : 'X\(.*[-.]t\)[abglx]z$'`ar;;
91    *.tbz2)
92      FILE=`expr "X$1" : 'X\(.*[-.]t\)bz2$'`ar;;
93    *.tzo)
94      FILE=`expr "X$1" : 'X\(.*[-.]t\)zo$'`ar;;
95  esac
96  xz_status=$(
97    exec 4>&1
98    ($xz1 -cd -- "$1" 4>&-; echo $? >&4) 3>&- | eval "$cmp" - '"$FILE"' >&3
99  )
100elif test $# -eq 2; then
101  case $1 in
102    *[-.]bz2 | *.tbz | *.tbz2) xz1=bzip2;;
103    *[-.][zZ] | *_z | *[-.]gz | *.t[ag]z) xz1=gzip;;
104    *[-.]lzo | *.tzo) xz1=lzop;;
105  esac
106  case $2 in
107    *[-.]bz2 | *.tbz | *.tbz2) xz2=bzip2;;
108    *[-.][zZ] | *_z | *[-.]gz | *.t[ag]z) xz2=gzip;;
109    *[-.]lzo | *.tzo) xz2=lzop;;
110  esac
111  case $1 in
112    *[-.][zZ] | *_z | *[-.][gx]z | *[-.]bz2 | *[-.]lzma | *.t[abglx]z | *.tbz2 | *[-.]lzo | *.tzo | -)
113      case "$2" in
114        *[-.][zZ] | *_z | *[-.][gx]z | *[-.]bz2 | *[-.]lzma | *.t[abglx]z | *.tbz2 | *[-.]lzo | *.tzo | -)
115          if test "$1$2" = --; then
116            xz_status=$(
117              exec 4>&1
118              ($xz1 -cdfq - 4>&-; echo $? >&4) 3>&- |
119                eval "$cmp" - - >&3
120            )
121          elif # Reject Solaris 8's buggy /bin/bash 2.03.
122              echo X | (echo X | eval "$cmp" /dev/fd/5 - >/dev/null 2>&1) 5<&0; then
123            xz_status=$(
124              exec 4>&1
125              ($xz1 -cdfq -- "$1" 4>&-; echo $? >&4) 3>&- |
126                ( ($xz2 -cdfq -- "$2" 4>&-; echo $? >&4) 3>&- 5<&- </dev/null |
127                eval "$cmp" /dev/fd/5 - >&3) 5<&0
128            )
129            cmp_status=$?
130            case $xz_status in
131              *[1-9]*) xz_status=1;;
132              *) xz_status=0;;
133            esac
134            (exit $cmp_status)
135          else
136            F=`expr "/$2" : '.*/\(.*\)[-.][ablmotxz2]*$'` || F=$prog
137            tmp=
138            trap '
139              test -n "$tmp" && rm -rf "$tmp"
140              (exit 2); exit 2
141            ' HUP INT PIPE TERM 0
142            if type mktemp >/dev/null 2>&1; then
143              # Note that FreeBSD's mktemp isn't fully compatible with
144              # the implementations from mktemp.org and GNU coreutils.
145              # It is important that the -t argument is the last argument
146              # and that no "--" is used between -t and the template argument.
147              # This way this command works on all implementations.
148              tmp=`mktemp -d -t "$prog.XXXXXXXXXX"` || exit 2
149            else
150              # Fallback code if mktemp is missing. This isn't as
151              # robust as using mktemp since this doesn't try with
152              # different file names in case of a file name conflict.
153              #
154              # There's no need to save the original umask since
155              # we don't create any non-temp files. Note that using
156              # mkdir -m 0077 isn't secure since some mkdir implementations
157              # create the dir with the default umask and chmod the
158              # the dir afterwards.
159              umask 0077
160              mkdir -- "${TMPDIR-/tmp}/$prog.$$" || exit 2
161              tmp="${TMPDIR-/tmp}/$prog.$$"
162            fi
163            $xz2 -cdfq -- "$2" > "$tmp/$F" || exit 2
164            xz_status=$(
165              exec 4>&1
166              ($xz1 -cdfq -- "$1" 4>&-; echo $? >&4) 3>&- |
167                eval "$cmp" - '"$tmp/$F"' >&3
168            )
169            cmp_status=$?
170            rm -rf "$tmp" || xz_status=$?
171            trap - HUP INT PIPE TERM 0
172            (exit $cmp_status)
173          fi;;
174      *)
175        xz_status=$(
176          exec 4>&1
177          ($xz1 -cdfq -- "$1" 4>&-; echo $? >&4) 3>&- |
178            eval "$cmp" - '"$2"' >&3
179        );;
180    esac;;
181  *)
182    case "$2" in
183      *[-.][zZ] | *_z | *[-.][gx]z | *[-.]bz2 | *[-.]lzma | *.t[abglx]z | *.tbz2 | *[-.]lzo | *.tzo | -)
184        xz_status=$(
185          exec 4>&1
186          ($xz2 -cdfq -- "$2" 4>&-; echo $? >&4) 3>&- |
187            eval "$cmp" '"$1"' - >&3
188         );;
189      *)
190        eval "$cmp" '"$1"' '"$2"';;
191    esac;;
192  esac
193else
194  echo >&2 "$0: Invalid number of operands; try \`${0##*/} --help' for help"
195  exit 2
196fi
197
198cmp_status=$?
199test "$xz_status" -eq 0 || exit 2
200exit $cmp_status
201