
NNNpN -> N.NN.N NNN.N -> N.NN.0.N This is better than mapping NNN.N to N.NN.N, because it follows the fact that NNN.N were not release versions, so they're mapped to numbers that are not release versions now. svn: r11398
72 lines
2.6 KiB
Scheme
72 lines
2.6 KiB
Scheme
#lang scheme/base
|
|
|
|
(provide valid-version? version->list version<? version<=? alpha-version?
|
|
version->integer)
|
|
|
|
(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}"
|
|
"(?<![.]0))$")))
|
|
|
|
(define (valid-version? s)
|
|
(and (string? s) (regexp-match? rx:version s)))
|
|
|
|
;; the following functions assume valid version string inputs
|
|
|
|
;; returns a list of 4 integers (see src/mzscheme/src/schvers.h)
|
|
(define (version->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 (version<? a b)
|
|
(let loop ([a (version->list 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) (version<? a b)))
|
|
|
|
(define (alpha-version? v)
|
|
(let ([l (version->list v)])
|
|
(or ((list-ref l 1) . >= . 90) ((list-ref l 2) . >= . 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))))
|