1// Copyright 2012 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
5package main
6
7import (
8	"flag"
9	"fmt"
10	"os"
11	"strconv"
12)
13
14// cmdtab records the available commands.
15var cmdtab = []struct {
16	name string
17	f    func()
18}{
19	{"banner", cmdbanner},
20	{"bootstrap", cmdbootstrap},
21	{"clean", cmdclean},
22	{"env", cmdenv},
23	{"install", cmdinstall},
24	{"list", cmdlist},
25	{"test", cmdtest},
26	{"version", cmdversion},
27}
28
29// The OS-specific main calls into the portable code here.
30func xmain() {
31	if len(os.Args) < 2 {
32		usage()
33	}
34	cmd := os.Args[1]
35	os.Args = os.Args[1:] // for flag parsing during cmd
36	for _, ct := range cmdtab {
37		if ct.name == cmd {
38			flag.Usage = func() {
39				fmt.Fprintf(os.Stderr, "usage: go tool dist %s [options]\n", cmd)
40				flag.PrintDefaults()
41				os.Exit(2)
42			}
43			ct.f()
44			return
45		}
46	}
47
48	xprintf("unknown command %s\n", cmd)
49	usage()
50}
51
52func xflagparse(maxargs int) {
53	flag.Var((*count)(&vflag), "v", "verbosity")
54	flag.Parse()
55	if maxargs >= 0 && flag.NArg() > maxargs {
56		flag.Usage()
57	}
58}
59
60// count is a flag.Value that is like a flag.Bool and a flag.Int.
61// If used as -name, it increments the count, but -name=x sets the count.
62// Used for verbose flag -v.
63type count int
64
65func (c *count) String() string {
66	return fmt.Sprint(int(*c))
67}
68
69func (c *count) Set(s string) error {
70	switch s {
71	case "true":
72		*c++
73	case "false":
74		*c = 0
75	default:
76		n, err := strconv.Atoi(s)
77		if err != nil {
78			return fmt.Errorf("invalid count %q", s)
79		}
80		*c = count(n)
81	}
82	return nil
83}
84
85func (c *count) IsBoolFlag() bool {
86	return true
87}
88