document mingw linker fix and close associated bug
[debian/gzip] / zgrep.in
1 #!/bin/sh
2
3 # zgrep -- a wrapper around a grep program that decompresses files as needed
4 # Adapted from a version sent by Charles Levert <charles@comm.polymtl.ca>
5
6 # Copyright (C) 1998, 2001-2002, 2006-2007, 2009-2018 Free Software Foundation,
7 # Inc.
8
9 # Copyright (C) 1993 Jean-loup Gailly
10
11 # This program is free software; you can redistribute it and/or modify
12 # it under the terms of the GNU General Public License as published by
13 # the Free Software Foundation; either version 3 of the License, or
14 # (at your option) any later version.
15
16 # This program is distributed in the hope that it will be useful,
17 # but WITHOUT ANY WARRANTY; without even the implied warranty of
18 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 # GNU General Public License for more details.
20
21 # You should have received a copy of the GNU General Public License along
22 # with this program; if not, write to the Free Software Foundation, Inc.,
23 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24
25 grep='${GREP-'\''@GREP@'\''}'
26
27 version='zgrep (gzip) @VERSION@
28 Copyright (C) 2010-2018 Free Software Foundation, Inc.
29 This is free software.  You may redistribute copies of it under the terms of
30 the GNU General Public License <https://www.gnu.org/licenses/gpl.html>.
31 There is NO WARRANTY, to the extent permitted by law.
32
33 Written by Jean-loup Gailly.'
34
35 usage="Usage: $0 [OPTION]... [-e] PATTERN [FILE]...
36 Look for instances of PATTERN in the input FILEs, using their
37 uncompressed contents if they are compressed.
38
39 OPTIONs are the same as for 'grep', except that the following 'grep'
40 options are not supported: --dereference-recursive (-R), --directories (-d),
41 --exclude, --exclude-from, --exclude-dir, --include, --null (-Z),
42 --null-data (-z), and --recursive (-r).
43
44 Report bugs to <bug-gzip@gnu.org>."
45
46 # sed script to escape all ' for the shell, and then (to handle trailing
47 # newlines correctly) append ' to the last line.
48 escape='
49   s/'\''/'\''\\'\'''\''/g
50   $s/$/'\''/
51 '
52 operands=
53 have_pat=0
54 files_with_matches=0
55 files_without_matches=0
56 no_filename=0
57 with_filename=0
58 pattmp=
59
60 while test $# -ne 0; do
61   option=$1
62   shift
63   optarg=
64
65   case $option in
66   (-[0123456789EFGHIKLPRTUVZabchilnoqrsuvwxyz]*[!0123456789]*)
67     arg2=-\'$(expr "X$option" : 'X-.[0-9]*\(.*\)' | sed "$escape")
68     eval "set -- $arg2 "'${1+"$@"}'
69     option=$(expr "X$option" : 'X\(-.[0-9]*\)');;
70   (--binary-*=* | --[lm]a*=* | --reg*=*)
71     ;;
72   (-[ABCDXdefm] | binary-* | --file | --[lm]a* | --reg*)
73     case ${1?"$option option requires an argument"} in
74     (*\'*)
75       optarg=" '"$(printf '%s\n' "$1" | sed "$escape");;
76     (*)
77       optarg=" '$1'";;
78     esac
79     shift;;
80   (-f?*\'*)
81     optarg=" '"$(expr "X$option" : 'X-f\(.*\)' | sed "$escape")
82     option=-f;;
83   (-f?*)
84     optarg=" '"$(expr "X$option" : 'X-f\(.*\)')\'
85     option=-f;;
86   (--file=*\'*)
87     optarg=" '"$(expr "X$option" : 'X--file=\(.*\)' | sed "$escape")
88     option=--file;;
89   (--file=*)
90     optarg=" '"$(expr "X$option" : 'X--file=\(.*\)')\'
91     option=--file;;
92   (--)
93     break;;
94   (-?*)
95     ;;
96   (*)
97     case $option in
98     (*\'*)
99       operands="$operands '"$(printf '%s\n' "$option" | sed "$escape");;
100     (*)
101       operands="$operands '$option'";;
102     esac
103     ${POSIXLY_CORRECT+break}
104     continue;;
105   esac
106
107   case $option in
108   (-[drRzZ] | --di* | --exc* | --inc* | --rec* | --nu*)
109     printf >&2 '%s: %s: option not supported\n' "$0" "$option"
110     exit 2;;
111   (-e* | --reg*)
112     have_pat=1;;
113   (-f | --file)
114     # The pattern is coming from a file rather than the command-line.
115     # If the file is actually stdin then we need to do a little
116     # magic, since we use stdin to pass the gzip output to grep.
117     # Similarly if it is not a regular file, since it might be read repeatedly.
118     # In either of these two cases, copy the pattern into a temporary file,
119     # and use that file instead.  The pattern might contain null bytes,
120     # so we cannot simply switch to -e here.
121     if case $optarg in
122        (" '-'" | " '/dev/stdin'" | " '/dev/fd/0'")
123          :;;
124        (*)
125          eval "test ! -f$optarg";;
126        esac
127     then
128       if test -n "$pattmp"; then
129         eval "cat --$optarg" >>"$pattmp" || exit 2
130         continue
131       fi
132       trap '
133         test -n "$pattmp" && rm -f "$pattmp"
134         (exit 2); exit 2
135       ' HUP INT PIPE TERM 0
136       case $TMPDIR in
137         / | /*/) ;;
138         /*) TMPDIR=$TMPDIR/;;
139         *) TMPDIR=/tmp/;;
140       esac
141       if type mktemp >/dev/null 2>&1; then
142         pattmp=$(mktemp "${TMPDIR}zgrepXXXXXXXXX") || exit 2
143       else
144         set -C
145         pattmp=${TMPDIR}zgrep$$
146       fi
147       eval "cat --$optarg" >"$pattmp" || exit 2
148       optarg=' "$pattmp"'
149     fi
150     have_pat=1;;
151   (--h | --he | --hel | --help)
152     printf '%s\n' "$usage" || exit 2
153     exit;;
154   (-H | --wi | --wit | --with | --with- | --with-f | --with-fi \
155   | --with-fil | --with-file | --with-filen | --with-filena | --with-filenam \
156   | --with-filename)
157     with_filename=1
158     continue;;
159   (-l | --files-with-*)
160     files_with_matches=1;;
161   (-L | --files-witho*)
162     files_without_matches=1;;
163   (-h | --no-f*)
164     no_filename=1;;
165   (-V | --v | --ve | --ver | --vers | --versi | --versio | --version)
166     printf '%s\n' "$version" || exit 2
167     exit;;
168   esac
169
170   case $option in
171   (*\'?*)
172     option=\'$(printf '%s\n' "$option" | sed "$escape");;
173   (*)
174     option="'$option'";;
175   esac
176
177   grep="$grep $option$optarg"
178 done
179
180 eval "set -- $operands "'${1+"$@"}'
181
182 if test $have_pat -eq 0; then
183   case ${1?"missing pattern; try \`$0 --help' for help"} in
184   (*\'*)
185     grep="$grep -- '"$(printf '%s\n' "$1" | sed "$escape");;
186   (*)
187     grep="$grep -- '$1'";;
188   esac
189   shift
190 fi
191
192 if test $# -eq 0; then
193   set -- -
194 fi
195
196 exec 3>&1
197 res=1
198
199 for i
200 do
201   # Fail if gzip or grep (or sed) fails.
202   gzip_status=$(
203     exec 5>&1
204     (gzip -cdfq -- "$i" 5>&-; echo $? >&5) 3>&- |
205     if test $files_with_matches -eq 1; then
206       eval "$grep" >/dev/null && { printf '%s\n' "$i" || exit 2; }
207     elif test $files_without_matches -eq 1; then
208       eval "$grep" >/dev/null || {
209         r=$?
210         if test $r -eq 1; then
211           printf '%s\n' "$i" || r=2
212         fi
213         test 256 -le $r && r=$(expr 128 + $r % 128)
214         exit $r
215       }
216     elif test $with_filename -eq 0 &&
217          { test $# -eq 1 || test $no_filename -eq 1; }; then
218       eval "$grep"
219     else
220       case $i in
221       (*'
222 '* | *'&'* | *'\'* | *'|'*)
223         i=$(printf '%s\n' "$i" |
224             sed '
225               $!N
226               $s/[&\|]/\\&/g
227               $s/\n/\\n/g
228             ');;
229       esac
230       sed_script="s|^|$i:|"
231
232       # Fail if grep or sed fails.
233       r=$(
234         exec 4>&1
235         (eval "$grep" 4>&-; echo $? >&4) 3>&- | sed "$sed_script" >&3 4>&-
236       ) || { r=$?; test $r -lt 2 && r=2; }
237       test 256 -le $r && r=$(expr 128 + $r % 128)
238       exit $r
239     fi >&3 5>&-
240   )
241   r=$?
242
243   # Ignore gzip status 2, as it is just a warning.
244   # gzip status 1 is an error, like grep status 2.
245   test $gzip_status -eq 2 && gzip_status=0
246   test $gzip_status -eq 1 && gzip_status=2
247
248   # Use the more serious of the grep and gzip statuses.
249   test $r -lt $gzip_status && r=$gzip_status
250
251   # Accumulate the greatest status, except consider 0 to be greater than 1.
252   if test $r -le 1 && test $res -le 1; then
253      test $r -lt $res
254   else
255      test $res -lt $r
256   fi && res=$r
257
258   # Exit immediately on a serious error.
259   test 126 -le $res && break
260 done
261
262 if test -n "$pattmp"; then
263   rm -f "$pattmp" || {
264     r=$?
265     test $r -lt 2 && r=2
266     test $res -lt $r && res=$r
267   }
268   trap - HUP INT PIPE TERM 0
269 fi
270
271 test 128 -le $res && kill -$(expr $res % 128) $$
272 exit $res