Commit 5a1d3323 authored by Robert Griesemer's avatar Robert Griesemer

1) Change default gofmt default settings for

                  parsing and printing to new syntax.

                  Use -oldparser to parse the old syntax,
                  use -oldprinter to print the old syntax.

               2) Change default gofmt formatting settings
                  to use tabs for indentation only and to use
                  spaces for alignment. This will make the code
                  alignment insensitive to an editor's tabwidth.

                  Use -spaces=false to use tabs for alignment.

               3) Manually changed src/exp/parser/parser_test.go
                  so that it doesn't try to parse the parser's
                  source files using the old syntax (they have
                  new syntax now).

               4) gofmt -w src misc test/bench

	       1st set of files.

R=rsc
CC=agl, golang-dev, iant, ken2, r
https://golang.org/cl/180047
parent 34356e9a
......@@ -10,33 +10,33 @@
package main
import (
big "gmp";
"runtime";
big "gmp"
"runtime"
)
func fibber(c chan *big.Int, out chan string, n int64) {
// Keep the fibbers in dedicated operating system
// threads, so that this program tests coordination
// between pthreads and not just goroutines.
runtime.LockOSThread();
runtime.LockOSThread()
i := big.NewInt(n);
i := big.NewInt(n)
if n == 0 {
c <- i
}
for {
j := <-c;
out <- j.String();
i.Add(i, j);
c <- i;
j := <-c
out <- j.String()
i.Add(i, j)
c <- i
}
}
func main() {
c := make(chan *big.Int);
out := make(chan string);
go fibber(c, out, 0);
go fibber(c, out, 1);
c := make(chan *big.Int)
out := make(chan string)
go fibber(c, out, 0)
go fibber(c, out, 1)
for i := 0; i < 200; i++ {
println(<-out)
}
......
......@@ -104,8 +104,8 @@ package gmp
import "C"
import (
"os";
"unsafe";
"os"
"unsafe"
)
/*
......@@ -115,12 +115,12 @@ import (
// An Int represents a signed multi-precision integer.
// The zero value for an Int represents the value 0.
type Int struct {
i C.mpz_t;
init bool;
i C.mpz_t
init bool
}
// NewInt returns a new Int initialized to x.
func NewInt(x int64) *Int { return new(Int).SetInt64(x) }
func NewInt(x int64) *Int { return new(Int).SetInt64(x) }
// Int promises that the zero value is a 0, but in gmp
// the zero value is a crash. To bridge the gap, the
......@@ -132,65 +132,65 @@ func (z *Int) doinit() {
if z.init {
return
}
z.init = true;
C.mpz_init(&z.i[0]);
z.init = true
C.mpz_init(&z.i[0])
}
// Bytes returns z's representation as a big-endian byte array.
func (z *Int) Bytes() []byte {
b := make([]byte, (z.Len()+7)/8);
n := C.size_t(len(b));
C.mpz_export(unsafe.Pointer(&b[0]), &n, 1, 1, 1, 0, &z.i[0]);
return b[0:n];
b := make([]byte, (z.Len()+7)/8)
n := C.size_t(len(b))
C.mpz_export(unsafe.Pointer(&b[0]), &n, 1, 1, 1, 0, &z.i[0])
return b[0:n]
}
// Len returns the length of z in bits. 0 is considered to have length 1.
func (z *Int) Len() int {
z.doinit();
return int(C.mpz_sizeinbase(&z.i[0], 2));
z.doinit()
return int(C.mpz_sizeinbase(&z.i[0], 2))
}
// Set sets z = x and returns z.
func (z *Int) Set(x *Int) *Int {
z.doinit();
C.mpz_set(&z.i[0], &x.i[0]);
return z;
z.doinit()
C.mpz_set(&z.i[0], &x.i[0])
return z
}
// SetBytes interprets b as the bytes of a big-endian integer
// and sets z to that value.
func (z *Int) SetBytes(b []byte) *Int {
z.doinit();
z.doinit()
if len(b) == 0 {
z.SetInt64(0)
} else {
C.mpz_import(&z.i[0], C.size_t(len(b)), 1, 1, 1, 0, unsafe.Pointer(&b[0]))
}
return z;
return z
}
// SetInt64 sets z = x and returns z.
func (z *Int) SetInt64(x int64) *Int {
z.doinit();
z.doinit()
// TODO(rsc): more work on 32-bit platforms
C.mpz_set_si(&z.i[0], C.long(x));
return z;
C.mpz_set_si(&z.i[0], C.long(x))
return z
}
// SetString interprets s as a number in the given base
// and sets z to that value. The base must be in the range [2,36].
// SetString returns an error if s cannot be parsed or the base is invalid.
func (z *Int) SetString(s string, base int) os.Error {
z.doinit();
z.doinit()
if base < 2 || base > 36 {
return os.EINVAL
}
p := C.CString(s);
defer C.free(unsafe.Pointer(p));
p := C.CString(s)
defer C.free(unsafe.Pointer(p))
if C.mpz_set_str(&z.i[0], p, C.int(base)) < 0 {
return os.EINVAL
}
return z;
return z
}
// String returns the decimal representation of z.
......@@ -198,18 +198,18 @@ func (z *Int) String() string {
if z == nil {
return "nil"
}
z.doinit();
p := C.mpz_get_str(nil, 10, &z.i[0]);
s := C.GoString(p);
C.free(unsafe.Pointer(p));
return s;
z.doinit()
p := C.mpz_get_str(nil, 10, &z.i[0])
s := C.GoString(p)
C.free(unsafe.Pointer(p))
return s
}
func (z *Int) destroy() {
if z.init {
C.mpz_clear(&z.i[0])
}
z.init = false;
z.init = false
}
......@@ -219,103 +219,103 @@ func (z *Int) destroy() {
// Add sets z = x + y and returns z.
func (z *Int) Add(x, y *Int) *Int {
x.doinit();
y.doinit();
z.doinit();
C.mpz_add(&z.i[0], &x.i[0], &y.i[0]);
return z;
x.doinit()
y.doinit()
z.doinit()
C.mpz_add(&z.i[0], &x.i[0], &y.i[0])
return z
}
// Sub sets z = x - y and returns z.
func (z *Int) Sub(x, y *Int) *Int {
x.doinit();
y.doinit();
z.doinit();
C.mpz_sub(&z.i[0], &x.i[0], &y.i[0]);
return z;
x.doinit()
y.doinit()
z.doinit()
C.mpz_sub(&z.i[0], &x.i[0], &y.i[0])
return z
}
// Mul sets z = x * y and returns z.
func (z *Int) Mul(x, y *Int) *Int {
x.doinit();
y.doinit();
z.doinit();
C.mpz_mul(&z.i[0], &x.i[0], &y.i[0]);
return z;
x.doinit()
y.doinit()
z.doinit()
C.mpz_mul(&z.i[0], &x.i[0], &y.i[0])
return z
}
// Div sets z = x / y, rounding toward zero, and returns z.
func (z *Int) Div(x, y *Int) *Int {
x.doinit();
y.doinit();
z.doinit();
C.mpz_tdiv_q(&z.i[0], &x.i[0], &y.i[0]);
return z;
x.doinit()
y.doinit()
z.doinit()
C.mpz_tdiv_q(&z.i[0], &x.i[0], &y.i[0])
return z
}
// Mod sets z = x % y and returns z.
// Like the result of the Go % operator, z has the same sign as x.
func (z *Int) Mod(x, y *Int) *Int {
x.doinit();
y.doinit();
z.doinit();
C.mpz_tdiv_r(&z.i[0], &x.i[0], &y.i[0]);
return z;
x.doinit()
y.doinit()
z.doinit()
C.mpz_tdiv_r(&z.i[0], &x.i[0], &y.i[0])
return z
}
// Lsh sets z = x << s and returns z.
func (z *Int) Lsh(x *Int, s uint) *Int {
x.doinit();
z.doinit();
C.mpz_mul_2exp(&z.i[0], &x.i[0], C.ulong(s));
return z;
x.doinit()
z.doinit()
C.mpz_mul_2exp(&z.i[0], &x.i[0], C.ulong(s))
return z
}
// Rsh sets z = x >> s and returns z.
func (z *Int) Rsh(x *Int, s uint) *Int {
x.doinit();
z.doinit();
C.mpz_div_2exp(&z.i[0], &x.i[0], C.ulong(s));
return z;
x.doinit()
z.doinit()
C.mpz_div_2exp(&z.i[0], &x.i[0], C.ulong(s))
return z
}
// Exp sets z = x^y % m and returns z.
// If m == nil, Exp sets z = x^y.
func (z *Int) Exp(x, y, m *Int) *Int {
m.doinit();
x.doinit();
y.doinit();
z.doinit();
m.doinit()
x.doinit()
y.doinit()
z.doinit()
if m == nil {
C.mpz_pow_ui(&z.i[0], &x.i[0], C.mpz_get_ui(&y.i[0]))
} else {
C.mpz_powm(&z.i[0], &x.i[0], &y.i[0], &m.i[0])
}
return z;
return z
}
func (z *Int) Int64() int64 {
if !z.init {
return 0
}
return int64(C.mpz_get_si(&z.i[0]));
return int64(C.mpz_get_si(&z.i[0]))
}
// Neg sets z = -x and returns z.
func (z *Int) Neg(x *Int) *Int {
x.doinit();
z.doinit();
C.mpz_neg(&z.i[0], &x.i[0]);
return z;
x.doinit()
z.doinit()
C.mpz_neg(&z.i[0], &x.i[0])
return z
}
// Abs sets z to the absolute value of x and returns z.
func (z *Int) Abs(x *Int) *Int {
x.doinit();
z.doinit();
C.mpz_abs(&z.i[0], &x.i[0]);
return z;
x.doinit()
z.doinit()
C.mpz_abs(&z.i[0], &x.i[0])
return z
}
......@@ -330,24 +330,24 @@ func (z *Int) Abs(x *Int) *Int {
// +1 if x > y
//
func CmpInt(x, y *Int) int {
x.doinit();
y.doinit();
x.doinit()
y.doinit()
switch cmp := C.mpz_cmp(&x.i[0], &y.i[0]); {
case cmp < 0:
return -1
case cmp == 0:
return 0
}
return +1;
return +1
}
// DivModInt sets q = x / y and r = x % y.
func DivModInt(q, r, x, y *Int) {
q.doinit();
r.doinit();
x.doinit();
y.doinit();
C.mpz_tdiv_qr(&q.i[0], &r.i[0], &x.i[0], &y.i[0]);
q.doinit()
r.doinit()
x.doinit()
y.doinit()
C.mpz_tdiv_qr(&q.i[0], &r.i[0], &x.i[0], &y.i[0])
}
// GcdInt sets d to the greatest common divisor of a and b,
......@@ -355,18 +355,18 @@ func DivModInt(q, r, x, y *Int) {
// If x and y are not nil, GcdInt sets x and y such that d = a*x + b*y.
// If either a or b is not positive, GcdInt sets d = x = y = 0.
func GcdInt(d, x, y, a, b *Int) {
d.doinit();
x.doinit();
y.doinit();
a.doinit();
b.doinit();
C.mpz_gcdext(&d.i[0], &x.i[0], &y.i[0], &a.i[0], &b.i[0]);
d.doinit()
x.doinit()
y.doinit()
a.doinit()
b.doinit()
C.mpz_gcdext(&d.i[0], &x.i[0], &y.i[0], &a.i[0], &b.i[0])
}
// ProbablyPrime performs n Miller-Rabin tests to check whether z is prime.
// If it returns true, z is prime with probability 1 - 1/4^n.
// If it returns false, z is not prime.
func (z *Int) ProbablyPrime(n int) bool {
z.doinit();
return int(C.mpz_probab_prime_p(&z.i[0], C.int(n))) > 0;
z.doinit()
return int(C.mpz_probab_prime_p(&z.i[0], C.int(n))) > 0
}
......@@ -38,67 +38,67 @@ POSSIBILITY OF SUCH DAMAGE.
package main
import (
big "gmp";
"fmt";
"runtime";
big "gmp"
"fmt"
"runtime"
)
var (
tmp1 = big.NewInt(0);
tmp2 = big.NewInt(0);
numer = big.NewInt(1);
accum = big.NewInt(0);
denom = big.NewInt(1);
ten = big.NewInt(10);
tmp1 = big.NewInt(0)
tmp2 = big.NewInt(0)
numer = big.NewInt(1)
accum = big.NewInt(0)
denom = big.NewInt(1)
ten = big.NewInt(10)
)
func extractDigit() int64 {
if big.CmpInt(numer, accum) > 0 {
return -1
}
tmp1.Lsh(numer, 1).Add(tmp1, numer).Add(tmp1, accum);
big.DivModInt(tmp1, tmp2, tmp1, denom);
tmp2.Add(tmp2, numer);
tmp1.Lsh(numer, 1).Add(tmp1, numer).Add(tmp1, accum)
big.DivModInt(tmp1, tmp2, tmp1, denom)
tmp2.Add(tmp2, numer)
if big.CmpInt(tmp2, denom) >= 0 {
return -1
}
return tmp1.Int64();
return tmp1.Int64()
}
func nextTerm(k int64) {
y2 := k*2 + 1;
accum.Add(accum, tmp1.Lsh(numer, 1));
accum.Mul(accum, tmp1.SetInt64(y2));
numer.Mul(numer, tmp1.SetInt64(k));
denom.Mul(denom, tmp1.SetInt64(y2));
y2 := k*2 + 1
accum.Add(accum, tmp1.Lsh(numer, 1))
accum.Mul(accum, tmp1.SetInt64(y2))
numer.Mul(numer, tmp1.SetInt64(k))
denom.Mul(denom, tmp1.SetInt64(y2))
}
func eliminateDigit(d int64) {
accum.Sub(accum, tmp1.Mul(denom, tmp1.SetInt64(d)));
accum.Mul(accum, ten);
numer.Mul(numer, ten);
accum.Sub(accum, tmp1.Mul(denom, tmp1.SetInt64(d)))
accum.Mul(accum, ten)
numer.Mul(numer, ten)
}
func main() {
i := 0;
k := int64(0);
i := 0
k := int64(0)
for {
d := int64(-1);
d := int64(-1)
for d < 0 {
k++;
nextTerm(k);
d = extractDigit();
k++
nextTerm(k)
d = extractDigit()
}
eliminateDigit(d);
fmt.Printf("%c", d+'0');
eliminateDigit(d)
fmt.Printf("%c", d+'0')
if i++; i%50 == 0 {
fmt.Printf("\n");
fmt.Printf("\n")
if i >= 1000 {
break
}
}
}
fmt.Printf("\n%d calls; bit sizes: %d %d %d\n", runtime.Cgocalls(), numer.Len(), accum.Len(), denom.Len());
fmt.Printf("\n%d calls; bit sizes: %d %d %d\n", runtime.Cgocalls(), numer.Len(), accum.Len(), denom.Len())
}
......@@ -7,9 +7,9 @@
package main
import (
"runtime";
"stdio";
"strconv";
"runtime"
"stdio"
"strconv"
)
const N = 10
......@@ -19,25 +19,25 @@ func link(left chan<- int, right <-chan int) {
// Keep the links in dedicated operating system
// threads, so that this program tests coordination
// between pthreads and not just goroutines.
runtime.LockOSThread();
runtime.LockOSThread()
for {
v := <-right;
stdio.Puts(strconv.Itoa(v));
left <- 1+v;
v := <-right
stdio.Puts(strconv.Itoa(v))
left <- 1+v
}
}
func main() {
leftmost := make(chan int);
var left chan int;
right := leftmost;
leftmost := make(chan int)
var left chan int
right := leftmost
for i := 0; i < N; i++ {
left, right = right, make(chan int);
go link(left, right);
left, right = right, make(chan int)
go link(left, right)
}
for i := 0; i < R; i++ {
right <- 0;
x := <-leftmost;
stdio.Puts(strconv.Itoa(x));
right <- 0
x := <-leftmost
stdio.Puts(strconv.Itoa(x))
}
}
......@@ -10,38 +10,38 @@
package main
import (
"runtime";
"stdio";
"strconv";
"runtime"
"stdio"
"strconv"
)
func fibber(c, out chan int64, i int64) {
// Keep the fibbers in dedicated operating system
// threads, so that this program tests coordination
// between pthreads and not just goroutines.
runtime.LockOSThread();
runtime.LockOSThread()
if i == 0 {
c <- i
}
for {
j := <-c;
stdio.Puts(strconv.Itoa64(j));
out <- j;
<-out;
i += j;
c <- i;
j := <-c
stdio.Puts(strconv.Itoa64(j))
out <- j
<-out
i += j
c <- i
}
}
func main() {
c := make(chan int64);
out := make(chan int64);
go fibber(c, out, 0);
go fibber(c, out, 1);
<-out;
c := make(chan int64)
out := make(chan int64)
go fibber(c, out, 0)
go fibber(c, out, 1)
<-out
for i := 0; i < 90; i++ {
out <- 1;
<-out;
out <- 1
<-out
}
}
......@@ -35,8 +35,8 @@ func (f *File) WriteString(s string) {
*/
func Puts(s string) {
p := C.CString(s);
C.puts(p);
C.free(unsafe.Pointer(p));
C.fflushstdout();
p := C.CString(s)
C.puts(p)
C.free(unsafe.Pointer(p))
C.fflushstdout()
}
......@@ -7,57 +7,57 @@
package main
import (
"fmt";
"go/ast";
"go/doc";
"go/parser";
"go/scanner";
"os";
"fmt"
"go/ast"
"go/doc"
"go/parser"
"go/scanner"
"os"
)
// A Cref refers to an expression of the form C.xxx in the AST.
type Cref struct {
Name string;
Expr *ast.Expr;
Context string; // "type", "expr", or "call"
TypeName bool; // whether xxx is a C type name
Type *Type; // the type of xxx
FuncType *FuncType;
Name string
Expr *ast.Expr
Context string // "type", "expr", or "call"
TypeName bool // whether xxx is a C type name
Type *Type // the type of xxx
FuncType *FuncType
}
// A Prog collects information about a cgo program.
type Prog struct {
AST *ast.File; // parsed AST
Preamble string; // C preamble (doc comment on import "C")
PackagePath string;
Package string;
Crefs []*Cref;
Typedef map[string]ast.Expr;
Vardef map[string]*Type;
Funcdef map[string]*FuncType;
PtrSize int64;
GccOptions []string;
AST *ast.File // parsed AST
Preamble string // C preamble (doc comment on import "C")
PackagePath string
Package string
Crefs []*Cref
Typedef map[string]ast.Expr
Vardef map[string]*Type
Funcdef map[string]*FuncType
PtrSize int64
GccOptions []string
}
// A Type collects information about a type in both the C and Go worlds.
type Type struct {
Size int64;
Align int64;
C string;
Go ast.Expr;
Size int64
Align int64
C string
Go ast.Expr
}
// A FuncType collects information about a function type in both the C and Go worlds.
type FuncType struct {
Params []*Type;
Result *Type;
Go *ast.FuncType;
Params []*Type
Result *Type
Go *ast.FuncType
}
func openProg(name string) *Prog {
p := new(Prog);
var err os.Error;
p.AST, err = parser.ParsePkgFile("", name, parser.ParseComments);
p := new(Prog)
var err os.Error
p.AST, err = parser.ParsePkgFile("", name, parser.ParseComments)
if err != nil {
if list, ok := err.(scanner.ErrorList); ok {
// If err is a scanner.ErrorList, its String will print just
......@@ -67,32 +67,32 @@ func openProg(name string) *Prog {
for _, e := range list {
fmt.Fprintln(os.Stderr, e)
}
os.Exit(2);
os.Exit(2)
}
fatal("parsing %s: %s", name, err);
fatal("parsing %s: %s", name, err)
}
p.Package = p.AST.Name.Value;
p.Package = p.AST.Name.Value
// Find the import "C" line and get any extra C preamble.
// Delete the import "C" line along the way.
sawC := false;
w := 0;
sawC := false
w := 0
for _, decl := range p.AST.Decls {
d, ok := decl.(*ast.GenDecl);
d, ok := decl.(*ast.GenDecl)
if !ok {
p.AST.Decls[w] = decl;
w++;
continue;
p.AST.Decls[w] = decl
w++
continue
}
ws := 0;
ws := 0
for _, spec := range d.Specs {
s, ok := spec.(*ast.ImportSpec);
s, ok := spec.(*ast.ImportSpec)
if !ok || len(s.Path) != 1 || string(s.Path[0].Value) != `"C"` {
d.Specs[ws] = spec;
ws++;
continue;
d.Specs[ws] = spec
ws++
continue
}
sawC = true;
sawC = true
if s.Name != nil {
error(s.Path[0].Pos(), `cannot rename import "C"`)
}
......@@ -105,20 +105,20 @@ func openProg(name string) *Prog {
if ws == 0 {
continue
}
d.Specs = d.Specs[0:ws];
p.AST.Decls[w] = d;
w++;
d.Specs = d.Specs[0:ws]
p.AST.Decls[w] = d
w++
}
p.AST.Decls = p.AST.Decls[0:w];
p.AST.Decls = p.AST.Decls[0:w]
if !sawC {
error(noPos, `cannot find import "C"`)
}
// Accumulate pointers to uses of C.x.
p.Crefs = make([]*Cref, 0, 8);
walk(p.AST, p, "prog");
return p;
p.Crefs = make([]*Cref, 0, 8)
walk(p.AST, p, "prog")
return p
}
func walk(x interface{}, p *Prog, context string) {
......@@ -131,29 +131,29 @@ func walk(x interface{}, p *Prog, context string) {
// so that we will be able to distinguish a "top-level C"
// from a local C.
if l, ok := sel.X.(*ast.Ident); ok && l.Value == "C" {
i := len(p.Crefs);
i := len(p.Crefs)
if i >= cap(p.Crefs) {
new := make([]*Cref, 2*i);
new := make([]*Cref, 2*i)
for j, v := range p.Crefs {
new[j] = v
}
p.Crefs = new;
p.Crefs = new
}
p.Crefs = p.Crefs[0 : i+1];
p.Crefs = p.Crefs[0 : i+1]
p.Crefs[i] = &Cref{
Name: sel.Sel.Value,
Expr: n,
Context: context,
};
break;
}
break
}
}
walk(*n, p, context);
walk(*n, p, context)
// everything else just recurs
default:
error(noPos, "unexpected type %T in walk", x);
panic();
error(noPos, "unexpected type %T in walk", x)
panic()
case nil:
......@@ -166,54 +166,54 @@ func walk(x interface{}, p *Prog, context string) {
case *ast.BasicLit:
case *ast.StringList:
case *ast.FuncLit:
walk(n.Type, p, "type");
walk(n.Body, p, "stmt");
walk(n.Type, p, "type")
walk(n.Body, p, "stmt")
case *ast.CompositeLit:
walk(&n.Type, p, "type");
walk(n.Elts, p, "expr");
walk(&n.Type, p, "type")
walk(n.Elts, p, "expr")
case *ast.ParenExpr:
walk(&n.X, p, context)
case *ast.SelectorExpr:
walk(&n.X, p, "selector")
case *ast.IndexExpr:
walk(&n.X, p, "expr");
walk(&n.Index, p, "expr");
walk(&n.X, p, "expr")
walk(&n.Index, p, "expr")
case *ast.SliceExpr:
walk(&n.X, p, "expr");
walk(&n.Index, p, "expr");
walk(&n.X, p, "expr")
walk(&n.Index, p, "expr")
if n.End != nil {
walk(&n.End, p, "expr")
}
case *ast.TypeAssertExpr:
walk(&n.X, p, "expr");
walk(&n.Type, p, "type");
walk(&n.X, p, "expr")
walk(&n.Type, p, "type")
case *ast.CallExpr:
walk(&n.Fun, p, "call");
walk(n.Args, p, "expr");
walk(&n.Fun, p, "call")
walk(n.Args, p, "expr")
case *ast.StarExpr:
walk(&n.X, p, context)
case *ast.UnaryExpr:
walk(&n.X, p, "expr")
case *ast.BinaryExpr:
walk(&n.X, p, "expr");
walk(&n.Y, p, "expr");
walk(&n.X, p, "expr")
walk(&n.Y, p, "expr")
case *ast.KeyValueExpr:
walk(&n.Key, p, "expr");
walk(&n.Value, p, "expr");
walk(&n.Key, p, "expr")
walk(&n.Value, p, "expr")
case *ast.ArrayType:
walk(&n.Len, p, "expr");
walk(&n.Elt, p, "type");
walk(&n.Len, p, "expr")
walk(&n.Elt, p, "type")
case *ast.StructType:
walk(n.Fields, p, "field")
case *ast.FuncType:
walk(n.Params, p, "field");
walk(n.Results, p, "field");
walk(n.Params, p, "field")
walk(n.Results, p, "field")
case *ast.InterfaceType:
walk(n.Methods, p, "field")
case *ast.MapType:
walk(&n.Key, p, "type");
walk(&n.Value, p, "type");
walk(&n.Key, p, "type")
walk(&n.Value, p, "type")
case *ast.ChanType:
walk(&n.Value, p, "type")
......@@ -228,8 +228,8 @@ func walk(x interface{}, p *Prog, context string) {
case *ast.IncDecStmt:
walk(&n.X, p, "expr")
case *ast.AssignStmt:
walk(n.Lhs, p, "expr");
walk(n.Rhs, p, "expr");
walk(n.Lhs, p, "expr")
walk(n.Rhs, p, "expr")
case *ast.GoStmt:
walk(n.Call, p, "expr")
case *ast.DeferStmt:
......@@ -240,45 +240,45 @@ func walk(x interface{}, p *Prog, context string) {
case *ast.BlockStmt:
walk(n.List, p, "stmt")
case *ast.IfStmt:
walk(n.Init, p, "stmt");
walk(&n.Cond, p, "expr");
walk(n.Body, p, "stmt");
walk(n.Else, p, "stmt");
walk(n.Init, p, "stmt")
walk(&n.Cond, p, "expr")
walk(n.Body, p, "stmt")
walk(n.Else, p, "stmt")
case *ast.CaseClause:
walk(n.Values, p, "expr");
walk(n.Body, p, "stmt");
walk(n.Values, p, "expr")
walk(n.Body, p, "stmt")
case *ast.SwitchStmt:
walk(n.Init, p, "stmt");
walk(&n.Tag, p, "expr");
walk(n.Body, p, "stmt");
walk(n.Init, p, "stmt")
walk(&n.Tag, p, "expr")
walk(n.Body, p, "stmt")
case *ast.TypeCaseClause:
walk(n.Types, p, "type");
walk(n.Body, p, "stmt");
walk(n.Types, p, "type")
walk(n.Body, p, "stmt")
case *ast.TypeSwitchStmt:
walk(n.Init, p, "stmt");
walk(n.Assign, p, "stmt");
walk(n.Body, p, "stmt");
walk(n.Init, p, "stmt")
walk(n.Assign, p, "stmt")
walk(n.Body, p, "stmt")
case *ast.CommClause:
walk(n.Lhs, p, "expr");
walk(n.Rhs, p, "expr");
walk(n.Body, p, "stmt");
walk(n.Lhs, p, "expr")
walk(n.Rhs, p, "expr")
walk(n.Body, p, "stmt")
case *ast.SelectStmt:
walk(n.Body, p, "stmt")
case *ast.ForStmt:
walk(n.Init, p, "stmt");
walk(&n.Cond, p, "expr");
walk(n.Post, p, "stmt");
walk(n.Body, p, "stmt");
walk(n.Init, p, "stmt")
walk(&n.Cond, p, "expr")
walk(n.Post, p, "stmt")
walk(n.Body, p, "stmt")
case *ast.RangeStmt:
walk(&n.Key, p, "expr");
walk(&n.Value, p, "expr");
walk(&n.X, p, "expr");
walk(n.Body, p, "stmt");
walk(&n.Key, p, "expr")
walk(&n.Value, p, "expr")
walk(&n.X, p, "expr")
walk(n.Body, p, "stmt")
case *ast.ImportSpec:
case *ast.ValueSpec:
walk(&n.Type, p, "type");
walk(n.Values, p, "expr");
walk(&n.Type, p, "type")
walk(n.Values, p, "expr")
case *ast.TypeSpec:
walk(&n.Type, p, "type")
......@@ -289,7 +289,7 @@ func walk(x interface{}, p *Prog, context string) {
if n.Recv != nil {
walk(n.Recv, p, "field")
}
walk(n.Type, p, "type");
walk(n.Type, p, "type")
if n.Body != nil {
walk(n.Body, p, "stmt")
}
......
This diff is collapsed.
......@@ -11,12 +11,12 @@
package main
import (
"fmt";
"go/ast";
"os";
"fmt"
"go/ast"
"os"
)
func usage() { fmt.Fprint(os.Stderr, "usage: cgo [compiler options] file.go\n") }
func usage() { fmt.Fprint(os.Stderr, "usage: cgo [compiler options] file.go\n") }
var ptrSizeMap = map[string]int64{
"386": 4,
......@@ -35,29 +35,29 @@ var expandName = map[string]string{
}
func main() {
args := os.Args;
args := os.Args
if len(args) < 2 {
usage();
os.Exit(2);
usage()
os.Exit(2)
}
gccOptions := args[1 : len(args)-1];
input := args[len(args)-1];
gccOptions := args[1 : len(args)-1]
input := args[len(args)-1]
arch := os.Getenv("GOARCH");
arch := os.Getenv("GOARCH")
if arch == "" {
fatal("$GOARCH is not set")
}
ptrSize, ok := ptrSizeMap[arch];
ptrSize, ok := ptrSizeMap[arch]
if !ok {
fatal("unknown architecture %s", arch)
}
// Clear locale variables so gcc emits English errors [sic].
os.Setenv("LANG", "en_US.UTF-8");
os.Setenv("LC_ALL", "C");
os.Setenv("LC_CTYPE", "C");
os.Setenv("LANG", "en_US.UTF-8")
os.Setenv("LC_ALL", "C")
os.Setenv("LC_CTYPE", "C")
p := openProg(input);
p := openProg(input)
for _, cref := range p.Crefs {
// Convert C.ulong to C.unsigned long, etc.
if expand, ok := expandName[cref.Name]; ok {
......@@ -65,42 +65,42 @@ func main() {
}
}
p.PtrSize = ptrSize;
p.Preamble = p.Preamble + "\n" + builtinProlog;
p.GccOptions = gccOptions;
p.loadDebugInfo();
p.Vardef = make(map[string]*Type);
p.Funcdef = make(map[string]*FuncType);
p.PtrSize = ptrSize
p.Preamble = p.Preamble + "\n" + builtinProlog
p.GccOptions = gccOptions
p.loadDebugInfo()
p.Vardef = make(map[string]*Type)
p.Funcdef = make(map[string]*FuncType)
for _, cref := range p.Crefs {
switch cref.Context {
case "call":
if !cref.TypeName {
// Is an actual function call.
*cref.Expr = &ast.Ident{Value: "_C_" + cref.Name};
p.Funcdef[cref.Name] = cref.FuncType;
break;
*cref.Expr = &ast.Ident{Value: "_C_" + cref.Name}
p.Funcdef[cref.Name] = cref.FuncType
break
}
*cref.Expr = cref.Type.Go;
*cref.Expr = cref.Type.Go
case "expr":
if cref.TypeName {
error((*cref.Expr).Pos(), "type C.%s used as expression", cref.Name)
}
// Reference to C variable.
// We declare a pointer and arrange to have it filled in.
*cref.Expr = &ast.StarExpr{X: &ast.Ident{Value: "_C_" + cref.Name}};
p.Vardef[cref.Name] = cref.Type;
*cref.Expr = &ast.StarExpr{X: &ast.Ident{Value: "_C_" + cref.Name}}
p.Vardef[cref.Name] = cref.Type
case "type":
if !cref.TypeName {
error((*cref.Expr).Pos(), "expression C.%s used as type", cref.Name)
}
*cref.Expr = cref.Type.Go;
*cref.Expr = cref.Type.Go
}
}
if nerrors > 0 {
os.Exit(2)
}
p.PackagePath = os.Getenv("CGOPKGPATH") + "/" + p.Package;
p.writeOutput(input);
p.PackagePath = os.Getenv("CGOPKGPATH") + "/" + p.Package
p.writeOutput(input)
}
......@@ -5,78 +5,78 @@
package main
import (
"fmt";
"go/ast";
"go/printer";
"os";
"strings";
"fmt"
"go/ast"
"go/printer"
"os"
"strings"
)
func creat(name string) *os.File {
f, err := os.Open(name, os.O_WRONLY|os.O_CREAT|os.O_TRUNC, 0666);
f, err := os.Open(name, os.O_WRONLY|os.O_CREAT|os.O_TRUNC, 0666)
if err != nil {
fatal("%s", err)
}
return f;
return f
}
// writeOutput creates output files to be compiled by 6g, 6c, and gcc.
// (The comments here say 6g and 6c but the code applies to the 8 and 5 tools too.)
func (p *Prog) writeOutput(srcfile string) {
pkgroot := os.Getenv("GOROOT") + "/pkg/" + os.Getenv("GOOS") + "_" + os.Getenv("GOARCH");
pkgroot := os.Getenv("GOROOT") + "/pkg/" + os.Getenv("GOOS") + "_" + os.Getenv("GOARCH")
base := srcfile;
base := srcfile
if strings.HasSuffix(base, ".go") {
base = base[0 : len(base)-3]
}
fgo1 := creat(base + ".cgo1.go");
fgo2 := creat(base + ".cgo2.go");
fc := creat(base + ".cgo3.c");
fgcc := creat(base + ".cgo4.c");
fgo1 := creat(base + ".cgo1.go")
fgo2 := creat(base + ".cgo2.go")
fc := creat(base + ".cgo3.c")
fgcc := creat(base + ".cgo4.c")
// Write Go output: Go input with rewrites of C.xxx to _C_xxx.
fmt.Fprintf(fgo1, "// Created by cgo - DO NOT EDIT\n");
fmt.Fprintf(fgo1, "//line %s:1\n", srcfile);
printer.Fprint(fgo1, p.AST);
fmt.Fprintf(fgo1, "// Created by cgo - DO NOT EDIT\n")
fmt.Fprintf(fgo1, "//line %s:1\n", srcfile)
printer.Fprint(fgo1, p.AST)
// Write second Go output: definitions of _C_xxx.
// In a separate file so that the import of "unsafe" does not
// pollute the original file.
fmt.Fprintf(fgo2, "// Created by cgo - DO NOT EDIT\n");
fmt.Fprintf(fgo2, "package %s\n\n", p.Package);
fmt.Fprintf(fgo2, "import \"unsafe\"\n\n");
fmt.Fprintf(fgo2, "type _ unsafe.Pointer\n\n");
fmt.Fprintf(fgo2, "// Created by cgo - DO NOT EDIT\n")
fmt.Fprintf(fgo2, "package %s\n\n", p.Package)
fmt.Fprintf(fgo2, "import \"unsafe\"\n\n")
fmt.Fprintf(fgo2, "type _ unsafe.Pointer\n\n")
for name, def := range p.Typedef {
fmt.Fprintf(fgo2, "type %s ", name);
printer.Fprint(fgo2, def);
fmt.Fprintf(fgo2, "\n");
fmt.Fprintf(fgo2, "type %s ", name)
printer.Fprint(fgo2, def)
fmt.Fprintf(fgo2, "\n")
}
fmt.Fprintf(fgo2, "type _C_void [0]byte\n");
fmt.Fprintf(fgo2, "type _C_void [0]byte\n")
// While we process the vars and funcs, also write 6c and gcc output.
// Gcc output starts with the preamble.
fmt.Fprintf(fgcc, "%s\n", p.Preamble);
fmt.Fprintf(fgcc, "%s\n", gccProlog);
fmt.Fprintf(fgcc, "%s\n", p.Preamble)
fmt.Fprintf(fgcc, "%s\n", gccProlog)
fmt.Fprintf(fc, cProlog, pkgroot, pkgroot, pkgroot, pkgroot, p.Package, p.Package);
fmt.Fprintf(fc, cProlog, pkgroot, pkgroot, pkgroot, pkgroot, p.Package, p.Package)
for name, def := range p.Vardef {
fmt.Fprintf(fc, "#pragma dynld %s·_C_%s %s \"%s/%s_%s.so\"\n", p.Package, name, name, pkgroot, p.PackagePath, base);
fmt.Fprintf(fgo2, "var _C_%s ", name);
printer.Fprint(fgo2, &ast.StarExpr{X: def.Go});
fmt.Fprintf(fgo2, "\n");
fmt.Fprintf(fc, "#pragma dynld %s·_C_%s %s \"%s/%s_%s.so\"\n", p.Package, name, name, pkgroot, p.PackagePath, base)
fmt.Fprintf(fgo2, "var _C_%s ", name)
printer.Fprint(fgo2, &ast.StarExpr{X: def.Go})
fmt.Fprintf(fgo2, "\n")
}
fmt.Fprintf(fc, "\n");
fmt.Fprintf(fc, "\n")
for name, def := range p.Funcdef {
// Go func declaration.
d := &ast.FuncDecl{
Name: &ast.Ident{Value: "_C_" + name},
Type: def.Go,
};
printer.Fprint(fgo2, d);
fmt.Fprintf(fgo2, "\n");
}
printer.Fprint(fgo2, d)
fmt.Fprintf(fgo2, "\n")
if name == "CString" || name == "GoString" {
// The builtins are already defined in the C prolog.
......@@ -88,86 +88,86 @@ func (p *Prog) writeOutput(srcfile string) {
// These assumptions are checked by the gccProlog.
// Also assumes that 6c convention is to word-align the
// input and output parameters.
structType := "struct {\n";
off := int64(0);
npad := 0;
structType := "struct {\n"
off := int64(0)
npad := 0
for i, t := range def.Params {
if off%t.Align != 0 {
pad := t.Align - off%t.Align;
structType += fmt.Sprintf("\t\tchar __pad%d[%d];\n", npad, pad);
off += pad;
npad++;
pad := t.Align - off%t.Align
structType += fmt.Sprintf("\t\tchar __pad%d[%d];\n", npad, pad)
off += pad
npad++
}
structType += fmt.Sprintf("\t\t%s p%d;\n", t.C, i);
off += t.Size;
structType += fmt.Sprintf("\t\t%s p%d;\n", t.C, i)
off += t.Size
}
if off%p.PtrSize != 0 {
pad := p.PtrSize - off%p.PtrSize;
structType += fmt.Sprintf("\t\tchar __pad%d[%d];\n", npad, pad);
off += pad;
npad++;
pad := p.PtrSize - off%p.PtrSize
structType += fmt.Sprintf("\t\tchar __pad%d[%d];\n", npad, pad)
off += pad
npad++
}
if t := def.Result; t != nil {
if off%t.Align != 0 {
pad := t.Align - off%t.Align;
structType += fmt.Sprintf("\t\tchar __pad%d[%d];\n", npad, pad);
off += pad;
npad++;
pad := t.Align - off%t.Align
structType += fmt.Sprintf("\t\tchar __pad%d[%d];\n", npad, pad)
off += pad
npad++
}
structType += fmt.Sprintf("\t\t%s r;\n", t.C);
off += t.Size;
structType += fmt.Sprintf("\t\t%s r;\n", t.C)
off += t.Size
}
if off%p.PtrSize != 0 {
pad := p.PtrSize - off%p.PtrSize;
structType += fmt.Sprintf("\t\tchar __pad%d[%d];\n", npad, pad);
off += pad;
npad++;
pad := p.PtrSize - off%p.PtrSize
structType += fmt.Sprintf("\t\tchar __pad%d[%d];\n", npad, pad)
off += pad
npad++
}
if len(def.Params) == 0 && def.Result == nil {
structType += "\t\tchar unused;\n"; // avoid empty struct
off++;
structType += "\t\tchar unused;\n" // avoid empty struct
off++
}
structType += "\t}";
argSize := off;
structType += "\t}"
argSize := off
// C wrapper calls into gcc, passing a pointer to the argument frame.
// Also emit #pragma to get a pointer to the gcc wrapper.
fmt.Fprintf(fc, "#pragma dynld _cgo_%s _cgo_%s \"%s/%s_%s.so\"\n", name, name, pkgroot, p.PackagePath, base);
fmt.Fprintf(fc, "void (*_cgo_%s)(void*);\n", name);
fmt.Fprintf(fc, "\n");
fmt.Fprintf(fc, "void\n");
fmt.Fprintf(fc, "%s·_C_%s(struct{uint8 x[%d];}p)\n", p.Package, name, argSize);
fmt.Fprintf(fc, "{\n");
fmt.Fprintf(fc, "\tcgocall(_cgo_%s, &p);\n", name);
fmt.Fprintf(fc, "}\n");
fmt.Fprintf(fc, "\n");
fmt.Fprintf(fc, "#pragma dynld _cgo_%s _cgo_%s \"%s/%s_%s.so\"\n", name, name, pkgroot, p.PackagePath, base)
fmt.Fprintf(fc, "void (*_cgo_%s)(void*);\n", name)
fmt.Fprintf(fc, "\n")
fmt.Fprintf(fc, "void\n")
fmt.Fprintf(fc, "%s·_C_%s(struct{uint8 x[%d];}p)\n", p.Package, name, argSize)
fmt.Fprintf(fc, "{\n")
fmt.Fprintf(fc, "\tcgocall(_cgo_%s, &p);\n", name)
fmt.Fprintf(fc, "}\n")
fmt.Fprintf(fc, "\n")
// Gcc wrapper unpacks the C argument struct
// and calls the actual C function.
fmt.Fprintf(fgcc, "void\n");
fmt.Fprintf(fgcc, "_cgo_%s(void *v)\n", name);
fmt.Fprintf(fgcc, "{\n");
fmt.Fprintf(fgcc, "\t%s *a = v;\n", structType);
fmt.Fprintf(fgcc, "\t");
fmt.Fprintf(fgcc, "void\n")
fmt.Fprintf(fgcc, "_cgo_%s(void *v)\n", name)
fmt.Fprintf(fgcc, "{\n")
fmt.Fprintf(fgcc, "\t%s *a = v;\n", structType)
fmt.Fprintf(fgcc, "\t")
if def.Result != nil {
fmt.Fprintf(fgcc, "a->r = ")
}
fmt.Fprintf(fgcc, "%s(", name);
fmt.Fprintf(fgcc, "%s(", name)
for i := range def.Params {
if i > 0 {
fmt.Fprintf(fgcc, ", ")
}
fmt.Fprintf(fgcc, "a->p%d", i);
fmt.Fprintf(fgcc, "a->p%d", i)
}
fmt.Fprintf(fgcc, ");\n");
fmt.Fprintf(fgcc, "}\n");
fmt.Fprintf(fgcc, "\n");
fmt.Fprintf(fgcc, ");\n")
fmt.Fprintf(fgcc, "}\n")
fmt.Fprintf(fgcc, "\n")
}
fgo1.Close();
fgo2.Close();
fc.Close();
fgcc.Close();
fgo1.Close()
fgo2.Close()
fc.Close()
fgcc.Close()
}
const gccProlog = `
......
......@@ -5,11 +5,11 @@
package main
import (
"exec";
"fmt";
"go/token";
"io/ioutil";
"os";
"exec"
"fmt"
"go/token"
"io/ioutil"
"os"
)
// A ByteReaderAt implements io.ReadAt using a slice of bytes.
......@@ -19,76 +19,76 @@ func (r ByteReaderAt) ReadAt(p []byte, off int64) (n int, err os.Error) {
if off >= int64(len(r)) || off < 0 {
return 0, os.EOF
}
return copy(p, r[off:]), nil;
return copy(p, r[off:]), nil
}
// run runs the command argv, feeding in stdin on standard input.
// It returns the output to standard output and standard error.
// ok indicates whether the command exited successfully.
func run(stdin []byte, argv []string) (stdout, stderr []byte, ok bool) {
cmd, err := exec.LookPath(argv[0]);
cmd, err := exec.LookPath(argv[0])
if err != nil {
fatal("exec %s: %s", argv[0], err)
}
r0, w0, err := os.Pipe();
r0, w0, err := os.Pipe()
if err != nil {
fatal("%s", err)
}
r1, w1, err := os.Pipe();
r1, w1, err := os.Pipe()
if err != nil {
fatal("%s", err)
}
r2, w2, err := os.Pipe();
r2, w2, err := os.Pipe()
if err != nil {
fatal("%s", err)
}
pid, err := os.ForkExec(cmd, argv, os.Environ(), "", []*os.File{r0, w1, w2});
pid, err := os.ForkExec(cmd, argv, os.Environ(), "", []*os.File{r0, w1, w2})
if err != nil {
fatal("%s", err)
}
r0.Close();
w1.Close();
w2.Close();
c := make(chan bool);
r0.Close()
w1.Close()
w2.Close()
c := make(chan bool)
go func() {
w0.Write(stdin);
w0.Close();
c <- true;
}();
var xstdout []byte; // TODO(rsc): delete after 6g can take address of out parameter
w0.Write(stdin)
w0.Close()
c <- true
}()
var xstdout []byte // TODO(rsc): delete after 6g can take address of out parameter
go func() {
xstdout, _ = ioutil.ReadAll(r1);
r1.Close();
c <- true;
}();
stderr, _ = ioutil.ReadAll(r2);
r2.Close();
<-c;
<-c;
stdout = xstdout;
xstdout, _ = ioutil.ReadAll(r1)
r1.Close()
c <- true
}()
stderr, _ = ioutil.ReadAll(r2)
r2.Close()
<-c
<-c
stdout = xstdout
w, err := os.Wait(pid, 0);
w, err := os.Wait(pid, 0)
if err != nil {
fatal("%s", err)
}
ok = w.Exited() && w.ExitStatus() == 0;
return;
ok = w.Exited() && w.ExitStatus() == 0
return
}
// Die with an error message.
func fatal(msg string, args ...) {
fmt.Fprintf(os.Stderr, msg+"\n", args);
os.Exit(2);
fmt.Fprintf(os.Stderr, msg+"\n", args)
os.Exit(2)
}
var nerrors int
var noPos token.Position
func error(pos token.Position, msg string, args ...) {
nerrors++;
nerrors++
if pos.IsValid() {
fmt.Fprintf(os.Stderr, "%s: ", pos)
}
fmt.Fprintf(os.Stderr, msg, args);
fmt.Fprintf(os.Stderr, "\n");
fmt.Fprintf(os.Stderr, msg, args)
fmt.Fprintf(os.Stderr, "\n")
}
......@@ -5,15 +5,15 @@
package main
import (
"bytes";
"ebnf";
"flag";
"fmt";
"go/scanner";
"io/ioutil";
"os";
"path";
"strings";
"bytes"
"ebnf"
"flag"
"fmt"
"go/scanner"
"io/ioutil"
"os"
"path"
"strings"
)
......@@ -21,29 +21,29 @@ var start = flag.String("start", "Start", "name of start production")
func usage() {
fmt.Fprintf(os.Stderr, "usage: ebnflint [flags] [filename]\n");
flag.PrintDefaults();
os.Exit(1);
fmt.Fprintf(os.Stderr, "usage: ebnflint [flags] [filename]\n")
flag.PrintDefaults()
os.Exit(1)
}
// Markers around EBNF sections in .html files
var (
open = strings.Bytes(`<pre class="ebnf">`);
close = strings.Bytes(`</pre>`);
open = strings.Bytes(`<pre class="ebnf">`)
close = strings.Bytes(`</pre>`)
)
func extractEBNF(src []byte) []byte {
var buf bytes.Buffer;
var buf bytes.Buffer
for {
// i = beginning of EBNF text
i := bytes.Index(src, open);
i := bytes.Index(src, open)
if i < 0 {
break // no EBNF found - we are done
break // no EBNF found - we are done
}
i += len(open);
i += len(open)
// write as many newlines as found in the excluded text
// to maintain correct line numbers in error messages
......@@ -54,27 +54,27 @@ func extractEBNF(src []byte) []byte {
}
// j = end of EBNF text (or end of source)
j := bytes.Index(src[i:], close); // close marker
j := bytes.Index(src[i:], close) // close marker
if j < 0 {
j = len(src) - i
}
j += i;
j += i
// copy EBNF text
buf.Write(src[i:j]);
buf.Write(src[i:j])
// advance
src = src[j:];
src = src[j:]
}
return buf.Bytes();
return buf.Bytes()
}
func main() {
flag.Parse();
flag.Parse()
var filename string;
var filename string
switch flag.NArg() {
case 0:
filename = "/dev/stdin"
......@@ -84,7 +84,7 @@ func main() {
usage()
}
src, err := ioutil.ReadFile(filename);
src, err := ioutil.ReadFile(filename)
if err != nil {
scanner.PrintError(os.Stderr, err)
}
......@@ -93,7 +93,7 @@ func main() {
src = extractEBNF(src)
}
grammar, err := ebnf.Parse(filename, src);
grammar, err := ebnf.Parse(filename, src)
if err != nil {
scanner.PrintError(os.Stderr, err)
}
......
......@@ -84,7 +84,7 @@ func sliceslice1(old []any, lb int, width int) (ary []any)
func sliceslice(old []any, lb int, hb int, width int) (ary []any)
func slicearray(old *any, nel int, lb int, hb int, width int) (ary []any)
func closure() // has args, but compiler fills in
func closure() // has args, but compiler fills in
// only used on 32-bit
func int64div(int64, int64) int64
......
This diff is collapsed.
This diff is collapsed.
......@@ -26,74 +26,74 @@
package main
import (
"bytes";
"flag";
"fmt";
"http";
"io";
"log";
"os";
"time";
"bytes"
"flag"
"fmt"
"http"
"io"
"log"
"os"
"time"
)
var (
// periodic sync
syncCmd = flag.String("sync", "", "sync command; disabled if empty");
syncMin = flag.Int("sync_minutes", 0, "sync interval in minutes; disabled if <= 0");
syncDelay delayTime; // actual sync delay in minutes; usually syncDelay == syncMin, but delay may back off exponentially
syncCmd = flag.String("sync", "", "sync command; disabled if empty")
syncMin = flag.Int("sync_minutes", 0, "sync interval in minutes; disabled if <= 0")
syncDelay delayTime // actual sync delay in minutes; usually syncDelay == syncMin, but delay may back off exponentially
// server control
httpaddr = flag.String("http", "", "HTTP service address (e.g., ':6060')");
httpaddr = flag.String("http", "", "HTTP service address (e.g., ':6060')")
// layout control
html = flag.Bool("html", false, "print HTML in command-line mode");
html = flag.Bool("html", false, "print HTML in command-line mode")
)
func exec(c *http.Conn, args []string) (status int) {
r, w, err := os.Pipe();
r, w, err := os.Pipe()
if err != nil {
log.Stderrf("os.Pipe(): %v\n", err);
return 2;
log.Stderrf("os.Pipe(): %v\n", err)
return 2
}
bin := args[0];
fds := []*os.File{nil, w, w};
bin := args[0]
fds := []*os.File{nil, w, w}
if *verbose {
log.Stderrf("executing %v", args)
}
pid, err := os.ForkExec(bin, args, os.Environ(), goroot, fds);
defer r.Close();
w.Close();
pid, err := os.ForkExec(bin, args, os.Environ(), goroot, fds)
defer r.Close()
w.Close()
if err != nil {
log.Stderrf("os.ForkExec(%q): %v\n", bin, err);
return 2;
log.Stderrf("os.ForkExec(%q): %v\n", bin, err)
return 2
}
var buf bytes.Buffer;
io.Copy(&buf, r);
wait, err := os.Wait(pid, 0);
var buf bytes.Buffer
io.Copy(&buf, r)
wait, err := os.Wait(pid, 0)
if err != nil {
os.Stderr.Write(buf.Bytes());
log.Stderrf("os.Wait(%d, 0): %v\n", pid, err);
return 2;
os.Stderr.Write(buf.Bytes())
log.Stderrf("os.Wait(%d, 0): %v\n", pid, err)
return 2
}
status = wait.ExitStatus();
status = wait.ExitStatus()
if !wait.Exited() || status > 1 {
os.Stderr.Write(buf.Bytes());
log.Stderrf("executing %v failed (exit status = %d)", args, status);
return;
os.Stderr.Write(buf.Bytes())
log.Stderrf("executing %v failed (exit status = %d)", args, status)
return
}
if *verbose {
os.Stderr.Write(buf.Bytes())
}
if c != nil {
c.SetHeader("content-type", "text/plain; charset=utf-8");
c.Write(buf.Bytes());
c.SetHeader("content-type", "text/plain; charset=utf-8")
c.Write(buf.Bytes())
}
return;
return
}
......@@ -101,7 +101,7 @@ func exec(c *http.Conn, args []string) (status int) {
const maxDirDepth = 24
func dosync(c *http.Conn, r *http.Request) {
args := []string{"/bin/sh", "-c", *syncCmd};
args := []string{"/bin/sh", "-c", *syncCmd}
switch exec(c, args) {
case 0:
// sync succeeded and some files have changed;
......@@ -109,12 +109,12 @@ func dosync(c *http.Conn, r *http.Request) {
// TODO(gri): The directory tree may be temporarily out-of-sync.
// Consider keeping separate time stamps so the web-
// page can indicate this discrepancy.
fsTree.set(newDirectory(".", maxDirDepth));
fallthrough;
fsTree.set(newDirectory(".", maxDirDepth))
fallthrough
case 1:
// sync failed because no files changed;
// don't change the package tree
syncDelay.set(*syncMin) // revert to regular sync schedule
syncDelay.set(*syncMin) // revert to regular sync schedule
default:
// sync failed because of an error - back off exponentially, but try at least once a day
syncDelay.backoff(24 * 60)
......@@ -125,23 +125,23 @@ func dosync(c *http.Conn, r *http.Request) {
func usage() {
fmt.Fprintf(os.Stderr,
"usage: godoc package [name ...]\n"+
" godoc -http=:6060\n");
flag.PrintDefaults();
os.Exit(2);
" godoc -http=:6060\n")
flag.PrintDefaults()
os.Exit(2)
}
func loggingHandler(h http.Handler) http.Handler {
return http.HandlerFunc(func(c *http.Conn, req *http.Request) {
log.Stderrf("%s\t%s", c.RemoteAddr, req.URL);
h.ServeHTTP(c, req);
log.Stderrf("%s\t%s", c.RemoteAddr, req.URL)
h.ServeHTTP(c, req)
})
}
func main() {
flag.Usage = usage;
flag.Parse();
flag.Usage = usage
flag.Parse()
// Check usage: either server and no args, or command line and args
if (*httpaddr != "") != (flag.NArg() == 0) {
......@@ -156,23 +156,23 @@ func main() {
log.Exitf("chdir %s: %v", goroot, err)
}
readTemplates();
readTemplates()
if *httpaddr != "" {
// HTTP server mode.
var handler http.Handler = http.DefaultServeMux;
var handler http.Handler = http.DefaultServeMux
if *verbose {
log.Stderrf("Go Documentation Server\n");
log.Stderrf("address = %s\n", *httpaddr);
log.Stderrf("goroot = %s\n", goroot);
log.Stderrf("cmdroot = %s\n", *cmdroot);
log.Stderrf("pkgroot = %s\n", *pkgroot);
log.Stderrf("tmplroot = %s\n", *tmplroot);
log.Stderrf("tabwidth = %d\n", *tabwidth);
handler = loggingHandler(handler);
log.Stderrf("Go Documentation Server\n")
log.Stderrf("address = %s\n", *httpaddr)
log.Stderrf("goroot = %s\n", goroot)
log.Stderrf("cmdroot = %s\n", *cmdroot)
log.Stderrf("pkgroot = %s\n", *pkgroot)
log.Stderrf("tmplroot = %s\n", *tmplroot)
log.Stderrf("tabwidth = %d\n", *tabwidth)
handler = loggingHandler(handler)
}
registerPublicHandlers(http.DefaultServeMux);
registerPublicHandlers(http.DefaultServeMux)
if *syncCmd != "" {
http.Handle("/debug/sync", http.HandlerFunc(dosync))
}
......@@ -180,39 +180,39 @@ func main() {
// Initialize directory tree with corresponding timestamp.
// Do it in two steps:
// 1) set timestamp right away so that the indexer is kicked on
fsTree.set(nil);
fsTree.set(nil)
// 2) compute initial directory tree in a goroutine so that launch is quick
go func() { fsTree.set(newDirectory(".", maxDirDepth)) }();
go func() { fsTree.set(newDirectory(".", maxDirDepth)) }()
// Start sync goroutine, if enabled.
if *syncCmd != "" && *syncMin > 0 {
syncDelay.set(*syncMin); // initial sync delay
syncDelay.set(*syncMin) // initial sync delay
go func() {
for {
dosync(nil, nil);
delay, _ := syncDelay.get();
dosync(nil, nil)
delay, _ := syncDelay.get()
if *verbose {
log.Stderrf("next sync in %dmin", delay.(int))
}
time.Sleep(int64(delay.(int)) * 60e9);
time.Sleep(int64(delay.(int)) * 60e9)
}
}();
}()
}
// Start indexing goroutine.
go indexer();
go indexer()
// The server may have been restarted; always wait 1sec to
// give the forking server a chance to shut down and release
// the http port.
// TODO(gri): Do we still need this?
time.Sleep(1e9);
time.Sleep(1e9)
// Start http server.
if err := http.ListenAndServe(*httpaddr, handler); err != nil {
log.Exitf("ListenAndServe %s: %v", *httpaddr, err)
}
return;
return
}
// Command line mode.
......@@ -220,7 +220,7 @@ func main() {
packageText = packageHTML
}
info := pkgHandler.getPageInfo(flag.Arg(0));
info := pkgHandler.getPageInfo(flag.Arg(0))
if info.PDoc == nil && info.Dirs == nil {
// try again, this time assume it's a command
......@@ -228,8 +228,8 @@ func main() {
}
if info.PDoc != nil && flag.NArg() > 1 {
args := flag.Args();
info.PDoc.Filter(args[1:]);
args := flag.Args()
info.PDoc.Filter(args[1:])
}
if err := packageText.Execute(info, os.Stdout); err != nil {
......
......@@ -10,44 +10,44 @@
package main
import (
"bytes";
"go/ast";
"go/printer";
"fmt";
"strings";
"bytes"
"go/ast"
"go/printer"
"fmt"
"strings"
)
type Snippet struct {
Line int;
Text string;
Line int
Text string
}
type snippetStyler struct {
Styler; // defined in godoc.go
highlight *ast.Ident; // identifier to highlight
Styler // defined in godoc.go
highlight *ast.Ident // identifier to highlight
}
func (s *snippetStyler) LineTag(line int) (text []uint8, tag printer.HTMLTag) {
return // no LineTag for snippets
return // no LineTag for snippets
}
func (s *snippetStyler) Ident(id *ast.Ident) (text []byte, tag printer.HTMLTag) {
text = strings.Bytes(id.Value);
text = strings.Bytes(id.Value)
if s.highlight == id {
tag = printer.HTMLTag{"<span class=highlight>", "</span>"}
}
return;
return
}
func newSnippet(decl ast.Decl, id *ast.Ident) *Snippet {
var buf bytes.Buffer;
writeNode(&buf, decl, true, &snippetStyler{highlight: id});
return &Snippet{id.Pos().Line, buf.String()};
var buf bytes.Buffer
writeNode(&buf, decl, true, &snippetStyler{highlight: id})
return &Snippet{id.Pos().Line, buf.String()}
}
......@@ -70,32 +70,32 @@ func findSpec(list []ast.Spec, id *ast.Ident) ast.Spec {
}
}
}
return nil;
return nil
}
func genSnippet(d *ast.GenDecl, id *ast.Ident) *Snippet {
s := findSpec(d.Specs, id);
s := findSpec(d.Specs, id)
if s == nil {
return nil // declaration doesn't contain id - exit gracefully
return nil // declaration doesn't contain id - exit gracefully
}
// only use the spec containing the id for the snippet
dd := &ast.GenDecl{d.Doc, d.Position, d.Tok, d.Lparen, []ast.Spec{s}, d.Rparen};
dd := &ast.GenDecl{d.Doc, d.Position, d.Tok, d.Lparen, []ast.Spec{s}, d.Rparen}
return newSnippet(dd, id);
return newSnippet(dd, id)
}
func funcSnippet(d *ast.FuncDecl, id *ast.Ident) *Snippet {
if d.Name != id {
return nil // declaration doesn't contain id - exit gracefully
return nil // declaration doesn't contain id - exit gracefully
}
// only use the function signature for the snippet
dd := &ast.FuncDecl{d.Doc, d.Recv, d.Name, d.Type, nil};
dd := &ast.FuncDecl{d.Doc, d.Recv, d.Name, d.Type, nil}
return newSnippet(dd, id);
return newSnippet(dd, id)
}
......@@ -118,5 +118,5 @@ func NewSnippet(decl ast.Decl, id *ast.Ident) (s *Snippet) {
fmt.Sprintf(`could not generate a snippet for <span class="highlight">%s</span>`, id.Value),
}
}
return;
return
}
......@@ -11,35 +11,35 @@
package main
import (
"bytes";
"fmt";
"go/scanner";
"go/token";
"io";
"strings";
"bytes"
"fmt"
"go/scanner"
"go/token"
"io"
"strings"
)
type ebnfParser struct {
out io.Writer; // parser output
src []byte; // parser source
scanner scanner.Scanner;
prev int; // offset of previous token
pos token.Position; // token position
tok token.Token; // one token look-ahead
lit []byte; // token literal
out io.Writer // parser output
src []byte // parser source
scanner scanner.Scanner
prev int // offset of previous token
pos token.Position // token position
tok token.Token // one token look-ahead
lit []byte // token literal
}
func (p *ebnfParser) flush() {
p.out.Write(p.src[p.prev:p.pos.Offset]);
p.prev = p.pos.Offset;
p.out.Write(p.src[p.prev:p.pos.Offset])
p.prev = p.pos.Offset
}
func (p *ebnfParser) next() {
p.flush();
p.pos, p.tok, p.lit = p.scanner.Scan();
p.flush()
p.pos, p.tok, p.lit = p.scanner.Scan()
if p.tok.IsKeyword() {
// TODO Should keyword mapping always happen outside scanner?
// Or should there be a flag to scanner to enable keyword mapping?
......@@ -54,38 +54,38 @@ func (p *ebnfParser) Error(pos token.Position, msg string) {
func (p *ebnfParser) 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 *ebnfParser) 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 *ebnfParser) parseIdentifier(def bool) {
name := string(p.lit);
p.expect(token.IDENT);
name := string(p.lit)
p.expect(token.IDENT)
if def {
fmt.Fprintf(p.out, `<a id="%s">%s</a>`, name, name)
} else {
fmt.Fprintf(p.out, `<a href="#%s" class="noline">%s</a>`, name, name)
}
p.prev += len(name); // skip identifier when calling flush
p.prev += len(name) // skip identifier when calling flush
}
......@@ -95,32 +95,32 @@ func (p *ebnfParser) parseTerm() bool {
p.parseIdentifier(false)
case token.STRING:
p.next();
p.next()
if p.tok == token.ELLIPSIS {
p.next();
p.expect(token.STRING);
p.next()
p.expect(token.STRING)
}
case token.LPAREN:
p.next();
p.parseExpression();
p.expect(token.RPAREN);
p.next()
p.parseExpression()
p.expect(token.RPAREN)
case token.LBRACK:
p.next();
p.parseExpression();
p.expect(token.RBRACK);
p.next()
p.parseExpression()
p.expect(token.RBRACK)
case token.LBRACE:
p.next();
p.parseExpression();
p.expect(token.RBRACE);
p.next()
p.parseExpression()
p.expect(token.RBRACE)
default:
return false
}
return true;
return true
}
......@@ -132,70 +132,70 @@ func (p *ebnfParser) parseSequence() {
func (p *ebnfParser) parseExpression() {
for {
p.parseSequence();
p.parseSequence()
if p.tok != token.OR {
break
}
p.next();
p.next()
}
}
func (p *ebnfParser) parseProduction() {
p.parseIdentifier(true);
p.expect(token.ASSIGN);
p.parseExpression();
p.expect(token.PERIOD);
p.parseIdentifier(true)
p.expect(token.ASSIGN)
p.parseExpression()
p.expect(token.PERIOD)
}
func (p *ebnfParser) parse(out io.Writer, src []byte) {
// initialize ebnfParser
p.out = out;
p.src = src;
p.scanner.Init("", src, p, 0);
p.next(); // initializes pos, tok, lit
p.out = out
p.src = src
p.scanner.Init("", src, p, 0)
p.next() // initializes pos, tok, lit
// process source
for p.tok != token.EOF {
p.parseProduction()
}
p.flush();
p.flush()
}
// Markers around EBNF sections
var (
openTag = strings.Bytes(`<pre class="ebnf">`);
closeTag = strings.Bytes(`</pre>`);
openTag = strings.Bytes(`<pre class="ebnf">`)
closeTag = strings.Bytes(`</pre>`)
)
func linkify(out io.Writer, src []byte) {
for len(src) > 0 {
n := len(src);
n := len(src)
// i: beginning of EBNF text (or end of source)
i := bytes.Index(src, openTag);
i := bytes.Index(src, openTag)
if i < 0 {
i = n - len(openTag)
}
i += len(openTag);
i += len(openTag)
// j: end of EBNF text (or end of source)
j := bytes.Index(src[i:n], closeTag); // close marker
j := bytes.Index(src[i:n], closeTag) // close marker
if j < 0 {
j = n - i
}
j += i;
j += i
// write text before EBNF
out.Write(src[0:i]);
out.Write(src[0:i])
// parse and write EBNF
var p ebnfParser;
p.parse(out, src[i:j]);
var p ebnfParser
p.parse(out, src[i:j])
// advance
src = src[j:n];
src = src[j:n]
}
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -9,9 +9,9 @@
package flate
import (
"bytes";
"reflect";
"testing";
"bytes"
"reflect"
"testing"
)
// The Huffman code lengths used by the fixed-format Huffman blocks.
......@@ -45,9 +45,9 @@ var fixedHuffmanBits = [...]int{
}
type InitDecoderTest struct {
in []int;
out huffmanDecoder;
ok bool;
in []int
out huffmanDecoder
ok bool
}
var initDecoderTests = []*InitDecoderTest{
......@@ -115,10 +115,10 @@ var initDecoderTests = []*InitDecoderTest{
func TestInitDecoder(t *testing.T) {
for i, tt := range initDecoderTests {
var h huffmanDecoder;
var h huffmanDecoder
if h.init(tt.in) != tt.ok {
t.Errorf("test %d: init = %v", i, !tt.ok);
continue;
t.Errorf("test %d: init = %v", i, !tt.ok)
continue
}
if !reflect.DeepEqual(&h, &tt.out) {
t.Errorf("test %d:\nhave %v\nwant %v", i, h, tt.out)
......@@ -127,9 +127,9 @@ func TestInitDecoder(t *testing.T) {
}
func TestUncompressedSource(t *testing.T) {
decoder := NewInflater(bytes.NewBuffer([]byte{0x01, 0x01, 0x00, 0xfe, 0xff, 0x11}));
output := make([]byte, 1);
n, error := decoder.Read(output);
decoder := NewInflater(bytes.NewBuffer([]byte{0x01, 0x01, 0x00, 0xfe, 0xff, 0x11}))
output := make([]byte, 1)
n, error := decoder.Read(output)
if n != 1 || error != nil {
t.Fatalf("decoder.Read() = %d, %v, want 1, nil", n, error)
}
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment