Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
go
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
go
Commits
0998eaf4
Commit
0998eaf4
authored
Nov 20, 2008
by
Robert Griesemer
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
- correct error handling throughout
- documentation, cleanups - more options R=r OCL=19736 CL=19736
parent
bd6e0bc8
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
150 additions
and
117 deletions
+150
-117
usr/gri/pretty/printer.go
usr/gri/pretty/printer.go
+2
-2
usr/gri/pretty/tabwriter.go
usr/gri/pretty/tabwriter.go
+146
-113
usr/gri/pretty/untab.go
usr/gri/pretty/untab.go
+2
-2
No files found.
usr/gri/pretty/printer.go
View file @
0998eaf4
...
@@ -15,8 +15,8 @@ import OS "os"
...
@@ -15,8 +15,8 @@ import OS "os"
import
TabWriter
"tabwriter"
import
TabWriter
"tabwriter"
var
(
var
(
usetabs
=
Flag
.
Bool
(
"usetabs"
,
false
,
nil
,
"align with tabs instead of blanks"
);
tabwidth
=
Flag
.
Int
(
"tabwidth"
,
4
,
nil
,
"tab width"
);
tabwidth
=
Flag
.
Int
(
"tabwidth"
,
4
,
nil
,
"tab width"
);
usetabs
=
Flag
.
Bool
(
"usetabs"
,
false
,
nil
,
"align with tabs instead of blanks"
);
comments
=
Flag
.
Bool
(
"comments"
,
false
,
nil
,
"enable printing of comments"
);
comments
=
Flag
.
Bool
(
"comments"
,
false
,
nil
,
"enable printing of comments"
);
)
)
...
@@ -604,7 +604,7 @@ func (P *Printer) Declaration(d *AST.Decl, parenthesized bool) {
...
@@ -604,7 +604,7 @@ func (P *Printer) Declaration(d *AST.Decl, parenthesized bool) {
func
(
P
*
Printer
)
Program
(
p
*
AST
.
Program
)
{
func
(
P
*
Printer
)
Program
(
p
*
AST
.
Program
)
{
// TODO should initialize all fields?
// TODO should initialize all fields?
P
.
writer
=
TabWriter
.
MakeTabWriter
(
OS
.
Stdout
,
usetabs
.
BVal
(),
int
(
tabwidth
.
IVal
()
));
P
.
writer
=
TabWriter
.
New
(
OS
.
Stdout
,
int
(
tabwidth
.
IVal
()),
1
,
usetabs
.
BVal
(
));
P
.
clist
=
p
.
comments
;
P
.
clist
=
p
.
comments
;
P
.
cindex
=
0
;
P
.
cindex
=
0
;
...
...
usr/gri/pretty/tabwriter.go
View file @
0998eaf4
...
@@ -13,7 +13,7 @@ import (
...
@@ -13,7 +13,7 @@ import (
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// ByteArray
// ByteArray
// TODO
move this into std lib
eventually
// TODO
should use a ByteArray library
eventually
type
ByteArray
struct
{
type
ByteArray
struct
{
a
*
[]
byte
;
a
*
[]
byte
;
...
@@ -30,21 +30,6 @@ func (b *ByteArray) Clear() {
...
@@ -30,21 +30,6 @@ func (b *ByteArray) Clear() {
}
}
func
(
b
*
ByteArray
)
Len
()
int
{
return
len
(
b
.
a
);
}
func
(
b
*
ByteArray
)
At
(
i
int
)
byte
{
return
b
.
a
[
i
];
}
func
(
b
*
ByteArray
)
Set
(
i
int
,
x
byte
)
{
b
.
a
[
i
]
=
x
;
}
func
(
b
*
ByteArray
)
Slice
(
i
,
j
int
)
*
[]
byte
{
func
(
b
*
ByteArray
)
Slice
(
i
,
j
int
)
*
[]
byte
{
return
b
.
a
[
i
:
j
];
// BUG should really be &b.a[i : j]
return
b
.
a
[
i
:
j
];
// BUG should really be &b.a[i : j]
}
}
...
@@ -76,27 +61,42 @@ func (b *ByteArray) Append(s *[]byte) {
...
@@ -76,27 +61,42 @@ func (b *ByteArray) Append(s *[]byte) {
// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------
// Implementation of flexible tab stops.
// Tabwriter is a filter implementing the IO.Write interface. It assumes
// that the incoming bytes represent ASCII encoded text consisting of
// TabWriter is a representation for a list of lines consisting of
// lines of tab-separated "cells". Cells in adjacent lines constitute
// cells. A new cell is added for each Tab() call, and a new line
// a column. Tabwriter rewrites the incoming text such that all cells
// is added for each Newline() call.
// in a column have the same width; thus it effectively aligns cells.
// It does this by adding padding where necessary.
//
//
// The lines are formatted and printed such that all cells in a column
// Formatting can be controlled via parameters:
// of adjacent cells have the same width (by adding padding). For more
//
// details see: http://nickgravgaard.com/elastictabstops/index.html .
// tabwidth the minimal with of a cell
// padding additional padding
// usetabs use tabs instead of blanks for padding
// (for correct-looking results, tabwidth must correspond
// to the tabwidth in the editor used to look at the result)
//
// (See alse http://nickgravgaard.com/elastictabstops/index.html)
// TODO Should support UTF-8
// TODO Should probably implement a couple of trivial customization options
// such as arbitrary padding character, left/right alignment, and inde-
// pendant cell and tab width.
export
type
TabWriter
struct
{
export
type
TabWriter
struct
{
// TODO should not export any of the fields
// configuration
// configuration
writer
io
.
Write
;
writer
io
.
Write
;
usetabs
bool
;
tabwidth
int
;
tabwidth
int
;
padding
int
;
usetabs
bool
;
// current state
// current state
buf
ByteArray
;
// the collected text w/o tabs and newlines
buf
ByteArray
;
// the collected text w/o tabs and newlines
width
int
;
// width of last incomplete cell
width
int
;
// width of last incomplete cell
lines
array
.
Array
;
// list of lines; each line is a list of cell widths
lines
array
.
Array
;
// list of lines; each line is a list of cell widths
widths
array
.
IntArray
;
// list of column widths -
(re-)
used during formatting
widths
array
.
IntArray
;
// list of column widths -
re-
used during formatting
}
}
...
@@ -105,15 +105,18 @@ func (b *TabWriter) AddLine() {
...
@@ -105,15 +105,18 @@ func (b *TabWriter) AddLine() {
}
}
func
(
b
*
TabWriter
)
Init
(
writer
io
.
Write
,
usetabs
bool
,
tabwidth
int
)
{
func
(
b
*
TabWriter
)
Init
(
writer
io
.
Write
,
tabwidth
,
padding
int
,
usetabs
bool
)
*
TabWriter
{
b
.
writer
=
writer
;
b
.
writer
=
writer
;
b
.
usetabs
=
usetabs
;
b
.
tabwidth
=
tabwidth
;
b
.
tabwidth
=
tabwidth
;
b
.
padding
=
padding
;
b
.
usetabs
=
usetabs
;
b
.
buf
.
Init
(
1024
);
b
.
buf
.
Init
(
1024
);
b
.
lines
.
Init
(
0
);
b
.
lines
.
Init
(
0
);
b
.
widths
.
Init
(
0
);
b
.
widths
.
Init
(
0
);
b
.
AddLine
();
// the very first line
b
.
AddLine
();
// the very first line
return
b
;
}
}
...
@@ -135,7 +138,7 @@ func (b *TabWriter) Dump() {
...
@@ -135,7 +138,7 @@ func (b *TabWriter) Dump() {
print
(
"("
,
i
,
") "
);
print
(
"("
,
i
,
") "
);
for
j
:=
0
;
j
<
line
.
Len
();
j
++
{
for
j
:=
0
;
j
<
line
.
Len
();
j
++
{
w
:=
line
.
At
(
j
);
w
:=
line
.
At
(
j
);
print
(
"["
,
string
(
b
.
buf
.
a
[
pos
:
pos
+
w
]
),
"]"
);
print
(
"["
,
string
(
b
.
buf
.
Slice
(
pos
,
pos
+
w
)
),
"]"
);
pos
+=
w
;
pos
+=
w
;
}
}
print
(
"
\n
"
);
print
(
"
\n
"
);
...
@@ -144,59 +147,95 @@ func (b *TabWriter) Dump() {
...
@@ -144,59 +147,95 @@ func (b *TabWriter) Dump() {
}
}
func
(
b
*
TabWriter
)
Write0
(
buf
*
[]
byte
)
*
os
.
Error
{
n
,
err
:=
b
.
writer
.
Write
(
buf
);
if
n
!=
len
(
buf
)
&&
err
==
nil
{
err
=
os
.
EIO
;
}
return
err
;
}
var
Tabs
=
&
[]
byte
{
'\t'
,
'\t'
,
'\t'
,
'\t'
,
'\t'
,
'\t'
,
'\t'
,
'\t'
}
var
Tabs
=
&
[]
byte
{
'\t'
,
'\t'
,
'\t'
,
'\t'
,
'\t'
,
'\t'
,
'\t'
,
'\t'
}
var
Blanks
=
&
[]
byte
{
' '
,
' '
,
' '
,
' '
,
' '
,
' '
,
' '
,
' '
}
var
Blanks
=
&
[]
byte
{
' '
,
' '
,
' '
,
' '
,
' '
,
' '
,
' '
,
' '
}
var
Newline
=
&
[]
byte
{
'\n'
}
var
Newline
=
&
[]
byte
{
'\n'
}
func
(
b
*
TabWriter
)
Padding
(
textwidth
,
cellwidth
int
)
{
func
(
b
*
TabWriter
)
WritePadding
(
textw
,
cellw
int
)
(
err
*
os
.
Error
)
{
n
:=
cellwidth
-
textwidth
;
if
b
.
usetabs
{
// make cell width a multiple of tabwidth
cellw
=
((
cellw
+
b
.
tabwidth
-
1
)
/
b
.
tabwidth
)
*
b
.
tabwidth
;
}
n
:=
cellw
-
textw
;
if
n
<
0
{
if
n
<
0
{
panic
(
"internal error"
);
panic
(
"internal error"
);
}
}
padding
:=
Blanks
;
if
b
.
usetabs
{
if
b
.
usetabs
{
if
cellwidth
%
b
.
tabwidth
!=
0
{
panic
(
"internal error"
);
// cellwidth should be a multiple of tabwidth
}
n
=
(
n
+
b
.
tabwidth
-
1
)
/
b
.
tabwidth
;
n
=
(
n
+
b
.
tabwidth
-
1
)
/
b
.
tabwidth
;
for
n
>
len
(
Tabs
)
{
padding
=
Tabs
;
m
,
err
:=
b
.
writer
.
Write
(
Tabs
);
n
-=
len
(
Tabs
);
}
}
m
,
err
:=
b
.
writer
.
Write
(
Tabs
[
0
:
n
]);
}
else
{
for
n
>
len
(
padding
)
{
for
n
>
len
(
Blanks
)
{
err
=
b
.
Write0
(
padding
);
m
,
err
:=
b
.
writer
.
Write
(
Blanks
);
if
err
!=
nil
{
n
-=
len
(
Blanks
)
;
goto
exit
;
}
}
m
,
err
:=
b
.
writer
.
Write
(
Blanks
[
0
:
n
]
);
n
-=
len
(
padding
);
}
}
err
=
b
.
Write0
(
padding
[
0
:
n
]);
exit
:
return
err
;
}
}
func
(
b
*
TabWriter
)
PrintLines
(
pos
int
,
line0
,
line1
int
)
int
{
func
(
b
*
TabWriter
)
WriteLines
(
pos0
int
,
line0
,
line1
int
)
(
pos
int
,
err
*
os
.
Error
)
{
pos
=
pos0
;
for
i
:=
line0
;
i
<
line1
;
i
++
{
for
i
:=
line0
;
i
<
line1
;
i
++
{
line
:=
b
.
Line
(
i
);
line
:=
b
.
Line
(
i
);
for
j
:=
0
;
j
<
line
.
Len
();
j
++
{
for
j
:=
0
;
j
<
line
.
Len
();
j
++
{
w
:=
line
.
At
(
j
);
w
:=
line
.
At
(
j
);
m
,
err
:=
b
.
writer
.
Write
(
b
.
buf
.
a
[
pos
:
pos
+
w
]);
err
=
b
.
Write0
(
b
.
buf
.
a
[
pos
:
pos
+
w
]);
if
m
!=
w
{
if
err
!=
nil
{
panic
()
;
goto
exit
;
}
}
pos
+=
w
;
pos
+=
w
;
if
j
<
b
.
widths
.
Len
()
{
if
j
<
b
.
widths
.
Len
()
{
b
.
Padding
(
w
,
b
.
widths
.
At
(
j
));
err
=
b
.
WritePadding
(
w
,
b
.
widths
.
At
(
j
));
if
err
!=
nil
{
goto
exit
;
}
}
}
}
}
m
,
err
:=
b
.
writer
.
Write
(
Newline
);
err
=
b
.
Write0
(
Newline
);
if
err
!=
nil
{
goto
exit
;
}
}
return
pos
;
}
exit
:
return
pos
,
err
;
}
}
func
(
b
*
TabWriter
)
Format
(
pos
int
,
line0
,
line1
int
)
int
{
// TODO use utflen for correct formatting
column
:=
b
.
widths
.
Len
();
func
utflen
(
buf
*
[]
byte
)
int
{
n
:=
0
;
for
i
:=
0
;
i
<
len
(
buf
);
i
++
{
if
buf
[
i
]
&
0xC0
!=
0x80
{
n
++
}
}
return
n
}
func
(
b
*
TabWriter
)
Format
(
pos0
int
,
line0
,
line1
int
)
(
pos
int
,
err
*
os
.
Error
)
{
pos
=
pos0
;
column
:=
b
.
widths
.
Len
();
last
:=
line0
;
last
:=
line0
;
for
this
:=
line0
;
this
<
line1
;
this
++
{
for
this
:=
line0
;
this
<
line1
;
this
++
{
line
:=
b
.
Line
(
this
);
line
:=
b
.
Line
(
this
);
...
@@ -206,7 +245,10 @@ func (b *TabWriter) Format(pos int, line0, line1 int) int {
...
@@ -206,7 +245,10 @@ func (b *TabWriter) Format(pos int, line0, line1 int) int {
// (note that the last cell per line is ignored)
// (note that the last cell per line is ignored)
// print unprinted lines until beginning of block
// print unprinted lines until beginning of block
pos
=
b
.
PrintLines
(
pos
,
last
,
this
);
pos
,
err
=
b
.
WriteLines
(
pos
,
last
,
this
);
if
err
!=
nil
{
goto
exit
;
}
last
=
this
;
last
=
this
;
// column block begin
// column block begin
...
@@ -214,9 +256,8 @@ func (b *TabWriter) Format(pos int, line0, line1 int) int {
...
@@ -214,9 +256,8 @@ func (b *TabWriter) Format(pos int, line0, line1 int) int {
for
;
this
<
line1
;
this
++
{
for
;
this
<
line1
;
this
++
{
line
=
b
.
Line
(
this
);
line
=
b
.
Line
(
this
);
if
column
<
line
.
Len
()
-
1
{
if
column
<
line
.
Len
()
-
1
{
// cell exists in this column
// cell exists in this column => update width
// update width
w
:=
line
.
At
(
column
)
+
b
.
padding
;
w
:=
line
.
At
(
column
)
+
1
;
// 1 = minimum space between cells
if
w
>
width
{
if
w
>
width
{
width
=
w
;
width
=
w
;
}
}
...
@@ -226,85 +267,77 @@ func (b *TabWriter) Format(pos int, line0, line1 int) int {
...
@@ -226,85 +267,77 @@ func (b *TabWriter) Format(pos int, line0, line1 int) int {
}
}
// column block end
// column block end
if
b
.
usetabs
{
// make width a multiple of the tab width
width
=
((
width
+
b
.
tabwidth
-
1
)
/
b
.
tabwidth
)
*
b
.
tabwidth
;
}
// format and print all columns to the right of this column
// format and print all columns to the right of this column
// (we know the widths of this column and all columns to the left)
// (we know the widths of this column and all columns to the left)
b
.
widths
.
Push
(
width
);
b
.
widths
.
Push
(
width
);
pos
=
b
.
Format
(
pos
,
last
,
this
);
pos
,
err
=
b
.
Format
(
pos
,
last
,
this
);
b
.
widths
.
Pop
();
b
.
widths
.
Pop
();
last
=
this
;
last
=
this
;
}
}
}
}
// print unprinted lines until end
// print unprinted lines until end
return
b
.
PrintLines
(
pos
,
last
,
line1
);
pos
,
err
=
b
.
WriteLines
(
pos
,
last
,
line1
);
exit
:
return
pos
,
err
;
}
}
func
(
b
*
TabWriter
)
EmptyLine
()
bool
{
func
(
b
*
TabWriter
)
Append
(
buf
*
[]
byte
)
{
return
b
.
LastLine
()
.
Len
()
==
0
&&
b
.
width
==
0
;
b
.
buf
.
Append
(
buf
);
b
.
width
+=
len
(
buf
);
}
}
func
(
b
*
TabWriter
)
Tab
()
{
/* export */
func
(
b
*
TabWriter
)
Flush
()
*
os
.
Error
{
b
.
LastLine
()
.
Push
(
b
.
width
);
dummy
,
err
:=
b
.
Format
(
0
,
0
,
b
.
lines
.
Len
());
// reset (even in the presence of errors)
b
.
buf
.
Clear
();
b
.
width
=
0
;
b
.
width
=
0
;
b
.
lines
.
Init
(
0
);
b
.
AddLine
();
return
err
;
}
}
func
(
b
*
TabWriter
)
Newline
(
)
{
/* export */
func
(
b
*
TabWriter
)
Write
(
buf
*
[]
byte
)
(
written
int
,
err
*
os
.
Error
)
{
b
.
Tab
();
// add last cell to current line
i0
,
n
:=
0
,
len
(
buf
);
if
b
.
LastLine
()
.
Len
()
==
1
{
// split text into cells
// The current line has only one cell which does not have an impact
for
i
:=
0
;
i
<
n
;
i
++
{
// on the formatting of the following lines (the last cell per line
if
ch
:=
buf
[
i
];
ch
==
'\t'
||
ch
==
'\n'
{
// is ignored by Format), thus we can print the TabWriter contents.
b
.
Append
(
buf
[
i0
:
i
]);
if
b
.
widths
.
Len
()
!=
0
{
i0
=
i
+
1
;
// exclude ch from (next) cell
panic
(
"internal error"
);
}
b
.
Format
(
0
,
0
,
b
.
lines
.
Len
());
if
b
.
widths
.
Len
()
!=
0
{
panic
(
"internal error"
);
}
// reset TabWriter
// terminate cell
b
.
LastLine
()
.
Push
(
b
.
width
);
b
.
width
=
0
;
b
.
width
=
0
;
b
.
buf
.
Clear
();
b
.
lines
.
Init
(
0
);
}
if
ch
==
'\n'
{
if
b
.
LastLine
()
.
Len
()
==
1
{
// 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.
err
=
b
.
Flush
();
if
err
!=
nil
{
return
i0
,
err
;
}
}
else
{
// We can't flush yet - just add a new line.
b
.
AddLine
();
b
.
AddLine
();
}
func
(
b
*
TabWriter
)
Write
(
buf
*
[]
byte
)
(
i
int
,
err
*
os
.
Error
)
{
i0
,
n
:=
0
,
len
(
buf
);
for
i
=
0
;
i
<
n
;
i
++
{
switch
buf
[
i
]
{
case
'\t'
:
b
.
width
+=
i
-
i0
;
b
.
buf
.
Append
(
buf
[
i0
:
i
]);
i0
=
i
+
1
;
// don't append '\t'
b
.
Tab
();
case
'\n'
:
b
.
width
+=
i
-
i0
;
b
.
buf
.
Append
(
buf
[
i0
:
i
]);
i0
=
i
+
1
;
// don't append '\n'
b
.
Newline
();
}
}
}
}
b
.
width
+=
n
-
i0
;
}
b
.
buf
.
Append
(
buf
[
i0
:
n
]);
}
return
i
,
nil
;
// append leftover text
b
.
Append
(
buf
[
i0
:
n
]);
return
n
,
nil
;
}
}
export
func
MakeTabWriter
(
writer
io
.
Write
,
usetabs
bool
,
tabwidth
int
)
*
TabWriter
{
export
func
New
(
writer
io
.
Write
,
tabwidth
,
padding
int
,
usetabs
bool
)
*
TabWriter
{
b
:=
new
(
TabWriter
);
return
new
(
TabWriter
)
.
Init
(
writer
,
tabwidth
,
padding
,
usetabs
)
b
.
Init
(
writer
,
usetabs
,
tabwidth
);
return
b
;
}
}
usr/gri/pretty/untab.go
View file @
0998eaf4
...
@@ -14,8 +14,8 @@ import (
...
@@ -14,8 +14,8 @@ import (
var
(
var
(
usetabs
=
flag
.
Bool
(
"usetabs"
,
false
,
nil
,
"align with tabs instead of blanks"
);
tabwidth
=
flag
.
Int
(
"tabwidth"
,
4
,
nil
,
"tab width"
);
tabwidth
=
flag
.
Int
(
"tabwidth"
,
4
,
nil
,
"tab width"
);
usetabs
=
flag
.
Bool
(
"usetabs"
,
false
,
nil
,
"align with tabs instead of blanks"
);
)
)
...
@@ -36,7 +36,7 @@ func Untab(name string, src *os.FD, dst *tabwriter.TabWriter) {
...
@@ -36,7 +36,7 @@ func Untab(name string, src *os.FD, dst *tabwriter.TabWriter) {
func
main
()
{
func
main
()
{
flag
.
Parse
();
flag
.
Parse
();
dst
:=
tabwriter
.
MakeTabWriter
(
os
.
Stdout
,
usetabs
.
BVal
(),
int
(
tabwidth
.
IVal
()
));
dst
:=
tabwriter
.
New
(
os
.
Stdout
,
int
(
tabwidth
.
IVal
()),
1
,
usetabs
.
BVal
(
));
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
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment