-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
util.go
124 lines (110 loc) · 3.26 KB
/
util.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
package cmd
import (
"net"
"os"
"path/filepath"
"runtime"
"strings"
"git.parallelcoin.io/dev/9/pkg/util"
)
// MinUint32 is a helper function to return the minimum of two uint32s. This avoids a math import and the need to cast to floats.
func MinUint32(a, b uint32) uint32 {
if a < b {
return a
}
return b
}
func isWindows() bool {
return runtime.GOOS == "windows"
}
// EnsureDir checks a file could be written to a path, creates the directories as needed
func EnsureDir(fileName string) bool {
dirName := filepath.Dir(fileName)
if _, serr := os.Stat(dirName); serr != nil {
merr := os.MkdirAll(dirName, os.ModePerm)
if merr != nil {
panic(merr)
}
return true
}
return false
}
// FileExists reports whether the named file or directory exists.
func FileExists(filePath string) bool {
_, err := os.Stat(filePath)
return err == nil
}
// CleanAndExpandPath expands environment variables and leading ~ in the passed path, cleans the result, and returns it.
func CleanAndExpandPath(path, datadir string) string {
// Expand initial ~ to OS specific home directory.
homeDir := filepath.Dir(util.AppDataDir("9", false))
if strings.HasPrefix(path, "~") {
return strings.Replace(path, "~", homeDir, 1)
}
if strings.HasPrefix(path, "./") {
// explicitly prefix is this must be a relative path
pwd, _ := os.Getwd()
return filepath.Join(pwd, path)
} else if !strings.HasPrefix(path, "/") && !strings.HasPrefix(path, "\\") {
if path != datadir {
return filepath.Join(datadir, path)
}
}
// NOTE: The os.ExpandEnv doesn't work with Windows-style %VARIABLE%, but they variables can still be expanded via POSIX-style $VARIABLE.
path = filepath.Clean(os.ExpandEnv(path))
return path
}
// NormalizeAddress returns addr with the passed default port appended if there is not already a port specified.
func NormalizeAddress(addr, defaultPort string) string {
_, _, err := net.SplitHostPort(addr)
if err != nil {
return net.JoinHostPort(addr, defaultPort)
}
return addr
}
// NormalizeAddresses returns a new slice with all the passed peer addresses normalized with the given default port, and all duplicates removed.
func NormalizeAddresses(addrs []string, defaultPort string) []string {
for i, addr := range addrs {
addrs[i] = NormalizeAddress(addr, defaultPort)
}
return RemoveDuplicateAddresses(addrs)
}
// RemoveDuplicateAddresses returns a new slice with all duplicate entries in addrs removed.
func RemoveDuplicateAddresses(addrs []string) []string {
result := make([]string, 0, len(addrs))
seen := map[string]struct{}{}
for _, val := range addrs {
if _, ok := seen[val]; !ok {
result = append(result, val)
seen[val] = struct{}{}
}
}
return result
}
func intersection(a, b []string) (out []string) {
for _, x := range a {
for _, y := range b {
if x == y {
out = append(out, x)
}
}
}
return
}
func uniq(elements []string) []string {
// Use map to record duplicates as we find them.
encountered := map[string]bool{}
result := []string{}
for v := range elements {
if encountered[elements[v]] == true {
// Do not add duplicate.
} else {
// Record this element as an encountered element.
encountered[elements[v]] = true
// Append to result slice.
result = append(result, elements[v])
}
}
// Return the new slice.
return result
}