1
2
3
4
5 package base
6
7 import (
8 "flag"
9 "fmt"
10 "runtime"
11 "strings"
12
13 "cmd/go/internal/cfg"
14 "cmd/internal/quoted"
15 )
16
17 var goflags []string
18
19
20
21
22 func GOFLAGS() []string {
23 InitGOFLAGS()
24 return goflags
25 }
26
27
28
29 func InitGOFLAGS() {
30 if goflags != nil {
31 return
32 }
33
34
35
36
37
38 hideErrors := cfg.CmdName == "env" || cfg.CmdName == "bug"
39
40 var err error
41 goflags, err = quoted.Split(cfg.Getenv("GOFLAGS"))
42 if err != nil {
43 if hideErrors {
44 return
45 }
46 Fatalf("go: parsing $GOFLAGS: %v", err)
47 }
48
49 if len(goflags) == 0 {
50
51 goflags = []string{}
52 return
53 }
54
55
56
57
58 for _, f := range goflags {
59
60 if !strings.HasPrefix(f, "-") || f == "-" || f == "--" || strings.HasPrefix(f, "---") || strings.HasPrefix(f, "-=") || strings.HasPrefix(f, "--=") {
61 if hideErrors {
62 continue
63 }
64 Fatalf("go: parsing $GOFLAGS: non-flag %q", f)
65 }
66
67 name := f[1:]
68 if name[0] == '-' {
69 name = name[1:]
70 }
71 if i := strings.Index(name, "="); i >= 0 {
72 name = name[:i]
73 }
74 if !hasFlag(Go, name) {
75 if hideErrors {
76 continue
77 }
78 Fatalf("go: parsing $GOFLAGS: unknown flag -%s", name)
79 }
80 }
81 }
82
83
84
85 type boolFlag interface {
86 flag.Value
87 IsBoolFlag() bool
88 }
89
90
91 func SetFromGOFLAGS(flags *flag.FlagSet) {
92 InitGOFLAGS()
93
94
95
96
97
98 where := "$GOFLAGS"
99 if runtime.GOOS == "windows" {
100 where = "%GOFLAGS%"
101 }
102 for _, goflag := range goflags {
103 name, value, hasValue := goflag, "", false
104
105
106 if i := strings.Index(goflag, "="); i == 0 {
107 continue
108 } else if i > 0 {
109 name, value, hasValue = goflag[:i], goflag[i+1:], true
110 }
111 if strings.HasPrefix(name, "--") {
112 name = name[1:]
113 }
114 f := flags.Lookup(name[1:])
115 if f == nil {
116 continue
117 }
118
119
120
121
122 if fb, ok := f.Value.(boolFlag); ok && fb.IsBoolFlag() {
123 if hasValue {
124 if err := flags.Set(f.Name, value); err != nil {
125 fmt.Fprintf(flags.Output(), "go: invalid boolean value %q for flag %s (from %s): %v\n", value, name, where, err)
126 flags.Usage()
127 }
128 } else {
129 if err := flags.Set(f.Name, "true"); err != nil {
130 fmt.Fprintf(flags.Output(), "go: invalid boolean flag %s (from %s): %v\n", name, where, err)
131 flags.Usage()
132 }
133 }
134 } else {
135 if !hasValue {
136 fmt.Fprintf(flags.Output(), "go: flag needs an argument: %s (from %s)\n", name, where)
137 flags.Usage()
138 }
139 if err := flags.Set(f.Name, value); err != nil {
140 fmt.Fprintf(flags.Output(), "go: invalid value %q for flag %s (from %s): %v\n", value, name, where, err)
141 flags.Usage()
142 }
143 }
144 }
145 }
146
147
148 func InGOFLAGS(flag string) bool {
149 for _, goflag := range GOFLAGS() {
150 name := goflag
151 if strings.HasPrefix(name, "--") {
152 name = name[1:]
153 }
154 if i := strings.Index(name, "="); i >= 0 {
155 name = name[:i]
156 }
157 if name == flag {
158 return true
159 }
160 }
161 return false
162 }
163
View as plain text