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