emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

master 993853531a: Fix sorting in ls-lisp.el under -v


From: Eli Zaretskii
Subject: master 993853531a: Fix sorting in ls-lisp.el under -v
Date: Sun, 5 Jun 2022 02:53:01 -0400 (EDT)

branch: master
commit 993853531aebb303870d6ff1ba7db2007d464b63
Author: Eli Zaretskii <eliz@gnu.org>
Commit: Eli Zaretskii <eliz@gnu.org>

    Fix sorting in ls-lisp.el under -v
    
    * lisp/ls-lisp.el (ls-lisp-version-lessp): Handle correctly the
    case where strings begin with numerical parts.  More faithful
    implementation of the 'strverscmp' spec for fractional parts.
    (Bug#55787)
    
    * test/lisp/ls-lisp-tests.el (ls-lisp-test-bug55787): New test.
---
 lisp/ls-lisp.el            | 18 +++++++++++++-----
 test/lisp/ls-lisp-tests.el | 39 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 52 insertions(+), 5 deletions(-)

diff --git a/lisp/ls-lisp.el b/lisp/ls-lisp.el
index 33dd98ef8d..6d1f449568 100644
--- a/lisp/ls-lisp.el
+++ b/lisp/ls-lisp.el
@@ -621,14 +621,22 @@ in some standard C libraries does."
                 (sub2 (substring s2 ni2 e2))
                 ;; "Fraction" is a numerical sequence with leading zeros.
                 (fr1 (string-match "\\`0+" sub1))
-                (fr2 (string-match "\\`0+" sub2)))
+                (efr1 (match-end 0))
+                (fr2 (string-match "\\`0+" sub2))
+                (efr2 (match-end 0)))
            (cond
-            ((and fr1 fr2)     ; two fractions, the shortest wins
-             (setq val (- val (- (length sub1) (length sub2)))))
+             ;; Two fractions: the longer one is less than the other,
+             ;; but only if the "common prefix" is all-zeroes,
+             ;; otherwise fall back on numerical comparison.
+            ((and fr1 fr2)
+             (if (or (and (< efr1 (- e1 ni1)) (< efr2 (- e2 ni2))
+                          (not (eq (aref sub1 efr1) (aref sub2 efr2))))
+                     (= efr1 (- e1 ni1)) (=  efr2 (- e2 ni2)))
+                 (setq val (- val (- (length sub1) (length sub2))))))
             (fr1               ; a fraction is always less than an integral
-             (setq val (- ni1)))
+             (setq val (- 0 ni1 1)))   ; make sure val is non-zero
             (fr2
-             (setq val ni2)))
+             (setq val (1+ ni2))))     ; make sure val is non-zero
            (if (zerop val)     ; fall back on numerical comparison
                (setq val (- (string-to-number sub1)
                             (string-to-number sub2))))
diff --git a/test/lisp/ls-lisp-tests.el b/test/lisp/ls-lisp-tests.el
index 3e23fc7454..39843defc2 100644
--- a/test/lisp/ls-lisp-tests.el
+++ b/test/lisp/ls-lisp-tests.el
@@ -93,5 +93,44 @@
           (should (looking-back "[[:space:]]" (1- (point)))))
       (when (buffer-live-p buf) (kill-buffer buf)))))
 
+(ert-deftest ls-lisp-test-bug55787 ()
+  "Test proper sorting by version."
+  (let ((files1 (vector "34 klmn-300dpi.jpg"
+                        "34 klmn-300dpi.png"
+                        "054_xyz.jpg"
+                        "054_xyz.png"
+                        "91 opqrs.jpg"
+                        "91 opqrs.png"
+                        "0717-abcd.jpg"
+                        "0717-abcd.png"
+                        "1935 uv.jpg"
+                        "1935 uv.png"
+                        "FFFF_fghk.jpg"
+                        "FFFF_fghk.png"
+                        "hhhh.jpg"
+                       "hhhh.png"))
+        (files2 (vector "01.0" "10" "010" "01.2")))
+    (should (equal (sort files1
+                         (lambda (x y)
+                           (ls-lisp-version-lessp x y)))
+                   '["0717-abcd.jpg"
+                     "0717-abcd.png"
+                     "054_xyz.jpg"
+                     "054_xyz.png"
+                     "34 klmn-300dpi.jpg"
+                     "34 klmn-300dpi.png"
+                     "91 opqrs.jpg"
+                     "91 opqrs.png"
+                     "1935 uv.jpg"
+                     "1935 uv.png"
+                     "FFFF_fghk.jpg"
+                     "FFFF_fghk.png"
+                     "hhhh.jpg"
+                     "hhhh.png"]))
+    (should (equal (sort files2
+                         (lambda (x y)
+                           (ls-lisp-version-lessp x y)))
+                   '["01.0" "01.2" "010" "10"]))))
+
 (provide 'ls-lisp-tests)
 ;;; ls-lisp-tests.el ends here



reply via email to

[Prev in Thread] Current Thread [Next in Thread]