From 127c65b400ef27c3c02242ffd9809f91069218e5 Mon Sep 17 00:00:00 2001
From: Robert Griesemer <gri@golang.org>
Date: Tue, 18 Nov 2008 18:44:17 -0800
Subject: [PATCH] - untab app (snapshot - not quite complete)

R=r
OCL=19558
CL=19558
---
 usr/gri/pretty/Makefile     |  6 +++++
 usr/gri/pretty/tabwriter.go | 17 ++++++------
 usr/gri/pretty/untab.go     | 53 +++++++++++++++++++++++++++++++++++++
 3 files changed, 67 insertions(+), 9 deletions(-)
 create mode 100644 usr/gri/pretty/untab.go

diff --git a/usr/gri/pretty/Makefile b/usr/gri/pretty/Makefile
index 462ab5f556..835654652e 100644
--- a/usr/gri/pretty/Makefile
+++ b/usr/gri/pretty/Makefile
@@ -5,6 +5,11 @@
 G=6g
 L=6l
 
+all: untab pretty
+
+untab: untab.6
+	$(L) -o untab untab.6
+	
 pretty: pretty.6
 	$(L) -o pretty pretty.6
 
@@ -34,6 +39,7 @@ platform.6:	 utils.6
 
 printer.6:	 scanner.6 ast.6 tabwriter.6
 
+untab.6:	tabwriter.6
 
 %.6:	%.go
 	$(G) $(F) $<
diff --git a/usr/gri/pretty/tabwriter.go b/usr/gri/pretty/tabwriter.go
index fa3331da45..e97eea9c4b 100644
--- a/usr/gri/pretty/tabwriter.go
+++ b/usr/gri/pretty/tabwriter.go
@@ -85,7 +85,7 @@ func (b *ByteArray) Append(s *[]byte) {
 // of adjacent cells have the same width (by adding padding). For more
 // details see: http://nickgravgaard.com/elastictabstops/index.html .
 
-type TabWriter struct {
+export type TabWriter struct {
 	// configuration
 	writer IO.Write;
 	tabwidth int;
@@ -232,26 +232,25 @@ func (b *TabWriter) Tab() {
 
 func (b *TabWriter) Newline() {
 	b.Tab();  // add last cell to current line
-	
+
 	if b.LastLine().Len() == 1 {
 		// The current 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 print the TabWriter contents.
 		if b.widths.Len() != 0 {
-			panic();
+			panic("internal error");
 		}
-		//b.Dump();
 		b.Format(0, 0, b.lines.Len());
 		if b.widths.Len() != 0 {
-			panic();
+			panic("internal error");
 		}
-		
-		// reset the TabWriter
+
+		// reset TabWriter
 		b.width = 0;
 		b.buf.Clear();
 		b.lines.Reset();
 	}
-	
+
 	b.AddLine();
 }
 
@@ -278,7 +277,7 @@ func (b *TabWriter) Write(buf *[]byte) (i int, err *OS.Error) {
 }
 
 
-export func MakeTabWriter(writer IO.Write, tabwidth int) IO.Write {
+export func MakeTabWriter(writer IO.Write, tabwidth int) *TabWriter {
 	b := new(TabWriter);
 	b.Init(writer, tabwidth);
 	return b;
diff --git a/usr/gri/pretty/untab.go b/usr/gri/pretty/untab.go
new file mode 100644
index 0000000000..48f1bcf385
--- /dev/null
+++ b/usr/gri/pretty/untab.go
@@ -0,0 +1,53 @@
+// 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 main
+
+import (
+	OS "os";
+	IO "io";
+	Flag "flag";
+	Fmt "fmt";
+	TabWriter "tabwriter";
+)
+
+
+var (
+	tabwidth = Flag.Int("tabwidth", 4, nil, "tab width");
+)
+
+
+func Error(fmt string, params ...) {
+	Fmt.printf(fmt, params);
+	sys.exit(1);
+}
+
+
+func Untab(name string, src *OS.FD, dst *TabWriter.TabWriter) {
+	n, err := IO.Copyn(src, dst, 2e9 /* inf */);  // TODO use Copy
+	if err != nil {
+		Error("error while processing %s (%v)", name, err);
+	}
+	//dst.Flush();
+}
+
+
+func main() {
+	Flag.Parse();
+	dst := TabWriter.MakeTabWriter(OS.Stdout, int(tabwidth.IVal()));
+	if Flag.NArg() > 0 {
+		for i := 0; i < Flag.NArg(); i++ {
+			name := Flag.Arg(i);
+			src, err := OS.Open(name, OS.O_RDONLY, 0);
+			if err != nil {
+				Error("could not open %s (%v)\n", name, err);
+			}
+			Untab(name, src, dst);
+			src.Close();  // ignore errors
+		}
+	} else {
+		// no files => use stdin
+		Untab("/dev/stdin", OS.Stdin, dst);
+	}
+}
-- 
2.30.9