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; |
