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
This commit is contained in:
Rob Pike 2009-01-09 13:42:46 -08:00
parent 863dafb9ae
commit c45d2a767c
10 changed files with 236 additions and 278 deletions

View file

@ -8,21 +8,22 @@ package flag
* Flags * Flags
* *
* Usage: * 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" * import flag "flag"
* var i int64 * var ip *int = flag.Int("flagname", 1234, "help message for flagname")
* var fi *flag.Flag = flag.Int("flagname", 1234, &i, "help message for flagname") * If you like, you can bind the flag to a variable using the Var() functions.
* The pointer may be nil; if non-nil, it points to a cell of the appropriate type to store the * var flagvar int
* flag's value. * func init() {
* * flag.IntVar(&flagvar, "flagname", 1234, "help message for flagname")
* }
* 2) After all flags are defined, call * 2) After all flags are defined, call
* flag.Parse() * flag.Parse()
* to parse the command line into the defined flags. * 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 * 3) Flags may then be used directly. If you're using the flags themselves,
* cell, if set: * they are all pointers; if you bind to variables, they're values.
* print("fi has value ", fi.IVal(), "\n"); * print("ip has value ", *ip, "\n");
* print("i has value ", i, "\n"); * print("flagvar has value ", flagvar, "\n");
* *
* 4) After parsing, flag.Arg(i) is the i'th argument after the flags. * 4) After parsing, flag.Arg(i) is the i'th argument after the flags.
* Args are indexed from 0 up to flag.NArg(). * 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. * Boolean flags may be 1, 0, t, f, true, false, TRUE, FALSE, True, False.
*/ */
import fmt "fmt" import "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
// BUG: ctoi, atoi, atob belong elsewhere // BUG: ctoi, atoi, atob belong elsewhere
func ctoi(c int64) int64 { func ctoi(c int64) int64 {
@ -104,180 +98,123 @@ func atob(str string) (value bool, ok bool) {
type ( type (
BoolValue struct; BoolValue struct;
IntValue struct; IntValue struct;
Int64Value struct;
UintValue struct;
Uint64Value struct;
StringValue struct; StringValue struct;
) )
// -- Bool Value // -- Bool Value
type BoolValue struct { type BoolValue struct {
val bool;
p *bool; p *bool;
} }
func NewBoolValue(val bool, p *bool) *BoolValue { func NewBoolValue(val bool, p *bool) *BoolValue {
if p != nil { *p = val;
*p = val return &BoolValue{p}
}
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;
} }
func (b *BoolValue) Set(val bool) { func (b *BoolValue) Set(val bool) {
if b.p != nil { *b.p = val;
*b.p = val
}
b.val = val
} }
func (b *BoolValue) Str() string { func (b *BoolValue) Str() string {
if b.val { return fmt.sprintf("%v", *b.p)
return "true"
}
return "false"
} }
// -- Int Value // -- Int Value
type IntValue struct { type IntValue struct {
val int64; p *int;
p *int64;
} }
func NewIntValue(val int64, p *int64) *IntValue { func NewIntValue(val int, p *int) *IntValue {
if p != nil { *p = val;
*p = val return &IntValue{p}
}
return &IntValue{val, p}
} }
func (i *IntValue) AsBool() *BoolValue { func (i *IntValue) Set(val int) {
return nil *i.p = val;
}
func (i *IntValue) AsInt() *IntValue {
return i
}
func (i *IntValue) AsString() *StringValue{
return nil
}
func (i *IntValue) IsBool() bool {
return false
}
func (i *IntValue) IsInt() bool {
return true
}
func (i *IntValue) IsString() bool {
return false
}
func (i *IntValue) ValidValue(str string) bool {
k, ok := atoi(str);
return ok;
}
func (i *IntValue) Set(val int64) {
if i.p != nil {
*i.p = val
}
i.val = val
} }
func (i *IntValue) Str() string { func (i *IntValue) Str() string {
return fmt.New().d64(i.val).str() return fmt.sprintf("%v", *i.p)
}
// -- Int64 Value
type Int64Value struct {
p *int64;
}
func NewInt64Value(val int64, p *int64) *Int64Value {
*p = val;
return &Int64Value{p}
}
func (i *Int64Value) Set(val int64) {
*i.p = val;
}
func (i *Int64Value) Str() string {
return fmt.sprintf("%v", *i.p)
}
// -- Uint Value
type UintValue struct {
p *uint;
}
func NewUintValue(val uint, p *uint) *UintValue {
*p = val;
return &UintValue{p}
}
func (i *UintValue) Set(val uint) {
*i.p = val
}
func (i *UintValue) Str() string {
return fmt.sprintf("%v", *i.p)
}
// -- Uint64 Value
type Uint64Value struct {
p *uint64;
}
func NewUint64Value(val uint64, p *uint64) *Uint64Value {
*p = val;
return &Uint64Value{p}
}
func (i *Uint64Value) Set(val uint64) {
*i.p = val;
}
func (i *Uint64Value) Str() string {
return fmt.sprintf("%v", *i.p)
} }
// -- String Value // -- String Value
type StringValue struct { type StringValue struct {
val string;
p *string; p *string;
} }
func NewStringValue(val string, p *string) *StringValue { func NewStringValue(val string, p *string) *StringValue {
if p != nil { *p = val;
*p = val return &StringValue{p}
}
return &StringValue{val, p}
}
func (e *StringValue) AsBool() *BoolValue {
return nil
}
func (e *StringValue) AsInt() *IntValue {
return nil
}
func (s *StringValue) AsString() *StringValue{
return s
}
func (s *StringValue) IsBool() bool {
return false
}
func (s *StringValue) IsInt() bool {
return false
}
func (s *StringValue) IsString() bool {
return true
}
func (s *StringValue) ValidValue(str string) bool {
return true
} }
func (s *StringValue) Set(val string) { func (s *StringValue) Set(val string) {
if s.p != nil { *s.p = val;
*s.p = val
}
s.val = val
} }
func (s *StringValue) Str() string { func (s *StringValue) Str() string {
return `"` + s.val + `"` return fmt.sprintf("%#q", *s.p)
} }
// -- Value interface // -- Value interface
type Value interface { type Value interface {
AsBool() *BoolValue; Str() string;
AsInt() *IntValue;
AsString() *StringValue;
IsBool() bool;
IsInt() bool;
IsString() bool;
Str() string;
ValidValue(str string) bool;
} }
// -- Flag structure (internal) // -- Flag structure (internal)
@ -285,37 +222,14 @@ export type Flag struct {
name string; name string;
usage string; usage string;
value Value; value Value;
next *Flag; // BUG: remove when we can iterate over maps
} }
type Flags struct { type Flags struct {
actual map[string] *Flag; actual map[string] *Flag;
formal map[string] *Flag; formal map[string] *Flag;
first_arg int; 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 { func New() *Flags {
f := new(Flags); f := new(Flags);
@ -328,8 +242,7 @@ func New() *Flags {
var flags *Flags = New(); var flags *Flags = New();
export func PrintDefaults() { export func PrintDefaults() {
// BUG: use map iteration when available for k, f := range flags.formal {
for f := flags.flag_list; f != nil; f = f.next {
print(" -", f.name, "=", f.value.Str(), ": ", f.usage, "\n"); print(" -", f.name, "=", f.value.Str(), ": ", f.usage, "\n");
} }
} }
@ -360,7 +273,7 @@ export func NArg() int {
return sys.argc() - flags.first_arg 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 := new(Flag);
f.name = name; f.name = name;
f.usage = usage; f.usage = usage;
@ -371,21 +284,66 @@ func Add(name string, value Value, usage string) *Flag {
panic("flag redefinition"); panic("flag redefinition");
} }
flags.formal[name] = f; 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 { export func Bool(name string, value bool, usage string) *bool {
return Add(name, NewBoolValue(value, p), usage); p := new(bool);
Add(name, NewBoolValue(value, p), usage);
return p;
} }
export func Int(name string, value int64, p *int64, usage string) *Flag { export func BoolVar(p *bool, name string, value bool, usage string) {
return Add(name, NewIntValue(value, p), usage); Add(name, NewBoolValue(value, p), usage);
} }
export func String(name, value string, p *string, usage string) *Flag { export func Int(name string, value int, usage string) *int {
return Add(name, NewStringValue(value, p), usage); 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 Uint64(name string, value uint64, usage string) *uint64 {
p := new(uint64);
Add(name, NewUint64Value(value, p), usage);
return p;
}
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) 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"); print("flag provided but not defined: -", name, "\n");
Usage(); Usage();
} }
if !has_value && index < sys.argc()-1 && flag.value.ValidValue(sys.argv(index+1)) { if f, ok := flag.value.(*BoolValue); ok {
// value is the next arg if has_value {
has_value = true; k, ok := atob(value);
index++; if !ok {
value = sys.argv(index); print("invalid boolean value ", value, " for flag: -", name, "\n");
}
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");
Usage(); 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); k, ok := atoi(value);
if !ok { if !ok {
print("invalid integer value ", value, " for flag: -", name, "\n"); print("invalid integer value ", value, " for flag: -", name, "\n");
Usage(); Usage();
} }
flag.value.AsInt().Set(k); if f, ok := flag.value.(*IntValue); ok {
case flag.value.IsString(): f.Set(int(k));
if !has_value { } else if f, ok := flag.value.(*Int64Value); ok {
print("flag needs an argument: -", name, "\n"); f.Set(k);
Usage(); } 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; flags.actual[name] = flag;
return true, index + 1 return true, index + 1
} }
export func Parse() { export func Parse() {
for i := 1; i < sys.argc(); { for i := 1; i < sys.argc(); {
ok, next := flags.ParseOne(i); ok, next := flags.ParseOne(i);
if next > 0 { if next > 0 {
flags.first_arg = next; flags.first_arg = next;

View file

@ -13,8 +13,7 @@ import (
) )
// If an IPv6 tunnel is running (see go/stubl), we can try dialing a real IPv6 address. // If an IPv6 tunnel is running (see go/stubl), we can try dialing a real IPv6 address.
var ipv6 = false var ipv6 = flag.Bool("ipv6", false, "assume ipv6 tunnel is present")
var ipv6_flag = flag.Bool("ipv6", false, &ipv6, "assume ipv6 tunnel is present")
// fd is already connected to www.google.com port 80. // fd is already connected to www.google.com port 80.
// Run an HTTP request to fetch the main page. // Run an HTTP request to fetch the main page.
@ -67,7 +66,7 @@ var googleaddrs = []string {
export func TestDialGoogle(t *testing.T) { export func TestDialGoogle(t *testing.T) {
// If no ipv6 tunnel, don't try the last address. // If no ipv6 tunnel, don't try the last address.
if !ipv6 { if !*ipv6 {
googleaddrs[len(googleaddrs)-1] = "" googleaddrs[len(googleaddrs)-1] = ""
} }

View file

@ -9,10 +9,7 @@ import (
"flag"; "flag";
) )
var chatty bool; var chatty = flag.Bool("chatty", false, "chatty")
func init() {
flag.Bool("chatty", false, &chatty, "chatty");
}
// Insert tabs after newlines - but not the last one // Insert tabs after newlines - but not the last one
func Tabify(s string) string { func Tabify(s string) string {
@ -89,7 +86,7 @@ export func Main(tests []Test) {
println("testing: warning: no tests to run"); println("testing: warning: no tests to run");
} }
for i := 0; i < len(tests); i++ { for i := 0; i < len(tests); i++ {
if chatty { if *chatty {
println("=== RUN ", tests[i].name); println("=== RUN ", tests[i].name);
} }
t := new(T); t := new(T);
@ -100,7 +97,7 @@ export func Main(tests []Test) {
println("--- FAIL:", tests[i].name); println("--- FAIL:", tests[i].name);
print(t.errors); print(t.errors);
ok = false; ok = false;
} else if chatty { } else if *chatty {
println("--- PASS:", tests[i].name); println("--- PASS:", tests[i].name);
print(t.errors); print(t.errors);
} }

View file

@ -14,12 +14,11 @@ import (
"malloc"; "malloc";
) )
var chatty bool; var chatty = flag.Bool("v", false, "chatty");
var chatty_flag = flag.Bool("v", false, &chatty, "chatty");
func main() { func main() {
malloc.Free(malloc.Alloc(1)); malloc.Free(malloc.Alloc(1));
if chatty { if *chatty {
fmt.printf("%+v %v\n", *malloc.GetStats(), uint64(0)); fmt.printf("%+v %v\n", *malloc.GetStats(), uint64(0));
} }
} }

View file

@ -15,15 +15,14 @@ import (
"unsafe"; "unsafe";
) )
var chatty bool; var chatty = flag.Bool("v", false, "chatty");
var chatty_flag = flag.Bool("v", false, &chatty, "chatty");
var footprint uint64; var footprint uint64;
var allocated uint64; var allocated uint64;
func bigger() { func bigger() {
if f := malloc.GetStats().sys; footprint < f { if f := malloc.GetStats().sys; footprint < f {
footprint = f; footprint = f;
if chatty { if *chatty {
println("Footprint", footprint, " for ", allocated); println("Footprint", footprint, " for ", allocated);
} }
if footprint > 1e9 { if footprint > 1e9 {
@ -58,7 +57,7 @@ func main() {
// prime(); // prime();
var blocks [1] struct { base *byte; siz uint64; }; var blocks [1] struct { base *byte; siz uint64; };
for i := 0; i < 1<<12; i++ { for i := 0; i < 1<<12; i++ {
if i%(1<<10) == 0 && chatty { if i%(1<<10) == 0 && *chatty {
println(i); println(i);
} }
b := rand.rand() % len(blocks); b := rand.rand() % len(blocks);

View file

@ -13,14 +13,13 @@ import (
"malloc" "malloc"
) )
var chatty bool; var chatty = flag.Bool("v", false, "chatty");
var chatty_flag = flag.Bool("v", false, &chatty, "chatty");
var oldsys uint64; var oldsys uint64;
func bigger() { func bigger() {
if st := malloc.GetStats(); oldsys < st.sys { if st := malloc.GetStats(); oldsys < st.sys {
oldsys = st.sys; oldsys = st.sys;
if chatty { if *chatty {
println(st.sys, " system bytes for ", st.alloc, " Go bytes"); println(st.sys, " system bytes for ", st.alloc, " Go bytes");
} }
if st.sys > 1e9 { if st.sys > 1e9 {
@ -34,7 +33,7 @@ func main() {
malloc.GetStats().alloc = 0; // ignore stacks malloc.GetStats().alloc = 0; // ignore stacks
for i := 0; i < 1<<8; i++ { for i := 0; i < 1<<8; i++ {
for j := 1; j <= 1<<22; j<<=1 { for j := 1; j <= 1<<22; j<<=1 {
if i == 0 && chatty { if i == 0 && *chatty {
println("First alloc:", j); println("First alloc:", j);
} }
b := malloc.Alloc(uint64(j)); b := malloc.Alloc(uint64(j));
@ -45,11 +44,11 @@ func main() {
} }
bigger(); bigger();
} }
if i%(1<<10) == 0 && chatty { if i%(1<<10) == 0 && *chatty {
println(i); println(i);
} }
if i == 0 { if i == 0 {
if chatty { if *chatty {
println("Primed", i); println("Primed", i);
} }
// malloc.frozen = true; // malloc.frozen = true;

View file

@ -15,12 +15,9 @@ import (
"strconv" "strconv"
) )
var chatty bool; var chatty = flag.Bool("v", false, "chatty");
var chatty_flag = flag.Bool("v", false, &chatty, "chatty"); var reverse = flag.Bool("r", false, "reverse");
var reverse bool; var longtest = flag.Bool("l", false, "long test");
var reverse_flag = flag.Bool("r", false, &reverse, "reverse");
var longtest bool;
var longtest_flag = flag.Bool("l", false, &longtest, "long test");
var b []*byte; var b []*byte;
var stats = malloc.GetStats(); var stats = malloc.GetStats();
@ -42,7 +39,7 @@ func OkAmount(size, n uint64) bool {
} }
func AllocAndFree(size, count int) { func AllocAndFree(size, count int) {
if chatty { if *chatty {
fmt.printf("size=%d count=%d ...\n", size, count); fmt.printf("size=%d count=%d ...\n", size, count);
} }
n1 := stats.alloc; n1 := stats.alloc;
@ -57,13 +54,13 @@ func AllocAndFree(size, count int) {
} }
} }
n2 := stats.alloc; n2 := stats.alloc;
if chatty { if *chatty {
fmt.printf("size=%d count=%d stats=%+v\n", size, count, *stats); fmt.printf("size=%d count=%d stats=%+v\n", size, count, *stats);
} }
n3 := stats.alloc; n3 := stats.alloc;
for j := 0; j < count; j++ { for j := 0; j < count; j++ {
i := j; i := j;
if reverse { if *reverse {
i = count - 1 - j; i = count - 1 - j;
} }
alloc := stats.alloc; alloc := stats.alloc;
@ -81,7 +78,7 @@ func AllocAndFree(size, count int) {
} }
n4 := stats.alloc; n4 := stats.alloc;
if chatty { if *chatty {
fmt.printf("size=%d count=%d stats=%+v\n", size, count, *stats); fmt.printf("size=%d count=%d stats=%+v\n", size, count, *stats);
} }
if n2-n1 != n3-n4 { if n2-n1 != n3-n4 {
@ -104,7 +101,7 @@ func main() {
for j := 1; j <= 1<<22; j<<=1 { for j := 1; j <= 1<<22; j<<=1 {
n := len(b); n := len(b);
max := uint64(1<<28); max := uint64(1<<28);
if !longtest { if !*longtest {
max = 1<<22; max = 1<<22;
} }
if uint64(j)*uint64(n) > max { if uint64(j)*uint64(n) > max {

View file

@ -14,16 +14,19 @@ import (
var ( var (
flags Compilation.Flags; flags Compilation.Flags;
silent = Flag.Bool("s", false, nil, "silent mode: no pretty print output"); silent = Flag.Bool("s", false, "silent mode: no pretty print output");
verbose = Flag.Bool("v", false, &flags.verbose, "verbose mode: trace parsing");
sixg = Flag.Bool("6g", true, &flags.sixg, "6g compatibility mode");
//TODO fix this code again
//deps = Flag.Bool("d", false, &flags.deps, "print dependency information only");
columns = Flag.Bool("columns", Platform.USER == "gri", &flags.columns, "print column info in error messages");
testmode = Flag.Bool("t", false, &flags.testmode, "test mode: interprets /* ERROR */ and /* SYNC */ comments");
tokenchan = Flag.Bool("token_chan", false, &flags.tokenchan, "use token channel for scanner-parser connection");
) )
func init() {
Flag.BoolVar(&flags.verbose, "v", false, "verbose mode: trace parsing");
Flag.BoolVar(&flags.sixg, "6g", true, "6g compatibility mode");
//TODO fix this code again
//Flag.BoolVar(&flags.deps, "d", false, "print dependency information only");
Flag.BoolVar(&flags.columns, "columns", Platform.USER == "gri", "print column info in error messages");
Flag.BoolVar(&flags.testmode, "t", false, "test mode: interprets /* ERROR */ and /* SYNC */ comments");
Flag.BoolVar(&flags.tokenchan, "token_chan", false, "use token channel for scanner-parser connection");
}
func Usage() { func Usage() {
print("usage: pretty { flags } { files }\n"); print("usage: pretty { flags } { files }\n");
@ -51,7 +54,7 @@ func main() {
if nerrors > 0 { if nerrors > 0 {
return; return;
} }
if !silent.BVal() && !flags.testmode { if !*silent && !flags.testmode {
Printer.Print(prog); Printer.Print(prog);
} }
} }

View file

@ -19,18 +19,18 @@ import (
) )
var ( var (
debug = flag.Bool("debug", false, nil, "print debugging information"); debug = flag.Bool("debug", false, "print debugging information");
// layout control // layout control
tabwidth = flag.Int("tabwidth", 8, nil, "tab width"); tabwidth = flag.Int("tabwidth", 8, "tab width");
usetabs = flag.Bool("usetabs", true, nil, "align with tabs instead of blanks"); usetabs = flag.Bool("usetabs", true, "align with tabs instead of blanks");
newlines = flag.Bool("newlines", true, nil, "respect newlines in source"); newlines = flag.Bool("newlines", true, "respect newlines in source");
maxnewlines = flag.Int("maxnewlines", 3, nil, "max. number of consecutive newlines"); maxnewlines = flag.Int("maxnewlines", 3, "max. number of consecutive newlines");
// formatting control // formatting control
html = flag.Bool("html", false, nil, "generate html"); html = flag.Bool("html", false, "generate html");
comments = flag.Bool("comments", true, nil, "print comments"); comments = flag.Bool("comments", true, "print comments");
optsemicolons = flag.Bool("optsemicolons", false, nil, "print optional semicolons"); optsemicolons = flag.Bool("optsemicolons", false, "print optional semicolons");
) )
@ -81,7 +81,7 @@ type Printer struct {
func (P *Printer) HasComment(pos int) bool { func (P *Printer) HasComment(pos int) bool {
return comments.BVal() && P.cpos < pos; return *comments && P.cpos < pos;
} }
@ -112,7 +112,7 @@ func (P *Printer) Init(text io.Write, comments *array.Array) {
// Printing support // Printing support
func HtmlEscape(s string) string { func HtmlEscape(s string) string {
if html.BVal() { if *html {
var esc string; var esc string;
for i := 0; i < len(s); i++ { for i := 0; i < len(s); i++ {
switch s[i] { switch s[i] {
@ -137,7 +137,7 @@ func (P *Printer) Printf(format string, s ...) {
func (P *Printer) Newline(n int) { func (P *Printer) Newline(n int) {
if n > 0 { if n > 0 {
m := int(maxnewlines.IVal()); m := int(*maxnewlines);
if n > m { if n > m {
n = m; n = m;
} }
@ -208,7 +208,7 @@ func (P *Printer) TaggedString(pos int, tag, s, endtag string) {
// only white space before comment on this line // only white space before comment on this line
// or file starts with comment // or file starts with comment
// - indent // - indent
if !newlines.BVal() && P.cpos != 0 { if !*newlines && P.cpos != 0 {
nlcount = 1; nlcount = 1;
} }
P.Newline(nlcount); P.Newline(nlcount);
@ -243,7 +243,7 @@ func (P *Printer) TaggedString(pos int, tag, s, endtag string) {
} }
// print comment // print comment
if debug.BVal() { if *debug {
P.Printf("[%d]", P.cpos); P.Printf("[%d]", P.cpos);
} }
P.Printf("%s", HtmlEscape(ctext)); P.Printf("%s", HtmlEscape(ctext));
@ -275,7 +275,7 @@ func (P *Printer) TaggedString(pos int, tag, s, endtag string) {
// -------------------------------- // --------------------------------
// print pending newlines // print pending newlines
if newlines.BVal() && (P.newlines > 0 || P.state == inside_list) && nlcount > P.newlines { if *newlines && (P.newlines > 0 || P.state == inside_list) && nlcount > P.newlines {
// Respect additional newlines in the source, but only if we // Respect additional newlines in the source, but only if we
// enabled this feature (newlines.BVal()) and we are expecting // enabled this feature (newlines.BVal()) and we are expecting
// newlines (P.newlines > 0 || P.state == inside_list). // newlines (P.newlines > 0 || P.state == inside_list).
@ -289,7 +289,7 @@ func (P *Printer) TaggedString(pos int, tag, s, endtag string) {
// -------------------------------- // --------------------------------
// print string // print string
if debug.BVal() { if *debug {
P.Printf("[%d]", pos); P.Printf("[%d]", pos);
} }
P.Printf("%s%s%s", tag, HtmlEscape(s), endtag); P.Printf("%s%s%s", tag, HtmlEscape(s), endtag);
@ -337,7 +337,7 @@ func (P *Printer) Error(pos int, tok int, msg string) {
// HTML support // HTML support
func (P *Printer) HtmlPrologue(title string) { func (P *Printer) HtmlPrologue(title string) {
if html.BVal() { if *html {
P.TaggedString(0, P.TaggedString(0,
"<html>\n" "<html>\n"
"<head>\n" "<head>\n"
@ -355,7 +355,7 @@ func (P *Printer) HtmlPrologue(title string) {
func (P *Printer) HtmlEpilogue() { func (P *Printer) HtmlEpilogue() {
if html.BVal() { if *html {
P.TaggedString(0, P.TaggedString(0,
"</pre>\n" "</pre>\n"
"</body>\n" "</body>\n"
@ -371,7 +371,7 @@ func (P *Printer) HtmlIdentifier(x *AST.Expr) {
panic(); panic();
} }
obj := x.obj; obj := x.obj;
if html.BVal() && obj.kind != Object.NONE { if *html && obj.kind != Object.NONE {
// depending on whether we have a declaration or use, generate different html // depending on whether we have a declaration or use, generate different html
// - no need to HtmlEscape ident // - no need to HtmlEscape ident
id := Utils.IntToString(obj.id, 10); id := Utils.IntToString(obj.id, 10);
@ -647,7 +647,7 @@ func (P *Printer) Block(pos int, list *array.Array, end int, indent bool) {
if !indent { if !indent {
P.indentation++; P.indentation++;
} }
if !optsemicolons.BVal() { if !*optsemicolons {
P.separator = none; P.separator = none;
} }
P.state = closing_scope; P.state = closing_scope;
@ -874,10 +874,10 @@ export func Print(prog *AST.Program) {
// setup // setup
var P Printer; var P Printer;
padchar := byte(' '); padchar := byte(' ');
if usetabs.BVal() { if *usetabs {
padchar = '\t'; padchar = '\t';
} }
text := tabwriter.New(os.Stdout, int(tabwidth.IVal()), 1, padchar, true, html.BVal()); text := tabwriter.New(os.Stdout, *tabwidth, 1, padchar, true, *html);
P.Init(text, prog.comments); P.Init(text, prog.comments);
// TODO would be better to make the name of the src file be the title // TODO would be better to make the name of the src file be the title

View file

@ -14,8 +14,8 @@ import (
var ( var (
tabwidth = flag.Int("tabwidth", 4, nil, "tab width"); tabwidth = flag.Int("tabwidth", 4, "tab width");
usetabs = flag.Bool("usetabs", false, nil, "align with tabs instead of blanks"); usetabs = flag.Bool("usetabs", false, "align with tabs instead of blanks");
) )
@ -37,10 +37,10 @@ func Untab(name string, src *os.FD, dst *tabwriter.Writer) {
func main() { func main() {
flag.Parse(); flag.Parse();
padchar := byte(' '); padchar := byte(' ');
if usetabs.BVal() { if *usetabs {
padchar = '\t'; padchar = '\t';
} }
dst := tabwriter.New(os.Stdout, int(tabwidth.IVal()), 1, padchar, true, false); dst := tabwriter.New(os.Stdout, *tabwidth, 1, padchar, true, false);
if flag.NArg() > 0 { if flag.NArg() > 0 {
for i := 0; i < flag.NArg(); i++ { for i := 0; i < flag.NArg(); i++ {
name := flag.Arg(i); name := flag.Arg(i);