cmd/go, cmd/vet: make vet work with gccgo
[gcc.git] / libgo / go / cmd / go / internal / vet / vetflag.go
1 // Copyright 2017 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 package vet
6
7 import (
8 "flag"
9 "fmt"
10 "os"
11 "strings"
12
13 "cmd/go/internal/base"
14 "cmd/go/internal/cmdflag"
15 "cmd/go/internal/work"
16 )
17
18 const cmd = "vet"
19
20 // vetFlagDefn is the set of flags we process.
21 var vetFlagDefn = []*cmdflag.Defn{
22 // Note: Some flags, in particular -tags and -v, are known to
23 // vet but also defined as build flags. This works fine, so we
24 // don't define them here but use AddBuildFlags to init them.
25 // However some, like -x, are known to the build but not
26 // to vet. We handle them in vetFlags.
27
28 // local.
29 {Name: "all", BoolVar: new(bool)},
30 {Name: "asmdecl", BoolVar: new(bool)},
31 {Name: "assign", BoolVar: new(bool)},
32 {Name: "atomic", BoolVar: new(bool)},
33 {Name: "bool", BoolVar: new(bool)},
34 {Name: "buildtags", BoolVar: new(bool)},
35 {Name: "cgocall", BoolVar: new(bool)},
36 {Name: "composites", BoolVar: new(bool)},
37 {Name: "copylocks", BoolVar: new(bool)},
38 {Name: "httpresponse", BoolVar: new(bool)},
39 {Name: "lostcancel", BoolVar: new(bool)},
40 {Name: "methods", BoolVar: new(bool)},
41 {Name: "nilfunc", BoolVar: new(bool)},
42 {Name: "printf", BoolVar: new(bool)},
43 {Name: "printfuncs"},
44 {Name: "rangeloops", BoolVar: new(bool)},
45 {Name: "shadow", BoolVar: new(bool)},
46 {Name: "shadowstrict", BoolVar: new(bool)},
47 {Name: "shift", BoolVar: new(bool)},
48 {Name: "source", BoolVar: new(bool)},
49 {Name: "structtags", BoolVar: new(bool)},
50 {Name: "tests", BoolVar: new(bool)},
51 {Name: "unreachable", BoolVar: new(bool)},
52 {Name: "unsafeptr", BoolVar: new(bool)},
53 {Name: "unusedfuncs"},
54 {Name: "unusedresult", BoolVar: new(bool)},
55 {Name: "unusedstringmethods"},
56 }
57
58 var vetTool string
59
60 // add build flags to vetFlagDefn.
61 func init() {
62 var cmd base.Command
63 work.AddBuildFlags(&cmd)
64 cmd.Flag.StringVar(&vetTool, "vettool", "", "path to vet tool binary") // for cmd/vet tests; undocumented for now
65 cmd.Flag.VisitAll(func(f *flag.Flag) {
66 vetFlagDefn = append(vetFlagDefn, &cmdflag.Defn{
67 Name: f.Name,
68 Value: f.Value,
69 })
70 })
71 }
72
73 // vetFlags processes the command line, splitting it at the first non-flag
74 // into the list of flags and list of packages.
75 func vetFlags(args []string) (passToVet, packageNames []string) {
76 for i := 0; i < len(args); i++ {
77 if !strings.HasPrefix(args[i], "-") {
78 return args[:i], args[i:]
79 }
80
81 f, value, extraWord := cmdflag.Parse(cmd, vetFlagDefn, args, i)
82 if f == nil {
83 fmt.Fprintf(os.Stderr, "vet: flag %q not defined\n", args[i])
84 fmt.Fprintf(os.Stderr, "Run \"go help vet\" for more information\n")
85 os.Exit(2)
86 }
87 if f.Value != nil {
88 if err := f.Value.Set(value); err != nil {
89 base.Fatalf("invalid flag argument for -%s: %v", f.Name, err)
90 }
91 switch f.Name {
92 // Flags known to the build but not to vet, so must be dropped.
93 case "x", "n", "vettool", "compiler":
94 if extraWord {
95 args = append(args[:i], args[i+2:]...)
96 extraWord = false
97 } else {
98 args = append(args[:i], args[i+1:]...)
99 }
100 i--
101 }
102 }
103 if extraWord {
104 i++
105 }
106 }
107 return args, nil
108 }