summaryrefslogtreecommitdiffstats
path: root/src/util/doc.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/doc.go')
-rw-r--r--src/util/doc.go76
1 files changed, 47 insertions, 29 deletions
diff --git a/src/util/doc.go b/src/util/doc.go
index 540d6ca..23cd5f4 100644
--- a/src/util/doc.go
+++ b/src/util/doc.go
@@ -48,9 +48,8 @@ type HeaderSection struct {
// Preamble contains a comment for a group of functions.
Preamble []string
Decls []HeaderDecl
- // Num is just the index of the section. It's included in order to help
- // text/template generate anchors.
- Num int
+ // Anchor, if non-empty, is the URL fragment to use in anchor tags.
+ Anchor string
// IsPrivate is true if the section contains private functions (as
// indicated by its name).
IsPrivate bool
@@ -65,10 +64,8 @@ type HeaderDecl struct {
Name string
// Decl contains the preformatted C declaration itself.
Decl string
- // Num is an index for the declaration, but the value is unique for all
- // declarations in a HeaderFile. It's included in order to help
- // text/template generate anchors.
- Num int
+ // Anchor, if non-empty, is the URL fragment to use in anchor tags.
+ Anchor string
}
const (
@@ -192,14 +189,6 @@ func extractDecl(lines []string, lineNo int) (decl string, rest []string, restLi
return
}
-func skipPast(s, skip string) string {
- i := strings.Index(s, skip)
- if i > 0 {
- return s[i:]
- }
- return s
-}
-
func skipLine(s string) string {
i := strings.Index(s, "\n")
if i > 0 {
@@ -227,8 +216,9 @@ func getNameFromDecl(decl string) (string, bool) {
}
return decl[:i], true
}
- decl = skipPast(decl, "STACK_OF(")
- decl = skipPast(decl, "LHASH_OF(")
+ decl = strings.TrimPrefix(decl, "OPENSSL_EXPORT ")
+ decl = strings.TrimPrefix(decl, "STACK_OF(")
+ decl = strings.TrimPrefix(decl, "LHASH_OF(")
i := strings.Index(decl, "(")
if i < 0 {
return "", false
@@ -243,6 +233,10 @@ func getNameFromDecl(decl string) (string, bool) {
return decl[j+1 : i], true
}
+func sanitizeAnchor(name string) string {
+ return strings.Replace(name, " ", "-", -1)
+}
+
func (config *Config) parseHeader(path string) (*HeaderFile, error) {
headerPath := filepath.Join(config.BaseDirectory, path)
@@ -314,7 +308,7 @@ func (config *Config) parseHeader(path string) (*HeaderFile, error) {
}
}
- var sectionNumber, declNumber int
+ allAnchors := make(map[string]struct{})
for {
// Start of a section.
@@ -330,10 +324,7 @@ func (config *Config) parseHeader(path string) (*HeaderFile, error) {
return nil, fmt.Errorf("blank line at start of section on line %d", lineNo)
}
- section := HeaderSection{
- Num: sectionNumber,
- }
- sectionNumber++
+ var section HeaderSection
if strings.HasPrefix(line, commentStart) {
comment, rest, restLineNo, err := extractComment(lines, lineNo)
@@ -341,8 +332,17 @@ func (config *Config) parseHeader(path string) (*HeaderFile, error) {
return nil, err
}
if len(rest) > 0 && len(rest[0]) == 0 {
+ anchor := sanitizeAnchor(firstSentence(comment))
+ if len(anchor) > 0 {
+ if _, ok := allAnchors[anchor]; ok {
+ return nil, fmt.Errorf("duplicate anchor: %s", anchor)
+ }
+ allAnchors[anchor] = struct{}{}
+ }
+
section.Preamble = comment
section.IsPrivate = len(comment) > 0 && strings.HasPrefix(comment[0], "Private functions")
+ section.Anchor = anchor
lines = rest[1:]
lineNo = restLineNo + 1
}
@@ -381,13 +381,18 @@ func (config *Config) parseHeader(path string) (*HeaderFile, error) {
if last := len(section.Decls) - 1; len(name) == 0 && len(comment) == 0 && last >= 0 {
section.Decls[last].Decl += "\n" + decl
} else {
+ anchor := sanitizeAnchor(name)
+ // TODO(davidben): Enforce uniqueness. This is
+ // skipped because #ifdefs currently result in
+ // duplicate table-of-contents entries.
+ allAnchors[anchor] = struct{}{}
+
section.Decls = append(section.Decls, HeaderDecl{
Comment: comment,
Name: name,
Decl: decl,
- Num: declNumber,
+ Anchor: anchor,
})
- declNumber++
}
if len(lines) > 0 && len(lines[0]) == 0 {
@@ -451,7 +456,7 @@ again:
if end > 0 {
end += start
w := strings.ToLower(string(s[start:end]))
- if w == "a" || w == "an" || w == "deprecated:" {
+ if w == "a" || w == "an" {
start = end + 1
goto again
}
@@ -495,9 +500,9 @@ func generate(outPath string, config *Config) (map[string]string, error) {
<ol>
{{range .Sections}}
{{if not .IsPrivate}}
- {{if .Preamble}}<li class="header"><a href="#section-{{.Num}}">{{.Preamble | firstSentence | html | markupPipeWords}}</a></li>{{end}}
+ {{if .Anchor}}<li class="header"><a href="#{{.Anchor}}">{{.Preamble | firstSentence | html | markupPipeWords}}</a></li>{{end}}
{{range .Decls}}
- {{if .Name}}<li><a href="#decl-{{.Num}}"><tt>{{.Name}}</tt></a></li>{{end}}
+ {{if .Anchor}}<li><a href="#{{.Anchor}}"><tt>{{.Name}}</tt></a></li>{{end}}
{{end}}
{{end}}
{{end}}
@@ -508,7 +513,7 @@ func generate(outPath string, config *Config) (map[string]string, error) {
<div class="section">
{{if .Preamble}}
<div class="sectionpreamble">
- <a name="section-{{.Num}}">
+ <a{{if .Anchor}} name="{{.Anchor}}"{{end}}>
{{range .Preamble}}<p>{{. | html | markupPipeWords}}</p>{{end}}
</a>
</div>
@@ -516,7 +521,7 @@ func generate(outPath string, config *Config) (map[string]string, error) {
{{range .Decls}}
<div class="decl">
- <a name="decl-{{.Num}}">
+ <a{{if .Anchor}} name="{{.Anchor}}"{{end}}>
{{range .Comment}}
<p>{{. | html | markupPipeWords | newlinesToBR | markupFirstWord}}</p>
{{end}}
@@ -605,6 +610,14 @@ func generateIndex(outPath string, config *Config, headerDescriptions map[string
return nil
}
+func copyFile(outPath string, inFilePath string) error {
+ bytes, err := ioutil.ReadFile(inFilePath)
+ if err != nil {
+ return err
+ }
+ return ioutil.WriteFile(filepath.Join(outPath, filepath.Base(inFilePath)), bytes, 0666)
+}
+
func main() {
var (
configFlag *string = flag.String("config", "doc.config", "Location of config file")
@@ -645,4 +658,9 @@ func main() {
fmt.Printf("Failed to generate index: %s\n", err)
os.Exit(1)
}
+
+ if err := copyFile(*outputDir, "doc.css"); err != nil {
+ fmt.Printf("Failed to copy static file: %s\n", err)
+ os.Exit(1)
+ }
}