Hello,

as reported by Sven Joachim at 
http://lists.gnu.org/archive/html/bug-coreutils/2009-02/msg00264.html
current filevercmp implementation does not work well for hidden files. 
Attached patch fixes the strange behavior. It does not affect visible files. 
The only thing changed is the regular expression matching file suffix - there 
must be [^.] before suffix.


Kamil
From 595a83946c9846730c246321e043f03ec0653c15 Mon Sep 17 00:00:00 2001
From: Kamil Dudka <kdu...@redhat.com>
Date: Fri, 27 Feb 2009 14:56:19 +0100
Subject: [PATCH] filevercmp: fix regular expression of file suffix

* lib/filevercmp.c (match suffix): Change regular expression.
* lib/filevercmp.h: Update comment.
* tests/test-filevercmp.c: Enhance test.
---
 ChangeLog               |    7 +++++++
 lib/filevercmp.c        |    8 ++++++--
 lib/filevercmp.h        |    6 +++---
 tests/test-filevercmp.c |   10 ++++++++++
 4 files changed, 26 insertions(+), 5 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 9946a0c..c3468cb 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2009-02-27  Kamil Dudka  <kdu...@redhat.com>
+
+	filevercmp: fix regular expression of file suffix
+	* lib/filevercmp.c (match suffix): Change regular expression.
+	* lib/filevercmp.h: Update comment.
+	* tests/test-filevercmp.c: Enhance test.
+
 2009-02-27  Eric Blake  <e...@byu.net>
 
 	doc: mention more functions added in cygwin 1.7.0
diff --git a/lib/filevercmp.c b/lib/filevercmp.c
index 856f30f..513d8f2 100644
--- a/lib/filevercmp.c
+++ b/lib/filevercmp.c
@@ -27,7 +27,7 @@
 #include <limits.h>
 
 /* Match a file suffix defined by this regular expression:
-   /(\.[A-Za-z][A-Za-z0-9]*)*$/
+   /[^.](\.[A-Za-z][A-Za-z0-9]*)*$/
    Scan the string *STR and return a pointer to the matching suffix, or
    NULL if not found.  Upon return, *STR points to terminating NUL.  */
 static const char *
@@ -35,6 +35,7 @@ match_suffix (const char **str)
 {
   const char *match = NULL;
   bool read_alpha = false;
+  bool read_dot = false;
   while (**str)
     {
       if (read_alpha)
@@ -42,8 +43,11 @@ match_suffix (const char **str)
           read_alpha = false;
           if (!c_isalpha (**str))
             match = NULL;
+          continue;
         }
-      else if ('.' == **str)
+      if ('.' != **str)
+        read_dot = true;
+      else if (read_dot)
         {
           read_alpha = true;
           if (!match)
diff --git a/lib/filevercmp.h b/lib/filevercmp.h
index 569b4d0..bf244b1 100644
--- a/lib/filevercmp.h
+++ b/lib/filevercmp.h
@@ -32,9 +32,9 @@
    It returns number >0 for S1 > S2, 0 for S1 == S2 and number <0 for S1 < S2.
 
    This function compares strings, in a way that if VER1 and VER2 are version
-   numbers and PREFIX and SUFFIX (SUFFIX defined as (\.[A-Za-z][A-Za-z0-9]*)*)
-   are strings then VER1 < VER2 implies filevercmp (PREFIX VER1 SUFFIX,
-   PREFIX VER2 SUFFIX) < 0.
+   numbers and PREFIX and SUFFIX (SUFFIX defined as
+   [^.](\.[A-Za-z][A-Za-z0-9]*)*) are strings then VER1 < VER2 implies
+   filevercmp (PREFIX VER1 SUFFIX, PREFIX VER2 SUFFIX) < 0.
 
    This function is intended to be a replacement for strverscmp. */
 int filevercmp (const char *s1, const char *s2);
diff --git a/tests/test-filevercmp.c b/tests/test-filevercmp.c
index 4efd108..7477db7 100644
--- a/tests/test-filevercmp.c
+++ b/tests/test-filevercmp.c
@@ -37,6 +37,10 @@
 /* set of well sorted examples */
 static const char *const examples[] =
 {
+  "a~",
+  "a",
+  "b~",
+  "b",
   "gcc-c++-10.fc9.tar.gz",
   "gcc-c++-10.8.12-0.7rc2.fc9.tar.bz2",
   "glibc-2-0.1.beta1.fc10.rpm",
@@ -56,6 +60,12 @@ static const char *const examples[] =
   "nss_ldap-1.0-0.1a.tar.gz",
   "nss_ldap-10beta1.fc8.tar.gz",
   "nss_ldap-10.11.8.6.20040204cvs.fc10.ebuild",
+  ".",
+  ".a~",
+  ".a",
+  ".b~",
+  ".b",
+  "..",
   NULL
 };
 
-- 
1.6.1.2

Reply via email to