aboutsummaryrefslogtreecommitdiff
path: root/src/util.lisp
diff options
context:
space:
mode:
authorSean Whitton <spwhitton@spwhitton.name>2021-11-28 14:42:46 -0700
committerSean Whitton <spwhitton@spwhitton.name>2021-11-28 19:07:24 -0700
commitb16512b1803e65a987967d407285d2af37a159e3 (patch)
tree87e08892f0a83ed5c1471c8d786fdbd8354fafb5 /src/util.lisp
parent0c4336893f4781da3abf9390e8a9c3601083e5f3 (diff)
downloadconsfigurator-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.lisp40
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