1
2
3
4
5 package toolchain
6
7 import (
8 "io/fs"
9 "os"
10 "path/filepath"
11 "strings"
12 "sync"
13
14 "cmd/go/internal/gover"
15 )
16
17
18 var pathExts struct {
19 once sync.Once
20 list []string
21 }
22
23 func initPathExts() {
24 var exts []string
25 x := os.Getenv(`PATHEXT`)
26 if x != "" {
27 for _, e := range strings.Split(strings.ToLower(x), `;`) {
28 if e == "" {
29 continue
30 }
31 if e[0] != '.' {
32 e = "." + e
33 }
34 exts = append(exts, e)
35 }
36 } else {
37 exts = []string{".com", ".exe", ".bat", ".cmd"}
38 }
39 pathExts.list = exts
40 }
41
42
43 func pathDirs() []string {
44 return filepath.SplitList(os.Getenv("PATH"))
45 }
46
47
48
49
50 func pathVersion(dir string, de fs.DirEntry, info fs.FileInfo) (string, bool) {
51 pathExts.once.Do(initPathExts)
52 name, _, ok := cutExt(de.Name(), pathExts.list)
53 if !ok {
54 return "", false
55 }
56 v := gover.FromToolchain(name)
57 if v == "" {
58 return "", false
59 }
60 return v, true
61 }
62
63
64
65
66
67 func cutExt(file string, exts []string) (name, ext string, found bool) {
68 i := strings.LastIndex(file, ".")
69 if i < 0 {
70 return file, "", false
71 }
72 for _, x := range exts {
73 if strings.EqualFold(file[i:], x) {
74 return file[:i], file[i:], true
75 }
76 }
77 return file, "", false
78 }
79
View as plain text