aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorspf13 <[email protected]>2013-09-24 16:33:33 -0400
committerspf13 <[email protected]>2014-04-26 15:16:00 -0600
commit87069834a9898e4d06e9f96e7c957b5d952ad100 (patch)
treea8c643e1b51043011c1ba0dde7507b07832a1c15
parentf235ad33d48a41975db57c0b52cec7b70529db0d (diff)
adding changed status on flag and some general clean upforOgier
-rw-r--r--flag.go201
1 files changed, 130 insertions, 71 deletions
diff --git a/flag.go b/flag.go
index b4b7b85..b09c34e 100644
--- a/flag.go
+++ b/flag.go
@@ -99,6 +99,7 @@
package pflag
import (
+ "bytes"
"errors"
"fmt"
"io"
@@ -145,6 +146,7 @@ type Flag struct {
Usage string // help message
Value Value // value as set
DefValue string // default value (as text); for usage message
+ Changed bool // If the user set the value (or if left to default)
}
// sortFlags returns the flags as a slice in lexicographical sorted order.
@@ -184,6 +186,10 @@ func (f *FlagSet) VisitAll(fn func(*Flag)) {
}
}
+func (f *FlagSet) HasFlags() bool {
+ return len(f.formal) > 0
+}
+
// VisitAll visits the command-line flags in lexicographical order, calling
// fn for each. It visits all flags, even those not set.
func VisitAll(fn func(*Flag)) {
@@ -229,6 +235,7 @@ func (f *FlagSet) Set(name, value string) error {
f.actual = make(map[string]*Flag)
}
f.actual[name] = flag
+ f.Lookup(name).Changed = true
return nil
}
@@ -255,6 +262,26 @@ func (f *FlagSet) PrintDefaults() {
})
}
+func (f *FlagSet) FlagUsages() string {
+ x := new(bytes.Buffer)
+
+ f.VisitAll(func(flag *Flag) {
+ format := "--%s=%s: %s\n"
+ if _, ok := flag.Value.(*stringValue); ok {
+ // put quotes on the value
+ format = "--%s=%q: %s\n"
+ }
+ if len(flag.Shorthand) > 0 {
+ format = " -%s, " + format
+ } else {
+ format = " %s " + format
+ }
+ fmt.Fprintf(x, format, flag.Shorthand, flag.Name, flag.DefValue, flag.Usage)
+ })
+
+ return x.String()
+}
+
// PrintDefaults prints to standard error the default values of all defined command-line flags.
func PrintDefaults() {
commandLine.PrintDefaults()
@@ -323,32 +350,36 @@ func (f *FlagSet) Var(value Value, name string, usage string) {
// Like Var, but accepts a shorthand letter that can be used after a single dash.
func (f *FlagSet) VarP(value Value, name, shorthand, usage string) {
// Remember the default value as a string; it won't change.
- flag := &Flag{name, shorthand, usage, value, value.String()}
- _, alreadythere := f.formal[name]
+ flag := &Flag{name, shorthand, usage, value, value.String(), false}
+ f.AddFlag(flag)
+}
+
+func (f *FlagSet) AddFlag(flag *Flag) {
+ _, alreadythere := f.formal[flag.Name]
if alreadythere {
- msg := fmt.Sprintf("%s flag redefined: %s", f.name, name)
+ msg := fmt.Sprintf("%s flag redefined: %s", f.name, flag.Name)
fmt.Fprintln(f.out(), msg)
panic(msg) // Happens only if flags are declared with identical names
}
if f.formal == nil {
f.formal = make(map[string]*Flag)
}
- f.formal[name] = flag
+ f.formal[flag.Name] = flag
- if len(shorthand) == 0 {
+ if len(flag.Shorthand) == 0 {
return
}
- if len(shorthand) > 1 {
- fmt.Fprintf(f.out(), "%s shorthand more than ASCII character: %s\n", f.name, shorthand)
+ if len(flag.Shorthand) > 1 {
+ fmt.Fprintf(f.out(), "%s shorthand more than ASCII character: %s\n", f.name, flag.Shorthand)
panic("shorthand is more than one character")
}
if f.shorthands == nil {
f.shorthands = make(map[byte]*Flag)
}
- c := shorthand[0]
+ c := flag.Shorthand[0]
old, alreadythere := f.shorthands[c]
if alreadythere {
- fmt.Fprintf(f.out(), "%s shorthand reused: %q for %s already used for %s\n", f.name, c, name, old.Name)
+ fmt.Fprintf(f.out(), "%s shorthand reused: %q for %s already used for %s\n", f.name, c, flag.Name, old.Name)
panic("shorthand redefinition")
}
f.shorthands[c] = flag
@@ -399,11 +430,96 @@ func (f *FlagSet) setFlag(flag *Flag, value string, origArg string) error {
f.actual = make(map[string]*Flag)
}
f.actual[flag.Name] = flag
-
+ flag.Changed = true
return nil
}
-func (f *FlagSet) parseArgs(args []string) error {
+func (f *FlagSet) parseLongArg(s string, args []string) (a []string, err error) {
+ a = args
+ if len(s) == 2 { // "--" terminates the flags
+ f.args = append(f.args, args...)
+ return
+ }
+ name := s[2:]
+ if len(name) == 0 || name[0] == '-' || name[0] == '=' {
+ err = f.failf("bad flag syntax: %s", s)
+ return
+ }
+ split := strings.SplitN(name, "=", 2)
+ name = split[0]
+ m := f.formal
+ flag, alreadythere := m[name] // BUG
+ if !alreadythere {
+ if name == "help" { // special case for nice help message.
+ f.usage()
+ return args, ErrHelp
+ }
+ err = f.failf("unknown flag: --%s", name)
+ return
+ }
+ if len(split) == 1 {
+ if _, ok := flag.Value.(*boolValue); !ok {
+ err = f.failf("flag needs an argument: %s", s)
+ return
+ }
+ f.setFlag(flag, "true", s)
+ } else {
+ if e := f.setFlag(flag, split[1], s); e != nil {
+ err = e
+ return
+ }
+ }
+ return args, nil
+}
+
+func (f *FlagSet) parseShortArg(s string, args []string) (a []string, err error) {
+ a = args
+ shorthands := s[1:]
+
+ for i := 0; i < len(shorthands); i++ {
+ c := shorthands[i]
+ flag, alreadythere := f.shorthands[c]
+ if !alreadythere {
+ if c == 'h' { // special case for nice help message.
+ f.usage()
+ err = ErrHelp
+ return
+ }
+ //TODO continue on error
+ err = f.failf("unknown shorthand flag: %q in -%s", c, shorthands)
+ if len(args) == 0 {
+ return
+ }
+ }
+ if alreadythere {
+ if _, ok := flag.Value.(*boolValue); ok {
+ f.setFlag(flag, "true", s)
+ continue
+ }
+ if i < len(shorthands)-1 {
+ if e := f.setFlag(flag, shorthands[i+1:], s); e != nil {
+ err = e
+ return
+ }
+ break
+ }
+ if len(args) == 0 {
+ err = f.failf("flag needs an argument: %q in -%s", c, shorthands)
+ return
+ }
+ if e := f.setFlag(flag, args[0], s); e != nil {
+ err = e
+ return
+ }
+ }
+ a = args[1:]
+ break // should be unnecessary
+ }
+
+ return
+}
+
+func (f *FlagSet) parseArgs(args []string) (err error) {
for len(args) > 0 {
s := args[0]
args = args[1:]
@@ -418,69 +534,12 @@ func (f *FlagSet) parseArgs(args []string) error {
}
if s[1] == '-' {
- if len(s) == 2 { // "--" terminates the flags
- f.args = append(f.args, args...)
- return nil
- }
- name := s[2:]
- if len(name) == 0 || name[0] == '-' || name[0] == '=' {
- return f.failf("bad flag syntax: %s", s)
- }
- split := strings.SplitN(name, "=", 2)
- name = split[0]
- m := f.formal
- flag, alreadythere := m[name] // BUG
- if !alreadythere {
- if name == "help" { // special case for nice help message.
- f.usage()
- return ErrHelp
- }
- return f.failf("unknown flag: --%s", name)
- }
- if len(split) == 1 {
- if _, ok := flag.Value.(*boolValue); !ok {
- return f.failf("flag needs an argument: %s", s)
- }
- f.setFlag(flag, "true", s)
- } else {
- if err := f.setFlag(flag, split[1], s); err != nil {
- return err
- }
- }
+ args, err = f.parseLongArg(s, args)
} else {
- shorthands := s[1:]
- for i := 0; i < len(shorthands); i++ {
- c := shorthands[i]
- flag, alreadythere := f.shorthands[c]
- if !alreadythere {
- if c == 'h' { // special case for nice help message.
- f.usage()
- return ErrHelp
- }
- return f.failf("unknown shorthand flag: %q in -%s", c, shorthands)
- }
- if _, ok := flag.Value.(*boolValue); ok {
- f.setFlag(flag, "true", s)
- continue
- }
- if i < len(shorthands)-1 {
- if err := f.setFlag(flag, shorthands[i+1:], s); err != nil {
- return err
- }
- break
- }
- if len(args) == 0 {
- return f.failf("flag needs an argument: %q in -%s", c, shorthands)
- }
- if err := f.setFlag(flag, args[0], s); err != nil {
- return err
- }
- args = args[1:]
- break // should be unnecessary
- }
+ args, err = f.parseShortArg(s, args)
}
}
- return nil
+ return
}
// Parse parses flag definitions from the argument list, which should not