Skip to content

Commit 284a275

Browse files
committed
feat: upgrade goNixArgParser
1 parent 657f768 commit 284a275

File tree

4 files changed

+222
-14
lines changed

4 files changed

+222
-14
lines changed

src/goNixArgParser/common_test.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package goNixArgParser
2+
3+
func expectStrings(actuals []string, expects ...string) bool {
4+
if len(actuals) != len(expects) {
5+
return false
6+
}
7+
8+
for i := range actuals {
9+
if actuals[i] != expects[i] {
10+
return false
11+
}
12+
}
13+
14+
return true
15+
}

src/goNixArgParser/helper.go

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
package goNixArgParser
2+
3+
import (
4+
"os"
5+
"regexp"
6+
)
7+
8+
// ==================================================
9+
10+
func removeEmptyInplace(inputs []string) (outputs []string) {
11+
// remove empty item
12+
nextIndex := 0
13+
for i := range inputs {
14+
if len(inputs[i]) == 0 {
15+
continue
16+
}
17+
if nextIndex != i {
18+
inputs[nextIndex] = inputs[i]
19+
}
20+
nextIndex++
21+
}
22+
23+
return inputs[:nextIndex]
24+
}
25+
26+
// ==================================================
27+
28+
/*
29+
- non-quoted: [^'"\s]*
30+
- repeat of quoted and non-quoted: (?:(?:'[^']*'|"[^"]*")[^'"\s]*)*
31+
- rest unpaired quote: \S*
32+
*/
33+
var reLexical = regexp.MustCompile(`[^'"\s]*(?:(?:'[^']*'|"[^"]*")[^'"\s]*)*\S*`)
34+
35+
func splitLexicals(input string) (output []string) {
36+
lexicals := reLexical.FindAllString(input, -1)
37+
lexicals = removeEmptyInplace(lexicals)
38+
39+
return lexicals
40+
}
41+
42+
// ==================================================
43+
44+
var reQuoted = regexp.MustCompile(`'[^']*'|"[^"]*"`)
45+
46+
func removeQuotes(input string) (output string) {
47+
output = reQuoted.ReplaceAllStringFunc(input, func(matched string) string {
48+
return matched[1 : len(matched)-1]
49+
})
50+
return output
51+
}
52+
53+
func removeAllQuotesInPlace(inputs []string) []string {
54+
for i := range inputs {
55+
inputs[i] = removeQuotes(inputs[i])
56+
}
57+
inputs = removeEmptyInplace(inputs)
58+
return inputs
59+
}
60+
61+
// ==================================================
62+
63+
func SplitToArgs(input string) (args []string) {
64+
lexicals := splitLexicals(input)
65+
args = removeAllQuotesInPlace(lexicals)
66+
return args
67+
}
68+
69+
func LoadConfigArgs(filename string) (args []string, err error) {
70+
input, err := os.ReadFile(filename)
71+
if err != nil {
72+
return nil, err
73+
}
74+
75+
strConfig := string(input)
76+
return SplitToArgs(strConfig), nil
77+
}

