...
Source file src/pkg/cmd/go/internal/cmdflag/flag.go
1
2
3
4
5
6 package cmdflag
7
8 import (
9 "flag"
10 "fmt"
11 "os"
12 "strconv"
13 "strings"
14
15 "cmd/go/internal/base"
16 )
17
18
19
20
21
22
23
24 type Defn struct {
25 Name string
26 BoolVar *bool
27 Value flag.Value
28 PassToTest bool
29 Present bool
30 }
31
32
33 func IsBool(v flag.Value) bool {
34 vv, ok := v.(interface {
35 IsBoolFlag() bool
36 })
37 if ok {
38 return vv.IsBoolFlag()
39 }
40 return false
41 }
42
43
44 func SetBool(cmd string, flag *bool, value string) {
45 x, err := strconv.ParseBool(value)
46 if err != nil {
47 SyntaxError(cmd, "illegal bool flag value "+value)
48 }
49 *flag = x
50 }
51
52
53 func SetInt(cmd string, flag *int, value string) {
54 x, err := strconv.Atoi(value)
55 if err != nil {
56 SyntaxError(cmd, "illegal int flag value "+value)
57 }
58 *flag = x
59 }
60
61
62 func SyntaxError(cmd, msg string) {
63 fmt.Fprintf(os.Stderr, "go %s: %s\n", cmd, msg)
64 if cmd == "test" {
65 fmt.Fprintf(os.Stderr, `run "go help %s" or "go help testflag" for more information`+"\n", cmd)
66 } else {
67 fmt.Fprintf(os.Stderr, `run "go help %s" for more information`+"\n", cmd)
68 }
69 base.SetExitStatus(2)
70 base.Exit()
71 }
72
73
74 func AddKnownFlags(cmd string, defns []*Defn) {
75 for _, f := range defns {
76 base.AddKnownFlag(f.Name)
77 base.AddKnownFlag(cmd + "." + f.Name)
78 }
79 }
80
81
82
83
84 func Parse(cmd string, usage func(), defns []*Defn, args []string, i int) (f *Defn, value string, extra bool) {
85 arg := args[i]
86 if strings.HasPrefix(arg, "--") {
87 arg = arg[1:]
88 }
89 switch arg {
90 case "-?", "-h", "-help":
91 usage()
92 }
93 if arg == "" || arg[0] != '-' {
94 return
95 }
96 name := arg[1:]
97
98 name = strings.TrimPrefix(name, cmd+".")
99 equals := strings.Index(name, "=")
100 if equals >= 0 {
101 value = name[equals+1:]
102 name = name[:equals]
103 }
104 for _, f = range defns {
105 if name == f.Name {
106
107 if f.BoolVar != nil || IsBool(f.Value) {
108 if equals < 0 {
109 value = "true"
110 } else {
111
112 SetBool(cmd, new(bool), value)
113 }
114 } else {
115 extra = equals < 0
116 if extra {
117 if i+1 >= len(args) {
118 SyntaxError(cmd, "missing argument for flag "+f.Name)
119 }
120 value = args[i+1]
121 }
122 }
123 if f.Present {
124 SyntaxError(cmd, f.Name+" flag may be set only once")
125 }
126 f.Present = true
127 return
128 }
129 }
130 f = nil
131 return
132 }
133
134
135
136
137 func FindGOFLAGS(defns []*Defn) []string {
138 var flags []string
139 for _, flag := range base.GOFLAGS() {
140
141
142
143
144
145 if strings.HasPrefix(flag, "--") {
146 flag = flag[1:]
147 }
148 name := flag[1:]
149 if i := strings.Index(name, "="); i >= 0 {
150 name = name[:i]
151 }
152 for _, f := range defns {
153 if name == f.Name {
154 flags = append(flags, flag)
155 break
156 }
157 }
158 }
159 return flags
160 }
161
View as plain text