// 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. //go:build ignore /* The headscan command extracts comment headings from package files; it is used to detect false positives which may require an adjustment to the comment formatting heuristics in comment.go. Usage: headscan [-root root_directory] By default, the $GOROOT/src directory is scanned. */ package main import ( "bytes" "flag" "fmt" "go/doc" "go/parser" "go/token" "io/fs" "os" "path/filepath" "regexp" "runtime" "strings" ) var ( root = flag.String("root", filepath.Join(runtime.GOROOT(), "src"), "root of filesystem tree to scan") verbose = flag.Bool("v", false, "verbose mode") ) // ToHTML in comment.go assigns a (possibly blank) ID to each heading var html_h = regexp.MustCompile(`

`) const html_endh = "

\n" func isGoFile(fi fs.FileInfo) bool { return strings.HasSuffix(fi.Name(), ".go") && !strings.HasSuffix(fi.Name(), "_test.go") } func appendHeadings(list []string, comment string) []string { var buf bytes.Buffer doc.ToHTML(&buf, comment, nil) for s := buf.String(); s != ""; { loc := html_h.FindStringIndex(s) if len(loc) == 0 { break } var inner string inner, s, _ = strings.Cut(s[loc[1]:], html_endh) list = append(list, inner) } return list } func main() { flag.Parse() fset := token.NewFileSet() nheadings := 0 err := filepath.WalkDir(*root, func(path string, info fs.DirEntry, err error) error { if !info.IsDir() { return nil } pkgs, err := parser.ParseDir(fset, path, isGoFile, parser.ParseComments) if err != nil { if *verbose { fmt.Fprintln(os.Stderr, err) } return nil } for _, pkg := range pkgs { d := doc.New(pkg, path, doc.Mode(0)) list := appendHeadings(nil, d.Doc) for _, d := range d.Consts { list = appendHeadings(list, d.Doc) } for _, d := range d.Types { list = appendHeadings(list, d.Doc) } for _, d := range d.Vars { list = appendHeadings(list, d.Doc) } for _, d := range d.Funcs { list = appendHeadings(list, d.Doc) } if len(list) > 0 { // directories may contain multiple packages; // print path and package name fmt.Printf("%s (package %s)\n", path, pkg.Name) for _, h := range list { fmt.Printf("\t%s\n", h) } nheadings += len(list) } } return nil }) if err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } fmt.Println(nheadings, "headings found") }