-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcmd.go
109 lines (96 loc) · 2.52 KB
/
cmd.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
package flag
import (
"fmt"
"os"
"strings"
)
func findValue(params map[string]string, tag string, full string) (string, bool) {
if v, ok := params[tag]; ok {
return v, true
} else if v, ok := params[full]; ok {
return v, true
}
return "", false
}
// findOnCmdLine 在命令行中获取对应的参数,如果存在则返回对应的值及设置ok为true
func findOnCmdLine(tag string, full string, isArg bool) (string, bool) {
result, ok := "", false
if isArg {
result, ok = findValue(ctx.sufParams, tag, full)
delete(ctx.sufParams, tag)
delete(ctx.sufParams, full)
} else {
result, ok = findValue(ctx.preParams, tag, full)
delete(ctx.preParams, tag)
delete(ctx.preParams, full)
}
return result, ok
}
// split 根据指定分隔符,返回 k,v对,如果不存在分隔符, 则v为空字符串
func split(token string, sep string) (k, v string) {
if strings.Index(token, sep) >= 1 {
arr := strings.Split(token, "=")
if len(arr) < 2 {
panic("error")
}
return arr[0], arr[1]
}
return token, ""
}
// processToken 处理当前位置的token,如果是参数名,则向后读取一个,如果是value,则放入map, 否则认为就是个标记
func processToken(token string, pos int) (int, string, string) {
isSingleFlag := true
if token[0] == '-' {
token = token[1:]
isSingleFlag = false
}
step, k, v := 1, "", ""
if strings.Index(token, "=") >= 1 {
k, v = split(token, "=")
step = 1
} else if strings.Index(token, ":") >= 1 {
k, v = split(token, ":")
step = 1
} else {
if len(os.Args) > 1 && pos <= len(os.Args)-1 && len(os.Args) > pos+1 && os.Args[pos+1][0] != '-' {
step, k, v = 2, token, os.Args[pos+1]
} else {
step, k, v = 1, token, ""
}
}
if isSingleFlag && len(k) != 1 {
panic(fmt.Sprintf(InvalidParam, k))
}
return step, k, v
}
// parseCmdLine 分解当前命令行,解析出参数, 放入context的map中
func parseCmdLine() {
pos := ctx.startIndex
state := -1 // 设置为前导参数解析阶段, 遇到第一个不在token后的且不带 - 的token,则认为是target
for pos < len(os.Args) {
token := os.Args[pos]
if token[0] == '-' {
token = token[1:]
step, k, v := processToken(token, pos)
if state == -1 {
ctx.preParams[k] = v
} else {
ctx.sufParams[k] = v
}
pos += step
} else {
ctx.target = token
state = 1
pos++
}
}
}
// showHelp 显示帮助信息
func showHelp() {
_, hasTagHelp := ctx.preParams["h"]
_, hasTagHelpFull := ctx.preParams["help"]
if hasTagHelp || hasTagHelpFull {
Usage()
os.Exit(0)
}
}