#lang scheme/base (provide valid-version? version->list versioninteger) (define rx:version ;; (this restricts the last component to be below 999 too, which is ;; not really proper according to the spec in schvers.h) (pregexp (string-append "^(0|[1-9][0-9]*)[.]" "(0|(0|[1-9][0-9]{0,1})([.](0|[1-9][0-9]{0,2})){0,2}" "(?list str) (let ([ver (map string->number (regexp-split #rx"[.]" str))]) (case (length ver) [(2) (append ver '(0 0))] [(3) (append ver '(0))] [(4) ver] [else (error 'version->list "bad version: ~e" str)]))) (define (versionlist a)] [b (version->list b)]) (cond [(null? a) #f] [(< (car a) (car b)) #t] [(> (car a) (car b)) #f] [else (loop (cdr a) (cdr b))]))) (define (version<=? a b) (or (equal? a b) (versionlist v)]) (or ((list-ref l 1) . >= . 90) ((list-ref l 2) . >= . 900) ((list-ref l 3) . >= . 900)))) ;; returns an integer representing the version (XXYYZZZWWW) or #f if invalid ;; works for pre v4 versions too (define (version->integer ver) (define m (regexp-match-positions #rx"^(?:0|[1-9][0-9]*)" ver)) ; takes all digits ;; translate old versions to new-style versions (define n (and m (string->number (substring ver 0 (cdar m))))) (define v (cond [(not n) #f] ;; new versions [(< n 49) ver] ;; old versions (earliest useful is 49, changed at 3.99) [(<= 49 n 379) (let*-values ([(q r) (quotient/remainder n 100)] [(sfx) (substring ver (cdar m))] [(sfx) (cond [(equal? sfx "") ""] ;; NNNpN -> N.NN.N [(regexp-match? #rx"^p[0-9]" sfx) (string-append "." (substring sfx 1))] ;; NNN.N -> N.NN.0.N (not a release version) [(regexp-match? #rx"^[.]" sfx) (string-append ".0" sfx)] [else #f])]) (and sfx (format "~a.~a~a" q r sfx)))] ;; bad strings [else #f])) (and v (valid-version? v) (foldl (lambda (ver mul acc) (+ ver (* mul acc))) 0 (version->list v) '(0 100 1000 1000))))