Merge pull request #163 from pierrec/master

Option new methods
diff --git a/ini.go b/ini.go
index b8153f7..16e27c0 100644
--- a/ini.go
+++ b/ini.go
@@ -58,6 +58,8 @@
 // IniParser is a utility to read and write flags options from and to ini
 // formatted strings.
 type IniParser struct {
+	ParseAsDefaults bool // override default flags
+
 	parser *Parser
 }
 
@@ -539,6 +541,12 @@
 				continue
 			}
 
+			// ini value is ignored if override is set and
+			// value was previously set from non default
+			if i.ParseAsDefaults && !opt.isSetDefault {
+				continue
+			}
+
 			pval := &inival.Value
 
 			if !opt.canArgument() && len(inival.Value) == 0 {
diff --git a/ini_test.go b/ini_test.go
index dfe49ce..1d25d45 100644
--- a/ini_test.go
+++ b/ini_test.go
@@ -802,7 +802,7 @@
 	}
 
 	if opts.Values[1] != 222 {
-		t.Fatalf("Expected Values[0] to be 222, but got '%d'", opts.Values[1])
+		t.Fatalf("Expected Values[1] to be 222, but got '%d'", opts.Values[1])
 	}
 }
 
@@ -948,3 +948,74 @@
 		}
 	}
 }
+
+func TestIniOverwriteOptions(t *testing.T) {
+	var tests = []struct {
+		args     []string
+		expected string
+		toggled  bool
+	}{
+		{
+			args:     []string{},
+			expected: "from default",
+		},
+		{
+			args:     []string{"--value", "from CLI"},
+			expected: "from CLI",
+		},
+		{
+			args:     []string{"--config", "no file name"},
+			expected: "from INI",
+			toggled:  true,
+		},
+		{
+			args:     []string{"--value", "from CLI before", "--config", "no file name"},
+			expected: "from CLI before",
+			toggled:  true,
+		},
+		{
+			args:     []string{"--config", "no file name", "--value", "from CLI after"},
+			expected: "from CLI after",
+			toggled:  true,
+		},
+		{
+			args:     []string{"--toggle"},
+			toggled:  true,
+			expected: "from default",
+		},
+	}
+
+	for _, test := range tests {
+		var opts struct {
+			Config string `long:"config" no-ini:"true"`
+			Value  string `long:"value" default:"from default"`
+			Toggle bool   `long:"toggle"`
+		}
+
+		p := NewParser(&opts, Default)
+
+		_, err := p.ParseArgs(test.args)
+		if err != nil {
+			t.Fatalf("Unexpected error %s with args %+v", err, test.args)
+		}
+
+		if opts.Config != "" {
+			inip := NewIniParser(p)
+			inip.ParseAsDefaults = true
+
+			err = inip.Parse(bytes.NewBufferString("value = from INI\ntoggle = true"))
+			if err != nil {
+				t.Fatalf("Unexpected error %s with args %+v", err, test.args)
+			}
+		}
+
+		if opts.Value != test.expected {
+			t.Fatalf("Expected Value to be \"%s\" but was \"%s\" with args %+v", test.expected, opts.Value, test.args)
+		}
+
+		if opts.Toggle != test.toggled {
+			t.Fatalf("Expected Toggle to be \"%v\" but was \"%v\" with args %+v", test.toggled, opts.Toggle, test.args)
+		}
+
+	}
+}
diff --git a/option.go b/option.go
index b2a69c7..3635df3 100644
--- a/option.go
+++ b/option.go
@@ -82,6 +82,7 @@
 
 	tag            multiTag
 	isSet          bool
+	isSetDefault   bool
 	preventDefault bool
 
 	defaultLiteral string
@@ -262,11 +263,14 @@
 		}
 	}
 
+	option.isSetDefault = true
+
 	if len(usedDefault) > 0 {
 		option.empty()
 
 		for _, d := range usedDefault {
 			option.set(&d)
+			option.isSetDefault = true
 		}
 	} else {
 		tp := option.value.Type()
diff --git a/parser.go b/parser.go
index 137bc07..6477daa 100644
--- a/parser.go
+++ b/parser.go
@@ -203,6 +203,7 @@
 
 	p.eachOption(func(c *Command, g *Group, option *Option) {
 		option.isSet = false
+		option.isSetDefault = false
 		option.updateDefaultLiteral()
 	})