src/goNixArgParser/helper_test.go

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
package goNixArgParser
2+
3+
import "testing"
4+
5+
func TestRemoveEmpetyInplace(t *testing.T) {
6+
var output []string
7+
8+
output = removeEmptyInplace([]string{"aa", "", "bb", "cc"})
9+
if !expectStrings(output, "aa", "bb", "cc") {
10+
t.Error(output)
11+
}
12+
}
13+
14+
func TestRemoveQuotes(t *testing.T) {
15+
var output string
16+
17+
output = removeQuotes("")
18+
if output != "" {
19+
t.Error(output)
20+
}
21+
22+
output = removeQuotes("abc")
23+
if output != "abc" {
24+
t.Error(output)
25+
}
26+
27+
output = removeQuotes(`hello "world" here`)
28+
if output != "hello world here" {
29+
t.Error(output)
30+
}
31+
32+
output = removeQuotes(`hello 'world' there`)
33+
if output != "hello world there" {
34+
t.Error(output)
35+
}
36+
37+
output = removeQuotes(`lorem 'ipsum`)
38+
if output != `lorem 'ipsum` {
39+
t.Error(output)
40+
}
41+
42+
output = removeQuotes(`lorem "ipsum`)
43+
if output != `lorem "ipsum` {
44+
t.Error(output)
45+
}
46+
47+
output = removeQuotes(`foo "bar" 'baz`)
48+
if output != `foo bar 'baz` {
49+
t.Error(output)
50+
}
51+
52+
output = removeQuotes(`"Content-Security-Policy: default-src 'self'"`)
53+
if output != `Content-Security-Policy: default-src 'self'` {
54+
t.Error(output)
55+
}
56+
}
57+
58+
func TestSplitLexicals(t *testing.T) {
59+
var output []string
60+
61+
output = splitLexicals("")
62+
if !expectStrings(output) {
63+
t.Error(len(output), output)
64+
}
65+
66+
output = splitLexicals(` aaa bbb `)
67+
if !expectStrings(output, "aaa", "bbb") {
68+
t.Error(len(output), output)
69+
}
70+
71+
output = splitLexicals(`aaa bbb "c c c" 'ddd' "ee'ee" 'ff"ff' ggg`)
72+
if !expectStrings(output, "aaa", "bbb", `"c c c"`, "'ddd'", `"ee'ee"`, `'ff"ff'`, "ggg") {
73+
t.Error(len(output), output)
74+
}
75+
76+
output = splitLexicals(`aa"bb"cc dd'ee'ff`)
77+
if !expectStrings(output, `aa"bb"cc`, `dd'ee'ff`) {
78+
t.Error(len(output), output)
79+
}
80+
81+
// unpaired quotes
82+
output = splitLexicals(`aa"bb"cc"xxx dd'ee'ff'xxx`)
83+
if !expectStrings(output, `aa"bb"cc"xxx`, `dd'ee'ff'xxx`) {
84+
t.Error(len(output), output)
85+
}
86+
}
87+
88+
func TestSplitToArgs(t *testing.T) {
89+
var output []string
90+
91+
output = SplitToArgs(` aaa bbb `)
92+
if !expectStrings(output, "aaa", "bbb") {
93+
t.Error(len(output), output)
94+
}
95+
96+
output = SplitToArgs(`aaa bbb "c c c" 'ddd' "ee'ee" 'ff"ff' ggg`)
97+
if !expectStrings(output, "aaa", "bbb", "c c c", "ddd", "ee'ee", `ff"ff`, "ggg") {
98+
t.Error(len(output), output)
99+
}
100+
101+
output = SplitToArgs(`aa"bb"cc dd'ee'ff`)
102+
if !expectStrings(output, "aabbcc", "ddeeff") {
103+
t.Error(len(output), output)
104+
}
105+
106+
// unpaired quotes
107+
output = SplitToArgs(`aa"bb"cc"xxx dd'ee'ff'xxx`)
108+
if !expectStrings(output, `aabbcc"xxx`, `ddeeff'xxx`) {
109+
t.Error(len(output), output)
110+
}
111+
}

src/goNixArgParser/parseResult.go

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
package goNixArgParser
22

3-
///////////////////////////////
3+
// =============================
44
// set configOptions
5-
//////////////////////////////
5+
// =============================
6+
67
func (r *ParseResult) SetConfigOption(key, value string) {
78
r.configOptions[key] = []string{value}
89
}
@@ -19,9 +20,9 @@ func (r *ParseResult) SetConfigOptions(key string, values []string) {
1920
r.configOptions[key] = configValues
2021
}
2122

22-
///////////////////////////////
23+
//=============================
2324
// has xxx
24-
//////////////////////////////
25+
//=============================
2526

2627
func (r *ParseResult) HasFlagKey(key string) bool {
2728
_, found := r.specifiedOptions[key]
@@ -67,9 +68,9 @@ func (r *ParseResult) HasValue(key string) bool {
6768
return r.HasFlagValue(key) || r.HasEnvValue(key) || r.HasConfigValue(key) || r.HasDefaultValue(key)
6869
}
6970

70-
///////////////////////////////
71+
//=============================
7172
// get single value
72-
//////////////////////////////
73+
//=============================
7374

7475
func (r *ParseResult) GetString(key string) (value string, found bool) {
7576
value, found = getValue(r.specifiedOptions, key)
@@ -150,9 +151,10 @@ func (r *ParseResult) GetFloat64(key string) (value float64, found bool) {
150151
return
151152
}
152153

153-
///////////////////////////////
154+
// =============================
154155
// get multi values
155-
//////////////////////////////
156+
// =============================
157+
156158
func (r *ParseResult) GetStrings(key string) (values []string, found bool) {
157159
values, found = getValues(r.specifiedOptions, key)
158160
if found {
@@ -242,16 +244,18 @@ func (r *ParseResult) GetRests() (rests []string) {
242244
return
243245
}
244246

245-
///////////////////////////////
247+
// =============================
246248
// commands
247-
//////////////////////////////
249+
// =============================
250+
248251
func (r *ParseResult) GetCommands() []string {
249252
return copys(r.commands)
250253
}
251254

252-
///////////////////////////////
255+
// =============================
253256
// ambigus
254-
//////////////////////////////
257+
// =============================
258+
255259
func (r *ParseResult) HasAmbigu() bool {
256260
return len(r.specifiedAmbigus) > 0 || len(r.configAmbigus) > 0
257261
}
@@ -274,9 +278,10 @@ func (r *ParseResult) GetAmbigus() []string {
274278
return flags
275279
}
276280

277-
///////////////////////////////
281+
// =============================
278282
// undefs
279-
//////////////////////////////
283+
// =============================
284+
280285
func (r *ParseResult) HasUndef() bool {
281286
return len(r.specifiedUndefs) > 0 || len(r.configUndefs) > 0
282287
}

0 commit comments

Comments
 (0)