Function: mpc-compare-strings

mpc-compare-strings is a byte-compiled function defined in mpc.el.gz.

Signature

(mpc-compare-strings STR1 STR2 &optional IGNORE-CASE)

Documentation

Compare strings STR1 and STR2.

Contrary to compare-strings, this tries to get numbers sorted numerically rather than lexicographically.

Source Code

;; Defined in /usr/src/emacs/lisp/mpc.el.gz
(defun mpc-compare-strings (str1 str2 &optional ignore-case)
  "Compare strings STR1 and STR2.
Contrary to `compare-strings', this tries to get numbers sorted
numerically rather than lexicographically."
  (let ((res (compare-strings str1 nil nil str2 nil nil ignore-case)))
    (if (not (integerp res)) res
      (let ((index (1- (abs res))))
        (if (or (>= index (length str1)) (>= index (length str2)))
            res
          (let ((digit1 (memq (aref str1 index)
                              '(?0 ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9)))
                (digit2 (memq (aref str2 index)
                              '(?0 ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9))))
            (if digit1
                (if digit2
                    (let ((num1 (progn (string-match "[0-9]+" str1 index)
                                       (match-string 0 str1)))
                          (num2 (progn (string-match "[0-9]+" str2 index)
                                       (match-string 0 str2))))
                      (cond
                       ;; Here we presume that leading zeroes are only used
                       ;; for same-length numbers.  So we'll incorrectly
                       ;; consider that "000" comes after "01", but I don't
                       ;; think it matters.
                       ((< (length num1) (length num2)) (- (abs res)))
                       ((> (length num1) (length num2)) (abs res))
                       ((< (string-to-number num1) (string-to-number num2))
                        (- (abs res)))
                       (t (abs res))))
                  ;; "1a" comes before "10", but "0" comes before "a".
                  (if (and (not (zerop index))
                           (memq (aref str1 (1- index))
                                 '(?0 ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9)))
                      (abs res)
                    (- (abs res))))
              (if digit2
                  ;; "1a" comes before "10", but "0" comes before "a".
                  (if (and (not (zerop index))
                           (memq (aref str1 (1- index))
                                 '(?0 ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9)))
                      (- (abs res))
                    (abs res))
                res))))))))