summaryrefslogtreecommitdiff
path: root/src/cmd
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd')
-rw-r--r--src/cmd/5c/reg.c1
-rw-r--r--src/cmd/5l/l.h1
-rw-r--r--src/cmd/6c/cgen.c8
-rw-r--r--src/cmd/6l/asm.c5
-rw-r--r--src/cmd/6l/l.h1
-rw-r--r--src/cmd/8l/l.h5
-rw-r--r--src/cmd/cgo/out.go14
-rw-r--r--src/cmd/gc/Makefile4
-rw-r--r--src/cmd/gc/builtin.c.boot27
-rwxr-xr-xsrc/cmd/gc/mkbuiltin2
-rw-r--r--src/cmd/gc/mkbuiltin1.c6
-rw-r--r--src/cmd/gc/range.c2
-rw-r--r--src/cmd/gc/runtime.go27
-rw-r--r--src/cmd/gc/select.c15
-rw-r--r--src/cmd/gc/walk.c18
-rw-r--r--src/cmd/godoc/godoc.go316
-rw-r--r--src/cmd/godoc/main.go9
-rwxr-xr-xsrc/cmd/godoc/snippet.go9
-rw-r--r--src/cmd/gofix/Makefile1
-rw-r--r--src/cmd/gofix/fix.go15
-rw-r--r--src/cmd/gofix/url.go106
-rw-r--r--src/cmd/gofix/url_test.go147
-rwxr-xr-xsrc/cmd/gofmt/test.sh2
-rw-r--r--src/cmd/goinstall/main.go14
-rw-r--r--src/cmd/goinstall/make.go2
-rw-r--r--src/cmd/ld/data.c2
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;