-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathparse.go
128 lines (119 loc) · 2.59 KB
/
parse.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
package args
import (
"sort"
"strings"
)
type Opts []string
func (opts Opts) index(opt string) int {
off := 1
if len(opt) > 1 {
off = 2
}
for i, o := range opts {
if len(o) >= 2 && o[0] == '-' {
if o[off:] == opt {
return i
}
}
}
return -1
}
// Has returns true if opt flag is in opts.
func (opts Opts) Has(opt string) bool {
return opts.index(opt) != -1
}
// Val return the value of the first occurrence of opt.
func (opts Opts) Val(opt string) string {
if idx := opts.index(opt); idx != -1 && idx+1 < len(opts) {
return opts[idx+1]
}
return ""
}
// Vals return the values of all occurrences of opt.
func (opts Opts) Vals(opt string) []string {
var vals []string
off := 1
if len(opt) > 1 {
off = 2
}
for i, o := range opts {
if len(o) >= 2 && o[0] == '-' {
if o[off:] == opt {
if i+1 < len(opts) {
i++
vals = append(vals, opts[i])
}
}
}
}
return vals
}
// Remove removes all occurrences of opt and return true if found.
func (opts *Opts) Remove(opt string) bool {
found := false
for idx := opts.index(opt); idx != -1 && idx < len(*opts); idx = opts.index(opt) {
*opts = append((*opts)[:idx], (*opts)[idx+1:]...)
found = true
}
return found
}
// Parse converts an HTTPie like argv into a list of curl options.
func Parse(argv Opts) (opts Opts) {
isForm := argv.Has("F") || argv.Has("form")
if isForm {
argv.Remove("F")
argv.Remove("form")
}
args := []string{}
sort.Strings(curlLongValues)
more := true
for i := 1; i < len(argv); i++ {
arg := argv[i]
if !more || len(arg) < 2 || arg[0] != '-' {
args = append(args, arg)
continue
}
if arg == "--" {
// Enf of opts marker
more = false
continue
}
if arg[1] == '-' {
opts = append(opts, arg)
if longHasValue(arg[2:]) && i+1 < len(argv) {
opts = append(opts, argv[i+1])
i++
}
continue
}
// Parse componed short args
for j := 1; j < len(arg); j++ {
opts = append(opts, string([]byte{'-', arg[j]}))
if strings.IndexByte(curlShortValues, arg[j]) != -1 {
// Short arg as value, it must be last in compound.
// The value is either the remaining or the next arg.
if j == len(arg)-1 {
if i+1 < len(argv) {
opts = append(opts, argv[i+1])
i++
}
} else {
opts = append(opts, arg[j+1:])
}
break
}
}
}
if len(args) > 0 {
postMode := PostModeJSON
if isForm {
postMode = PostModeFORM
}
opts = append(opts, parseFancyArgs(args, postMode)...)
}
return
}
func longHasValue(arg string) bool {
i := sort.SearchStrings(curlLongValues, arg)
return i < len(curlLongValues) && curlLongValues[i] == arg
}