Something went wrong. Try again.
Maps Linux distribution source packages to their upstream repositories, and through them to each other
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120package debian
import ( "strconv" "strings")
// CompareVersions compares two Debian package versions the way dpkg does (Debian Policy// 5.6.12): epoch first, then the upstream part, then the Debian revision. Within a part,// alternating non-digit and digit runs are compared; letters sort before non-letters, `~`// sorts before everything including the empty string, and digit runs compare numerically.// It returns -1, 0 or 1.func CompareVersions(a, b string) int { ea, ua, ra := SplitVersion(a) eb, ub, rb := SplitVersion(b) if ea != eb { if ea < eb { return -1 } return 1 } if c := verrevcmp(ua, ub); c != 0 { return c } return verrevcmp(ra, rb)}
// SplitVersion splits a version into epoch, upstream version and Debian revision.// "1:1.3.dfsg+really1.3.2-3" -> (1, "1.3.dfsg+really1.3.2", "3"); a native version has an// empty revision.func SplitVersion(v string) (epoch int, upstream, revision string) { v = strings.TrimSpace(v) if i := strings.Index(v, ":"); i >= 0 { if n, err := strconv.Atoi(v[:i]); err == nil { epoch = n v = v[i+1:] } } if i := strings.LastIndex(v, "-"); i >= 0 { return epoch, v[:i], v[i+1:] } return epoch, v, ""}
func order(c byte) int { switch { case c >= '0' && c <= '9': return 0 case (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'): return int(c) case c == '~': return -1 case c == 0: return 0 default: return int(c) + 256 }}
func isDigit(c byte) bool { return c >= '0' && c <= '9' }
// verrevcmp is a transliteration of dpkg's lib/dpkg/version.c verrevcmp.func verrevcmp(a, b string) int { i, j := 0, 0 for i < len(a) || j < len(b) { first := 0 for (i < len(a) && !isDigit(a[i])) || (j < len(b) && !isDigit(b[j])) { var ac, bc int if i < len(a) { ac = order(a[i]) } if j < len(b) { bc = order(b[j]) } if ac != bc { return sign(ac - bc) } if i < len(a) { i++ } if j < len(b) { j++ } } for i < len(a) && a[i] == '0' { i++ } for j < len(b) && b[j] == '0' { j++ } for i < len(a) && isDigit(a[i]) && j < len(b) && isDigit(b[j]) { if first == 0 { first = int(a[i]) - int(b[j]) } i++ j++ } if i < len(a) && isDigit(a[i]) { return 1 } if j < len(b) && isDigit(b[j]) { return -1 } if first != 0 { return sign(first) } } return 0}
func sign(n int) int { switch { case n < 0: return -1 case n > 0: return 1 } return 0}