github.com/kdevb0x/go@v0.0.0-20180115030120-39687051e9e7/src/cmd/internal/objabi/flag.go (about) 1 // Copyright 2015 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 objabi 6 7 import ( 8 "flag" 9 "fmt" 10 "os" 11 "strconv" 12 "strings" 13 ) 14 15 func Flagcount(name, usage string, val *int) { 16 flag.Var((*count)(val), name, usage) 17 } 18 19 func Flagfn1(name, usage string, f func(string)) { 20 flag.Var(fn1(f), name, usage) 21 } 22 23 func Flagprint(fd int) { 24 if fd == 1 { 25 flag.CommandLine.SetOutput(os.Stdout) 26 } 27 flag.PrintDefaults() 28 } 29 30 func Flagparse(usage func()) { 31 flag.Usage = usage 32 flag.Parse() 33 } 34 35 func AddVersionFlag() { 36 flag.Var(versionFlag{}, "V", "print version and exit") 37 } 38 39 var buildID string // filled in by linker 40 41 type versionFlag struct{} 42 43 func (versionFlag) IsBoolFlag() bool { return true } 44 func (versionFlag) Get() interface{} { return nil } 45 func (versionFlag) String() string { return "" } 46 func (versionFlag) Set(s string) error { 47 name := os.Args[0] 48 name = name[strings.LastIndex(name, `/`)+1:] 49 name = name[strings.LastIndex(name, `\`)+1:] 50 name = strings.TrimSuffix(name, ".exe") 51 p := Expstring() 52 if p == DefaultExpstring() { 53 p = "" 54 } 55 sep := "" 56 if p != "" { 57 sep = " " 58 } 59 60 // The go command invokes -V=full to get a unique identifier 61 // for this tool. It is assumed that the release version is sufficient 62 // for releases, but during development we include the full 63 // build ID of the binary, so that if the compiler is changed and 64 // rebuilt, we notice and rebuild all packages. 65 if s == "full" && strings.HasPrefix(Version, "devel") { 66 p += " buildID=" + buildID 67 } 68 fmt.Printf("%s version %s%s%s\n", name, Version, sep, p) 69 os.Exit(0) 70 return nil 71 } 72 73 // count is a flag.Value that is like a flag.Bool and a flag.Int. 74 // If used as -name, it increments the count, but -name=x sets the count. 75 // Used for verbose flag -v. 76 type count int 77 78 func (c *count) String() string { 79 return fmt.Sprint(int(*c)) 80 } 81 82 func (c *count) Set(s string) error { 83 switch s { 84 case "true": 85 *c++ 86 case "false": 87 *c = 0 88 default: 89 n, err := strconv.Atoi(s) 90 if err != nil { 91 return fmt.Errorf("invalid count %q", s) 92 } 93 *c = count(n) 94 } 95 return nil 96 } 97 98 func (c *count) Get() interface{} { 99 return int(*c) 100 } 101 102 func (c *count) IsBoolFlag() bool { 103 return true 104 } 105 106 func (c *count) IsCountFlag() bool { 107 return true 108 } 109 110 type fn0 func() 111 112 func (f fn0) Set(s string) error { 113 f() 114 return nil 115 } 116 117 func (f fn0) Get() interface{} { return nil } 118 119 func (f fn0) String() string { return "" } 120 121 func (f fn0) IsBoolFlag() bool { 122 return true 123 } 124 125 type fn1 func(string) 126 127 func (f fn1) Set(s string) error { 128 f(s) 129 return nil 130 } 131 132 func (f fn1) String() string { return "" }