-
Notifications
You must be signed in to change notification settings - Fork 17
/
Copy pathslice_common.go
151 lines (132 loc) · 3.29 KB
/
slice_common.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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
package goflags
import (
"strings"
"github.com/pkg/errors"
fileutil "github.com/projectdiscovery/utils/file"
stringsutil "github.com/projectdiscovery/utils/strings"
)
var quotes = []rune{'"', '\'', '`'}
func isQuote(char rune) (bool, rune) {
for _, quote := range quotes {
if quote == char {
return true, quote
}
}
return false, 0
}
func searchPart(value string, stop rune) (bool, string) {
var result string
for _, char := range value {
if char != stop {
result += string(char)
} else {
return true, result
}
}
return false, result
}
func ToString(slice []string) string {
defaultBuilder := &strings.Builder{}
defaultBuilder.WriteString("[")
for i, k := range slice {
defaultBuilder.WriteString("\"")
defaultBuilder.WriteString(k)
defaultBuilder.WriteString("\"")
if i != len(slice)-1 {
defaultBuilder.WriteString(", ")
}
}
defaultBuilder.WriteString("]")
return defaultBuilder.String()
}
type Options struct {
// IsFromFile determines if the values are from file
IsFromFile func(string) bool
// IsEmpty determines if the values are empty
IsEmpty func(string) bool
// Normalize the value (eg. removing trailing spaces)
Normalize func(string) string
// IsRaw determines if the value should be considered as a raw string
IsRaw func(string) bool
}
// ToStringSlice converts a value to string slice based on options
func ToStringSlice(value string, options Options) ([]string, error) {
var result []string
if options.IsEmpty == nil && options.IsFromFile == nil && options.Normalize == nil {
return []string{value}, nil
}
addPartToResult := func(part string) {
if options.Normalize != nil {
part = options.Normalize(part)
}
if !options.IsEmpty(part) {
result = append(result, part)
}
}
if fileutil.FileExists(value) && options.IsFromFile != nil && options.IsFromFile(value) {
linesChan, err := fileutil.ReadFile(value)
if err != nil {
return nil, err
}
for line := range linesChan {
addPartToResult(line)
}
} else if options.IsRaw != nil && options.IsRaw(value) {
addPartToResult(value)
} else {
index := 0
for index < len(value) {
char := rune(value[index])
if isQuote, quote := isQuote(char); isQuote {
quoteFound, part := searchPart(value[index+1:], quote)
if !quoteFound {
return nil, errors.New("Unclosed quote in path")
}
index += len(part) + 2
addPartToResult(part)
} else {
commaFound, part := searchPart(value[index:], ',')
if commaFound {
index += len(part) + 1
} else {
index += len(part)
}
addPartToResult(part)
}
}
}
return result, nil
}
func isEmpty(s string) bool {
return strings.TrimSpace(s) == ""
}
func isFromFile(_ string) bool {
return true
}
func normalizeTrailingParts(s string) string {
return stringsutil.NormalizeWithOptions(s,
stringsutil.NormalizeOptions{
StripComments: true,
TrimSpaces: true,
},
)
}
func normalize(s string) string {
return stringsutil.NormalizeWithOptions(s,
stringsutil.NormalizeOptions{
StripComments: true,
TrimCutset: string(quotes),
TrimSpaces: true,
},
)
}
func normalizeLowercase(s string) string {
return stringsutil.NormalizeWithOptions(s,
stringsutil.NormalizeOptions{
StripComments: true,
TrimCutset: string(quotes),
TrimSpaces: true,
Lowercase: true,
},
)
}