- move tabwriter into library
- added preliminary tests (more to do)
- renamed type from TabWriter -> Writer
- adjusted my code where necessary

R=r
DELTA=825  (474 added, 346 deleted, 5 changed)
OCL=19744
CL=19753
diff --git a/src/lib/clean.bash b/src/lib/clean.bash
index e32e2eb..02f5aab 100755
--- a/src/lib/clean.bash
+++ b/src/lib/clean.bash
@@ -6,10 +6,8 @@
 
 rm -f $GOROOT/pkg/*
 
-for i in syscall os math fmt net time http reflect regexp
+for i in syscall math os strconv container/array reflect fmt tabwriter net time http regexp
 do
-	cd $i
-	make nuke
-	cd ..
+	(cd $i; make nuke)
 done
 
diff --git a/src/lib/make.bash b/src/lib/make.bash
index 76ae040..4398d44 100755
--- a/src/lib/make.bash
+++ b/src/lib/make.bash
@@ -38,7 +38,8 @@
 	
 buildfiles	io.go
 
-builddirs	fmt
+builddirs	fmt\
+		tabwriter\
 
 buildfiles	flag.go\
 		container/vector.go\
diff --git a/src/lib/tabwriter/Makefile b/src/lib/tabwriter/Makefile
new file mode 100644
index 0000000..7fbdf55
--- /dev/null
+++ b/src/lib/tabwriter/Makefile
@@ -0,0 +1,55 @@
+# Copyright 2009 The Go Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file.
+
+# DO NOT EDIT.  Automatically generated by gobuild.
+# gobuild -m >Makefile
+O=6
+GC=$(O)g
+CC=$(O)c -w
+AS=$(O)a
+AR=$(O)ar
+
+default: packages
+
+clean:
+	rm -f *.$O *.a $O.out
+
+test: packages
+	gotest
+
+coverage: packages
+	gotest
+	6cov -g `pwd` | grep -v '_test\.go:'
+
+%.$O: %.go
+	$(GC) $*.go
+
+%.$O: %.c
+	$(CC) $*.c
+
+%.$O: %.s
+	$(AS) $*.s
+
+O1=\
+	tabwriter.$O\
+
+tabwriter.a: a1
+
+a1:	$(O1)
+	$(AR) grc tabwriter.a tabwriter.$O
+	rm -f $(O1)
+
+newpkg: clean
+	$(AR) grc tabwriter.a
+
+$(O1): newpkg
+
+nuke: clean
+	rm -f $(GOROOT)/pkg/tabwriter.a
+
+packages: tabwriter.a
+
+install: packages
+	cp tabwriter.a $(GOROOT)/pkg/tabwriter.a
+
diff --git a/usr/gri/pretty/tabwriter.go b/src/lib/tabwriter/tabwriter.go
similarity index 84%
rename from usr/gri/pretty/tabwriter.go
rename to src/lib/tabwriter/tabwriter.go
index 58ae5ff..3eb0ba1 100644
--- a/usr/gri/pretty/tabwriter.go
+++ b/src/lib/tabwriter/tabwriter.go
@@ -61,12 +61,12 @@
 
 
 // ----------------------------------------------------------------------------
-// Tabwriter is a filter implementing the IO.Write interface. It assumes
+// Writer is a filter implementing the io.Write interface. It assumes
 // that the incoming bytes represent ASCII encoded text consisting of
 // lines of tab-separated "cells". Cells in adjacent lines constitute
-// a column. Tabwriter rewrites the incoming text such that all cells
-// in a column have the same width; thus it effectively aligns cells.
-// It does this by adding padding where necessary.
+// a column. Writer rewrites the incoming text such that all cells in
+// a column have the same width; thus it effectively aligns cells. It
+// does this by adding padding where necessary.
 //
 // Formatting can be controlled via parameters:
 //
@@ -84,7 +84,7 @@
 //      pendant cell and tab width.
 
 
-export type TabWriter struct {
+export type Writer struct {
 	// TODO should not export any of the fields
 	// configuration
 	writer io.Write;
@@ -100,12 +100,12 @@
 }
 
 
-func (b *TabWriter) AddLine() {
+func (b *Writer) AddLine() {
 	b.lines.Push(array.NewIntArray(0));
 }
 
 
-func (b *TabWriter) Init(writer io.Write, tabwidth, padding int, usetabs bool) *TabWriter {
+func (b *Writer) Init(writer io.Write, tabwidth, padding int, usetabs bool) *Writer {
 	b.writer = writer;
 	b.tabwidth = tabwidth;
 	b.padding = padding;
@@ -120,18 +120,18 @@
 }
 
 
-func (b *TabWriter) Line(i int) *array.IntArray {
+func (b *Writer) Line(i int) *array.IntArray {
 	return b.lines.At(i).(*array.IntArray);
 }
 
 
-func (b *TabWriter) LastLine() *array.IntArray {
+func (b *Writer) LastLine() *array.IntArray {
 	return b.lines.At(b.lines.Len() - 1).(*array.IntArray);
 }
 
 
 // debugging support
-func (b *TabWriter) Dump() {
+func (b *Writer) Dump() {
 	pos := 0;
 	for i := 0; i < b.lines.Len(); i++ {
 		line := b.Line(i);
@@ -147,7 +147,7 @@
 }
 
 
-func (b *TabWriter) Write0(buf *[]byte) *os.Error {
+func (b *Writer) Write0(buf *[]byte) *os.Error {
 	n, err := b.writer.Write(buf);
 	if n != len(buf) && err == nil {
 		err = os.EIO;
@@ -161,7 +161,7 @@
 var Newline = &[]byte{'\n'}
 
 
-func (b *TabWriter) WritePadding(textw, cellw int) (err *os.Error) {
+func (b *Writer) WritePadding(textw, cellw int) (err *os.Error) {
 	if b.usetabs {
 		// make cell width a multiple of tabwidth
 		cellw = ((cellw + b.tabwidth - 1) / b.tabwidth) * b.tabwidth;
@@ -192,7 +192,7 @@
 }
 
 
-func (b *TabWriter) WriteLines(pos0 int, line0, line1 int) (pos int, err *os.Error) {
+func (b *Writer) WriteLines(pos0 int, line0, line1 int) (pos int, err *os.Error) {
 	pos = pos0;
 	for i := line0; i < line1; i++ {
 		line := b.Line(i);
@@ -233,7 +233,7 @@
 }
 
 
-func (b *TabWriter) Format(pos0 int, line0, line1 int) (pos int, err *os.Error) {
+func (b *Writer) Format(pos0 int, line0, line1 int) (pos int, err *os.Error) {
 	pos = pos0;
 	column := b.widths.Len();	
 	last := line0;
@@ -284,13 +284,13 @@
 }
 
 
-func (b *TabWriter) Append(buf *[]byte) {
+func (b *Writer) Append(buf *[]byte) {
 	b.buf.Append(buf);
 	b.width += len(buf);
 }
 
 
-/* export */ func (b *TabWriter) Flush() *os.Error {
+/* export */ func (b *Writer) Flush() *os.Error {
 	dummy, err := b.Format(0, 0, b.lines.Len());
 	// reset (even in the presence of errors)
 	b.buf.Clear();
@@ -301,7 +301,7 @@
 }
 
 
-/* export */ func (b *TabWriter) Write(buf *[]byte) (written int, err *os.Error) {
+/* export */ func (b *Writer) Write(buf *[]byte) (written int, err *os.Error) {
 	i0, n := 0, len(buf);
 	
 	// split text into cells
@@ -319,7 +319,7 @@
 					// The last line has only one cell which does not have an
 					// impact on the formatting of the following lines (the
 					// last cell per line is ignored by Format), thus we can
-					// flush the TabWriter contents.
+					// flush the Writer contents.
 					err = b.Flush();
 					if err != nil {
 						return i0, err;
@@ -338,6 +338,6 @@
 }
 
 
-export func New(writer io.Write, tabwidth, padding int, usetabs bool) *TabWriter {
-	return new(TabWriter).Init(writer, tabwidth, padding, usetabs)
+export func New(writer io.Write, tabwidth, padding int, usetabs bool) *Writer {
+	return new(Writer).Init(writer, tabwidth, padding, usetabs)
 }
diff --git a/src/lib/tabwriter/tabwriter_test.go b/src/lib/tabwriter/tabwriter_test.go
new file mode 100644
index 0000000..42c443f
--- /dev/null
+++ b/src/lib/tabwriter/tabwriter_test.go
@@ -0,0 +1,81 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package tabwriter
+
+import (
+	"os";
+	"io";
+	"tabwriter";
+	"testing";
+)
+
+
+type Buffer struct {
+	a *[]byte;
+}
+
+
+func (b *Buffer) Init(n int) {
+	b.a = new([]byte, n)[0 : 0];
+}
+
+
+func (b *Buffer) Write(buf *[]byte) (written int, err *os.Error) {
+	n := len(b.a);
+	m := len(buf);
+	if n + m <= cap(b.a) {
+		b.a = b.a[0 : n + m];
+		for i := 0; i < m; i++ {
+			b.a[n+i] = buf[i];
+		}
+	} else {
+		panicln("buffer too small", n, m, cap(b.a));
+	}
+	return len(buf), nil;
+}
+
+
+func (b *Buffer) String() string {
+	return string(b.a);
+}
+
+
+func Check(t *testing.T, tabwidth, padding int, usetabs bool, src, expected string) {
+	var b Buffer;
+	b.Init(1000);
+
+	var w tabwriter.Writer;
+	w.Init(&b, tabwidth, padding, usetabs);
+
+	io.WriteString(&w, src);
+
+	res := b.String();
+	if res != expected {
+		t.Errorf("src:\n%s\nfound:\n%s\nexpected:\n%s\n", src, res, expected)
+	}
+}
+
+
+export func Test1(t *testing.T) {
+	Check(
+		t, 8, 1, false,
+		"\n",
+		"\n"
+	);
+
+	Check(
+		t, 8, 1, false,
+		"Hello, world!\n",
+		"Hello, world!\n"
+	);
+
+	Check(
+		t, 8, 1, false,
+		"a\tb\tc\naa\tbbb\tcccc\naaa\tbbbb\n\n",
+		"a       b       c\n"
+		"aa      bbb     cccc\n"
+		"aaa     bbbb\n\n"
+	);
+}
diff --git a/usr/gri/pretty/Makefile b/usr/gri/pretty/Makefile
index 8356546..50585fe 100644
--- a/usr/gri/pretty/Makefile
+++ b/usr/gri/pretty/Makefile
@@ -37,9 +37,7 @@
 
 platform.6:	 utils.6
 
-printer.6:	 scanner.6 ast.6 tabwriter.6
-
-untab.6:	tabwriter.6
+printer.6:	 scanner.6 ast.6
 
 %.6:	%.go
 	$(G) $(F) $<
diff --git a/usr/gri/pretty/untab.go b/usr/gri/pretty/untab.go
index d2a26f4..cd5981b 100644
--- a/usr/gri/pretty/untab.go
+++ b/usr/gri/pretty/untab.go
@@ -25,7 +25,7 @@
 }
 
 
-func Untab(name string, src *os.FD, dst *tabwriter.TabWriter) {
+func Untab(name string, src *os.FD, dst *tabwriter.Writer) {
 	n, err := io.Copy(src, dst);
 	if err != nil {
 		Error("error while processing %s (%v)", name, err);