Home | History | Annotate | Download | only in objabi
      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 "" }
    133