summaryrefslogtreecommitdiff
path: root/src/pkg/exp/datafmt
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/exp/datafmt')
-rw-r--r--src/pkg/exp/datafmt/datafmt.go274
-rw-r--r--src/pkg/exp/datafmt/datafmt_test.go270
-rw-r--r--src/pkg/exp/datafmt/parser.go222
3 files changed, 383 insertions, 383 deletions
diff --git a/src/pkg/exp/datafmt/datafmt.go b/src/pkg/exp/datafmt/datafmt.go
index 4ed9695ab..0a2354286 100644
--- a/src/pkg/exp/datafmt/datafmt.go
+++ b/src/pkg/exp/datafmt/datafmt.go
@@ -202,13 +202,13 @@
package datafmt
import (
- "bytes";
- "fmt";
- "go/token";
- "io";
- "os";
- "reflect";
- "runtime";
+ "bytes"
+ "fmt"
+ "go/token"
+ "io"
+ "os"
+ "reflect"
+ "runtime"
)
@@ -238,35 +238,35 @@ type FormatterMap map[string]Formatter
// A parsed format expression is built from the following nodes.
//
type (
- expr interface{};
+ expr interface{}
- alternatives []expr; // x | y | z
+ alternatives []expr // x | y | z
- sequence []expr; // x y z
+ sequence []expr // x y z
- literal [][]byte; // a list of string segments, possibly starting with '%'
+ literal [][]byte // a list of string segments, possibly starting with '%'
- field struct {
- fieldName string; // including "@", "*"
- ruleName string; // "" if no rule name specified
- };
+ field struct {
+ fieldName string // including "@", "*"
+ ruleName string // "" if no rule name specified
+ }
- group struct {
- indent, body expr; // (indent >> body)
- };
+ group struct {
+ indent, body expr // (indent >> body)
+ }
- option struct {
- body expr; // [body]
- };
+ option struct {
+ body expr // [body]
+ }
- repetition struct {
- body, separator expr; // {body / separator}
- };
+ repetition struct {
+ body, separator expr // {body / separator}
+ }
- custom struct {
- ruleName string;
- fun Formatter;
- };
+ custom struct {
+ ruleName string
+ fun Formatter
+ }
)
@@ -290,7 +290,7 @@ type Format map[string]expr
// the receiver, and thus can be very light-weight.
//
type Environment interface {
- Copy() Environment;
+ Copy() Environment
}
@@ -298,24 +298,24 @@ type Environment interface {
// It is provided as argument to custom formatters.
//
type State struct {
- fmt Format; // format in use
- env Environment; // user-supplied environment
- errors chan os.Error; // not chan *Error (errors <- nil would be wrong!)
- hasOutput bool; // true after the first literal has been written
- indent bytes.Buffer; // current indentation
- output bytes.Buffer; // format output
- linePos token.Position; // position of line beginning (Column == 0)
- default_ expr; // possibly nil
- separator expr; // possibly nil
+ fmt Format // format in use
+ env Environment // user-supplied environment
+ errors chan os.Error // not chan *Error (errors <- nil would be wrong!)
+ hasOutput bool // true after the first literal has been written
+ indent bytes.Buffer // current indentation
+ output bytes.Buffer // format output
+ linePos token.Position // position of line beginning (Column == 0)
+ default_ expr // possibly nil
+ separator expr // possibly nil
}
func newState(fmt Format, env Environment, errors chan os.Error) *State {
- s := new(State);
- s.fmt = fmt;
- s.env = env;
- s.errors = errors;
- s.linePos = token.Position{Line: 1};
+ s := new(State)
+ s.fmt = fmt
+ s.env = env
+ s.errors = errors
+ s.linePos = token.Position{Line: 1}
// if we have a default rule, cache it's expression for fast access
if x, found := fmt["default"]; found {
@@ -327,26 +327,26 @@ func newState(fmt Format, env Environment, errors chan os.Error) *State {
s.separator = x
}
- return s;
+ return s
}
// Env returns the environment passed to Format.Apply.
-func (s *State) Env() interface{} { return s.env }
+func (s *State) Env() interface{} { return s.env }
// LinePos returns the position of the current line beginning
// in the state's output buffer. Line numbers start at 1.
//
-func (s *State) LinePos() token.Position { return s.linePos }
+func (s *State) LinePos() token.Position { return s.linePos }
// Pos returns the position of the next byte to be written to the
// output buffer. Line numbers start at 1.
//
func (s *State) Pos() token.Position {
- offs := s.output.Len();
- return token.Position{Line: s.linePos.Line, Column: offs - s.linePos.Offset, Offset: offs};
+ offs := s.output.Len()
+ return token.Position{Line: s.linePos.Line, Column: offs - s.linePos.Offset, Offset: offs}
}
@@ -354,50 +354,50 @@ func (s *State) Pos() token.Position {
// string after each newline or form feed character. It cannot return an error.
//
func (s *State) Write(data []byte) (int, os.Error) {
- n := 0;
- i0 := 0;
+ n := 0
+ i0 := 0
for i, ch := range data {
if ch == '\n' || ch == '\f' {
// write text segment and indentation
- n1, _ := s.output.Write(data[i0 : i+1]);
- n2, _ := s.output.Write(s.indent.Bytes());
- n += n1 + n2;
- i0 = i + 1;
- s.linePos.Offset = s.output.Len();
- s.linePos.Line++;
+ n1, _ := s.output.Write(data[i0 : i+1])
+ n2, _ := s.output.Write(s.indent.Bytes())
+ n += n1 + n2
+ i0 = i + 1
+ s.linePos.Offset = s.output.Len()
+ s.linePos.Line++
}
}
- n3, _ := s.output.Write(data[i0:]);
- return n + n3, nil;
+ n3, _ := s.output.Write(data[i0:])
+ return n + n3, nil
}
type checkpoint struct {
- env Environment;
- hasOutput bool;
- outputLen int;
- linePos token.Position;
+ env Environment
+ hasOutput bool
+ outputLen int
+ linePos token.Position
}
func (s *State) save() checkpoint {
- saved := checkpoint{nil, s.hasOutput, s.output.Len(), s.linePos};
+ saved := checkpoint{nil, s.hasOutput, s.output.Len(), s.linePos}
if s.env != nil {
saved.env = s.env.Copy()
}
- return saved;
+ return saved
}
func (s *State) restore(m checkpoint) {
- s.env = m.env;
- s.output.Truncate(m.outputLen);
+ s.env = m.env
+ s.output.Truncate(m.outputLen)
}
func (s *State) error(msg string) {
- s.errors <- os.NewError(msg);
- runtime.Goexit();
+ s.errors <- os.NewError(msg)
+ runtime.Goexit()
}
@@ -426,7 +426,7 @@ func typename(typ reflect.Type) string {
case *reflect.PtrType:
return "ptr"
}
- return typ.String();
+ return typ.String()
}
func (s *State) getFormat(name string) expr {
@@ -438,8 +438,8 @@ func (s *State) getFormat(name string) expr {
return s.default_
}
- s.error(fmt.Sprintf("no format rule for type: '%s'", name));
- return nil;
+ s.error(fmt.Sprintf("no format rule for type: '%s'", name))
+ return nil
}
@@ -459,42 +459,42 @@ func (s *State) eval(fexpr expr, value reflect.Value, index int) bool {
case alternatives:
// append the result of the first alternative that evaluates to
// a non-nil []byte to the state's output
- mark := s.save();
+ mark := s.save()
for _, x := range t {
if s.eval(x, value, index) {
return true
}
- s.restore(mark);
+ s.restore(mark)
}
- return false;
+ return false
case sequence:
// append the result of all operands to the state's output
// unless a nil result is encountered
- mark := s.save();
+ mark := s.save()
for _, x := range t {
if !s.eval(x, value, index) {
- s.restore(mark);
- return false;
+ s.restore(mark)
+ return false
}
}
- return true;
+ return true
case literal:
// write separator, if any
if s.hasOutput {
// not the first literal
if s.separator != nil {
- sep := s.separator; // save current separator
- s.separator = nil; // and disable it (avoid recursion)
- mark := s.save();
+ sep := s.separator // save current separator
+ s.separator = nil // and disable it (avoid recursion)
+ mark := s.save()
if !s.eval(sep, value, index) {
s.restore(mark)
}
- s.separator = sep; // enable it again
+ s.separator = sep // enable it again
}
}
- s.hasOutput = true;
+ s.hasOutput = true
// write literal segments
for _, lit := range t {
if len(lit) > 1 && lit[0] == '%' {
@@ -511,7 +511,7 @@ func (s *State) eval(fexpr expr, value reflect.Value, index int) bool {
s.Write(lit)
}
}
- return true; // a literal never evaluates to nil
+ return true // a literal never evaluates to nil
case *field:
// determine field value
@@ -526,13 +526,13 @@ func (s *State) eval(fexpr expr, value reflect.Value, index int) bool {
if v.Len() <= index {
return false
}
- value = v.Elem(index);
+ value = v.Elem(index)
case *reflect.SliceValue:
if v.IsNil() || v.Len() <= index {
return false
}
- value = v.Elem(index);
+ value = v.Elem(index)
case *reflect.MapValue:
s.error("reflection support for maps incomplete")
@@ -541,13 +541,13 @@ func (s *State) eval(fexpr expr, value reflect.Value, index int) bool {
if v.IsNil() {
return false
}
- value = v.Elem();
+ value = v.Elem()
case *reflect.InterfaceValue:
if v.IsNil() {
return false
}
- value = v.Elem();
+ value = v.Elem()
case *reflect.ChanValue:
s.error("reflection support for chans incomplete")
@@ -561,98 +561,98 @@ func (s *State) eval(fexpr expr, value reflect.Value, index int) bool {
default:
// value is value of named field
- var field reflect.Value;
+ var field reflect.Value
if sval, ok := value.(*reflect.StructValue); ok {
- field = sval.FieldByName(t.fieldName);
+ field = sval.FieldByName(t.fieldName)
if field == nil {
// TODO consider just returning false in this case
s.error(fmt.Sprintf("error: no field `%s` in `%s`", t.fieldName, value.Type()))
}
}
- value = field;
+ value = field
}
// determine rule
- ruleName := t.ruleName;
+ ruleName := t.ruleName
if ruleName == "" {
// no alternate rule name, value type determines rule
ruleName = typename(value.Type())
}
- fexpr = s.getFormat(ruleName);
+ fexpr = s.getFormat(ruleName)
- mark := s.save();
+ mark := s.save()
if !s.eval(fexpr, value, index) {
- s.restore(mark);
- return false;
+ s.restore(mark)
+ return false
}
- return true;
+ return true
case *group:
// remember current indentation
- indentLen := s.indent.Len();
+ indentLen := s.indent.Len()
// update current indentation
- mark := s.save();
- s.eval(t.indent, value, index);
+ mark := s.save()
+ s.eval(t.indent, value, index)
// if the indentation evaluates to nil, the state's output buffer
// didn't change - either way it's ok to append the difference to
// the current identation
- s.indent.Write(s.output.Bytes()[mark.outputLen:s.output.Len()]);
- s.restore(mark);
+ s.indent.Write(s.output.Bytes()[mark.outputLen:s.output.Len()])
+ s.restore(mark)
// format group body
- mark = s.save();
- b := true;
+ mark = s.save()
+ b := true
if !s.eval(t.body, value, index) {
- s.restore(mark);
- b = false;
+ s.restore(mark)
+ b = false
}
// reset indentation
- s.indent.Truncate(indentLen);
- return b;
+ s.indent.Truncate(indentLen)
+ return b
case *option:
// evaluate the body and append the result to the state's output
// buffer unless the result is nil
- mark := s.save();
- if !s.eval(t.body, value, 0) { // TODO is 0 index correct?
+ mark := s.save()
+ if !s.eval(t.body, value, 0) { // TODO is 0 index correct?
s.restore(mark)
}
- return true; // an option never evaluates to nil
+ return true // an option never evaluates to nil
case *repetition:
// evaluate the body and append the result to the state's output
// buffer until a result is nil
for i := 0; ; i++ {
- mark := s.save();
+ mark := s.save()
// write separator, if any
if i > 0 && t.separator != nil {
// nil result from separator is ignored
- mark := s.save();
+ mark := s.save()
if !s.eval(t.separator, value, i) {
s.restore(mark)
}
}
if !s.eval(t.body, value, i) {
- s.restore(mark);
- break;
+ s.restore(mark)
+ break
}
}
- return true; // a repetition never evaluates to nil
+ return true // a repetition never evaluates to nil
case *custom:
// invoke the custom formatter to obtain the result
- mark := s.save();
+ mark := s.save()
if !t.fun(s, value.Interface(), t.ruleName) {
- s.restore(mark);
- return false;
+ s.restore(mark)
+ return false
}
- return true;
+ return true
}
- panic("unreachable");
- return false;
+ panic("unreachable")
+ return false
}
@@ -668,23 +668,23 @@ func (f Format) Eval(env Environment, args ...) ([]byte, os.Error) {
return nil, os.NewError("format is nil")
}
- errors := make(chan os.Error);
- s := newState(f, env, errors);
+ errors := make(chan os.Error)
+ s := newState(f, env, errors)
go func() {
- value := reflect.NewValue(args).(*reflect.StructValue);
+ value := reflect.NewValue(args).(*reflect.StructValue)
for i := 0; i < value.NumField(); i++ {
- fld := value.Field(i);
- mark := s.save();
- if !s.eval(s.getFormat(typename(fld.Type())), fld, 0) { // TODO is 0 index correct?
+ fld := value.Field(i)
+ mark := s.save()
+ if !s.eval(s.getFormat(typename(fld.Type())), fld, 0) { // TODO is 0 index correct?
s.restore(mark)
}
}
- errors <- nil; // no errors
- }();
+ errors <- nil // no errors
+ }()
- err := <-errors;
- return s.output.Bytes(), err;
+ err := <-errors
+ return s.output.Bytes(), err
}
@@ -696,12 +696,12 @@ func (f Format) Eval(env Environment, args ...) ([]byte, os.Error) {
// written and an os.Error, if any.
//
func (f Format) Fprint(w io.Writer, env Environment, args ...) (int, os.Error) {
- data, err := f.Eval(env, args);
+ data, err := f.Eval(env, args)
if err != nil {
// TODO should we print partial result in case of error?
return 0, err
}
- return w.Write(data);
+ return w.Write(data)
}
@@ -720,10 +720,10 @@ func (f Format) Print(args ...) (int, os.Error) {
// partially formatted result followed by an error message.
//
func (f Format) Sprint(args ...) string {
- var buf bytes.Buffer;
- _, err := f.Fprint(&buf, nil, args);
+ var buf bytes.Buffer
+ _, err := f.Fprint(&buf, nil, args)
if err != nil {
fmt.Fprintf(&buf, "--- Sprint(%s) failed: %v", fmt.Sprint(args), err)
}
- return buf.String();
+ return buf.String()
}
diff --git a/src/pkg/exp/datafmt/datafmt_test.go b/src/pkg/exp/datafmt/datafmt_test.go
index 61c0a972d..d1c6222a0 100644
--- a/src/pkg/exp/datafmt/datafmt_test.go
+++ b/src/pkg/exp/datafmt/datafmt_test.go
@@ -5,27 +5,27 @@
package datafmt
import (
- "fmt";
- "strings";
- "testing";
+ "fmt"
+ "strings"
+ "testing"
)
func parse(t *testing.T, form string, fmap FormatterMap) Format {
- f, err := Parse("", strings.Bytes(form), fmap);
+ f, err := Parse("", strings.Bytes(form), fmap)
if err != nil {
- t.Errorf("Parse(%s): %v", form, err);
- return nil;
+ t.Errorf("Parse(%s): %v", form, err)
+ return nil
}
- return f;
+ return f
}
func verify(t *testing.T, f Format, expected string, args ...) {
if f == nil {
- return // allow other tests to run
+ return // allow other tests to run
}
- result := f.Sprint(args);
+ result := f.Sprint(args)
if result != expected {
t.Errorf(
"result : `%s`\nexpected: `%s`\n\n",
@@ -37,54 +37,54 @@ func verify(t *testing.T, f Format, expected string, args ...) {
func formatter(s *State, value interface{}, rule_name string) bool {
switch rule_name {
case "/":
- fmt.Fprintf(s, "%d %d %d", s.Pos().Line, s.LinePos().Column, s.Pos().Column);
- return true;
+ fmt.Fprintf(s, "%d %d %d", s.Pos().Line, s.LinePos().Column, s.Pos().Column)
+ return true
case "blank":
- s.Write([]byte{' '});
- return true;
+ s.Write([]byte{' '})
+ return true
case "int":
if value.(int)&1 == 0 {
fmt.Fprint(s, "even ")
} else {
fmt.Fprint(s, "odd ")
}
- return true;
+ return true
case "nil":
return false
case "testing.T":
- s.Write(strings.Bytes("testing.T"));
- return true;
+ s.Write(strings.Bytes("testing.T"))
+ return true
}
- panic("unreachable");
- return false;
+ panic("unreachable")
+ return false
}
func TestCustomFormatters(t *testing.T) {
- fmap0 := FormatterMap{"/": formatter};
- fmap1 := FormatterMap{"int": formatter, "blank": formatter, "nil": formatter};
- fmap2 := FormatterMap{"testing.T": formatter};
+ fmap0 := FormatterMap{"/": formatter}
+ fmap1 := FormatterMap{"int": formatter, "blank": formatter, "nil": formatter}
+ fmap2 := FormatterMap{"testing.T": formatter}
- f := parse(t, `int=`, fmap0);
- verify(t, f, ``, 1, 2, 3);
+ f := parse(t, `int=`, fmap0)
+ verify(t, f, ``, 1, 2, 3)
- f = parse(t, `int="#"`, nil);
- verify(t, f, `###`, 1, 2, 3);
+ f = parse(t, `int="#"`, nil)
+ verify(t, f, `###`, 1, 2, 3)
- f = parse(t, `int="#";string="%s"`, fmap0);
- verify(t, f, "#1 0 1#1 0 7#1 0 13\n2 0 0foo2 0 8\n", 1, 2, 3, "\n", "foo", "\n");
+ f = parse(t, `int="#";string="%s"`, fmap0)
+ verify(t, f, "#1 0 1#1 0 7#1 0 13\n2 0 0foo2 0 8\n", 1, 2, 3, "\n", "foo", "\n")
- f = parse(t, ``, fmap1);
- verify(t, f, `even odd even odd `, 0, 1, 2, 3);
+ f = parse(t, ``, fmap1)
+ verify(t, f, `even odd even odd `, 0, 1, 2, 3)
- f = parse(t, `/ =@:blank; float="#"`, fmap1);
- verify(t, f, `# # #`, 0.0, 1.0, 2.0);
+ f = parse(t, `/ =@:blank; float="#"`, fmap1)
+ verify(t, f, `# # #`, 0.0, 1.0, 2.0)
- f = parse(t, `float=@:nil`, fmap1);
- verify(t, f, ``, 0.0, 1.0, 2.0);
+ f = parse(t, `float=@:nil`, fmap1)
+ verify(t, f, ``, 0.0, 1.0, 2.0)
- f = parse(t, `testing "testing"; ptr=*`, fmap2);
- verify(t, f, `testing.T`, t);
+ f = parse(t, `testing "testing"; ptr=*`, fmap2)
+ verify(t, f, `testing.T`, t)
// TODO needs more tests
}
@@ -94,11 +94,11 @@ func TestCustomFormatters(t *testing.T) {
// Formatting of basic and simple composite types
func check(t *testing.T, form, expected string, args ...) {
- f := parse(t, form, nil);
+ f := parse(t, form, nil)
if f == nil {
- return // allow other tests to run
+ return // allow other tests to run
}
- result := f.Sprint(args);
+ result := f.Sprint(args)
if result != expected {
t.Errorf(
"format : %s\nresult : `%s`\nexpected: `%s`\n\n",
@@ -108,120 +108,120 @@ func check(t *testing.T, form, expected string, args ...) {
func TestBasicTypes(t *testing.T) {
- check(t, ``, ``);
- check(t, `bool=":%v"`, `:true:false`, true, false);
- check(t, `int="%b %d %o 0x%x"`, `101010 42 52 0x2a`, 42);
-
- check(t, `int="%"`, `%`, 42);
- check(t, `int="%%"`, `%`, 42);
- check(t, `int="**%%**"`, `**%**`, 42);
- check(t, `int="%%%%%%"`, `%%%`, 42);
- check(t, `int="%%%d%%"`, `%42%`, 42);
-
- const i = -42;
- const is = `-42`;
- check(t, `int ="%d"`, is, i);
- check(t, `int8 ="%d"`, is, int8(i));
- check(t, `int16="%d"`, is, int16(i));
- check(t, `int32="%d"`, is, int32(i));
- check(t, `int64="%d"`, is, int64(i));
-
- const u = 42;
- const us = `42`;
- check(t, `uint ="%d"`, us, uint(u));
- check(t, `uint8 ="%d"`, us, uint8(u));
- check(t, `uint16="%d"`, us, uint16(u));
- check(t, `uint32="%d"`, us, uint32(u));
- check(t, `uint64="%d"`, us, uint64(u));
-
- const f = 3.141592;
- const fs = `3.141592`;
- check(t, `float ="%g"`, fs, f);
- check(t, `float32="%g"`, fs, float32(f));
- check(t, `float64="%g"`, fs, float64(f));
+ check(t, ``, ``)
+ check(t, `bool=":%v"`, `:true:false`, true, false)
+ check(t, `int="%b %d %o 0x%x"`, `101010 42 52 0x2a`, 42)
+
+ check(t, `int="%"`, `%`, 42)
+ check(t, `int="%%"`, `%`, 42)
+ check(t, `int="**%%**"`, `**%**`, 42)
+ check(t, `int="%%%%%%"`, `%%%`, 42)
+ check(t, `int="%%%d%%"`, `%42%`, 42)
+
+ const i = -42
+ const is = `-42`
+ check(t, `int ="%d"`, is, i)
+ check(t, `int8 ="%d"`, is, int8(i))
+ check(t, `int16="%d"`, is, int16(i))
+ check(t, `int32="%d"`, is, int32(i))
+ check(t, `int64="%d"`, is, int64(i))
+
+ const u = 42
+ const us = `42`
+ check(t, `uint ="%d"`, us, uint(u))
+ check(t, `uint8 ="%d"`, us, uint8(u))
+ check(t, `uint16="%d"`, us, uint16(u))
+ check(t, `uint32="%d"`, us, uint32(u))
+ check(t, `uint64="%d"`, us, uint64(u))
+
+ const f = 3.141592
+ const fs = `3.141592`
+ check(t, `float ="%g"`, fs, f)
+ check(t, `float32="%g"`, fs, float32(f))
+ check(t, `float64="%g"`, fs, float64(f))
}
func TestArrayTypes(t *testing.T) {
- var a0 [10]int;
- check(t, `array="array";`, `array`, a0);
+ var a0 [10]int
+ check(t, `array="array";`, `array`, a0)
- a1 := [...]int{1, 2, 3};
- check(t, `array="array";`, `array`, a1);
- check(t, `array={*}; int="%d";`, `123`, a1);
- check(t, `array={* / ", "}; int="%d";`, `1, 2, 3`, a1);
- check(t, `array={* / *}; int="%d";`, `12233`, a1);
+ a1 := [...]int{1, 2, 3}
+ check(t, `array="array";`, `array`, a1)
+ check(t, `array={*}; int="%d";`, `123`, a1)
+ check(t, `array={* / ", "}; int="%d";`, `1, 2, 3`, a1)
+ check(t, `array={* / *}; int="%d";`, `12233`, a1)
- a2 := []interface{}{42, "foo", 3.14};
- check(t, `array={* / ", "}; interface=*; string="bar"; default="%v";`, `42, bar, 3.14`, a2);
+ a2 := []interface{}{42, "foo", 3.14}
+ check(t, `array={* / ", "}; interface=*; string="bar"; default="%v";`, `42, bar, 3.14`, a2)
}
func TestChanTypes(t *testing.T) {
- var c0 chan int;
- check(t, `chan="chan"`, `chan`, c0);
+ var c0 chan int
+ check(t, `chan="chan"`, `chan`, c0)
- c1 := make(chan int);
- go func() { c1 <- 42 }();
- check(t, `chan="chan"`, `chan`, c1);
+ c1 := make(chan int)
+ go func() { c1 <- 42 }()
+ check(t, `chan="chan"`, `chan`, c1)
// check(t, `chan=*`, `42`, c1); // reflection support for chans incomplete
}
func TestFuncTypes(t *testing.T) {
- var f0 func() int;
- check(t, `func="func"`, `func`, f0);
+ var f0 func() int
+ check(t, `func="func"`, `func`, f0)
- f1 := func() int { return 42 };
- check(t, `func="func"`, `func`, f1);
+ f1 := func() int { return 42 }
+ check(t, `func="func"`, `func`, f1)
// check(t, `func=*`, `42`, f1); // reflection support for funcs incomplete
}
func TestInterfaceTypes(t *testing.T) {
var i0 interface{}
- check(t, `interface="interface"`, `interface`, i0);
+ check(t, `interface="interface"`, `interface`, i0)
- i0 = "foo";
- check(t, `interface="interface"`, `interface`, i0);
- check(t, `interface=*; string="%s"`, `foo`, i0);
+ i0 = "foo"
+ check(t, `interface="interface"`, `interface`, i0)
+ check(t, `interface=*; string="%s"`, `foo`, i0)
}
func TestMapTypes(t *testing.T) {
- var m0 map[string]int;
- check(t, `map="map"`, `map`, m0);
+ var m0 map[string]int
+ check(t, `map="map"`, `map`, m0)
- m1 := map[string]int{};
- check(t, `map="map"`, `map`, m1);
+ m1 := map[string]int{}
+ check(t, `map="map"`, `map`, m1)
// check(t, `map=*`, ``, m1); // reflection support for maps incomplete
}
func TestPointerTypes(t *testing.T) {
- var p0 *int;
- check(t, `ptr="ptr"`, `ptr`, p0);
- check(t, `ptr=*`, ``, p0);
- check(t, `ptr=*|"nil"`, `nil`, p0);
-
- x := 99991;
- p1 := &x;
- check(t, `ptr="ptr"`, `ptr`, p1);
- check(t, `ptr=*; int="%d"`, `99991`, p1);
+ var p0 *int
+ check(t, `ptr="ptr"`, `ptr`, p0)
+ check(t, `ptr=*`, ``, p0)
+ check(t, `ptr=*|"nil"`, `nil`, p0)
+
+ x := 99991
+ p1 := &x
+ check(t, `ptr="ptr"`, `ptr`, p1)
+ check(t, `ptr=*; int="%d"`, `99991`, p1)
}
func TestDefaultRule(t *testing.T) {
- check(t, `default="%v"`, `42foo3.14`, 42, "foo", 3.14);
- check(t, `default="%v"; int="%x"`, `abcdef`, 10, 11, 12, 13, 14, 15);
- check(t, `default="%v"; int="%x"`, `ab**ef`, 10, 11, "**", 14, 15);
- check(t, `default="%x"; int=@:default`, `abcdef`, 10, 11, 12, 13, 14, 15);
+ check(t, `default="%v"`, `42foo3.14`, 42, "foo", 3.14)
+ check(t, `default="%v"; int="%x"`, `abcdef`, 10, 11, 12, 13, 14, 15)
+ check(t, `default="%v"; int="%x"`, `ab**ef`, 10, 11, "**", 14, 15)
+ check(t, `default="%x"; int=@:default`, `abcdef`, 10, 11, 12, 13, 14, 15)
}
func TestGlobalSeparatorRule(t *testing.T) {
- check(t, `int="%d"; / ="-"`, `1-2-3-4`, 1, 2, 3, 4);
- check(t, `int="%x%x"; / ="*"`, `aa*aa`, 10, 10);
+ check(t, `int="%d"; / ="-"`, `1-2-3-4`, 1, 2, 3, 4)
+ check(t, `int="%x%x"; / ="*"`, `aa*aa`, 10, 10)
}
@@ -229,22 +229,22 @@ func TestGlobalSeparatorRule(t *testing.T) {
// Formatting of a struct
type T1 struct {
- a int;
+ a int
}
const F1 = `datafmt "datafmt";` +
`int = "%d";` +
`datafmt.T1 = "<" a ">";`
-func TestStruct1(t *testing.T) { check(t, F1, "<42>", T1{42}) }
+func TestStruct1(t *testing.T) { check(t, F1, "<42>", T1{42}) }
// ----------------------------------------------------------------------------
// Formatting of a struct with an optional field (ptr)
type T2 struct {
- s string;
- p *T1;
+ s string
+ p *T1
}
const F2a = F1 +
@@ -258,9 +258,9 @@ const F2b = F1 +
`datafmt.T2 = s ("-" p "-" | "empty");`
func TestStruct2(t *testing.T) {
- check(t, F2a, "foo", T2{"foo", nil});
- check(t, F2a, "bar-<17>-", T2{"bar", &T1{17}});
- check(t, F2b, "fooempty", T2{"foo", nil});
+ check(t, F2a, "foo", T2{"foo", nil})
+ check(t, F2a, "bar-<17>-", T2{"bar", &T1{17}})
+ check(t, F2b, "fooempty", T2{"foo", nil})
}
@@ -268,8 +268,8 @@ func TestStruct2(t *testing.T) {
// Formatting of a struct with a repetitive field (slice)
type T3 struct {
- s string;
- a []int;
+ s string
+ a []int
}
const F3a = `datafmt "datafmt";` +
@@ -286,10 +286,10 @@ const F3b = `datafmt "datafmt";` +
`datafmt.T3 = s [a:empty ": " {a / "-"}]`
func TestStruct3(t *testing.T) {
- check(t, F3a, "foo", T3{"foo", nil});
- check(t, F3a, "foo 00, 11, 22", T3{"foo", []int{0, 1, 2}});
- check(t, F3b, "bar", T3{"bar", nil});
- check(t, F3b, "bal: 2-3-5", T3{"bal", []int{2, 3, 5}});
+ check(t, F3a, "foo", T3{"foo", nil})
+ check(t, F3a, "foo 00, 11, 22", T3{"foo", []int{0, 1, 2}})
+ check(t, F3b, "bar", T3{"bar", nil})
+ check(t, F3b, "bal: 2-3-5", T3{"bal", []int{2, 3, 5}})
}
@@ -297,8 +297,8 @@ func TestStruct3(t *testing.T) {
// Formatting of a struct with alternative field
type T4 struct {
- x *int;
- a []int;
+ x *int
+ a []int
}
const F4a = `datafmt "datafmt";` +
@@ -318,11 +318,11 @@ const F4b = `datafmt "datafmt";` +
`datafmt.T4 = "<" (a:empty {a / ", "} | "-") ">" `
func TestStruct4(t *testing.T) {
- x := 7;
- check(t, F4a, "<->", T4{nil, nil});
- check(t, F4a, "<7>", T4{&x, nil});
- check(t, F4b, "<->", T4{nil, nil});
- check(t, F4b, "<2, 3, 7>", T4{nil, []int{2, 3, 7}});
+ x := 7
+ check(t, F4a, "<->", T4{nil, nil})
+ check(t, F4a, "<7>", T4{&x, nil})
+ check(t, F4b, "<->", T4{nil, nil})
+ check(t, F4b, "<2, 3, 7>", T4{nil, []int{2, 3, 7}})
}
@@ -330,8 +330,8 @@ func TestStruct4(t *testing.T) {
// Formatting a struct (documentation example)
type Point struct {
- name string;
- x, y int;
+ name string
+ x, y int
}
const FPoint = `datafmt "datafmt";` +
@@ -341,8 +341,8 @@ const FPoint = `datafmt "datafmt";` +
`datafmt.Point = name "{" x ", " y:hexInt "}";`
func TestStructPoint(t *testing.T) {
- p := Point{"foo", 3, 15};
- check(t, FPoint, "---foo---{3, 0xf}", p);
+ p := Point{"foo", 3, 15}
+ check(t, FPoint, "---foo---{3, 0xf}", p)
}
@@ -352,7 +352,7 @@ func TestStructPoint(t *testing.T) {
const FSlice = `int = "%b";` +
`array = { * / ", " }`
-func TestSlice(t *testing.T) { check(t, FSlice, "10, 11, 101, 111", []int{2, 3, 5, 7}) }
+func TestSlice(t *testing.T) { check(t, FSlice, "10, 11, 101, 111", []int{2, 3, 5, 7}) }
// TODO add more tests
diff --git a/src/pkg/exp/datafmt/parser.go b/src/pkg/exp/datafmt/parser.go
index c8144d9f2..653771674 100644
--- a/src/pkg/exp/datafmt/parser.go
+++ b/src/pkg/exp/datafmt/parser.go
@@ -5,83 +5,83 @@
package datafmt
import (
- "container/vector";
- "go/scanner";
- "go/token";
- "os";
- "strconv";
- "strings";
+ "container/vector"
+ "go/scanner"
+ "go/token"
+ "os"
+ "strconv"
+ "strings"
)
// ----------------------------------------------------------------------------
// Parsing
type parser struct {
- scanner.ErrorVector;
- scanner scanner.Scanner;
- pos token.Position; // token position
- tok token.Token; // one token look-ahead
- lit []byte; // token literal
-
- packs map[string]string; // PackageName -> ImportPath
- rules map[string]expr; // RuleName -> Expression
+ scanner.ErrorVector
+ scanner scanner.Scanner
+ pos token.Position // token position
+ tok token.Token // one token look-ahead
+ lit []byte // token literal
+
+ packs map[string]string // PackageName -> ImportPath
+ rules map[string]expr // RuleName -> Expression
}
func (p *parser) next() {
- p.pos, p.tok, p.lit = p.scanner.Scan();
+ p.pos, p.tok, p.lit = p.scanner.Scan()
switch p.tok {
case token.CHAN, token.FUNC, token.INTERFACE, token.MAP, token.STRUCT:
// Go keywords for composite types are type names
// returned by reflect. Accept them as identifiers.
- p.tok = token.IDENT // p.lit is already set correctly
+ p.tok = token.IDENT // p.lit is already set correctly
}
}
func (p *parser) init(filename string, src []byte) {
- p.ErrorVector.Reset();
- p.scanner.Init(filename, src, p, scanner.AllowIllegalChars); // return '@' as token.ILLEGAL w/o error message
- p.next(); // initializes pos, tok, lit
- p.packs = make(map[string]string);
- p.rules = make(map[string]expr);
+ p.ErrorVector.Reset()
+ p.scanner.Init(filename, src, p, scanner.AllowIllegalChars) // return '@' as token.ILLEGAL w/o error message
+ p.next() // initializes pos, tok, lit
+ p.packs = make(map[string]string)
+ p.rules = make(map[string]expr)
}
func (p *parser) errorExpected(pos token.Position, msg string) {
- msg = "expected " + msg;
+ msg = "expected " + msg
if pos.Offset == p.pos.Offset {
// the error happened at the current position;
// make the error message more specific
- msg += ", found '" + p.tok.String() + "'";
+ msg += ", found '" + p.tok.String() + "'"
if p.tok.IsLiteral() {
msg += " " + string(p.lit)
}
}
- p.Error(pos, msg);
+ p.Error(pos, msg)
}
func (p *parser) expect(tok token.Token) token.Position {
- pos := p.pos;
+ pos := p.pos
if p.tok != tok {
p.errorExpected(pos, "'"+tok.String()+"'")
}
- p.next(); // make progress in any case
- return pos;
+ p.next() // make progress in any case
+ return pos
}
func (p *parser) parseIdentifier() string {
- name := string(p.lit);
- p.expect(token.IDENT);
- return name;
+ name := string(p.lit)
+ p.expect(token.IDENT)
+ return name
}
func (p *parser) parseTypeName() (string, bool) {
- pos := p.pos;
- name, isIdent := p.parseIdentifier(), true;
+ pos := p.pos
+ name, isIdent := p.parseIdentifier(), true
if p.tok == token.PERIOD {
// got a package name, lookup package
if importPath, found := p.packs[name]; found {
@@ -89,10 +89,10 @@ func (p *parser) parseTypeName() (string, bool) {
} else {
p.Error(pos, "package not declared: "+name)
}
- p.next();
- name, isIdent = name+"."+p.parseIdentifier(), false;
+ p.next()
+ name, isIdent = name+"."+p.parseIdentifier(), false
}
- return name, isIdent;
+ return name, isIdent
}
@@ -102,99 +102,99 @@ func (p *parser) parseTypeName() (string, bool) {
// single identifier only (and thus could be a package name).
//
func (p *parser) parseRuleName() (string, bool) {
- name, isIdent := "", false;
+ name, isIdent := "", false
switch p.tok {
case token.IDENT:
name, isIdent = p.parseTypeName()
case token.DEFAULT:
- name = "default";
- p.next();
+ name = "default"
+ p.next()
case token.QUO:
- name = "/";
- p.next();
+ name = "/"
+ p.next()
default:
- p.errorExpected(p.pos, "rule name");
- p.next(); // make progress in any case
+ p.errorExpected(p.pos, "rule name")
+ p.next() // make progress in any case
}
- return name, isIdent;
+ return name, isIdent
}
func (p *parser) parseString() string {
- s := "";
+ s := ""
if p.tok == token.STRING {
- s, _ = strconv.Unquote(string(p.lit));
+ s, _ = strconv.Unquote(string(p.lit))
// Unquote may fail with an error, but only if the scanner found
// an illegal string in the first place. In this case the error
// has already been reported.
- p.next();
- return s;
+ p.next()
+ return s
} else {
p.expect(token.STRING)
}
- return s;
+ return s
}
func (p *parser) parseLiteral() literal {
- s := strings.Bytes(p.parseString());
+ s := strings.Bytes(p.parseString())
// A string literal may contain %-format specifiers. To simplify
// and speed up printing of the literal, split it into segments
// that start with "%" possibly followed by a last segment that
// starts with some other character.
- var list vector.Vector;
- i0 := 0;
+ var list vector.Vector
+ i0 := 0
for i := 0; i < len(s); i++ {
if s[i] == '%' && i+1 < len(s) {
// the next segment starts with a % format
if i0 < i {
// the current segment is not empty, split it off
- list.Push(s[i0:i]);
- i0 = i;
+ list.Push(s[i0:i])
+ i0 = i
}
- i++; // skip %; let loop skip over char after %
+ i++ // skip %; let loop skip over char after %
}
}
// the final segment may start with any character
// (it is empty iff the string is empty)
- list.Push(s[i0:]);
+ list.Push(s[i0:])
// convert list into a literal
- lit := make(literal, list.Len());
+ lit := make(literal, list.Len())
for i := 0; i < list.Len(); i++ {
lit[i] = list.At(i).([]byte)
}
- return lit;
+ return lit
}
func (p *parser) parseField() expr {
- var fname string;
+ var fname string
switch p.tok {
case token.ILLEGAL:
if string(p.lit) != "@" {
return nil
}
- fname = "@";
- p.next();
+ fname = "@"
+ p.next()
case token.MUL:
- fname = "*";
- p.next();
+ fname = "*"
+ p.next()
case token.IDENT:
fname = p.parseIdentifier()
default:
return nil
}
- var ruleName string;
+ var ruleName string
if p.tok == token.COLON {
- p.next();
- ruleName, _ = p.parseRuleName();
+ p.next()
+ ruleName, _ = p.parseRuleName()
}
- return &field{fname, ruleName};
+ return &field{fname, ruleName}
}
@@ -204,40 +204,40 @@ func (p *parser) parseOperand() (x expr) {
x = p.parseLiteral()
case token.LPAREN:
- p.next();
- x = p.parseExpression();
+ p.next()
+ x = p.parseExpression()
if p.tok == token.SHR {
- p.next();
- x = &group{x, p.parseExpression()};
+ p.next()
+ x = &group{x, p.parseExpression()}
}
- p.expect(token.RPAREN);
+ p.expect(token.RPAREN)
case token.LBRACK:
- p.next();
- x = &option{p.parseExpression()};
- p.expect(token.RBRACK);
+ p.next()
+ x = &option{p.parseExpression()}
+ p.expect(token.RBRACK)
case token.LBRACE:
- p.next();
- x = p.parseExpression();
- var div expr;
+ p.next()
+ x = p.parseExpression()
+ var div expr
if p.tok == token.QUO {
- p.next();
- div = p.parseExpression();
+ p.next()
+ div = p.parseExpression()
}
- x = &repetition{x, div};
- p.expect(token.RBRACE);
+ x = &repetition{x, div}
+ p.expect(token.RBRACE)
default:
- x = p.parseField() // may be nil
+ x = p.parseField() // may be nil
}
- return x;
+ return x
}
func (p *parser) parseSequence() expr {
- var list vector.Vector;
+ var list vector.Vector
for x := p.parseOperand(); x != nil; x = p.parseOperand() {
list.Push(x)
@@ -252,26 +252,26 @@ func (p *parser) parseSequence() expr {
}
// convert list into a sequence
- seq := make(sequence, list.Len());
+ seq := make(sequence, list.Len())
for i := 0; i < list.Len(); i++ {
seq[i] = list.At(i).(expr)
}
- return seq;
+ return seq
}
func (p *parser) parseExpression() expr {
- var list vector.Vector;
+ var list vector.Vector
for {
- x := p.parseSequence();
+ x := p.parseSequence()
if x != nil {
list.Push(x)
}
if p.tok != token.OR {
break
}
- p.next();
+ p.next()
}
// no need for an alternatives if list.Len() < 2
@@ -283,23 +283,23 @@ func (p *parser) parseExpression() expr {
}
// convert list into a alternatives
- alt := make(alternatives, list.Len());
+ alt := make(alternatives, list.Len())
for i := 0; i < list.Len(); i++ {
alt[i] = list.At(i).(expr)
}
- return alt;
+ return alt
}
func (p *parser) parseFormat() {
for p.tok != token.EOF {
- pos := p.pos;
+ pos := p.pos
- name, isIdent := p.parseRuleName();
+ name, isIdent := p.parseRuleName()
switch p.tok {
case token.STRING:
// package declaration
- importPath := p.parseString();
+ importPath := p.parseString()
// add package declaration
if !isIdent {
@@ -312,8 +312,8 @@ func (p *parser) parseFormat() {
case token.ASSIGN:
// format rule
- p.next();
- x := p.parseExpression();
+ p.next()
+ x := p.parseExpression()
// add rule
if _, found := p.rules[name]; !found {
@@ -323,8 +323,8 @@ func (p *parser) parseFormat() {
}
default:
- p.errorExpected(p.pos, "package declaration or format rule");
- p.next(); // make progress in any case
+ p.errorExpected(p.pos, "package declaration or format rule")
+ p.next() // make progress in any case
}
if p.tok == token.SEMICOLON {
@@ -333,23 +333,23 @@ func (p *parser) parseFormat() {
break
}
}
- p.expect(token.EOF);
+ p.expect(token.EOF)
}
func remap(p *parser, name string) string {
- i := strings.Index(name, ".");
+ i := strings.Index(name, ".")
if i >= 0 {
- packageName, suffix := name[0:i], name[i:];
+ packageName, suffix := name[0:i], name[i:]
// lookup package
if importPath, found := p.packs[packageName]; found {
name = importPath + suffix
} else {
- var invalidPos token.Position;
- p.Error(invalidPos, "package not declared: "+packageName);
+ var invalidPos token.Position
+ p.Error(invalidPos, "package not declared: "+packageName)
}
}
- return name;
+ return name
}
@@ -360,20 +360,20 @@ func remap(p *parser, name string) string {
//
func Parse(filename string, src []byte, fmap FormatterMap) (Format, os.Error) {
// parse source
- var p parser;
- p.init(filename, src);
- p.parseFormat();
+ var p parser
+ p.init(filename, src)
+ p.parseFormat()
// add custom formatters, if any
for name, form := range fmap {
- name = remap(&p, name);
+ name = remap(&p, name)
if _, found := p.rules[name]; !found {
p.rules[name] = &custom{name, form}
} else {
- var invalidPos token.Position;
- p.Error(invalidPos, "formatter already declared: "+name);
+ var invalidPos token.Position
+ p.Error(invalidPos, "formatter already declared: "+name)
}
}
- return p.rules, p.GetError(scanner.NoMultiples);
+ return p.rules, p.GetError(scanner.NoMultiples)
}