github.com/varialus/godfly@v0.0.0-20130904042352-1934f9f095ab/src/pkg/go/doc/headscan.go (about) 1 // Copyright 2011 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // +build ignore 6 7 /* 8 The headscan command extracts comment headings from package files; 9 it is used to detect false positives which may require an adjustment 10 to the comment formatting heuristics in comment.go. 11 12 Usage: headscan [-root root_directory] 13 14 By default, the $GOROOT/src directory is scanned. 15 */ 16 package main 17 18 import ( 19 "bytes" 20 "flag" 21 "fmt" 22 "go/doc" 23 "go/parser" 24 "go/token" 25 "os" 26 "path/filepath" 27 "runtime" 28 "strings" 29 ) 30 31 var ( 32 root = flag.String("root", filepath.Join(runtime.GOROOT(), "src"), "root of filesystem tree to scan") 33 verbose = flag.Bool("v", false, "verbose mode") 34 ) 35 36 const ( 37 html_h = "<h3>" 38 html_endh = "</h3>\n" 39 ) 40 41 func isGoFile(fi os.FileInfo) bool { 42 return strings.HasSuffix(fi.Name(), ".go") && 43 !strings.HasSuffix(fi.Name(), "_test.go") 44 } 45 46 func appendHeadings(list []string, comment string) []string { 47 var buf bytes.Buffer 48 doc.ToHTML(&buf, comment, nil) 49 for s := buf.String(); ; { 50 i := strings.Index(s, html_h) 51 if i < 0 { 52 break 53 } 54 i += len(html_h) 55 j := strings.Index(s, html_endh) 56 if j < 0 { 57 list = append(list, s[i:]) // incorrect HTML 58 break 59 } 60 list = append(list, s[i:j]) 61 s = s[j+len(html_endh):] 62 } 63 return list 64 } 65 66 func main() { 67 flag.Parse() 68 fset := token.NewFileSet() 69 nheadings := 0 70 err := filepath.Walk(*root, func(path string, fi os.FileInfo, err error) error { 71 if !fi.IsDir() { 72 return nil 73 } 74 pkgs, err := parser.ParseDir(fset, path, isGoFile, parser.ParseComments) 75 if err != nil { 76 if *verbose { 77 fmt.Fprintln(os.Stderr, err) 78 } 79 return nil 80 } 81 for _, pkg := range pkgs { 82 d := doc.New(pkg, path, doc.Mode(0)) 83 list := appendHeadings(nil, d.Doc) 84 for _, d := range d.Consts { 85 list = appendHeadings(list, d.Doc) 86 } 87 for _, d := range d.Types { 88 list = appendHeadings(list, d.Doc) 89 } 90 for _, d := range d.Vars { 91 list = appendHeadings(list, d.Doc) 92 } 93 for _, d := range d.Funcs { 94 list = appendHeadings(list, d.Doc) 95 } 96 if len(list) > 0 { 97 // directories may contain multiple packages; 98 // print path and package name 99 fmt.Printf("%s (package %s)\n", path, pkg.Name) 100 for _, h := range list { 101 fmt.Printf("\t%s\n", h) 102 } 103 nheadings += len(list) 104 } 105 } 106 return nil 107 }) 108 if err != nil { 109 fmt.Fprintln(os.Stderr, err) 110 os.Exit(1) 111 } 112 fmt.Println(nheadings, "headings found") 113 }