From 3839e3a0f63c8acc4cb11a87b862f159e5b2aedc Mon Sep 17 00:00:00 2001
From: Victor Vieux <victor.vieux@docker.com>
Date: Wed, 19 Feb 2014 00:24:32 +0000
Subject: [PATCH] enable docker run -it

Docker-DCO-1.1-Signed-off-by: Victor Vieux <victor.vieux@docker.com> (github: vieux)
---
 pkg/mflag/example/example.go |  1 +
 pkg/mflag/flag.go            | 48 +++++++++++++++++++++++++++---------
 2 files changed, 37 insertions(+), 12 deletions(-)

diff --git a/pkg/mflag/example/example.go b/pkg/mflag/example/example.go
index fa26c97e1b..b0d25fbfc6 100644
--- a/pkg/mflag/example/example.go
+++ b/pkg/mflag/example/example.go
@@ -27,4 +27,5 @@ func main() {
 	fmt.Printf("b: %b\n", b)
 	fmt.Printf("-bool: %b\n", b2)
 	fmt.Printf("s/#hidden/-string(via lookup): %s\n", flag.Lookup("s").Value.String())
+	fmt.Printf("ARGS: %v\n", flag.Args())
 }
diff --git a/pkg/mflag/flag.go b/pkg/mflag/flag.go
index f721e04557..7a0e8bfb79 100644
--- a/pkg/mflag/flag.go
+++ b/pkg/mflag/flag.go
@@ -77,6 +77,9 @@ import (
 // ErrHelp is the error returned if the flag -help is invoked but no such flag is defined.
 var ErrHelp = errors.New("flag: help requested")
 
+// ErrRetry is the error returned if you need to try letter by letter
+var ErrRetry = errors.New("flag: retry")
+
 // -- bool Value
 type boolValue bool
 
@@ -733,21 +736,21 @@ func (f *FlagSet) usage() {
 }
 
 // parseOne parses one flag. It reports whether a flag was seen.
-func (f *FlagSet) parseOne() (bool, error) {
+func (f *FlagSet) parseOne() (bool, string, error) {
 	if len(f.args) == 0 {
-		return false, nil
+		return false, "", nil
 	}
 	s := f.args[0]
 	if len(s) == 0 || s[0] != '-' || len(s) == 1 {
-		return false, nil
+		return false, "", nil
 	}
 	if s[1] == '-' && len(s) == 2 { // "--" terminates the flags
 		f.args = f.args[1:]
-		return false, nil
+		return false, "", nil
 	}
 	name := s[1:]
 	if len(name) == 0 || name[0] == '=' {
-		return false, f.failf("bad flag syntax: %s", s)
+		return false, "", f.failf("bad flag syntax: %s", s)
 	}
 
 	// it's a flag. does it have an argument?
@@ -767,14 +770,14 @@ func (f *FlagSet) parseOne() (bool, error) {
 	if !alreadythere {
 		if name == "-help" || name == "help" || name == "h" { // special case for nice help message.
 			f.usage()
-			return false, ErrHelp
+			return false, "", ErrHelp
 		}
-		return false, f.failf("flag provided but not defined: -%s", name)
+		return false, name, ErrRetry
 	}
 	if fv, ok := flag.Value.(boolFlag); ok && fv.IsBoolFlag() { // special case: doesn't need an arg
 		if has_value {
 			if err := fv.Set(value); err != nil {
-				return false, f.failf("invalid boolean value %q for  -%s: %v", value, name, err)
+				return false, "", f.failf("invalid boolean value %q for  -%s: %v", value, name, err)
 			}
 		} else {
 			fv.Set("true")
@@ -787,17 +790,17 @@ func (f *FlagSet) parseOne() (bool, error) {
 			value, f.args = f.args[0], f.args[1:]
 		}
 		if !has_value {
-			return false, f.failf("flag needs an argument: -%s", name)
+			return false, "", f.failf("flag needs an argument: -%s", name)
 		}
 		if err := flag.Value.Set(value); err != nil {
-			return false, f.failf("invalid value %q for flag -%s: %v", value, name, err)
+			return false, "", f.failf("invalid value %q for flag -%s: %v", value, name, err)
 		}
 	}
 	if f.actual == nil {
 		f.actual = make(map[string]*Flag)
 	}
 	f.actual[name] = flag
-	return true, nil
+	return true, "", nil
 }
 
 // Parse parses flag definitions from the argument list, which should not
@@ -808,13 +811,34 @@ func (f *FlagSet) Parse(arguments []string) error {
 	f.parsed = true
 	f.args = arguments
 	for {
-		seen, err := f.parseOne()
+		seen, name, err := f.parseOne()
 		if seen {
 			continue
 		}
 		if err == nil {
 			break
 		}
+		if err == ErrRetry {
+			if len(name) > 1 {
+				err = nil
+				for _, letter := range strings.Split(name, "") {
+					f.args = append([]string{"-" + letter}, f.args...)
+					seen2, _, err2 := f.parseOne()
+					if seen2 {
+						continue
+					}
+					if err2 != nil {
+						err = f.failf("flag provided but not defined: -%s", name)
+						break
+					}
+				}
+				if err == nil {
+					continue
+				}
+			} else {
+				err = f.failf("flag provided but not defined: -%s", name)
+			}
+		}
 		switch f.errorHandling {
 		case ContinueOnError:
 			return err