Skip to content

Commit fa3a121

Browse files
committed
runtime: add a simple version number parser
This will be used to parse the Linux kernel versions, but this code is generic and can be tested on its own. For #35777. Change-Id: If1df48d07250e5855dde45bc9d57c66f777b9fb4 Reviewed-on: https://go-review.googlesource.com/c/go/+/209597 Run-TryBot: Austin Clements <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Ian Lance Taylor <[email protected]> Reviewed-by: Brad Fitzpatrick <[email protected]>
1 parent 709dbd2 commit fa3a121

File tree

3 files changed

+67
-0
lines changed

3 files changed

+67
-0
lines changed

src/runtime/export_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,8 @@ var PhysHugePageSize = physHugePageSize
4343

4444
var NetpollGenericInit = netpollGenericInit
4545

46+
var ParseRelease = parseRelease
47+
4648
const PreemptMSupported = preemptMSupported
4749

4850
type LFNode struct {

src/runtime/string.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -495,3 +495,37 @@ func gostringw(strw *uint16) string {
495495
b[n2] = 0 // for luck
496496
return s[:n2]
497497
}
498+
499+
// parseRelease parses a dot-separated version number. It follows the
500+
// semver syntax, but allows the minor and patch versions to be
501+
// elided.
502+
func parseRelease(rel string) (major, minor, patch int, ok bool) {
503+
// Strip anything after a dash or plus.
504+
for i := 0; i < len(rel); i++ {
505+
if rel[i] == '-' || rel[i] == '+' {
506+
rel = rel[:i]
507+
break
508+
}
509+
}
510+
511+
next := func() (int, bool) {
512+
for i := 0; i < len(rel); i++ {
513+
if rel[i] == '.' {
514+
ver, ok := atoi(rel[:i])
515+
rel = rel[i+1:]
516+
return ver, ok
517+
}
518+
}
519+
ver, ok := atoi(rel)
520+
rel = ""
521+
return ver, ok
522+
}
523+
if major, ok = next(); !ok || rel == "" {
524+
return
525+
}
526+
if minor, ok = next(); !ok || rel == "" {
527+
return
528+
}
529+
patch, ok = next()
530+
return
531+
}

src/runtime/string_test.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -454,3 +454,34 @@ func TestAtoi32(t *testing.T) {
454454
}
455455
}
456456
}
457+
458+
type parseReleaseTest struct {
459+
in string
460+
major, minor, patch int
461+
}
462+
463+
var parseReleaseTests = []parseReleaseTest{
464+
{"", -1, -1, -1},
465+
{"x", -1, -1, -1},
466+
{"5", 5, 0, 0},
467+
{"5.12", 5, 12, 0},
468+
{"5.12-x", 5, 12, 0},
469+
{"5.12.1", 5, 12, 1},
470+
{"5.12.1-x", 5, 12, 1},
471+
{"5.12.1.0", 5, 12, 1},
472+
{"5.20496382327982653440", -1, -1, -1},
473+
}
474+
475+
func TestParseRelease(t *testing.T) {
476+
for _, test := range parseReleaseTests {
477+
major, minor, patch, ok := runtime.ParseRelease(test.in)
478+
if !ok {
479+
major, minor, patch = -1, -1, -1
480+
}
481+
if test.major != major || test.minor != minor || test.patch != patch {
482+
t.Errorf("parseRelease(%q) = (%v, %v, %v) want (%v, %v, %v)",
483+
test.in, major, minor, patch,
484+
test.major, test.minor, test.patch)
485+
}
486+
}
487+
}

0 commit comments

Comments
 (0)