diff options
Diffstat (limited to 'src/cmd')
| -rw-r--r-- | src/cmd/5c/reg.c | 1 | ||||
| -rw-r--r-- | src/cmd/5l/l.h | 1 | ||||
| -rw-r--r-- | src/cmd/6c/cgen.c | 8 | ||||
| -rw-r--r-- | src/cmd/6l/asm.c | 5 | ||||
| -rw-r--r-- | src/cmd/6l/l.h | 1 | ||||
| -rw-r--r-- | src/cmd/8l/l.h | 5 | ||||
| -rw-r--r-- | src/cmd/cgo/out.go | 14 | ||||
| -rw-r--r-- | src/cmd/gc/Makefile | 4 | ||||
| -rw-r--r-- | src/cmd/gc/builtin.c.boot | 27 | ||||
| -rwxr-xr-x | src/cmd/gc/mkbuiltin | 2 | ||||
| -rw-r--r-- | src/cmd/gc/mkbuiltin1.c | 6 | ||||
| -rw-r--r-- | src/cmd/gc/range.c | 2 | ||||
| -rw-r--r-- | src/cmd/gc/runtime.go | 27 | ||||
| -rw-r--r-- | src/cmd/gc/select.c | 15 | ||||
| -rw-r--r-- | src/cmd/gc/walk.c | 18 | ||||
| -rw-r--r-- | src/cmd/godoc/godoc.go | 316 | ||||
| -rw-r--r-- | src/cmd/godoc/main.go | 9 | ||||
| -rwxr-xr-x | src/cmd/godoc/snippet.go | 9 | ||||
| -rw-r--r-- | src/cmd/gofix/Makefile | 1 | ||||
| -rw-r--r-- | src/cmd/gofix/fix.go | 15 | ||||
| -rw-r--r-- | src/cmd/gofix/url.go | 106 | ||||
| -rw-r--r-- | src/cmd/gofix/url_test.go | 147 | ||||
| -rwxr-xr-x | src/cmd/gofmt/test.sh | 2 | ||||
| -rw-r--r-- | src/cmd/goinstall/main.go | 14 | ||||
| -rw-r--r-- | src/cmd/goinstall/make.go | 2 | ||||
| -rw-r--r-- | src/cmd/ld/data.c | 2 | 
26 files changed, 471 insertions, 288 deletions
| diff --git a/src/cmd/5c/reg.c b/src/cmd/5c/reg.c index 50b814598..1ccf74a35 100644 --- a/src/cmd/5c/reg.c +++ b/src/cmd/5c/reg.c @@ -66,6 +66,7 @@ rcmp(const void *a1, const void *a2)  void  regopt(Prog *p)  { +	USED(p);  	// TODO(kaib): optimizer disabled because it smashes R8 when running out of registers  	// the disable is unconventionally here because the call is in common code shared by 5c/6c/8c  	return; diff --git a/src/cmd/5l/l.h b/src/cmd/5l/l.h index e00f536a7..dabe93d37 100644 --- a/src/cmd/5l/l.h +++ b/src/cmd/5l/l.h @@ -324,6 +324,7 @@ EXTERN	Prog*	prog_modu;  #pragma	varargck	type	"N"	Adr*  #pragma	varargck	type	"P"	Prog*  #pragma	varargck	type	"S"	char* +#pragma	varargck	type	"Z"	char*  #pragma	varargck	type	"i"	char*  int	Aconv(Fmt*); diff --git a/src/cmd/6c/cgen.c b/src/cmd/6c/cgen.c index 7aa4aa976..7f717dcbb 100644 --- a/src/cmd/6c/cgen.c +++ b/src/cmd/6c/cgen.c @@ -930,9 +930,6 @@ cgen(Node *n, Node *nn)  			return;  		} -		o = 0; -		if(REGARG >= 0) -			o = reg[REGARG];  		gargs(r, &nod, &nod1);  		if(l->addable < INDEXED) {  			reglcgen(&nod, l, nn); @@ -941,9 +938,8 @@ cgen(Node *n, Node *nn)  			regfree(&nod);  		} else  			gopcode(OFUNC, n->type, Z, l); -		if(REGARG >= 0) -			if(o != reg[REGARG]) -				reg[REGARG]--; +		if(REGARG >= 0 && reg[REGARG]) +			reg[REGARG]--;  		if(nn != Z) {  			regret(&nod, n);  			gmove(&nod, nn); diff --git a/src/cmd/6l/asm.c b/src/cmd/6l/asm.c index f59a59efb..3a8223e65 100644 --- a/src/cmd/6l/asm.c +++ b/src/cmd/6l/asm.c @@ -298,6 +298,9 @@ adddynrel(Sym *s, Reloc *r)  int  archreloc(Reloc *r, Sym *s, vlong *val)  { +	USED(r); +	USED(s); +	USED(val);  	return -1;  } @@ -859,7 +862,7 @@ asmb(void)  		startva = INITTEXT - HEADR;  		/* This null SHdr must appear before all others */ -		sh = newElfShdr(elfstr[ElfStrEmpty]); +		newElfShdr(elfstr[ElfStrEmpty]);  		/* program header info */  		pph = newElfPhdr(); diff --git a/src/cmd/6l/l.h b/src/cmd/6l/l.h index 043568585..b291d5f3d 100644 --- a/src/cmd/6l/l.h +++ b/src/cmd/6l/l.h @@ -410,6 +410,7 @@ uint32	machheadr(void);  #pragma	varargck	type	"D"	Adr*  #pragma	varargck	type	"P"	Prog*  #pragma	varargck	type	"R"	int +#pragma	varargck	type	"Z"	char*  #pragma	varargck	type	"A"	int  #pragma	varargck	argpos	diag 1 diff --git a/src/cmd/8l/l.h b/src/cmd/8l/l.h index 94cbfc26a..4ee0db967 100644 --- a/src/cmd/8l/l.h +++ b/src/cmd/8l/l.h @@ -46,10 +46,6 @@ enum  #define	P		((Prog*)0)  #define	S		((Sym*)0)  #define	TNAME		(cursym?cursym->name:noname) -#define	cput(c)\ -	{ *cbp++ = c;\ -	if(--cbc <= 0)\ -		cflush(); }  typedef	struct	Adr	Adr;  typedef	struct	Prog	Prog; @@ -254,6 +250,7 @@ enum  #pragma	varargck	type	"R"	int  #pragma	varargck	type	"S"	char*  #pragma	varargck	type	"Y"	Sym* +#pragma	varargck	type	"Z"	char*  #pragma	varargck	type	"i"	char*  EXTERN	int32	HEADR; diff --git a/src/cmd/cgo/out.go b/src/cmd/cgo/out.go index 9c962b8ff..498ab1566 100644 --- a/src/cmd/cgo/out.go +++ b/src/cmd/cgo/out.go @@ -59,17 +59,21 @@ func (p *Package) writeDefs() {  	fmt.Fprintf(fc, cProlog) -	var cVars []string +	cVars := make(map[string]bool)  	for _, n := range p.Name {  		if n.Kind != "var" {  			continue  		} -		cVars = append(cVars, n.C) -		fmt.Fprintf(fm, "extern char %s[];\n", n.C) -		fmt.Fprintf(fm, "void *_cgohack_%s = %s;\n\n", n.C, n.C) +		if !cVars[n.C] { +			fmt.Fprintf(fm, "extern char %s[];\n", n.C) +			fmt.Fprintf(fm, "void *_cgohack_%s = %s;\n\n", n.C, n.C) + +			fmt.Fprintf(fc, "extern byte *%s;\n", n.C) + +			cVars[n.C] = true +		} -		fmt.Fprintf(fc, "extern byte *%s;\n", n.C)  		fmt.Fprintf(fc, "void *ยท%s = &%s;\n", n.Mangle, n.C)  		fmt.Fprintf(fc, "\n") diff --git a/src/cmd/gc/Makefile b/src/cmd/gc/Makefile index 286618ec1..0af7659e4 100644 --- a/src/cmd/gc/Makefile +++ b/src/cmd/gc/Makefile @@ -65,3 +65,7 @@ opnames.h:	mkopnames go.h  	./mkopnames go.h >opnames.h  CLEANFILES+=*.[568] [568].out y1.tab.c yerr.h mkbuiltin1 builtin.c _builtin.c opnames.h + +mkbuiltin1: mkbuiltin1.$O +	$(HOST_LD) -o $@ mkbuiltin1.$O -L"$(GOROOT)"/lib -lbio -l9 -lm $(HOST_LDFLAGS) + diff --git a/src/cmd/gc/builtin.c.boot b/src/cmd/gc/builtin.c.boot index 6419873a2..190c56008 100644 --- a/src/cmd/gc/builtin.c.boot +++ b/src/cmd/gc/builtin.c.boot @@ -57,24 +57,23 @@ char *runtimeimport =  	"func \"\".efaceeq (i1 any, i2 any) bool\n"  	"func \"\".ifacethash (i1 any) uint32\n"  	"func \"\".efacethash (i1 any) uint32\n" -	"func \"\".makemap (key *uint8, val *uint8, hint int64) map[any] any\n" -	"func \"\".mapaccess1 (hmap map[any] any, key any) any\n" -	"func \"\".mapaccess2 (hmap map[any] any, key any) (val any, pres bool)\n" -	"func \"\".mapassign1 (hmap map[any] any, key any, val any)\n" -	"func \"\".mapassign2 (hmap map[any] any, key any, val any, pres bool)\n" -	"func \"\".mapiterinit (hmap map[any] any, hiter *any)\n" +	"func \"\".makemap (mapType *uint8, hint int64) map[any] any\n" +	"func \"\".mapaccess1 (mapType *uint8, hmap map[any] any, key any) any\n" +	"func \"\".mapaccess2 (mapType *uint8, hmap map[any] any, key any) (val any, pres bool)\n" +	"func \"\".mapassign1 (mapType *uint8, hmap map[any] any, key any, val any)\n" +	"func \"\".mapassign2 (mapType *uint8, hmap map[any] any, key any, val any, pres bool)\n" +	"func \"\".mapiterinit (mapType *uint8, hmap map[any] any, hiter *any)\n"  	"func \"\".mapiternext (hiter *any)\n"  	"func \"\".mapiter1 (hiter *any) any\n"  	"func \"\".mapiter2 (hiter *any) (key any, val any)\n" -	"func \"\".makechan (elem *uint8, hint int64) chan any\n" -	"func \"\".chanrecv1 (hchan <-chan any) any\n" -	"func \"\".chanrecv2 (hchan <-chan any) (elem any, received bool)\n" -	"func \"\".chansend1 (hchan chan<- any, elem any)\n" +	"func \"\".makechan (chanType *uint8, hint int64) chan any\n" +	"func \"\".chanrecv1 (chanType *uint8, hchan <-chan any) any\n" +	"func \"\".chanrecv2 (chanType *uint8, hchan <-chan any) (elem any, received bool)\n" +	"func \"\".chansend1 (chanType *uint8, hchan chan<- any, elem any)\n"  	"func \"\".closechan (hchan any)\n" -	"func \"\".closedchan (hchan any) bool\n" -	"func \"\".selectnbsend (hchan chan<- any, elem any) bool\n" -	"func \"\".selectnbrecv (elem *any, hchan <-chan any) bool\n" -	"func \"\".selectnbrecv2 (elem *any, received *bool, hchan <-chan any) bool\n" +	"func \"\".selectnbsend (chanType *uint8, hchan chan<- any, elem any) bool\n" +	"func \"\".selectnbrecv (chanType *uint8, elem *any, hchan <-chan any) bool\n" +	"func \"\".selectnbrecv2 (chanType *uint8, elem *any, received *bool, hchan <-chan any) bool\n"  	"func \"\".newselect (size int) *uint8\n"  	"func \"\".selectsend (sel *uint8, hchan chan<- any, elem *any) bool\n"  	"func \"\".selectrecv (sel *uint8, hchan <-chan any, elem *any) bool\n" diff --git a/src/cmd/gc/mkbuiltin b/src/cmd/gc/mkbuiltin index 4dfff1caa..cfd6e59c1 100755 --- a/src/cmd/gc/mkbuiltin +++ b/src/cmd/gc/mkbuiltin @@ -16,7 +16,7 @@ if [ -z "$GC" ]; then  	exit 1  fi -gcc -o mkbuiltin1 mkbuiltin1.c +gomake mkbuiltin1  rm -f _builtin.c  for i in runtime unsafe  do diff --git a/src/cmd/gc/mkbuiltin1.c b/src/cmd/gc/mkbuiltin1.c index baa87fec9..ad83c0346 100644 --- a/src/cmd/gc/mkbuiltin1.c +++ b/src/cmd/gc/mkbuiltin1.c @@ -10,7 +10,7 @@  void esc(char*); -int +void  main(int argc, char **argv)  {  	char *name; @@ -64,13 +64,13 @@ begin:  		}  		esc(p); -		printf("\\n\"\n", p); +		printf("\\n\"\n");  	}  	sysfatal("did not find end of imports\n");  end:  	printf("\t\"$$\\n\";\n"); -	return 0; +	exits(0);  }  void diff --git a/src/cmd/gc/range.c b/src/cmd/gc/range.c index fb33e4e48..5ce693ae3 100644 --- a/src/cmd/gc/range.c +++ b/src/cmd/gc/range.c @@ -175,7 +175,7 @@ walkrange(Node *n)  		argtype(fn, t->down);  		argtype(fn, t->type);  		argtype(fn, th); -		init = list(init, mkcall1(fn, T, nil, ha, nod(OADDR, hit, N))); +		init = list(init, mkcall1(fn, T, nil, typename(t), ha, nod(OADDR, hit, N)));  		n->ntest = nod(ONE, nod(OINDEX, hit, nodintconst(0)), nodnil());  		fn = syslook("mapiternext", 1); diff --git a/src/cmd/gc/runtime.go b/src/cmd/gc/runtime.go index 7254f874e..549f7abe3 100644 --- a/src/cmd/gc/runtime.go +++ b/src/cmd/gc/runtime.go @@ -80,27 +80,26 @@ func ifacethash(i1 any) (ret uint32)  func efacethash(i1 any) (ret uint32)  // *byte is really *runtime.Type -func makemap(key, val *byte, hint int64) (hmap map[any]any) -func mapaccess1(hmap map[any]any, key any) (val any) -func mapaccess2(hmap map[any]any, key any) (val any, pres bool) -func mapassign1(hmap map[any]any, key any, val any) -func mapassign2(hmap map[any]any, key any, val any, pres bool) -func mapiterinit(hmap map[any]any, hiter *any) +func makemap(mapType *byte, hint int64) (hmap map[any]any) +func mapaccess1(mapType *byte, hmap map[any]any, key any) (val any) +func mapaccess2(mapType *byte, hmap map[any]any, key any) (val any, pres bool) +func mapassign1(mapType *byte, hmap map[any]any, key any, val any) +func mapassign2(mapType *byte, hmap map[any]any, key any, val any, pres bool) +func mapiterinit(mapType *byte, hmap map[any]any, hiter *any)  func mapiternext(hiter *any)  func mapiter1(hiter *any) (key any)  func mapiter2(hiter *any) (key any, val any)  // *byte is really *runtime.Type -func makechan(elem *byte, hint int64) (hchan chan any) -func chanrecv1(hchan <-chan any) (elem any) -func chanrecv2(hchan <-chan any) (elem any, received bool) -func chansend1(hchan chan<- any, elem any) +func makechan(chanType *byte, hint int64) (hchan chan any) +func chanrecv1(chanType *byte, hchan <-chan any) (elem any) +func chanrecv2(chanType *byte, hchan <-chan any) (elem any, received bool) +func chansend1(chanType *byte, hchan chan<- any, elem any)  func closechan(hchan any) -func closedchan(hchan any) bool -func selectnbsend(hchan chan<- any, elem any) bool -func selectnbrecv(elem *any, hchan <-chan any) bool -func selectnbrecv2(elem *any, received *bool, hchan <-chan any) bool +func selectnbsend(chanType *byte, hchan chan<- any, elem any) bool +func selectnbrecv(chanType *byte, elem *any, hchan <-chan any) bool +func selectnbrecv2(chanType *byte, elem *any, received *bool, hchan <-chan any) bool  func newselect(size int) (sel *byte)  func selectsend(sel *byte, hchan chan<- any, elem *any) (selected bool) diff --git a/src/cmd/gc/select.c b/src/cmd/gc/select.c index 8395dda31..909ad3aa4 100644 --- a/src/cmd/gc/select.c +++ b/src/cmd/gc/select.c @@ -250,9 +250,8 @@ walkselect(Node *sel)  		case OSEND:  			// if c != nil && selectnbsend(c, v) { body } else { default body }  			ch = cheapexpr(n->left, &r->ninit); -			r->ntest = nod(OANDAND, nod(ONE, ch, nodnil()), -				mkcall1(chanfn("selectnbsend", 2, ch->type), -					types[TBOOL], &r->ninit, ch, n->right)); +			r->ntest = mkcall1(chanfn("selectnbsend", 2, ch->type), +					types[TBOOL], &r->ninit, typename(ch->type), ch, n->right);  			break;  		case OSELRECV: @@ -260,9 +259,8 @@ walkselect(Node *sel)  			r = nod(OIF, N, N);  			r->ninit = cas->ninit;  			ch = cheapexpr(n->right->left, &r->ninit); -			r->ntest = nod(OANDAND, nod(ONE, ch, nodnil()), -				mkcall1(chanfn("selectnbrecv", 2, ch->type), -					types[TBOOL], &r->ninit, n->left, ch)); +			r->ntest = mkcall1(chanfn("selectnbrecv", 2, ch->type), +					types[TBOOL], &r->ninit, typename(ch->type), n->left, ch);  			break;  		case OSELRECV2: @@ -270,9 +268,8 @@ walkselect(Node *sel)  			r = nod(OIF, N, N);  			r->ninit = cas->ninit;  			ch = cheapexpr(n->right->left, &r->ninit); -			r->ntest = nod(OANDAND, nod(ONE, ch, nodnil()), -				mkcall1(chanfn("selectnbrecv2", 2, ch->type), -					types[TBOOL], &r->ninit, n->left, n->ntest, ch)); +			r->ntest = mkcall1(chanfn("selectnbrecv2", 2, ch->type), +					types[TBOOL], &r->ninit, typename(ch->type), n->left, n->ntest, ch);  			break;  		}  		typecheck(&r->ntest, Erv); diff --git a/src/cmd/gc/walk.c b/src/cmd/gc/walk.c index 0383e5a6a..9cd4ee919 100644 --- a/src/cmd/gc/walk.c +++ b/src/cmd/gc/walk.c @@ -591,7 +591,7 @@ walkexpr(Node **np, NodeList **init)  		walkexprlistsafe(n->list, init);  		walkexpr(&r->left, init);  		fn = chanfn("chanrecv2", 2, r->left->type); -		r = mkcall1(fn, getoutargx(fn->type), init, r->left); +		r = mkcall1(fn, getoutargx(fn->type), init, typename(r->left->type), r->left);  		n->rlist->n = r;  		n->op = OAS2FUNC;  		goto as2func; @@ -604,7 +604,7 @@ walkexpr(Node **np, NodeList **init)  		walkexprlistsafe(n->list, init);  		walkexpr(&r->left, init);  		fn = mapfn("mapaccess2", r->left->type); -		r = mkcall1(fn, getoutargx(fn->type), init, r->left, r->right); +		r = mkcall1(fn, getoutargx(fn->type), init, typename(r->left->type), r->left, r->right);  		n->rlist = list1(r);  		n->op = OAS2FUNC;  		goto as2func; @@ -617,7 +617,7 @@ walkexpr(Node **np, NodeList **init)  		walkexprlistsafe(n->list, init);  		l = n->list->n;  		t = l->left->type; -		n = mkcall1(mapfn("mapassign2", t), T, init, l->left, l->right, n->rlist->n, n->rlist->next->n); +		n = mkcall1(mapfn("mapassign2", t), T, init, typename(t), l->left, l->right, n->rlist->n, n->rlist->next->n);  		goto ret;  	case OAS2DOTTYPE: @@ -852,13 +852,13 @@ walkexpr(Node **np, NodeList **init)  			goto ret;  		t = n->left->type; -		n = mkcall1(mapfn("mapaccess1", t), t->type, init, n->left, n->right); +		n = mkcall1(mapfn("mapaccess1", t), t->type, init, typename(t), n->left, n->right);  		goto ret;  	case ORECV:  		walkexpr(&n->left, init);  		walkexpr(&n->right, init); -		n = mkcall1(chanfn("chanrecv1", 2, n->left->type), n->type, init, n->left); +		n = mkcall1(chanfn("chanrecv1", 2, n->left->type), n->type, init, typename(n->left->type), n->left);  		goto ret;  	case OSLICE: @@ -1078,7 +1078,7 @@ walkexpr(Node **np, NodeList **init)  	case OMAKECHAN:  		n = mkcall1(chanfn("makechan", 1, n->type), n->type, init, -			typename(n->type->type), +			typename(n->type),  			conv(n->left, types[TINT64]));  		goto ret; @@ -1090,8 +1090,7 @@ walkexpr(Node **np, NodeList **init)  		argtype(fn, t->type);	// any-2  		n = mkcall1(fn, n->type, init, -			typename(t->down),	// key type -			typename(t->type),		// value type +			typename(n->type),  			conv(n->left, types[TINT64]));  		goto ret; @@ -1164,7 +1163,7 @@ walkexpr(Node **np, NodeList **init)  		goto ret;  	case OSEND: -		n = mkcall1(chanfn("chansend1", 2, n->left->type), T, init, n->left, n->right); +		n = mkcall1(chanfn("chansend1", 2, n->left->type), T, init, typename(n->left->type), n->left, n->right);  		goto ret;  	case OCLOSURE: @@ -1697,6 +1696,7 @@ convas(Node *n, NodeList **init)  	if(n->left->op == OINDEXMAP) {  		n = mkcall1(mapfn("mapassign1", n->left->left->type), T, init, +			typename(n->left->left->type),  			n->left->left, n->left->right, n->right);  		goto out;  	} diff --git a/src/cmd/godoc/godoc.go b/src/cmd/godoc/godoc.go index 03ac1b98b..b8a839404 100644 --- a/src/cmd/godoc/godoc.go +++ b/src/cmd/godoc/godoc.go @@ -371,143 +371,24 @@ func writeNode(w io.Writer, fset *token.FileSet, x interface{}) {  	(&printer.Config{mode, *tabwidth}).Fprint(&tconv{output: w}, fset, x)  } -// Write anything to w. -func writeAny(w io.Writer, fset *token.FileSet, x interface{}) { -	switch v := x.(type) { -	case []byte: -		w.Write(v) -	case string: -		w.Write([]byte(v)) -	case ast.Decl, ast.Expr, ast.Stmt, *ast.File: -		writeNode(w, fset, x) -	default: -		fmt.Fprint(w, x) -	} -} - -// Write anything html-escaped to w. -func writeAnyHTML(w io.Writer, fset *token.FileSet, x interface{}) { -	switch v := x.(type) { -	case []byte: -		template.HTMLEscape(w, v) -	case string: -		template.HTMLEscape(w, []byte(v)) -	case ast.Decl, ast.Expr, ast.Stmt, *ast.File: -		var buf bytes.Buffer -		writeNode(&buf, fset, x) -		FormatText(w, buf.Bytes(), -1, true, "", nil) -	default: -		var buf bytes.Buffer -		fmt.Fprint(&buf, x) -		template.HTMLEscape(w, buf.Bytes()) -	} +func filenameFunc(path string) string { +	_, localname := filepath.Split(path) +	return localname  } -func fileset(x []interface{}) *token.FileSet { -	if len(x) > 1 { -		if fset, ok := x[1].(*token.FileSet); ok { -			return fset -		} +func fileInfoNameFunc(fi FileInfo) string { +	name := fi.Name() +	if fi.IsDirectory() { +		name += "/"  	} -	return nil -} - -// Template formatter for "html-esc" format. -func htmlEscFmt(w io.Writer, format string, x ...interface{}) { -	writeAnyHTML(w, fileset(x), x[0]) -} - -// Template formatter for "html-comment" format. -func htmlCommentFmt(w io.Writer, format string, x ...interface{}) { -	var buf bytes.Buffer -	writeAny(&buf, fileset(x), x[0]) -	// TODO(gri) Provide list of words (e.g. function parameters) -	//           to be emphasized by ToHTML. -	doc.ToHTML(w, buf.Bytes(), nil) // does html-escaping -} - -// Template formatter for "" (default) format. -func textFmt(w io.Writer, format string, x ...interface{}) { -	writeAny(w, fileset(x), x[0]) +	return name  } -// Template formatter for "urlquery-esc" format. -func urlQueryEscFmt(w io.Writer, format string, x ...interface{}) { -	var buf bytes.Buffer -	writeAny(&buf, fileset(x), x[0]) -	template.HTMLEscape(w, []byte(http.URLEscape(string(buf.Bytes())))) -} - -// Template formatter for the various "url-xxx" formats excluding url-esc. -func urlFmt(w io.Writer, format string, x ...interface{}) { -	var path string -	var line int -	var low, high int // selection - -	// determine path and position info, if any -	type positioner interface { -		Pos() token.Pos -		End() token.Pos -	} -	switch t := x[0].(type) { -	case string: -		path = t -	case positioner: -		fset := fileset(x) -		if p := t.Pos(); p.IsValid() { -			pos := fset.Position(p) -			path = pos.Filename -			line = pos.Line -			low = pos.Offset -		} -		if p := t.End(); p.IsValid() { -			high = fset.Position(p).Offset -		} -	default: -		// we should never reach here, but be resilient -		// and assume the position is invalid (empty path, -		// and line 0) -		log.Printf("INTERNAL ERROR: urlFmt(%s) without a string or positioner", format) -	} - -	// map path -	relpath := relativeURL(path) - -	// convert to relative URLs so that they can also -	// be used as relative file names in .txt templates -	switch format { -	default: -		// we should never reach here, but be resilient -		// and assume the url-pkg format instead -		log.Printf("INTERNAL ERROR: urlFmt(%s)", format) -		fallthrough -	case "url-pkg": -		// because of the irregular mapping under goroot -		// we need to correct certain relative paths -		if strings.HasPrefix(relpath, "src/pkg/") { -			relpath = relpath[len("src/pkg/"):] -		} -		template.HTMLEscape(w, []byte(pkgHandler.pattern[1:]+relpath)) // remove trailing '/' for relative URL -	case "url-src": -		template.HTMLEscape(w, []byte(relpath)) -	case "url-pos": -		template.HTMLEscape(w, []byte(relpath)) -		// selection ranges are of form "s=low:high" -		if low < high { -			fmt.Fprintf(w, "?s=%d:%d", low, high) -			// if we have a selection, position the page -			// such that the selection is a bit below the top -			line -= 10 -			if line < 1 { -				line = 1 -			} -		} -		// line id's in html-printed source are of the -		// form "L%d" where %d stands for the line number -		if line > 0 { -			fmt.Fprintf(w, "#L%d", line) -		} +func fileInfoTimeFunc(fi FileInfo) string { +	if t := fi.Mtime_ns(); t != 0 { +		return time.SecondsToLocalTime(t / 1e9).String()  	} +	return "" // don't return epoch if time is obviously not set  }  // The strings in infoKinds must be properly html-escaped. @@ -522,14 +403,11 @@ var infoKinds = [nKinds]string{  	Use:           "use",  } -// Template formatter for "infoKind" format. -func infoKindFmt(w io.Writer, format string, x ...interface{}) { -	fmt.Fprintf(w, infoKinds[x[0].(SpotKind)]) // infoKind entries are html-escaped +func infoKind_htmlFunc(kind SpotKind) string { +	return infoKinds[kind] // infoKind entries are html-escaped  } -// Template formatter for "infoLine" format. -func infoLineFmt(w io.Writer, format string, x ...interface{}) { -	info := x[0].(SpotInfo) +func infoLineFunc(info SpotInfo) int {  	line := info.Lori()  	if info.IsIndex() {  		index, _ := searchIndex.get() @@ -543,80 +421,113 @@ func infoLineFmt(w io.Writer, format string, x ...interface{}) {  			line = 0  		}  	} -	fmt.Fprintf(w, "%d", line) +	return line  } -// Template formatter for "infoSnippet" format. -func infoSnippetFmt(w io.Writer, format string, x ...interface{}) { -	info := x[0].(SpotInfo) -	text := []byte(`<span class="alert">no snippet text available</span>`) +func infoSnippet_htmlFunc(info SpotInfo) string {  	if info.IsIndex() {  		index, _ := searchIndex.get() -		// no escaping of snippet text needed; -		// snippet text is escaped when generated -		text = index.(*Index).Snippet(info.Lori()).Text +		// Snippet.Text was HTML-escaped when it was generated +		return index.(*Index).Snippet(info.Lori()).Text  	} -	w.Write(text) +	return `<span class="alert">no snippet text available</span>`  } -// Template formatter for "padding" format. -func paddingFmt(w io.Writer, format string, x ...interface{}) { -	for i := x[0].(int); i > 0; i-- { -		fmt.Fprint(w, `<td width="25"></td>`) -	} +func nodeFunc(node interface{}, fset *token.FileSet) string { +	var buf bytes.Buffer +	writeNode(&buf, fset, node) +	return buf.String()  } -// Template formatter for "localname" format. -func localnameFmt(w io.Writer, format string, x ...interface{}) { -	_, localname := filepath.Split(x[0].(string)) -	template.HTMLEscape(w, []byte(localname)) +func node_htmlFunc(node interface{}, fset *token.FileSet) string { +	var buf1 bytes.Buffer +	writeNode(&buf1, fset, node) +	var buf2 bytes.Buffer +	FormatText(&buf2, buf1.Bytes(), -1, true, "", nil) +	return buf2.String()  } -// Template formatter for "fileInfoName" format. -func fileInfoNameFmt(w io.Writer, format string, x ...interface{}) { -	fi := x[0].(FileInfo) -	template.HTMLEscape(w, []byte(fi.Name())) -	if fi.IsDirectory() { -		w.Write([]byte{'/'}) -	} +func comment_htmlFunc(comment string) string { +	var buf bytes.Buffer +	// TODO(gri) Provide list of words (e.g. function parameters) +	//           to be emphasized by ToHTML. +	doc.ToHTML(&buf, []byte(comment), nil) // does html-escaping +	return buf.String()  } -// Template formatter for "fileInfoSize" format. -func fileInfoSizeFmt(w io.Writer, format string, x ...interface{}) { -	fmt.Fprintf(w, "%d", x[0].(FileInfo).Size()) +func pkgLinkFunc(path string) string { +	relpath := relativeURL(path) +	// because of the irregular mapping under goroot +	// we need to correct certain relative paths +	if strings.HasPrefix(relpath, "src/pkg/") { +		relpath = relpath[len("src/pkg/"):] +	} +	return pkgHandler.pattern[1:] + relpath // remove trailing '/' for relative URL  } -// Template formatter for "fileInfoTime" format. -func fileInfoTimeFmt(w io.Writer, format string, x ...interface{}) { -	if t := x[0].(FileInfo).Mtime_ns(); t != 0 { -		template.HTMLEscape(w, []byte(time.SecondsToLocalTime(t/1e9).String())) +func posLink_urlFunc(node ast.Node, fset *token.FileSet) string { +	var relpath string +	var line int +	var low, high int // selection + +	if p := node.Pos(); p.IsValid() { +		pos := fset.Position(p) +		relpath = relativeURL(pos.Filename) +		line = pos.Line +		low = pos.Offset +	} +	if p := node.End(); p.IsValid() { +		high = fset.Position(p).Offset +	} + +	var buf bytes.Buffer +	template.HTMLEscape(&buf, []byte(relpath)) +	// selection ranges are of form "s=low:high" +	if low < high { +		fmt.Fprintf(&buf, "?s=%d:%d", low, high) // no need for URL escaping +		// if we have a selection, position the page +		// such that the selection is a bit below the top +		line -= 10 +		if line < 1 { +			line = 1 +		} +	} +	// line id's in html-printed source are of the +	// form "L%d" where %d stands for the line number +	if line > 0 { +		fmt.Fprintf(&buf, "#L%d", line) // no need for URL escaping  	} -	// don't print epoch if time is obviously not set -} -// Template formatter for "numlines" format. -func numlinesFmt(w io.Writer, format string, x ...interface{}) { -	list := x[0].([]int) -	fmt.Fprintf(w, "%d", len(list)) +	return buf.String()  } -var fmap = template.FormatterMap{ -	"":             textFmt, -	"html-esc":     htmlEscFmt, -	"html-comment": htmlCommentFmt, -	"urlquery-esc": urlQueryEscFmt, -	"url-pkg":      urlFmt, -	"url-src":      urlFmt, -	"url-pos":      urlFmt, -	"infoKind":     infoKindFmt, -	"infoLine":     infoLineFmt, -	"infoSnippet":  infoSnippetFmt, -	"padding":      paddingFmt, -	"fileInfoName": fileInfoNameFmt, -	"fileInfoSize": fileInfoSizeFmt, -	"fileInfoTime": fileInfoTimeFmt, -	"localname":    localnameFmt, -	"numlines":     numlinesFmt, +// fmap describes the template functions installed with all godoc templates. +// Convention: template function names ending in "_html" or "_url" produce +//             HTML- or URL-escaped strings; all other function results may +//             require explicit escaping in the template. +var fmap = template.FuncMap{ +	// various helpers +	"filename": filenameFunc, +	"repeat":   strings.Repeat, + +	// accss to FileInfos (directory listings) +	"fileInfoName": fileInfoNameFunc, +	"fileInfoTime": fileInfoTimeFunc, + +	// access to search result information +	"infoKind_html":    infoKind_htmlFunc, +	"infoLine":         infoLineFunc, +	"infoSnippet_html": infoSnippet_htmlFunc, + +	// formatting of AST nodes +	"node":         nodeFunc, +	"node_html":    node_htmlFunc, +	"comment_html": comment_htmlFunc, + +	// support for URL attributes +	"pkgLink":     pkgLinkFunc, +	"srcLink":     relativeURL, +	"posLink_url": posLink_urlFunc,  }  func readTemplate(name string) *template.Template { @@ -629,15 +540,7 @@ func readTemplate(name string) *template.Template {  			path = defaultpath  		}  	} -	data, err := fs.ReadFile(path) -	if err != nil { -		log.Fatalf("ReadFile %s: %v", path, err) -	} -	t, err := template.Parse(string(data), fmap) -	if err != nil { -		log.Fatalf("%s: %v", name, err) -	} -	return t +	return template.Must(template.New(name).Funcs(fmap).ParseFile(path))  }  var ( @@ -864,6 +767,10 @@ func serveFile(w http.ResponseWriter, r *http.Request) {  const fakePkgFile = "doc.go"  const fakePkgName = "documentation" +// Fake relative package path for built-ins. Documentation for all globals +// (not just exported ones) will be shown for packages in this directory. +const builtinPkgPath = "builtin/" +  type PageInfoMode uint  const ( @@ -1038,7 +945,10 @@ func (h *httpHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {  	relpath := r.URL.Path[len(h.pattern):]  	abspath := absolutePath(relpath, h.fsRoot) -	mode := exportsOnly +	var mode PageInfoMode +	if relpath != builtinPkgPath { +		mode = exportsOnly +	}  	if r.FormValue("m") != "src" {  		mode |= genDoc  	} @@ -1061,7 +971,7 @@ func (h *httpHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {  		title = "Package " + info.PAst.Name.Name  	case info.PDoc != nil:  		switch { -		case h.isPkg: +		case info.IsPkg:  			title = "Package " + info.PDoc.PackageName  		case info.PDoc.PackageName == fakePkgName:  			// assume that the directory name is the command name diff --git a/src/cmd/godoc/main.go b/src/cmd/godoc/main.go index 943c81cfb..89b12b9ac 100644 --- a/src/cmd/godoc/main.go +++ b/src/cmd/godoc/main.go @@ -44,6 +44,7 @@ import (  	"runtime"  	"strings"  	"time" +	"url"  )  const defaultAddr = ":6060" // default webserver address @@ -160,7 +161,7 @@ func loggingHandler(h http.Handler) http.Handler {  }  func remoteSearch(query string) (res *http.Response, err os.Error) { -	search := "/search?f=text&q=" + http.URLEscape(query) +	search := "/search?f=text&q=" + url.QueryEscape(query)  	// list of addresses to try  	var addrs []string @@ -401,9 +402,11 @@ func main() {  					fmt.Println()  				}  				if *html { -					writeAnyHTML(os.Stdout, info.FSet, d) +					var buf bytes.Buffer +					writeNode(&buf, info.FSet, d) +					FormatText(os.Stdout, buf.Bytes(), -1, true, "", nil)  				} else { -					writeAny(os.Stdout, info.FSet, d) +					writeNode(os.Stdout, info.FSet, d)  				}  				fmt.Println()  			} diff --git a/src/cmd/godoc/snippet.go b/src/cmd/godoc/snippet.go index 626b01455..68e27d9a0 100755 --- a/src/cmd/godoc/snippet.go +++ b/src/cmd/godoc/snippet.go @@ -18,7 +18,7 @@ import (  type Snippet struct {  	Line int -	Text []byte +	Text string // HTML-escaped  }  func newSnippet(fset *token.FileSet, decl ast.Decl, id *ast.Ident) *Snippet { @@ -30,7 +30,7 @@ func newSnippet(fset *token.FileSet, decl ast.Decl, id *ast.Ident) *Snippet {  	buf2.WriteString("<pre>")  	FormatText(&buf2, buf1.Bytes(), -1, true, id.Name, nil)  	buf2.WriteString("</pre>") -	return &Snippet{fset.Position(id.Pos()).Line, buf2.Bytes()} +	return &Snippet{fset.Position(id.Pos()).Line, buf2.String()}  }  func findSpec(list []ast.Spec, id *ast.Ident) ast.Spec { @@ -94,10 +94,7 @@ func NewSnippet(fset *token.FileSet, decl ast.Decl, id *ast.Ident) (s *Snippet)  	if s == nil {  		var buf bytes.Buffer  		fmt.Fprintf(&buf, `<span class="alert">could not generate a snippet for <span class="highlight">%s</span></span>`, id.Name) -		s = &Snippet{ -			fset.Position(id.Pos()).Line, -			buf.Bytes(), -		} +		s = &Snippet{fset.Position(id.Pos()).Line, buf.String()}  	}  	return  } diff --git a/src/cmd/gofix/Makefile b/src/cmd/gofix/Makefile index 7ce21e8aa..22033d7f8 100644 --- a/src/cmd/gofix/Makefile +++ b/src/cmd/gofix/Makefile @@ -23,6 +23,7 @@ GOFILES=\  	sortslice.go\  	stringssplit.go\  	typecheck.go\ +	url.go\  include ../../Make.cmd diff --git a/src/cmd/gofix/fix.go b/src/cmd/gofix/fix.go index c1c5a746c..cc85ceafa 100644 --- a/src/cmd/gofix/fix.go +++ b/src/cmd/gofix/fix.go @@ -71,17 +71,21 @@ func walkBeforeAfter(x interface{}, before, after func(interface{})) {  		walkBeforeAfter(*n, before, after)  	case **ast.FuncType:  		walkBeforeAfter(*n, before, after) +	case **ast.Ident: +		walkBeforeAfter(*n, before, after)  	// pointers to slices -	case *[]ast.Stmt: +	case *[]ast.Decl:  		walkBeforeAfter(*n, before, after)  	case *[]ast.Expr:  		walkBeforeAfter(*n, before, after) -	case *[]ast.Decl: +	case *[]*ast.File: +		walkBeforeAfter(*n, before, after) +	case *[]*ast.Ident:  		walkBeforeAfter(*n, before, after)  	case *[]ast.Spec:  		walkBeforeAfter(*n, before, after) -	case *[]*ast.File: +	case *[]ast.Stmt:  		walkBeforeAfter(*n, before, after)  	// These are ordered and grouped to match ../../pkg/go/ast/ast.go @@ -212,6 +216,7 @@ func walkBeforeAfter(x interface{}, before, after func(interface{})) {  	case *ast.ValueSpec:  		walkBeforeAfter(&n.Type, before, after)  		walkBeforeAfter(&n.Values, before, after) +		walkBeforeAfter(&n.Names, before, after)  	case *ast.TypeSpec:  		walkBeforeAfter(&n.Type, before, after) @@ -245,6 +250,10 @@ func walkBeforeAfter(x interface{}, before, after func(interface{})) {  		for i := range n {  			walkBeforeAfter(&n[i], before, after)  		} +	case []*ast.Ident: +		for i := range n { +			walkBeforeAfter(&n[i], before, after) +		}  	case []ast.Stmt:  		for i := range n {  			walkBeforeAfter(&n[i], before, after) diff --git a/src/cmd/gofix/url.go b/src/cmd/gofix/url.go new file mode 100644 index 000000000..c1e47bd4e --- /dev/null +++ b/src/cmd/gofix/url.go @@ -0,0 +1,106 @@ +// Copyright 2011 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 ( +	"fmt" +	"os" +	"go/ast" +) + +var _ fmt.Stringer +var _ os.Error + +var urlFix = fix{ +	"url", +	url, +	`Move the URL pieces of package http into a new package, url. + +http://codereview.appspot.com/4893043 +`, +} + +func init() { +	register(urlFix) +} + +var urlRenames = []struct{ in, out string }{ +	{"ParseURL", "Parse"}, +	{"ParseURLReference", "ParseWithReference"}, +	{"ParseQuery", "ParseQuery"}, +	{"Values", "Values"}, +	{"URLEscape", "QueryEscape"}, +	{"URLUnescape", "QueryUnescape"}, +	{"URLError", "Error"}, +	{"URLEscapeError", "EscapeError"}, +} + +func url(f *ast.File) bool { +	if imports(f, "url") || !imports(f, "http") { +		return false +	} + +	fixed := false + +	// Update URL code. +	urlWalk := func(n interface{}) { +		// Is it an identifier? +		if ident, ok := n.(*ast.Ident); ok && ident.Name == "url" { +			ident.Name = "url_" +			return +		} +		// Parameter and result names. +		if fn, ok := n.(*ast.FuncType); ok { +			fixed = urlDoFields(fn.Params) || fixed +			fixed = urlDoFields(fn.Results) || fixed +		} +	} + +	// Fix up URL code and add import, at most once. +	fix := func() { +		if fixed { +			return +		} +		walk(f, urlWalk) +		addImport(f, "url") +		fixed = true +	} + +	walk(f, func(n interface{}) { +		// Rename functions and methods. +		if expr, ok := n.(ast.Expr); ok { +			for _, s := range urlRenames { +				if isPkgDot(expr, "http", s.in) { +					fix() +					expr.(*ast.SelectorExpr).X.(*ast.Ident).Name = "url" +					expr.(*ast.SelectorExpr).Sel.Name = s.out +					return +				} +			} +		} +	}) + +	// Remove the http import if no longer needed. +	if fixed && !usesImport(f, "http") { +		deleteImport(f, "http") +	} + +	return fixed +} + +func urlDoFields(list *ast.FieldList) (fixed bool) { +	if list == nil { +		return +	} +	for _, field := range list.List { +		for _, ident := range field.Names { +			if ident.Name == "url" { +				fixed = true +				ident.Name = "url_" +			} +		} +	} +	return +} diff --git a/src/cmd/gofix/url_test.go b/src/cmd/gofix/url_test.go new file mode 100644 index 000000000..1a7095a5d --- /dev/null +++ b/src/cmd/gofix/url_test.go @@ -0,0 +1,147 @@ +// Copyright 2011 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 + +func init() { +	addTestCases(urlTests) +} + +var urlTests = []testCase{ +	{ +		Name: "url.0", +		In: `package main + +import ( +	"http" +) + +func f() { +	http.ParseURL(a) +	http.ParseURLReference(a) +	http.ParseQuery(a) +	m := http.Values{a: b} +	http.URLEscape(a) +	http.URLUnescape(a) +	var x http.URLError +	var y http.URLEscapeError +} +`, +		Out: `package main + +import "url" + +func f() { +	url.Parse(a) +	url.ParseWithReference(a) +	url.ParseQuery(a) +	m := url.Values{a: b} +	url.QueryEscape(a) +	url.QueryUnescape(a) +	var x url.Error +	var y url.EscapeError +} +`, +	}, +	{ +		Name: "url.1", +		In: `package main + +import ( +	"http" +) + +func f() { +	http.ParseURL(a) +	var x http.Request +} +`, +		Out: `package main + +import ( +	"http" +	"url" +) + +func f() { +	url.Parse(a) +	var x http.Request +} +`, +	}, +	{ +		Name: "url.2", +		In: `package main + +import ( +	"http" +) + +func f() { +	http.ParseURL(a) +	var url = 23 +	url, x := 45, y +} + +func g(url string) string { +	return url +} + +func h() (url string) { +	return url +} +`, +		Out: `package main + +import "url" + +func f() { +	url.Parse(a) +	var url_ = 23 +	url_, x := 45, y +} + +func g(url_ string) string { +	return url_ +} + +func h() (url_ string) { +	return url_ +} +`, +	}, +	{ +		Name: "url.3", +		In: `package main + +import "http" + +type U struct{ url string } + +func f() { +	var u U +	u.url = "x" +} + +func (url *T) m() string { +	return url +} +`, +		Out: `package main + +import "http" + +type U struct{ url string } + +func f() { +	var u U +	u.url = "x" +} + +func (url *T) m() string { +	return url +} +`, +	}, +} diff --git a/src/cmd/gofmt/test.sh b/src/cmd/gofmt/test.sh index 3e63d0c26..063a0727f 100755 --- a/src/cmd/gofmt/test.sh +++ b/src/cmd/gofmt/test.sh @@ -43,7 +43,7 @@ apply1() {  	bug226.go | bug228.go | bug248.go | bug274.go | bug280.go | \  	bug282.go | bug287.go | bug298.go | bug299.go | bug300.go | \  	bug302.go | bug306.go | bug322.go | bug324.go | bug335.go | \ -	bug340.go | bug349.go | bug351.go ) return ;; +	bug340.go | bug349.go | bug351.go | bug358.go ) return ;;  	esac  	# the following directories are skipped because they contain test  	# cases for syntax errors and thus won't parse in the first place: diff --git a/src/cmd/goinstall/main.go b/src/cmd/goinstall/main.go index 86e490e24..910ab7090 100644 --- a/src/cmd/goinstall/main.go +++ b/src/cmd/goinstall/main.go @@ -196,9 +196,17 @@ func install(pkg, parent string) {  	}  	// Download remote packages if not found or forced with -u flag.  	remote, public := isRemote(pkg), false -	if remote && (err == build.ErrNotFound || (err == nil && *update)) { -		printf("%s: download\n", pkg) -		public, err = download(pkg, tree.SrcDir()) +	if remote { +		if err == build.ErrNotFound || (err == nil && *update) { +			// Download remote package. +			printf("%s: download\n", pkg) +			public, err = download(pkg, tree.SrcDir()) +		} else { +			// Test if this is a public repository +			// (for reporting to dashboard). +			m, _ := findPublicRepo(pkg) +			public = m != nil +		}  	}  	if err != nil {  		errorf("%s: %v\n", pkg, err) diff --git a/src/cmd/goinstall/make.go b/src/cmd/goinstall/make.go index 25f79d60d..38a70ddfd 100644 --- a/src/cmd/goinstall/make.go +++ b/src/cmd/goinstall/make.go @@ -8,11 +8,11 @@ package main  import (  	"bytes" -	"exp/template"  	"go/build"  	"os"  	"path/filepath"  	"strings" +	"template"  )  // domake builds the package in dir. diff --git a/src/cmd/ld/data.c b/src/cmd/ld/data.c index 974c08708..e7269169e 100644 --- a/src/cmd/ld/data.c +++ b/src/cmd/ld/data.c @@ -687,7 +687,7 @@ addaddrplus(Sym *s, Sym *t, int32 add)  	return i;  } -vlong +static vlong  addaddrplus4(Sym *s, Sym *t, int32 add)  {  	vlong i; | 
