Merge tag 'upstream/1.6'
[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, 2010 Free Software
7 # Foundation
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 bindir=@bindir@
26 case $1 in
27 --__bindir) bindir=${2?}; shift; shift;;
28 esac
29 PATH=$bindir:$PATH
30
31 grep='${GREP-'\''@GREP@'\''}'
32
33 version='zgrep (gzip) @VERSION@
34 Copyright (C) 2010-2013 Free Software Foundation, Inc.
35 This is free software.  You may redistribute copies of it under the terms of
36 the GNU General Public License <http://www.gnu.org/licenses/gpl.html>.
37 There is NO WARRANTY, to the extent permitted by law.
38
39 Written by Jean-loup Gailly.'
40
41 usage="Usage: $0 [OPTION]... [-e] PATTERN [FILE]...
42 Look for instances of PATTERN in the input FILEs, using their
43 uncompressed contents if they are compressed.
44
45 OPTIONs are the same as for 'grep'.
46
47 Report bugs to <bug-gzip@gnu.org>."
48
49 # sed script to escape all ' for the shell, and then (to handle trailing
50 # newlines correctly) append ' to the last line.
51 escape='
52   s/'\''/'\''\\'\'''\''/g
53   $s/$/'\''/
54 '
55 operands=
56 have_pat=0
57 files_with_matches=0
58 files_without_matches=0
59 no_filename=0
60 with_filename=0
61
62 while test $# -ne 0; do
63   option=$1
64   shift
65   optarg=
66
67   case $option in
68   (-[0123456789EFGHIKLPRTUVZabchilnoqrsuvwxyz]*[!0123456789]*)
69     arg2=-\'$(expr "X$option" : 'X-.[0-9]*\(.*\)' | sed "$escape")
70     eval "set -- $arg2 "'${1+"$@"}'
71     option=$(expr "X$option" : 'X\(-.[0-9]*\)');;
72   (--binary-*=* | --[lm]a*=* | --reg*=*)
73     ;;
74   (-[ABCDXdefm] | binary-* | --file | --[lm]a* | --reg*)
75     case ${1?"$option option requires an argument"} in
76     (*\'*)
77       optarg=" '"$(printf '%s\n' "$1" | sed "$escape");;
78     (*)
79       optarg=" '$1'";;
80     esac
81     shift;;
82   (-f?*\'*)
83     optarg=" '"$(expr "X$option" : 'X-f\(.*\)' | sed "$escape")
84     option=-f;;
85   (-f?*)
86     optarg=" '"$(expr "X$option" : 'X-f\(.*\)')\'
87     option=-f;;
88   (--file=*\'*)
89     optarg=" '"$(expr "X$option" : 'X--file=\(.*\)' | sed "$escape")
90     option=--file;;
91   (--file=*)
92     optarg=" '"$(expr "X$option" : 'X--file=\(.*\)')\'
93     option=--file;;
94   (--)
95     break;;
96   (-?*)
97     ;;
98   (*)
99     case $option in
100     (*\'*)
101       operands="$operands '"$(printf '%s\n' "$option" | sed "$escape");;
102     (*)
103       operands="$operands '$option'";;
104     esac
105     ${POSIXLY_CORRECT+break}
106     continue;;
107   esac
108
109   case $option in
110   (-[drRzZ] | --di* | --exc* | --inc* | --rec* | --nu*)
111     printf >&2 '%s: %s: option not supported\n' "$0" "$option"
112     exit 2;;
113   (-e* | --reg*)
114     have_pat=1;;
115   (-f | --file)
116     # The pattern is coming from a file rather than the command-line.
117     # If the file is actually stdin then we need to do a little
118     # magic, since we use stdin to pass the gzip output to grep.
119     # Turn the -f option into an -e option by copying the file's
120     # contents into OPTARG.
121     case $optarg in
122     (" '-'" | " '/dev/stdin'" | " '/dev/fd/0'")
123       option=-e
124       optarg=" '"$(sed "$escape") || exit 2;;
125     esac
126     have_pat=1;;
127   (--h | --he | --hel | --help)
128     echo "$usage" || exit 2
129     exit;;
130   (-H | --wi | --wit | --with | --with- | --with-f | --with-fi \
131   | --with-fil | --with-file | --with-filen | --with-filena | --with-filenam \
132   | --with-filename)
133     with_filename=1
134     continue;;
135   (-l | --files-with-*)
136     files_with_matches=1;;
137   (-L | --files-witho*)
138     files_without_matches=1;;
139   (-h | --no-f*)
140     no_filename=1;;
141   (-V | --v | --ve | --ver | --vers | --versi | --versio | --version)
142     echo "$version" || exit 2
143     exit;;
144   esac
145
146   case $option in
147   (*\'?*)
148     option=\'$(printf '%s\n' "$option" | sed "$escape");;
149   (*)
150     option="'$option'";;
151   esac
152
153   grep="$grep $option$optarg"
154 done
155
156 eval "set -- $operands "'${1+"$@"}'
157
158 if test $have_pat -eq 0; then
159   case ${1?"missing pattern; try \`$0 --help' for help"} in
160   (*\'*)
161     grep="$grep -- '"$(printf '%s\n' "$1" | sed "$escape");;
162   (*)
163     grep="$grep -- '$1'";;
164   esac
165   shift
166 fi
167
168 if test $# -eq 0; then
169   set -- -
170 fi
171
172 exec 3>&1
173 res=0
174
175 for i
176 do
177   # Fail if gzip or grep (or sed) fails.
178   gzip_status=$(
179     exec 5>&1
180     (gzip -cdfq -- "$i" 5>&-; echo $? >&5) 3>&- |
181     if test $files_with_matches -eq 1; then
182       eval "$grep" >/dev/null && { printf '%s\n' "$i" || exit 2; }
183     elif test $files_without_matches -eq 1; then
184       eval "$grep" >/dev/null || {
185         r=$?
186         if test $r -eq 1; then
187           printf '%s\n' "$i" || r=2
188         fi
189         exit $r
190       }
191     elif test $with_filename -eq 0 &&
192          { test $# -eq 1 || test $no_filename -eq 1; }; then
193       eval "$grep"
194     else
195       case $i in
196       (*'
197 '* | *'&'* | *'\'* | *'|'*)
198         i=$(printf '%s\n' "$i" |
199             sed '
200               $!N
201               $s/[&\|]/\\&/g
202               $s/\n/\\n/g
203             ');;
204       esac
205       sed_script="s|^|$i:|"
206
207       # Fail if grep or sed fails.
208       r=$(
209         exec 4>&1
210         (eval "$grep" 4>&-; echo $? >&4) 3>&- | sed "$sed_script" >&3 4>&-
211       ) && exit $r
212       r=$?
213       test 1 -lt $r && exit $r || exit 2
214     fi >&3 5>&-
215   )
216   r=$?
217   test 128 -lt $r && exit $r
218   test "$gzip_status" -eq 0 || test "$gzip_status" -eq 2 || r=2
219   test $res -lt $r && res=$r
220 done
221 exit $res