mirror of
https://github.com/golang/go
synced 2024-11-26 06:47:58 -07:00
- incorporate suggestions from previous code review
R=rsc DELTA=64 (18 added, 3 deleted, 43 changed) OCL=26046 CL=26058
This commit is contained in:
parent
e7980732ee
commit
6906e3b884
@ -99,8 +99,7 @@ type Writer struct {
|
|||||||
cellwidth int;
|
cellwidth int;
|
||||||
padding int;
|
padding int;
|
||||||
padbytes [8]byte;
|
padbytes [8]byte;
|
||||||
align_left bool;
|
flags uint;
|
||||||
filter_html bool;
|
|
||||||
|
|
||||||
// current state
|
// current state
|
||||||
html_char byte; // terminating char of html tag/entity, or 0 ('>', ';', or 0)
|
html_char byte; // terminating char of html tag/entity, or 0 ('>', ';', or 0)
|
||||||
@ -144,6 +143,18 @@ func (b *Writer) addLine() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Formatting can be controlled with these flags.
|
||||||
|
const (
|
||||||
|
// Ignore html tags and treat entities (starting with '&'
|
||||||
|
// and ending in ';') as single characters (width = 1).
|
||||||
|
FilterHTML = 1 << iota;
|
||||||
|
|
||||||
|
// Force right-alignment of cell content.
|
||||||
|
// Default is left-alignment.
|
||||||
|
AlignRight;
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
// A Writer must be initialized with a call to Init. The first parameter (output)
|
// A Writer must be initialized with a call to Init. The first parameter (output)
|
||||||
// specifies the filter output. The remaining parameters control the formatting:
|
// specifies the filter output. The remaining parameters control the formatting:
|
||||||
//
|
//
|
||||||
@ -155,11 +166,9 @@ func (b *Writer) addLine() {
|
|||||||
// and cells are left-aligned independent of align_left
|
// and cells are left-aligned independent of align_left
|
||||||
// (for correct-looking results, cellwidth must correspond
|
// (for correct-looking results, cellwidth must correspond
|
||||||
// to the tab width in the viewer displaying the result)
|
// to the tab width in the viewer displaying the result)
|
||||||
// align_left alignment of cell content
|
// flags formatting control
|
||||||
// filter_html ignores html tags and treats entities (starting with '&'
|
|
||||||
// and ending in ';') as single characters (width = 1)
|
|
||||||
//
|
//
|
||||||
func (b *Writer) Init(output io.Write, cellwidth, padding int, padchar byte, align_left, filter_html bool) *Writer {
|
func (b *Writer) Init(output io.Write, cellwidth, padding int, padchar byte, flags uint) *Writer {
|
||||||
if cellwidth < 0 {
|
if cellwidth < 0 {
|
||||||
panic("negative cellwidth");
|
panic("negative cellwidth");
|
||||||
}
|
}
|
||||||
@ -172,8 +181,12 @@ func (b *Writer) Init(output io.Write, cellwidth, padding int, padchar byte, ali
|
|||||||
for i := len(b.padbytes) - 1; i >= 0; i-- {
|
for i := len(b.padbytes) - 1; i >= 0; i-- {
|
||||||
b.padbytes[i] = padchar;
|
b.padbytes[i] = padchar;
|
||||||
}
|
}
|
||||||
b.align_left = align_left || padchar == '\t'; // tab enforces left-alignment
|
if padchar == '\t' {
|
||||||
b.filter_html = filter_html;
|
// tab enforces left-alignment
|
||||||
|
t := ^AlignRight; // TODO 6g bug
|
||||||
|
flags &= uint(t);
|
||||||
|
}
|
||||||
|
b.flags = flags;
|
||||||
|
|
||||||
b.buf.Init(1024);
|
b.buf.Init(1024);
|
||||||
b.lines_size.Init(0);
|
b.lines_size.Init(0);
|
||||||
@ -256,7 +269,9 @@ func (b *Writer) writeLines(pos0 int, line0, line1 int) (pos int, err *os.Error)
|
|||||||
for j := 0; j < line_size.Len(); j++ {
|
for j := 0; j < line_size.Len(); j++ {
|
||||||
s, w := line_size.At(j), line_width.At(j);
|
s, w := line_size.At(j), line_width.At(j);
|
||||||
|
|
||||||
if b.align_left {
|
switch {
|
||||||
|
default: // align left
|
||||||
|
|
||||||
err = b.write0(b.buf.slice(pos, pos + s));
|
err = b.write0(b.buf.slice(pos, pos + s));
|
||||||
if err != nil {
|
if err != nil {
|
||||||
goto exit;
|
goto exit;
|
||||||
@ -269,7 +284,7 @@ func (b *Writer) writeLines(pos0 int, line0, line1 int) (pos int, err *os.Error)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else { // align right
|
case b.flags & AlignRight != 0: // align right
|
||||||
|
|
||||||
if j < b.widths.Len() {
|
if j < b.widths.Len() {
|
||||||
err = b.writePadding(w, b.widths.At(j));
|
err = b.writePadding(w, b.widths.At(j));
|
||||||
@ -433,7 +448,7 @@ func (b *Writer) Write(buf []byte) (written int, err *os.Error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case '<', '&':
|
case '<', '&':
|
||||||
if b.filter_html {
|
if b.flags & FilterHTML != 0 {
|
||||||
b.append(buf[i0 : i]);
|
b.append(buf[i0 : i]);
|
||||||
i0 = i;
|
i0 = i;
|
||||||
b.width += unicodeLen(b.buf.slice(b.pos, b.buf.Len()));
|
b.width += unicodeLen(b.buf.slice(b.pos, b.buf.Len()));
|
||||||
@ -467,9 +482,9 @@ func (b *Writer) Write(buf []byte) (written int, err *os.Error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// New allocates and initializes a new tabwriter.Writer.
|
// NewWriter allocates and initializes a new tabwriter.Writer.
|
||||||
// The parameters are the same as for the the Init function.
|
// The parameters are the same as for the the Init function.
|
||||||
//
|
//
|
||||||
func New(writer io.Write, cellwidth, padding int, padchar byte, align_left, filter_html bool) *Writer {
|
func NewWriter(writer io.Write, cellwidth, padding int, padchar byte, flags uint) *Writer {
|
||||||
return new(Writer).Init(writer, cellwidth, padding, padchar, align_left, filter_html)
|
return new(Writer).Init(writer, cellwidth, padding, padchar, flags)
|
||||||
}
|
}
|
||||||
|
@ -71,12 +71,12 @@ func verify(t *testing.T, w *tabwriter.Writer, b *buffer, src, expected string)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
func check(t *testing.T, tabwidth, padding int, padchar byte, align_left, filter_html bool, src, expected string) {
|
func check(t *testing.T, tabwidth, padding int, padchar byte, flags uint, src, expected string) {
|
||||||
var b buffer;
|
var b buffer;
|
||||||
b.init(1000);
|
b.init(1000);
|
||||||
|
|
||||||
var w tabwriter.Writer;
|
var w tabwriter.Writer;
|
||||||
w.Init(&b, tabwidth, padding, padchar, align_left, filter_html);
|
w.Init(&b, tabwidth, padding, padchar, flags);
|
||||||
|
|
||||||
// write all at once
|
// write all at once
|
||||||
b.clear();
|
b.clear();
|
||||||
@ -105,109 +105,109 @@ func check(t *testing.T, tabwidth, padding int, padchar byte, align_left, filter
|
|||||||
|
|
||||||
func Test(t *testing.T) {
|
func Test(t *testing.T) {
|
||||||
check(
|
check(
|
||||||
t, 8, 1, '.', true, false,
|
t, 8, 1, '.', 0,
|
||||||
"",
|
"",
|
||||||
""
|
""
|
||||||
);
|
);
|
||||||
|
|
||||||
check(
|
check(
|
||||||
t, 8, 1, '.', true, false,
|
t, 8, 1, '.', 0,
|
||||||
"\n\n\n",
|
"\n\n\n",
|
||||||
"\n\n\n"
|
"\n\n\n"
|
||||||
);
|
);
|
||||||
|
|
||||||
check(
|
check(
|
||||||
t, 8, 1, '.', true, false,
|
t, 8, 1, '.', 0,
|
||||||
"a\nb\nc",
|
"a\nb\nc",
|
||||||
"a\nb\nc"
|
"a\nb\nc"
|
||||||
);
|
);
|
||||||
|
|
||||||
check(
|
check(
|
||||||
t, 8, 1, '.', true, false,
|
t, 8, 1, '.', 0,
|
||||||
"\t", // '\t' terminates an empty cell on last line - nothing to print
|
"\t", // '\t' terminates an empty cell on last line - nothing to print
|
||||||
""
|
""
|
||||||
);
|
);
|
||||||
|
|
||||||
check(
|
check(
|
||||||
t, 8, 1, '.', false, false,
|
t, 8, 1, '.', tabwriter.AlignRight,
|
||||||
"\t", // '\t' terminates an empty cell on last line - nothing to print
|
"\t", // '\t' terminates an empty cell on last line - nothing to print
|
||||||
""
|
""
|
||||||
);
|
);
|
||||||
|
|
||||||
check(
|
check(
|
||||||
t, 8, 1, '.', true, false,
|
t, 8, 1, '.', 0,
|
||||||
"*\t*",
|
"*\t*",
|
||||||
"**"
|
"**"
|
||||||
);
|
);
|
||||||
|
|
||||||
check(
|
check(
|
||||||
t, 8, 1, '.', true, false,
|
t, 8, 1, '.', 0,
|
||||||
"*\t*\n",
|
"*\t*\n",
|
||||||
"*.......*\n"
|
"*.......*\n"
|
||||||
);
|
);
|
||||||
|
|
||||||
check(
|
check(
|
||||||
t, 8, 1, '.', true, false,
|
t, 8, 1, '.', 0,
|
||||||
"*\t*\t",
|
"*\t*\t",
|
||||||
"*.......*"
|
"*.......*"
|
||||||
);
|
);
|
||||||
|
|
||||||
check(
|
check(
|
||||||
t, 8, 1, '.', false, false,
|
t, 8, 1, '.', tabwriter.AlignRight,
|
||||||
"*\t*\t",
|
"*\t*\t",
|
||||||
".......**"
|
".......**"
|
||||||
);
|
);
|
||||||
|
|
||||||
check(
|
check(
|
||||||
t, 8, 1, '.', true, false,
|
t, 8, 1, '.', 0,
|
||||||
"\t\n",
|
"\t\n",
|
||||||
"........\n"
|
"........\n"
|
||||||
);
|
);
|
||||||
|
|
||||||
check(
|
check(
|
||||||
t, 8, 1, '.', true, false,
|
t, 8, 1, '.', 0,
|
||||||
"a) foo",
|
"a) foo",
|
||||||
"a) foo"
|
"a) foo"
|
||||||
);
|
);
|
||||||
|
|
||||||
check(
|
check(
|
||||||
t, 8, 1, ' ', true, false,
|
t, 8, 1, ' ', 0,
|
||||||
"b) foo\tbar", // "bar" is not in any cell - not formatted, just flushed
|
"b) foo\tbar", // "bar" is not in any cell - not formatted, just flushed
|
||||||
"b) foobar"
|
"b) foobar"
|
||||||
);
|
);
|
||||||
|
|
||||||
check(
|
check(
|
||||||
t, 8, 1, '.', true, false,
|
t, 8, 1, '.', 0,
|
||||||
"c) foo\tbar\t",
|
"c) foo\tbar\t",
|
||||||
"c) foo..bar"
|
"c) foo..bar"
|
||||||
);
|
);
|
||||||
|
|
||||||
check(
|
check(
|
||||||
t, 8, 1, '.', true, false,
|
t, 8, 1, '.', 0,
|
||||||
"d) foo\tbar\n",
|
"d) foo\tbar\n",
|
||||||
"d) foo..bar\n"
|
"d) foo..bar\n"
|
||||||
);
|
);
|
||||||
|
|
||||||
check(
|
check(
|
||||||
t, 8, 1, '.', true, false,
|
t, 8, 1, '.', 0,
|
||||||
"e) foo\tbar\t\n",
|
"e) foo\tbar\t\n",
|
||||||
"e) foo..bar.....\n"
|
"e) foo..bar.....\n"
|
||||||
);
|
);
|
||||||
|
|
||||||
check(
|
check(
|
||||||
t, 8, 1, '.', true, true,
|
t, 8, 1, '.', tabwriter.FilterHTML,
|
||||||
"e) f<o\t<b>bar</b>\t\n",
|
"e) f<o\t<b>bar</b>\t\n",
|
||||||
"e) f<o..<b>bar</b>.....\n"
|
"e) f<o..<b>bar</b>.....\n"
|
||||||
);
|
);
|
||||||
|
|
||||||
check(
|
check(
|
||||||
t, 8, 1, '*', true, false,
|
t, 8, 1, '*', 0,
|
||||||
"Hello, world!\n",
|
"Hello, world!\n",
|
||||||
"Hello, world!\n"
|
"Hello, world!\n"
|
||||||
);
|
);
|
||||||
|
|
||||||
check(
|
check(
|
||||||
t, 0, 0, '.', true, false,
|
t, 0, 0, '.', 0,
|
||||||
"1\t2\t3\t4\n"
|
"1\t2\t3\t4\n"
|
||||||
"11\t222\t3333\t44444\n",
|
"11\t222\t3333\t44444\n",
|
||||||
|
|
||||||
@ -216,19 +216,19 @@ func Test(t *testing.T) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
check(
|
check(
|
||||||
t, 5, 0, '.', true, false,
|
t, 5, 0, '.', 0,
|
||||||
"1\t2\t3\t4\n",
|
"1\t2\t3\t4\n",
|
||||||
"1....2....3....4\n"
|
"1....2....3....4\n"
|
||||||
);
|
);
|
||||||
|
|
||||||
check(
|
check(
|
||||||
t, 5, 0, '.', true, false,
|
t, 5, 0, '.', 0,
|
||||||
"1\t2\t3\t4\t\n",
|
"1\t2\t3\t4\t\n",
|
||||||
"1....2....3....4....\n"
|
"1....2....3....4....\n"
|
||||||
);
|
);
|
||||||
|
|
||||||
check(
|
check(
|
||||||
t, 8, 1, '.', true, false,
|
t, 8, 1, '.', 0,
|
||||||
"本\tb\tc\n"
|
"本\tb\tc\n"
|
||||||
"aa\t\u672c\u672c\u672c\tcccc\tddddd\n"
|
"aa\t\u672c\u672c\u672c\tcccc\tddddd\n"
|
||||||
"aaa\tbbbb\n",
|
"aaa\tbbbb\n",
|
||||||
@ -239,7 +239,7 @@ func Test(t *testing.T) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
check(
|
check(
|
||||||
t, 8, 1, ' ', false, false,
|
t, 8, 1, ' ', tabwriter.AlignRight,
|
||||||
"a\tè\tc\t\n"
|
"a\tè\tc\t\n"
|
||||||
"aa\tèèè\tcccc\tddddd\t\n"
|
"aa\tèèè\tcccc\tddddd\t\n"
|
||||||
"aaa\tèèèè\t\n",
|
"aaa\tèèèè\t\n",
|
||||||
@ -250,7 +250,7 @@ func Test(t *testing.T) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
check(
|
check(
|
||||||
t, 2, 0, ' ', true, false,
|
t, 2, 0, ' ', 0,
|
||||||
"a\tb\tc\n"
|
"a\tb\tc\n"
|
||||||
"aa\tbbb\tcccc\n"
|
"aa\tbbb\tcccc\n"
|
||||||
"aaa\tbbbb\n",
|
"aaa\tbbbb\n",
|
||||||
@ -261,7 +261,7 @@ func Test(t *testing.T) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
check(
|
check(
|
||||||
t, 8, 1, '_', true, false,
|
t, 8, 1, '_', 0,
|
||||||
"a\tb\tc\n"
|
"a\tb\tc\n"
|
||||||
"aa\tbbb\tcccc\n"
|
"aa\tbbb\tcccc\n"
|
||||||
"aaa\tbbbb\n",
|
"aaa\tbbbb\n",
|
||||||
@ -272,7 +272,7 @@ func Test(t *testing.T) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
check(
|
check(
|
||||||
t, 4, 1, '-', true, false,
|
t, 4, 1, '-', 0,
|
||||||
"4444\t日本語\t22\t1\t333\n"
|
"4444\t日本語\t22\t1\t333\n"
|
||||||
"999999999\t22\n"
|
"999999999\t22\n"
|
||||||
"7\t22\n"
|
"7\t22\n"
|
||||||
@ -291,7 +291,7 @@ func Test(t *testing.T) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
check(
|
check(
|
||||||
t, 4, 3, '.', true, false,
|
t, 4, 3, '.', 0,
|
||||||
"4444\t333\t22\t1\t333\n"
|
"4444\t333\t22\t1\t333\n"
|
||||||
"999999999\t22\n"
|
"999999999\t22\n"
|
||||||
"7\t22\n"
|
"7\t22\n"
|
||||||
@ -310,7 +310,7 @@ func Test(t *testing.T) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
check(
|
check(
|
||||||
t, 8, 1, '\t', true, true,
|
t, 8, 1, '\t', tabwriter.FilterHTML,
|
||||||
"4444\t333\t22\t1\t333\n"
|
"4444\t333\t22\t1\t333\n"
|
||||||
"999999999\t22\n"
|
"999999999\t22\n"
|
||||||
"7\t22\n"
|
"7\t22\n"
|
||||||
@ -329,7 +329,7 @@ func Test(t *testing.T) {
|
|||||||
);
|
);
|
||||||
|
|
||||||
check(
|
check(
|
||||||
t, 0, 2, ' ', false, false,
|
t, 0, 2, ' ', tabwriter.AlignRight,
|
||||||
".0\t.3\t2.4\t-5.1\t\n"
|
".0\t.3\t2.4\t-5.1\t\n"
|
||||||
"23.0\t12345678.9\t2.4\t-989.4\t\n"
|
"23.0\t12345678.9\t2.4\t-989.4\t\n"
|
||||||
"5.1\t12.0\t2.4\t-7.0\t\n"
|
"5.1\t12.0\t2.4\t-7.0\t\n"
|
||||||
|
Loading…
Reference in New Issue
Block a user