diff options
author | Sean Whitton <spwhitton@spwhitton.name> | 2021-11-28 14:42:46 -0700 |
---|---|---|
committer | Sean Whitton <spwhitton@spwhitton.name> | 2021-11-28 19:07:24 -0700 |
commit | b16512b1803e65a987967d407285d2af37a159e3 (patch) | |
tree | 87e08892f0a83ed5c1471c8d786fdbd8354fafb5 /src/util.lisp | |
parent | 0c4336893f4781da3abf9390e8a9c3601083e5f3 (diff) | |
download | consfigurator-b16512b1803e65a987967d407285d2af37a159e3.tar.gz |
replace usage of UIOP version comparison utilities with our own
DATA.GIT-SNAPSHOT generates version numbers like 2342423.ab09890f2bcd where
only the first, purely numerical component is intended for comparison, and the
second component is just additional information. UIOP's utilities don't give
the correct answers for cases like that; e.g. (uiop:version<= "1.a" "0") => T.
Signed-off-by: Sean Whitton <spwhitton@spwhitton.name>
Diffstat (limited to 'src/util.lisp')
-rw-r--r-- | src/util.lisp | 40 |
1 files changed, 32 insertions, 8 deletions
diff --git a/src/util.lisp b/src/util.lisp index 704a288..9f0a463 100644 --- a/src/util.lisp +++ b/src/util.lisp @@ -470,20 +470,44 @@ previous output." ;;;; Version numbers -(defun number->string (x) - (etypecase x (string x) (number (format nil "~D" x)))) +(defun compare-versions (x y &optional less-than-or-equal) + (flet + ((components (v) + (etypecase v + (number (list v)) + (string + (loop with buf + = (make-array 0 :fill-pointer 0 :element-type 'character) + for c across v + if (digit-char-p c) + do (vector-push-extend c buf) + else if (and (char= c #\.) (plusp (fill-pointer buf))) + collect (parse-integer buf) into accum + and do (setf (fill-pointer buf) 0) + else do (loop-finish) + finally (return (if (plusp (fill-pointer buf)) + (nconc accum (list (parse-integer buf))) + accum))))))) + (setq x (components x) y (components y)) + (if less-than-or-equal + (loop while (or x y) for a = (or (pop x) 0) and b = (or (pop y) 0) + never (> a b) + if (< a b) return t) + (loop while (or x y) for a = (or (pop x) 0) and b = (or (pop y) 0) + thereis (> b a) + if (< b a) return nil)))) (defun version< (x y) - (uiop:version< (number->string x) (number->string y))) - -(defun version> (x y) - (version< y x)) + (compare-versions x y)) (defun version<= (x y) - (uiop:version<= (number->string x) (number->string y))) + (compare-versions x y t)) + +(defun version> (x y) + (compare-versions y x)) (defun version>= (x y) - (version<= y x)) + (compare-versions y x t)) ;;;; Encoding of strings to filenames |