Merge pull request #67 from zimmski/fix-overwriting-defaults

Fix overwriting defaults
diff --git a/group_private.go b/group_private.go
index 5242f5d..3ce957b 100644
--- a/group_private.go
+++ b/group_private.go
@@ -17,6 +17,12 @@
 	}
 }
 
+func (g *Group) clear() {
+	for _, option := range g.options {
+		option.clear()
+	}
+}
+
 func (g *Group) optionByName(name string, namematch func(*Option, string) bool) *Option {
 	prio := 0
 	var retopt *Option
diff --git a/help_test.go b/help_test.go
index fe77f6d..c0566cd 100644
--- a/help_test.go
+++ b/help_test.go
@@ -44,9 +44,12 @@
 	Verbose          []bool       `short:"v" long:"verbose" description:"Show verbose debug information" ini-name:"verbose"`
 	Call             func(string) `short:"c" description:"Call phone number" ini-name:"call"`
 	PtrSlice         []*string    `long:"ptrslice" description:"A slice of pointers to string"`
-	Default          string       `long:"default" default:"Some value" description:"Test default value"`
 	EmptyDescription bool         `long:"empty-description"`
 
+	Default      string            `long:"default" default:"Some value" description:"Test default value"`
+	DefaultArray []string          `long:"default-array" default:"Some value" default:"Another value" description:"Test default array value"`
+	DefaultMap   map[string]string `long:"default-map" default:"some:value" default:"another:value" description:"Testdefault map value"`
+
 	OnlyIni string `ini-name:"only-ini" description:"Option only available in ini"`
 
 	Other struct {
@@ -85,8 +88,10 @@
   -v, --verbose            Show verbose debug information
   -c=                      Call phone number
       --ptrslice=          A slice of pointers to string
-      --default=           Test default value (Some value)
       --empty-description
+      --default=           Test default value (Some value)
+      --default-array=     Test default array value (Some value, Another value)
+      --default-map=       Testdefault map value (some:value, another:value)
 
 Other Options:
   -s=                      A slice of strings (some, value)
@@ -147,10 +152,16 @@
 \fB--ptrslice\fP
 A slice of pointers to string
 .TP
+\fB--empty-description\fP
+.TP
 \fB--default\fP
 Test default value
 .TP
-\fB--empty-description\fP
+\fB--default-array\fP
+Test default array value
+.TP
+\fB--default-map\fP
+Testdefault map value
 .TP
 \fB-s\fP
 A slice of strings
diff --git a/ini_test.go b/ini_test.go
index d4e2d5b..976c962 100644
--- a/ini_test.go
+++ b/ini_test.go
@@ -38,10 +38,18 @@
 ; A slice of pointers to string
 ; PtrSlice =
 
+EmptyDescription = false
+
 ; Test default value
 Default = Some value
 
-EmptyDescription = false
+; Test default array value
+DefaultArray = Some value
+DefaultArray = Another value
+
+; Testdefault map value
+DefaultMap = some:value
+DefaultMap = another:value
 
 ; Option only available in ini
 only-ini =
@@ -71,11 +79,57 @@
 ; A slice of pointers to string
 ; PtrSlice =
 
+; EmptyDescription = false
+
 ; Test default value
 ; Default = Some value
 
+; Test default array value
+; DefaultArray = Some value
+; DefaultArray = Another value
+
+; Testdefault map value
+; DefaultMap = some:value
+; DefaultMap = another:value
+
+; Option only available in ini
+; only-ini =
+
+[Other Options]
+; A slice of strings
+; StringSlice = some
+; StringSlice = value
+
+; A map from string to int
+; int-map = a:1
+
+[command.A command]
+; Use for extra verbosity
+; ExtraVerbose =
+
+`,
+		},
+		{
+			[]string{"--default=New value", "--default-array=New value", "--default-map=new:value", "command"},
+			IniDefault | IniIncludeDefaults | IniCommentDefaults,
+			`[Application Options]
+; Show verbose debug information
+; verbose =
+
+; A slice of pointers to string
+; PtrSlice =
+
 ; EmptyDescription = false
 
+; Test default value
+Default = New value
+
+; Test default array value
+DefaultArray = New value
+
+; Testdefault map value
+DefaultMap = new:value
+
 ; Option only available in ini
 ; only-ini =
 
diff --git a/parser.go b/parser.go
index 504cf56..2c1e98f 100644
--- a/parser.go
+++ b/parser.go
@@ -7,6 +7,7 @@
 import (
 	"os"
 	"path"
+	"reflect"
 )
 
 // A Parser provides command line option parsing. It can contain several
@@ -130,6 +131,7 @@
 	p.eachCommand(func(c *Command) {
 		c.eachGroup(func(g *Group) {
 			g.storeDefaults()
+			g.clear()
 		})
 	}, true)
 
@@ -195,6 +197,29 @@
 	}
 
 	if s.err == nil {
+		p.eachCommand(func(c *Command) {
+			c.eachGroup(func(g *Group) {
+				for _, option := range g.options {
+					tp := option.value.Type()
+
+					switch tp.Kind() {
+					case reflect.Func:
+						// Skip
+					case reflect.Map:
+						if option.value.Len() == 0 {
+							for _, k := range option.defaultValue.MapKeys() {
+								option.value.SetMapIndex(k, option.defaultValue.MapIndex(k))
+							}
+						}
+					default:
+						if reflect.DeepEqual(option.value.Interface(), reflect.Zero(tp).Interface()) {
+							option.value.Set(option.defaultValue)
+						}
+					}
+				}
+			})
+		}, true)
+
 		s.checkRequired()
 	}