From 311da7c314e27cf27cd003a848b468a0964be71a Mon Sep 17 00:00:00 2001 From: aarzilli Date: Tue, 28 Jul 2015 21:54:40 +0200 Subject: [PATCH] bugfix: version string parsing support for beta versions and tolerance for devel versions fixes issue #179 --- proc/arch.go | 2 +- proc/go_version.go | 64 ++++++++++++++++++++++++++++++++++++---------- proc/proc_test.go | 24 +++++++++++++++++ 3 files changed, 75 insertions(+), 15 deletions(-) diff --git a/proc/arch.go b/proc/arch.go index 48f15531..81a62fd2 100644 --- a/proc/arch.go +++ b/proc/arch.go @@ -39,7 +39,7 @@ func (a *AMD64) SetGStructOffset(ver GoVersion, isextld bool) { a.gStructOffset = 0xfffffffffffffff0 } - if isextld || ver.After(GoVersion{1, 5, 0}) { + if isextld || ver.After(GoVersion{1, 5, -1, 2}) || ver.IsDevel() { a.gStructOffset += 8 } } diff --git a/proc/go_version.go b/proc/go_version.go index f373f7f9..6aaa3ebd 100644 --- a/proc/go_version.go +++ b/proc/go_version.go @@ -9,28 +9,54 @@ type GoVersion struct { Major int Minor int Rev int + Beta int } func parseVersionString(ver string) (GoVersion, bool) { - if ver[:2] != "go" { - return GoVersion{}, false - } - v := strings.SplitN(ver[2:], ".", 3) - if len(v) != 3 { - return GoVersion{}, false - } - var r GoVersion var err1, err2, err3 error - r.Major, err1 = strconv.Atoi(v[0]) - r.Minor, err2 = strconv.Atoi(v[1]) - r.Rev, err3 = strconv.Atoi(v[2]) - if err1 != nil || err2 != nil || err3 != nil { - return GoVersion{}, false + if strings.HasPrefix(ver, "devel") { + return GoVersion{-1, 0, 0, 0}, true } - return r, true + if strings.HasPrefix(ver, "go") { + v := strings.SplitN(ver[2:], ".", 3) + switch len(v) { + case 2: + r.Major, err1 = strconv.Atoi(v[0]) + v = strings.SplitN(v[1], "beta", 2) + if len(v) != 2 { + return GoVersion{}, false + } + + r.Minor, err2 = strconv.Atoi(v[0]) + r.Rev = -1 + r.Beta, err3 = strconv.Atoi(v[1]) + + if err1 != nil || err2 != nil || err3 != nil { + return GoVersion{}, false + } + + return r, true + + case 3: + + r.Major, err1 = strconv.Atoi(v[0]) + r.Minor, err2 = strconv.Atoi(v[1]) + r.Rev, err3 = strconv.Atoi(v[2]) + if err1 != nil || err2 != nil || err3 != nil { + return GoVersion{}, false + } + + return r, true + + default: + return GoVersion{}, false + } + } + + return GoVersion{}, false } func (a *GoVersion) After(b GoVersion) bool { @@ -48,7 +74,17 @@ func (a *GoVersion) After(b GoVersion) bool { if a.Rev < b.Rev { return false + } else if a.Rev > b.Rev { + return true + } + + if a.Beta < b.Beta { + return false } return true } + +func (v *GoVersion) IsDevel() bool { + return v.Major < 0 +} diff --git a/proc/proc_test.go b/proc/proc_test.go index 220822f0..840c67a7 100644 --- a/proc/proc_test.go +++ b/proc/proc_test.go @@ -659,3 +659,27 @@ func TestContinueMulti(t *testing.T) { } }) } + +func versionAfter(t *testing.T, verStr string, ver GoVersion) { + pver, ok := parseVersionString(verStr) + if !ok { + t.Fatalf("Could not parse version string <%s>", verStr) + } + if !pver.After(ver) { + t.Fatalf("Version <%s> parsed as %v not after %v", verStr, pver, ver) + } + t.Logf("version string <%s> → %v", verStr, ver) +} + +func TestParseVersionString(t *testing.T) { + versionAfter(t, "go1.5.0", GoVersion{1, 5, 0, 0}) + versionAfter(t, "go1.4.2", GoVersion{1, 4, 2, 0}) + versionAfter(t, "go1.5beta2", GoVersion{1, 5, -1, 2}) + ver, ok := parseVersionString("devel +17efbfc Tue Jul 28 17:39:19 2015 +0000 linux/amd64") + if !ok { + t.Fatalf("Could not parse devel version string") + } + if !ver.IsDevel() { + t.Fatalf("Devel version string not correctly recognized") + } +}