summaryrefslogtreecommitdiff
path: root/src/cmd/godoc/godoc.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/godoc/godoc.go')
-rw-r--r--src/cmd/godoc/godoc.go82
1 files changed, 46 insertions, 36 deletions
diff --git a/src/cmd/godoc/godoc.go b/src/cmd/godoc/godoc.go
index c91dc33db..9dce5edf9 100644
--- a/src/cmd/godoc/godoc.go
+++ b/src/cmd/godoc/godoc.go
@@ -18,7 +18,8 @@ import (
"io/ioutil"
"log"
"os"
- pathutil "path"
+ "path"
+ "path/filepath"
"regexp"
"runtime"
"sort"
@@ -81,8 +82,8 @@ var (
func initHandlers() {
fsMap.Init(*pkgPath)
fileServer = http.FileServer(*goroot, "")
- cmdHandler = httpHandler{"/cmd/", pathutil.Join(*goroot, "src/cmd"), false}
- pkgHandler = httpHandler{"/pkg/", pathutil.Join(*goroot, "src/pkg"), true}
+ cmdHandler = httpHandler{"/cmd/", filepath.Join(*goroot, "src", "cmd"), false}
+ pkgHandler = httpHandler{"/pkg/", filepath.Join(*goroot, "src", "pkg"), true}
}
@@ -91,12 +92,13 @@ func registerPublicHandlers(mux *http.ServeMux) {
mux.Handle(pkgHandler.pattern, &pkgHandler)
mux.HandleFunc("/doc/codewalk/", codewalk)
mux.HandleFunc("/search", search)
+ mux.Handle("/robots.txt", fileServer)
mux.HandleFunc("/", serveFile)
}
func initFSTree() {
- fsTree.set(newDirectory(pathutil.Join(*goroot, *testDir), nil, -1))
+ fsTree.set(newDirectory(filepath.Join(*goroot, *testDir), nil, -1))
invalidateIndex()
}
@@ -147,8 +149,13 @@ func readDirList(filename string) ([]string, os.Error) {
}
// create a sorted list of valid directory names
filter := func(path string) bool {
- d, err := os.Lstat(path)
- return err == nil && isPkgDir(d)
+ d, e := os.Lstat(path)
+ if e != nil && err == nil {
+ // remember first error and return it from readDirList
+ // so we have at least some information if things go bad
+ err = e
+ }
+ return e == nil && isPkgDir(d)
}
list := canonicalizePaths(strings.Split(string(contents), "\n", -1), filter)
// for each parent path, remove all it's children q
@@ -160,7 +167,7 @@ func readDirList(filename string) ([]string, os.Error) {
i++
}
}
- return list[0:i], nil
+ return list[0:i], err
}
@@ -207,9 +214,10 @@ func initDirTrees() {
if *filter != "" {
list, err := readDirList(*filter)
if err != nil {
- log.Printf("%s", err)
- } else if len(list) == 0 {
- log.Printf("no directory paths in file %s", *filter)
+ log.Printf("readDirList(%s): %s", *filter, err)
+ }
+ if *verbose || len(list) == 0 {
+ log.Printf("found %d directory paths in file %s", len(list), *filter)
}
setPathFilter(list)
}
@@ -239,27 +247,30 @@ func initDirTrees() {
// ----------------------------------------------------------------------------
// Path mapping
-func absolutePath(path, defaultRoot string) string {
- abspath := fsMap.ToAbsolute(path)
+// Absolute paths are file system paths (backslash-separated on Windows),
+// but relative paths are always slash-separated.
+
+func absolutePath(relpath, defaultRoot string) string {
+ abspath := fsMap.ToAbsolute(relpath)
if abspath == "" {
// no user-defined mapping found; use default mapping
- abspath = pathutil.Join(defaultRoot, path)
+ abspath = filepath.Join(defaultRoot, filepath.FromSlash(relpath))
}
return abspath
}
-func relativePath(path string) string {
- relpath := fsMap.ToRelative(path)
+func relativeURL(abspath string) string {
+ relpath := fsMap.ToRelative(abspath)
if relpath == "" {
- // prefix must end in '/'
+ // prefix must end in a path separator
prefix := *goroot
- if len(prefix) > 0 && prefix[len(prefix)-1] != '/' {
- prefix += "/"
+ if len(prefix) > 0 && prefix[len(prefix)-1] != filepath.Separator {
+ prefix += string(filepath.Separator)
}
- if strings.HasPrefix(path, prefix) {
+ if strings.HasPrefix(abspath, prefix) {
// no user-defined mapping found; use default mapping
- relpath = path[len(prefix):]
+ relpath = filepath.ToSlash(abspath[len(prefix):])
}
}
// Only if path is an invalid absolute path is relpath == ""
@@ -474,7 +485,7 @@ func urlFmt(w io.Writer, format string, x ...interface{}) {
}
// map path
- relpath := relativePath(path)
+ relpath := relativeURL(path)
// convert to relative URLs so that they can also
// be used as relative file names in .txt templates
@@ -591,7 +602,7 @@ func dirslashFmt(w io.Writer, format string, x ...interface{}) {
// Template formatter for "localname" format.
func localnameFmt(w io.Writer, format string, x ...interface{}) {
- _, localname := pathutil.Split(x[0].(string))
+ _, localname := filepath.Split(x[0].(string))
template.HTMLEscape(w, []byte(localname))
}
@@ -623,7 +634,7 @@ var fmap = template.FormatterMap{
func readTemplate(name string) *template.Template {
- path := pathutil.Join(*goroot, "lib/godoc/"+name)
+ path := filepath.Join(*goroot, "lib", "godoc", name)
data, err := ioutil.ReadFile(path)
if err != nil {
log.Fatalf("ReadFile %s: %v", path, err)
@@ -760,14 +771,13 @@ func applyTemplate(t *template.Template, name string, data interface{}) []byte {
func redirect(w http.ResponseWriter, r *http.Request) (redirected bool) {
- if canonical := pathutil.Clean(r.URL.Path) + "/"; r.URL.Path != canonical {
+ if canonical := path.Clean(r.URL.Path) + "/"; r.URL.Path != canonical {
http.Redirect(w, r, canonical, http.StatusMovedPermanently)
redirected = true
}
return
}
-
func serveTextFile(w http.ResponseWriter, r *http.Request, abspath, relpath, title string) {
src, err := ioutil.ReadFile(abspath)
if err != nil {
@@ -778,7 +788,7 @@ func serveTextFile(w http.ResponseWriter, r *http.Request, abspath, relpath, tit
var buf bytes.Buffer
buf.WriteString("<pre>")
- FormatText(&buf, src, 1, pathutil.Ext(abspath) == ".go", r.FormValue("h"), rangeSelection(r.FormValue("s")))
+ FormatText(&buf, src, 1, filepath.Ext(abspath) == ".go", r.FormValue("h"), rangeSelection(r.FormValue("s")))
buf.WriteString("</pre>")
servePage(w, title+" "+relpath, "", "", buf.Bytes())
@@ -815,7 +825,7 @@ func serveFile(w http.ResponseWriter, r *http.Request) {
// pick off special cases and hand the rest to the standard file server
switch r.URL.Path {
case "/":
- serveHTMLDoc(w, r, pathutil.Join(*goroot, "doc/root.html"), "doc/root.html")
+ serveHTMLDoc(w, r, filepath.Join(*goroot, "doc", "root.html"), "doc/root.html")
return
case "/doc/root.html":
@@ -824,9 +834,9 @@ func serveFile(w http.ResponseWriter, r *http.Request) {
return
}
- switch pathutil.Ext(abspath) {
+ switch path.Ext(relpath) {
case ".html":
- if strings.HasSuffix(abspath, "/index.html") {
+ if strings.HasSuffix(relpath, "/index.html") {
// We'll show index.html for the directory.
// Use the dir/ version as canonical instead of dir/index.html.
http.Redirect(w, r, r.URL.Path[0:len(r.URL.Path)-len("index.html")], http.StatusMovedPermanently)
@@ -851,8 +861,8 @@ func serveFile(w http.ResponseWriter, r *http.Request) {
if redirect(w, r) {
return
}
- if index := abspath + "/index.html"; isTextFile(index) {
- serveHTMLDoc(w, r, index, relativePath(index))
+ if index := filepath.Join(abspath, "index.html"); isTextFile(index) {
+ serveHTMLDoc(w, r, index, relativeURL(index))
return
}
serveDirectory(w, r, abspath, relpath)
@@ -948,13 +958,13 @@ func (h *httpHandler) getPageInfo(abspath, relpath, pkgname string, mode PageInf
// the package with dirname, and the 3rd choice is a package
// that is not called "main" if there is exactly one such
// package. Otherwise, don't select a package.
- dirpath, dirname := pathutil.Split(abspath)
+ dirpath, dirname := filepath.Split(abspath)
// If the dirname is "go" we might be in a sub-directory for
// .go files - use the outer directory name instead for better
// results.
if dirname == "go" {
- _, dirname = pathutil.Split(pathutil.Clean(dirpath))
+ _, dirname = filepath.Split(filepath.Clean(dirpath))
}
var choice3 *ast.Package
@@ -995,7 +1005,7 @@ func (h *httpHandler) getPageInfo(abspath, relpath, pkgname string, mode PageInf
ast.PackageExports(pkg)
}
if mode&genDoc != 0 {
- pdoc = doc.NewPackageDoc(pkg, pathutil.Clean(relpath)) // no trailing '/' in importpath
+ pdoc = doc.NewPackageDoc(pkg, path.Clean(relpath)) // no trailing '/' in importpath
} else {
past = ast.MergePackageFiles(pkg, ast.FilterUnassociatedComments)
}
@@ -1081,13 +1091,13 @@ func (h *httpHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
title = "Package " + info.PDoc.PackageName
case info.PDoc.PackageName == fakePkgName:
// assume that the directory name is the command name
- _, pkgname := pathutil.Split(pathutil.Clean(relpath))
+ _, pkgname := path.Split(path.Clean(relpath))
title = "Command " + pkgname
default:
title = "Command " + info.PDoc.PackageName
}
default:
- title = "Directory " + relativePath(info.Dirname)
+ title = "Directory " + relativeURL(info.Dirname)
if *showTimestamps {
subtitle = "Last update: " + time.SecondsToLocalTime(info.DirTime).String()
}