On 3/7/22 18:22, Lv Ying via GNU gzip discussion and bug reports. wrote:
However this manual separation job can not handle filename before options.
...
getopt command from util-linux can handle such situation
We try to keep gzip portable to a wide variety of platforms, even those
with ancient shells that lack getopt. I reworked zdiff.in to handle
filenames before options (without using getopt) and installed the
attached additional patch.
Please let us know of further problems by replying to this email and
cc'ing to 54...@debbugs.gnu.org (there should be no need to open a new
bug report).From bb184b98c27fa46826eaa2f6272cb4d6eacc75a8 Mon Sep 17 00:00:00 2001
From: Paul Eggert <egg...@cs.ucla.edu>
Date: Tue, 8 Mar 2022 13:02:37 -0800
Subject: [PATCH] zdiff: fix another arg-handling bug
Also allow args after file names.
Problem reported by Lv Ying <https://bugs.gnu.org/54290#12>.
---
zdiff.in | 127 ++++++++++++++++++++++++++++++++-----------------------
1 file changed, 75 insertions(+), 52 deletions(-)
diff --git a/zdiff.in b/zdiff.in
index d982d9f..593cb6e 100644
--- a/zdiff.in
+++ b/zdiff.in
@@ -48,60 +48,85 @@ escape='
$s/X$/'\''/
'
-while :; do
- argdone=:
- case $1 in
+filesonly=
+file1=
+file2=
+needop=
+
+for arg
+do
+ case $filesonly$needop$arg in
--h*) printf '%s\n' "$usage" || exit 2; exit;;
--v*) printf '%s\n' "$version" || exit 2; exit;;
- --) shift; break;;
- -*\'*) argdone=false arg=$1;;
- -[CDFISUWXx])
- cmp="$cmp $1"
- case ${2?} in
- -*\'*) argdone=false arg=$2;;
- *) cmp="$cmp '$2'";;
- esac
- shift;;
- -?*) cmp="$cmp '$1'";;
- *) break;;
+ --) filesonly=t;;
+ -*\'*) cmp="$cmp '"`printf '%sX\n' "$arg" | sed "$escape"`;;
+ -[CDFISUWXx]) needop="'$arg'";;
+ -?*) cmp="$cmp '$arg'";;
+ *) case $needop in
+ '') case $arg in
+ '') printf >&2 '%s\n' "$0: empty file name"; exit 2;;
+ esac
+ case $file1 in
+ '') file1=$arg;;
+ *) case $file2 in
+ '') file2=$arg;;
+ *) printf >&2 '%s\n' "$0: extra operand '$arg'"; exit 2;;
+ esac;;
+ esac;;
+ *) cmp="$cmp $needop '$arg'"
+ needop=;;
+ esac;;
esac
- $argdone || cmp="$cmp '"`printf '%sX\n' "$arg" | sed "$escape"`
- shift
done
+case $needop in
+'') ;;
+*) printf >&2 '%s\n' "$0: $prevarg: option requires an argument -- $needop"
+ exit 2;;
+esac
+
cmp="$cmp --"
-for file
-do
- test "X$file" = X- || <"$file" || exit 2
-done
+case $file1 in
+'') printf >&2 '%s\n' "$0: missing operand"; exit 2;;
+-) ;;
+*) <"$file1" || exit 2;;
+esac
+case $file2 in
+''|-) ;;
+*) <"$file2" || exit 2;;
+esac
gzip_status=0
exec 3>&1
-if test $# -eq 1; then
- case $1 in
+case $file2 in
+'')
+ case $file1 in
*[-.]gz* | *[-.][zZ] | *.t[ga]z)
- FILE=`expr "X$1" : 'X\(.*\)[-.][zZtga]*$'`
+ FILE=`expr "X$file1" : 'X\(.*\)[-.][zZtga]*$'`
gzip_status=$(
exec 4>&1
- (gzip -cd -- "$1" 4>&-; echo $? >&4) 3>&- | eval "$cmp" - '"$FILE"' >&3
+ (gzip -cd -- "$file1" 4>&-; echo $? >&4) 3>&- |
+ eval "$cmp" - '"$FILE"' >&3
);;
*)
- printf >&2 '%s\n' "$0: $1: unknown compressed file extension"
+ printf >&2 '%s\n' "$0: $file1: unknown compressed file extension"
exit 2;;
- esac
-elif test $# -eq 2; then
- case "$1" in
+ esac;;
+*)
+ case $file1,$file2 in
+ -,-)
+ gzip_status=$(
+ exec 4>&1
+ (gzip -cdfq - 4>&-; echo $? >&4) 3>&- |
+ eval "$cmp" - - >&3
+ );;
+ *)
+ case $file1 in
*[-.]gz* | *[-.][zZ] | *.t[ga]z | -)
- case "$2" in
+ case $file2 in
*[-.]gz* | *[-.][zZ] | *.t[ga]z | -)
- if test "$1$2" = --; then
- gzip_status=$(
- exec 4>&1
- (gzip -cdfq - 4>&-; echo $? >&4) 3>&- |
- eval "$cmp" - - >&3
- )
- elif
+ if
# Reject Solaris 8's buggy /bin/bash 2.03.
echo X |
(echo X | eval "$cmp" /dev/fd/5 - >/dev/null 2>&1) \
@@ -109,8 +134,9 @@ elif test $# -eq 2; then
then
gzip_status=$(
exec 4>&1
- (gzip -cdfq -- "$1" 4>&-; echo $? >&4) 3>&- |
- ( (gzip -cdfq -- "$2" 4>&-; echo $? >&4) 3>&- 5<&- </dev/null |
+ (gzip -cdfq -- "$file1" 4>&-; echo $? >&4) 3>&- |
+ ((gzip -cdfq -- "$file2" 4>&-
+ echo $? >&4) 3>&- 5<&- </dev/null |
eval "$cmp" /dev/fd/5 - >&3) 5<&0
)
cmp_status=$?
@@ -137,10 +163,10 @@ elif test $# -eq 2; then
set -C
tmp=${TMPDIR}zdiff$$
fi
- gzip -cdfq -- "$2" > "$tmp" || exit 2
+ gzip -cdfq -- "$file2" > "$tmp" || exit 2
gzip_status=$(
exec 4>&1
- (gzip -cdfq -- "$1" 4>&-; echo $? >&4) 3>&- |
+ (gzip -cdfq -- "$file1" 4>&-; echo $? >&4) 3>&- |
eval "$cmp" - '"$tmp"' >&3
)
cmp_status=$?
@@ -151,25 +177,22 @@ elif test $# -eq 2; then
*)
gzip_status=$(
exec 4>&1
- (gzip -cdfq -- "$1" 4>&-; echo $? >&4) 3>&- |
- eval "$cmp" - '"$2"' >&3
+ (gzip -cdfq -- "$file1" 4>&-; echo $? >&4) 3>&- |
+ eval "$cmp" - '"$file2"' >&3
);;
esac;;
- *) case "$2" in
+ *) case $file2 in
*[-.]gz* | *[-.][zZ] | *.t[ga]z | -)
gzip_status=$(
exec 4>&1
- (gzip -cdfq -- "$2" 4>&-; echo $? >&4) 3>&- |
- eval "$cmp" '"$1"' - >&3
+ (gzip -cdfq -- "$file2" 4>&-; echo $? >&4) 3>&- |
+ eval "$cmp" '"$file1"' - >&3
);;
- *) eval "$cmp" '"$1"' '"$2"';;
+ *) eval "$cmp" '"$file1"' '"$file2"';;
esac;;
- esac
-else
- printf >&2 '%s\n' \
- "$0: invalid number of operands; try \`$0 --help' for help"
- exit 2
-fi
+ esac;;
+ esac;;
+esac
cmp_status=$?
test "$gzip_status" -eq 0 || exit 2
--
2.35.1