github.com/bir3/gocompiler@v0.9.2202/src/cmd/gocmd/internal/toolchain/path_windows.go (about) 1 // Copyright 2023 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package toolchain 6 7 import ( 8 "io/fs" 9 "os" 10 "path/filepath" 11 "strings" 12 "sync" 13 14 "github.com/bir3/gocompiler/src/cmd/gocmd/internal/gover" 15 ) 16 17 // pathExts is a cached PATHEXT list. 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 // pathDirs returns the directories in the system search path. 43 func pathDirs() []string { 44 return filepath.SplitList(os.Getenv("PATH")) 45 } 46 47 // pathVersion returns the Go version implemented by the file 48 // described by de and info in directory dir. 49 // The analysis only uses the name itself; it does not run the program. 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 // cutExt looks for any of the known extensions at the end of file. 64 // If one is found, cutExt returns the file name with the extension trimmed, 65 // the extension itself, and true to signal that an extension was found. 66 // Otherwise cutExt returns file, "", false. 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 }