diff options
Diffstat (limited to 'src/cmd/godoc/godoc.go')
-rw-r--r-- | src/cmd/godoc/godoc.go | 79 |
1 files changed, 72 insertions, 7 deletions
diff --git a/src/cmd/godoc/godoc.go b/src/cmd/godoc/godoc.go index 6b646a1a6..3bf721bcc 100644 --- a/src/cmd/godoc/godoc.go +++ b/src/cmd/godoc/godoc.go @@ -19,7 +19,7 @@ import ( "os" "path" "path/filepath" - "regexp" + "exp/regexp" "runtime" "sort" "strings" @@ -149,7 +149,7 @@ func getPathFilter() func(string) bool { // readDirList reads a file containing a newline-separated list // of directory paths and returns the list of paths. func readDirList(filename string) ([]string, os.Error) { - contents, err := fs.ReadFile(filename) + contents, err := ReadFile(fs, filename) if err != nil { return nil, err } @@ -546,7 +546,7 @@ func readTemplate(name string) *template.Template { // use underlying file system fs to read the template file // (cannot use template ParseFile functions directly) - data, err := fs.ReadFile(path) + data, err := ReadFile(fs, path) if err != nil { log.Fatal("readTemplate: ", err) } @@ -636,7 +636,7 @@ func extractString(src []byte, rx *regexp.Regexp) (s string) { func serveHTMLDoc(w http.ResponseWriter, r *http.Request, abspath, relpath string) { // get HTML body contents - src, err := fs.ReadFile(abspath) + src, err := ReadFile(fs, abspath) if err != nil { log.Printf("ReadFile: %s", err) serveError(w, r, relpath, err) @@ -685,7 +685,7 @@ func redirect(w http.ResponseWriter, r *http.Request) (redirected bool) { } func serveTextFile(w http.ResponseWriter, r *http.Request, abspath, relpath, title string) { - src, err := fs.ReadFile(abspath) + src, err := ReadFile(fs, abspath) if err != nil { log.Printf("ReadFile: %s", err) serveError(w, r, relpath, err) @@ -815,6 +815,41 @@ type httpHandler struct { isPkg bool // true if this handler serves real package documentation (as opposed to command documentation) } +// fsReadDir implements ReadDir for the go/build package. +func fsReadDir(dir string) ([]*os.FileInfo, os.Error) { + fi, err := fs.ReadDir(dir) + if err != nil { + return nil, err + } + + // Convert []FileInfo to []*os.FileInfo. + osfi := make([]*os.FileInfo, len(fi)) + for i, f := range fi { + mode := uint32(S_IFREG) + if f.IsDirectory() { + mode = S_IFDIR + } + osfi[i] = &os.FileInfo{Name: f.Name(), Size: f.Size(), Mtime_ns: f.Mtime_ns(), Mode: mode} + } + return osfi, nil +} + +// fsReadFile implements ReadFile for the go/build package. +func fsReadFile(dir, name string) (path string, data []byte, err os.Error) { + path = filepath.Join(dir, name) + data, err = ReadFile(fs, path) + return +} + +func inList(name string, list []string) bool { + for _, l := range list { + if name == l { + return true + } + } + return false +} + // getPageInfo returns the PageInfo for a package directory abspath. If the // parameter genAST is set, an AST containing only the package exports is // computed (PageInfo.PAst), otherwise package documentation (PageInfo.Doc) @@ -824,11 +859,40 @@ type httpHandler struct { // PageInfo.Err is set to the respective error but the error is not logged. // func (h *httpHandler) getPageInfo(abspath, relpath, pkgname string, mode PageInfoMode) PageInfo { + var pkgFiles []string + + // If we're showing the default package, restrict to the ones + // that would be used when building the package on this + // system. This makes sure that if there are separate + // implementations for, say, Windows vs Unix, we don't + // jumble them all together. + if pkgname == "" { + // Note: Uses current binary's GOOS/GOARCH. + // To use different pair, such as if we allowed the user + // to choose, set ctxt.GOOS and ctxt.GOARCH before + // calling ctxt.ScanDir. + ctxt := build.DefaultContext + ctxt.ReadDir = fsReadDir + ctxt.ReadFile = fsReadFile + dir, err := ctxt.ScanDir(abspath) + if err == nil { + pkgFiles = append(dir.GoFiles, dir.CgoFiles...) + } + } + // filter function to select the desired .go files filter := func(d FileInfo) bool { + // Only Go files. + if !isPkgFile(d) { + return false + } // If we are looking at cmd documentation, only accept // the special fakePkgFile containing the documentation. - return isPkgFile(d) && (h.isPkg || d.Name() == fakePkgFile) + if !h.isPkg { + return d.Name() == fakePkgFile + } + // Also restrict file list to pkgFiles. + return pkgFiles == nil || inList(d.Name(), pkgFiles) } // get package ASTs @@ -1016,6 +1080,7 @@ type SearchResult struct { Alert string // error or warning message // identifier matches + Pak HitList // packages matching Query Hit *LookupResult // identifier matches of Query Alt *AltWords // alternative identifiers to look for @@ -1034,7 +1099,7 @@ func lookup(query string) (result SearchResult) { // identifier search var err os.Error - result.Hit, result.Alt, err = index.Lookup(query) + result.Pak, result.Hit, result.Alt, err = index.Lookup(query) if err != nil && *maxResults <= 0 { // ignore the error if full text search is enabled // since the query may be a valid regular expression |