summaryrefslogtreecommitdiff
path: root/src/cmd/godoc/main.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/cmd/godoc/main.go')
-rw-r--r--src/cmd/godoc/main.go42
1 files changed, 26 insertions, 16 deletions
diff --git a/src/cmd/godoc/main.go b/src/cmd/godoc/main.go
index 51fcf8dd0..943c81cfb 100644
--- a/src/cmd/godoc/main.go
+++ b/src/cmd/godoc/main.go
@@ -26,6 +26,7 @@
package main
import (
+ "archive/zip"
"bytes"
_ "expvar" // to serve /debug/vars
"flag"
@@ -37,6 +38,7 @@ import (
"io"
"log"
"os"
+ "path"
"path/filepath"
"regexp"
"runtime"
@@ -47,6 +49,10 @@ import (
const defaultAddr = ":6060" // default webserver address
var (
+ // file system to serve
+ // (with e.g.: zip -r go.zip $GOROOT -i \*.go -i \*.html -i \*.css -i \*.js -i \*.txt -i \*.c -i \*.h -i \*.s -i \*.png -i \*.jpg -i \*.sh -i favicon.ico)
+ zipfile = flag.String("zip", "", "zip file providing the file system to serve; disabled if empty")
+
// periodic sync
syncCmd = flag.String("sync", "", "sync command; disabled if empty")
syncMin = flag.Int("sync_minutes", 0, "sync interval in minutes; disabled if <= 0")
@@ -64,14 +70,12 @@ var (
query = flag.Bool("q", false, "arguments are considered search queries")
)
-
func serveError(w http.ResponseWriter, r *http.Request, relpath string, err os.Error) {
contents := applyTemplate(errorHTML, "errorHTML", err) // err may contain an absolute path!
w.WriteHeader(http.StatusNotFound)
servePage(w, "File "+relpath, "", "", contents)
}
-
func exec(rw http.ResponseWriter, args []string) (status int) {
r, w, err := os.Pipe()
if err != nil {
@@ -119,7 +123,6 @@ func exec(rw http.ResponseWriter, args []string) (status int) {
return
}
-
func dosync(w http.ResponseWriter, r *http.Request) {
args := []string{"/bin/sh", "-c", *syncCmd}
switch exec(w, args) {
@@ -141,7 +144,6 @@ func dosync(w http.ResponseWriter, r *http.Request) {
}
}
-
func usage() {
fmt.Fprintf(os.Stderr,
"usage: godoc package [name ...]\n"+
@@ -150,7 +152,6 @@ func usage() {
os.Exit(2)
}
-
func loggingHandler(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
log.Printf("%s\t%s", req.RemoteAddr, req.URL)
@@ -158,7 +159,6 @@ 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)
@@ -190,13 +190,11 @@ func remoteSearch(query string) (res *http.Response, err os.Error) {
return
}
-
// Does s look like a regular expression?
func isRegexp(s string) bool {
return strings.IndexAny(s, ".(|)*+?^$[]") >= 0
}
-
// Make a regular expression of the form
// names[0]|names[1]|...names[len(names)-1].
// Returns nil if the regular expression is illegal.
@@ -218,18 +216,10 @@ func makeRx(names []string) (rx *regexp.Regexp) {
return
}
-
func main() {
flag.Usage = usage
flag.Parse()
- // Determine file system to use.
- // TODO(gri) Complete this - for now we only have one.
- fs = OS
-
- // Clean goroot: normalize path separator.
- *goroot = filepath.Clean(*goroot)
-
// Check usage: either server and no args, or command line and args
if (*httpAddr != "") != (flag.NArg() == 0) {
usage()
@@ -239,6 +229,26 @@ func main() {
log.Fatalf("negative tabwidth %d", *tabwidth)
}
+ // Determine file system to use.
+ // TODO(gri) - fs and fsHttp should really be the same. Try to unify.
+ // - fsHttp doesn't need to be set up in command-line mode,
+ // same is true for the http handlers in initHandlers.
+ if *zipfile == "" {
+ // use file system of underlying OS
+ *goroot = filepath.Clean(*goroot) // normalize path separator
+ fs = OS
+ fsHttp = http.Dir(*goroot)
+ } else {
+ // use file system specified via .zip file (path separator must be '/')
+ rc, err := zip.OpenReader(*zipfile)
+ if err != nil {
+ log.Fatalf("%s: %s\n", *zipfile, err)
+ }
+ *goroot = path.Join("/", *goroot) // fsHttp paths are relative to '/'
+ fs = NewZipFS(rc)
+ fsHttp = NewHttpZipFS(rc, *goroot)
+ }
+
initHandlers()
readTemplates()