summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRob Pike <r@golang.org>2009-01-09 13:42:46 -0800
committerRob Pike <r@golang.org>2009-01-09 13:42:46 -0800
commit55a86a6a5ca0df4645eef264749af0c330629fb1 (patch)
tree3ebfa1a54e00ad1ed251c95c02b24b370a25b64d /src
parent725dda33073ae0af232272d86cbb6ca1029feeb3 (diff)
downloadgolang-55a86a6a5ca0df4645eef264749af0c330629fb1.tar.gz
simplify flag interface. no more BVal etc. you just get a pointer.
fixed everything except the tutorial. R=rsc DELTA=404 (94 added, 139 deleted, 171 changed) OCL=22414 CL=22422
Diffstat (limited to 'src')
-rw-r--r--src/lib/flag.go349
-rw-r--r--src/lib/net/dialgoogle_test.go5
-rw-r--r--src/lib/testing.go9
3 files changed, 162 insertions, 201 deletions
diff --git a/src/lib/flag.go b/src/lib/flag.go
index 6db76bbde..49294bc4e 100644
--- a/src/lib/flag.go
+++ b/src/lib/flag.go
@@ -8,21 +8,22 @@ package flag
* Flags
*
* Usage:
- * 1) Define flags using flag.String(), Bool(), or Int(). Int flag values have type int64. Example:
+ * 1) Define flags using flag.String(), Bool(), Int(), etc. Example:
* import flag "flag"
- * var i int64
- * var fi *flag.Flag = flag.Int("flagname", 1234, &i, "help message for flagname")
- * The pointer may be nil; if non-nil, it points to a cell of the appropriate type to store the
- * flag's value.
- *
+ * var ip *int = flag.Int("flagname", 1234, "help message for flagname")
+ * If you like, you can bind the flag to a variable using the Var() functions.
+ * var flagvar int
+ * func init() {
+ * flag.IntVar(&flagvar, "flagname", 1234, "help message for flagname")
+ * }
* 2) After all flags are defined, call
* flag.Parse()
* to parse the command line into the defined flags.
*
- * 3) Flags may then be used directly (getters are SVal, BVal, Ival) or through the associated
- * cell, if set:
- * print("fi has value ", fi.IVal(), "\n");
- * print("i has value ", i, "\n");
+ * 3) Flags may then be used directly. If you're using the flags themselves,
+ * they are all pointers; if you bind to variables, they're values.
+ * print("ip has value ", *ip, "\n");
+ * print("flagvar has value ", flagvar, "\n");
*
* 4) After parsing, flag.Arg(i) is the i'th argument after the flags.
* Args are indexed from 0 up to flag.NArg().
@@ -40,14 +41,7 @@ package flag
* Boolean flags may be 1, 0, t, f, true, false, TRUE, FALSE, True, False.
*/
-import fmt "fmt"
-
-//export Bool, Int, String
-//export Arg, NArg
-//export Parse
-//export Flag.BVal BUG: variable exported but not defined: Flag.BVal
-//export Flag.SVal BUG: variable exported but not defined: Flag.SVal
-//export Flag
+import "fmt"
// BUG: ctoi, atoi, atob belong elsewhere
func ctoi(c int64) int64 {
@@ -104,180 +98,123 @@ func atob(str string) (value bool, ok bool) {
type (
BoolValue struct;
IntValue struct;
+ Int64Value struct;
+ UintValue struct;
+ Uint64Value struct;
StringValue struct;
)
// -- Bool Value
type BoolValue struct {
- val bool;
p *bool;
}
func NewBoolValue(val bool, p *bool) *BoolValue {
- if p != nil {
- *p = val
- }
- return &BoolValue{val, p}
-}
-
-func (b *BoolValue) AsBool() *BoolValue {
- return b
-}
-
-func (b *BoolValue) AsInt() *IntValue {
- return nil
-}
-
-func (b *BoolValue) AsString() *StringValue {
- return nil
-}
-
-func (b *BoolValue) IsBool() bool {
- return true
-}
-
-func (b *BoolValue) IsInt() bool {
- return false
-}
-
-func (b *BoolValue) IsString() bool {
- return false
-}
-
-func (b *BoolValue) ValidValue(str string) bool {
- i, ok := atob(str);
- return ok;
+ *p = val;
+ return &BoolValue{p}
}
func (b *BoolValue) Set(val bool) {
- if b.p != nil {
- *b.p = val
- }
- b.val = val
+ *b.p = val;
}
func (b *BoolValue) Str() string {
- if b.val {
- return "true"
- }
- return "false"
+ return fmt.sprintf("%v", *b.p)
}
// -- Int Value
type IntValue struct {
- val int64;
- p *int64;
+ p *int;
}
-func NewIntValue(val int64, p *int64) *IntValue {
- if p != nil {
- *p = val
- }
- return &IntValue{val, p}
+func NewIntValue(val int, p *int) *IntValue {
+ *p = val;
+ return &IntValue{p}
}
-func (i *IntValue) AsBool() *BoolValue {
- return nil
+func (i *IntValue) Set(val int) {
+ *i.p = val;
}
-func (i *IntValue) AsInt() *IntValue {
- return i
+func (i *IntValue) Str() string {
+ return fmt.sprintf("%v", *i.p)
}
-func (i *IntValue) AsString() *StringValue{
- return nil
+// -- Int64 Value
+type Int64Value struct {
+ p *int64;
}
-func (i *IntValue) IsBool() bool {
- return false
+func NewInt64Value(val int64, p *int64) *Int64Value {
+ *p = val;
+ return &Int64Value{p}
}
-func (i *IntValue) IsInt() bool {
- return true
+func (i *Int64Value) Set(val int64) {
+ *i.p = val;
}
-func (i *IntValue) IsString() bool {
- return false
+func (i *Int64Value) Str() string {
+ return fmt.sprintf("%v", *i.p)
}
-func (i *IntValue) ValidValue(str string) bool {
- k, ok := atoi(str);
- return ok;
+// -- Uint Value
+type UintValue struct {
+ p *uint;
}
-func (i *IntValue) Set(val int64) {
- if i.p != nil {
- *i.p = val
- }
- i.val = val
+func NewUintValue(val uint, p *uint) *UintValue {
+ *p = val;
+ return &UintValue{p}
}
-func (i *IntValue) Str() string {
- return fmt.New().d64(i.val).str()
+func (i *UintValue) Set(val uint) {
+ *i.p = val
}
-// -- String Value
-type StringValue struct {
- val string;
- p *string;
+func (i *UintValue) Str() string {
+ return fmt.sprintf("%v", *i.p)
}
-func NewStringValue(val string, p *string) *StringValue {
- if p != nil {
- *p = val
- }
- return &StringValue{val, p}
-}
-
-func (e *StringValue) AsBool() *BoolValue {
- return nil
-}
-
-func (e *StringValue) AsInt() *IntValue {
- return nil
+// -- Uint64 Value
+type Uint64Value struct {
+ p *uint64;
}
-func (s *StringValue) AsString() *StringValue{
- return s
+func NewUint64Value(val uint64, p *uint64) *Uint64Value {
+ *p = val;
+ return &Uint64Value{p}
}
-func (s *StringValue) IsBool() bool {
- return false
+func (i *Uint64Value) Set(val uint64) {
+ *i.p = val;
}
-func (s *StringValue) IsInt() bool {
- return false
+func (i *Uint64Value) Str() string {
+ return fmt.sprintf("%v", *i.p)
}
-func (s *StringValue) IsString() bool {
- return true
+// -- String Value
+type StringValue struct {
+ p *string;
}
-func (s *StringValue) ValidValue(str string) bool {
- return true
+func NewStringValue(val string, p *string) *StringValue {
+ *p = val;
+ return &StringValue{p}
}
func (s *StringValue) Set(val string) {
- if s.p != nil {
- *s.p = val
- }
- s.val = val
+ *s.p = val;
}
func (s *StringValue) Str() string {
- return `"` + s.val + `"`
+ return fmt.sprintf("%#q", *s.p)
}
// -- Value interface
type Value interface {
- AsBool() *BoolValue;
- AsInt() *IntValue;
- AsString() *StringValue;
- IsBool() bool;
- IsInt() bool;
- IsString() bool;
- Str() string;
- ValidValue(str string) bool;
+ Str() string;
}
// -- Flag structure (internal)
@@ -285,37 +222,14 @@ export type Flag struct {
name string;
usage string;
value Value;
- next *Flag; // BUG: remove when we can iterate over maps
}
type Flags struct {
actual map[string] *Flag;
formal map[string] *Flag;
first_arg int;
- flag_list *Flag; // BUG: remove when we can iterate over maps
-}
-
-// --Customer's value getters
-func (f *Flag) BVal() bool {
- if !f.value.IsBool() {
- return false;
- }
- return f.value.AsBool().val;
-}
-
-func (f *Flag) IVal() int64 {
- if !f.value.IsInt() {
- return 0
- }
- return f.value.AsInt().val;
}
-func (f *Flag) SVal() string {
- if !f.value.IsString() {
- return "???";
- }
- return f.value.AsString().val;
-}
func New() *Flags {
f := new(Flags);
@@ -328,8 +242,7 @@ func New() *Flags {
var flags *Flags = New();
export func PrintDefaults() {
- // BUG: use map iteration when available
- for f := flags.flag_list; f != nil; f = f.next {
+ for k, f := range flags.formal {
print(" -", f.name, "=", f.value.Str(), ": ", f.usage, "\n");
}
}
@@ -360,7 +273,7 @@ export func NArg() int {
return sys.argc() - flags.first_arg
}
-func Add(name string, value Value, usage string) *Flag {
+func Add(name string, value Value, usage string) {
f := new(Flag);
f.name = name;
f.usage = usage;
@@ -371,21 +284,66 @@ func Add(name string, value Value, usage string) *Flag {
panic("flag redefinition");
}
flags.formal[name] = f;
- f.next = flags.flag_list; // BUG: remove when we can iterate over maps
- flags.flag_list = f; // BUG: remove when we can iterate over maps
- return f;
}
-export func Bool(name string, value bool, p *bool, usage string) *Flag {
- return Add(name, NewBoolValue(value, p), usage);
+export func Bool(name string, value bool, usage string) *bool {
+ p := new(bool);
+ Add(name, NewBoolValue(value, p), usage);
+ return p;
+}
+
+export func BoolVar(p *bool, name string, value bool, usage string) {
+ Add(name, NewBoolValue(value, p), usage);
+}
+
+export func Int(name string, value int, usage string) *int {
+ p := new(int);
+ Add(name, NewIntValue(value, p), usage);
+ return p;
+}
+
+export func IntVar(p *int, name string, value int, usage string) {
+ Add(name, NewIntValue(value, p), usage);
+}
+
+export func Int64(name string, value int64, usage string) *int64 {
+ p := new(int64);
+ Add(name, NewInt64Value(value, p), usage);
+ return p;
+}
+
+export func Int64Var(p *int64, name string, value int64, usage string) {
+ Add(name, NewInt64Value(value, p), usage);
+}
+
+export func Uint(name string, value uint, usage string) *uint {
+ p := new(uint);
+ Add(name, NewUintValue(value, p), usage);
+ return p;
+}
+
+export func UintVar(p *uint, name string, value uint, usage string) {
+ Add(name, NewUintValue(value, p), usage);
}
-export func Int(name string, value int64, p *int64, usage string) *Flag {
- return Add(name, NewIntValue(value, p), usage);
+export func Uint64(name string, value uint64, usage string) *uint64 {
+ p := new(uint64);
+ Add(name, NewUint64Value(value, p), usage);
+ return p;
}
-export func String(name, value string, p *string, usage string) *Flag {
- return Add(name, NewStringValue(value, p), usage);
+export func Uint64Var(p *uint64, name string, value uint64, usage string) {
+ Add(name, NewUint64Value(value, p), usage);
+}
+
+export func String(name, value string, usage string) *string {
+ p := new(string);
+ Add(name, NewStringValue(value, p), usage);
+ return p;
+}
+
+export func StringVar(p *string, name, value string, usage string) {
+ Add(name, NewStringValue(value, p), usage);
}
func (f *Flags) ParseOne(index int) (ok bool, next int)
@@ -436,48 +394,55 @@ func (f *Flags) ParseOne(index int) (ok bool, next int)
print("flag provided but not defined: -", name, "\n");
Usage();
}
- if !has_value && index < sys.argc()-1 && flag.value.ValidValue(sys.argv(index+1)) {
- // value is the next arg
- has_value = true;
- index++;
- value = sys.argv(index);
- }
- switch {
- case flag.value.IsBool():
- if has_value {
- k, ok := atob(value);
- if !ok {
- print("invalid boolean value ", value, " for flag: -", name, "\n");
- Usage();
- }
- flag.value.AsBool().Set(k)
- } else {
- flag.value.AsBool().Set(true)
- }
- case flag.value.IsInt():
- if !has_value {
- print("flag needs an argument: -", name, "\n");
+ if f, ok := flag.value.(*BoolValue); ok {
+ if has_value {
+ k, ok := atob(value);
+ if !ok {
+ print("invalid boolean value ", value, " for flag: -", name, "\n");
Usage();
}
+ f.Set(k)
+ } else {
+ f.Set(true)
+ }
+ } else {
+ // It must have a value, which might be the next argument.
+ if !has_value && index < sys.argc()-1 {
+ // value is the next arg
+ has_value = true;
+ index++;
+ value = sys.argv(index);
+ }
+ if !has_value {
+ print("flag needs an argument: -", name, "\n");
+ Usage();
+ }
+ if f, ok := flag.value.(*StringValue); ok {
+ f.Set(value)
+ } else {
+ // It's an integer flag. TODO(r): check for overflow?
k, ok := atoi(value);
if !ok {
print("invalid integer value ", value, " for flag: -", name, "\n");
Usage();
}
- flag.value.AsInt().Set(k);
- case flag.value.IsString():
- if !has_value {
- print("flag needs an argument: -", name, "\n");
- Usage();
+ if f, ok := flag.value.(*IntValue); ok {
+ f.Set(int(k));
+ } else if f, ok := flag.value.(*Int64Value); ok {
+ f.Set(k);
+ } else if f, ok := flag.value.(*UintValue); ok {
+ f.Set(uint(k));
+ } else if f, ok := flag.value.(*Uint64Value); ok {
+ f.Set(uint64(k));
}
- flag.value.AsString().Set(value)
+ }
}
flags.actual[name] = flag;
return true, index + 1
}
export func Parse() {
- for i := 1; i < sys.argc(); {
+ for i := 1; i < sys.argc(); {
ok, next := flags.ParseOne(i);
if next > 0 {
flags.first_arg = next;
diff --git a/src/lib/net/dialgoogle_test.go b/src/lib/net/dialgoogle_test.go
index 86ef5b91e..4a9f7ffa6 100644
--- a/src/lib/net/dialgoogle_test.go
+++ b/src/lib/net/dialgoogle_test.go
@@ -13,8 +13,7 @@ import (
)
// If an IPv6 tunnel is running (see go/stubl), we can try dialing a real IPv6 address.
-var ipv6 = false
-var ipv6_flag = flag.Bool("ipv6", false, &ipv6, "assume ipv6 tunnel is present")
+var ipv6 = flag.Bool("ipv6", false, "assume ipv6 tunnel is present")
// fd is already connected to www.google.com port 80.
// Run an HTTP request to fetch the main page.
@@ -67,7 +66,7 @@ var googleaddrs = []string {
export func TestDialGoogle(t *testing.T) {
// If no ipv6 tunnel, don't try the last address.
- if !ipv6 {
+ if !*ipv6 {
googleaddrs[len(googleaddrs)-1] = ""
}
diff --git a/src/lib/testing.go b/src/lib/testing.go
index 6d3275f00..12512f5d2 100644
--- a/src/lib/testing.go
+++ b/src/lib/testing.go
@@ -9,10 +9,7 @@ import (
"flag";
)
-var chatty bool;
-func init() {
- flag.Bool("chatty", false, &chatty, "chatty");
-}
+var chatty = flag.Bool("chatty", false, "chatty")
// Insert tabs after newlines - but not the last one
func Tabify(s string) string {
@@ -89,7 +86,7 @@ export func Main(tests []Test) {
println("testing: warning: no tests to run");
}
for i := 0; i < len(tests); i++ {
- if chatty {
+ if *chatty {
println("=== RUN ", tests[i].name);
}
t := new(T);
@@ -100,7 +97,7 @@ export func Main(tests []Test) {
println("--- FAIL:", tests[i].name);
print(t.errors);
ok = false;
- } else if chatty {
+ } else if *chatty {
println("--- PASS:", tests[i].name);
print(t.errors);
}