Subject: Re: bug#18239: z suffix
From: Paul Eggert <[email-masked]>
To: Sam Geeraerts <[email-masked]>, [email-masked]
Date: Sun, 10 Aug 2014 16:31:10 -0700
List-Id: <debbugs-submit.debbugs.gnu.org>

Sam Geeraerts wrote:
> I've attached a patch
> that makes it work for me.

Thanks for re-reporting that.  I didn't see a patch in your email, but I 
installed one (attached); please give it a try.
From c52abdff05fa197539e162f070e14c0bbeab5e18 Mon Sep 17 00:00:00 2001
From: Paul Eggert <[email-masked]>
Date: Sun, 10 Aug 2014 16:29:06 -0700
Subject: [PATCH] gzip: fix --suffix=z bug (Bug#18239)

* gzip.c (get_suffix): Put --suffix string at the end
of the list of suffixes if it is a suffix of one one them.
* tests/z-suffix: New file.
* tests/Makefile.am (TESTS): Add it.
---
 gzip.c            | 22 ++++++++++++++++++----
 tests/Makefile.am |  1 +
 tests/z-suffix    | 30 ++++++++++++++++++++++++++++++
 3 files changed, 49 insertions(+), 4 deletions(-)
 create mode 100755 tests/z-suffix

diff --git a/gzip.c b/gzip.c
index 9c6849e..713a1c7 100644
--- a/gzip.c
+++ b/gzip.c
@@ -989,11 +989,25 @@ local char *get_suffix(name)
 #ifdef MAX_EXT_CHARS
           "z",
 #endif
-          NULL};
-    char const **suf = known_suffixes;
+        NULL, NULL};
+    char const **suf;
+    bool suffix_of_builtin = false;
 
-    *suf = z_suffix;
-    if (strequ(z_suffix, "z")) suf++; /* check long suffixes first */
+    /* Normally put Z_SUFFIX at the start of KNOWN_SUFFIXES, but if it
+       is a suffix of one of them, put it at the end.  */
+    for (suf = known_suffixes + 1; *suf; suf++)
+      {
+        size_t suflen = strlen (*suf);
+        if (z_len < suflen && strequ (z_suffix, *suf + suflen - z_len))
+          {
+            suffix_of_builtin = true;
+            break;
+          }
+      }
+    known_suffixes[suffix_of_builtin
+                   ? sizeof known_suffixes / sizeof *known_suffixes - 2
+                   : 0] = z_suffix;
+    suf = known_suffixes + suffix_of_builtin;
 
 #ifdef SUFFIX_SEP
     /* strip a version number from the file name */
diff --git a/tests/Makefile.am b/tests/Makefile.am
index b0a6d69..d1e934e 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -25,6 +25,7 @@ TESTS =					\
   stdin					\
   trailing-nul				\
   unpack-invalid			\
+  z-suffix				\
   zdiff					\
   zgrep-f				\
   zgrep-context				\
diff --git a/tests/z-suffix b/tests/z-suffix
new file mode 100755
index 0000000..de3a5fd
--- /dev/null
+++ b/tests/z-suffix
@@ -0,0 +1,30 @@
+#!/bin/sh
+# Check that -Sz works.
+
+# Copyright 2014 Free Software Foundation, Inc.
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+# limit so don't run it by default.
+
+. "${srcdir=.}/init.sh"; path_prepend_ ..
+
+printf anything > F && cp F G || framework_failure_
+gzip -Sz F || fail=1
+test ! -f F || fail=1
+test -f Fz || fail=1
+gzip -dSz F || fail=1
+test ! -f Fz || fail=1
+compare F G || fail\1
+
+Exit $fail
-- 
1.9.3