-
Notifications
You must be signed in to change notification settings - Fork 24
/
util.go
111 lines (101 loc) · 2.54 KB
/
util.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
package main
import (
"bytes"
"io"
"strings"
"unicode"
)
// TrimAPIPrefix removes the API-specific prefix from a spec name.
// e.g., glTest becomes Test; GLX_TEST becomes TEST; egl0Test stays egl0Test
func TrimAPIPrefix(name string) string {
prefixes := []string{"glX", "wgl", "egl", "gl", "GLX_", "WGL_", "EGL_", "GL_"}
trimmed := name
prefix := ""
for _, p := range prefixes {
if strings.HasPrefix(name, p) {
trimmed = strings.TrimPrefix(name, p)
prefix = p
break
}
}
if strings.IndexAny(trimmed, "0123456789") == 0 {
return prefix + trimmed
}
return trimmed
}
// BlankLineStrippingWriter removes whitespace- or comment-only lines delimited
// by \n. A necessary evil to work around how text/template handles whitespace.
// The template needs a new line at the end.
//
// Comment-based annotations are accepted to define sections of code that
// should have their blank lines kept intact, like so:
//
// //
// //glow:keepspace
// //
// // Hello World!
// //
// //glow:rmspace
// //
//
// The writer would produce output like:
// //
// // Hello World!
// //
//
type BlankLineStrippingWriter struct {
output io.Writer
buf *bytes.Buffer
stripping bool
}
// NewBlankLineStrippingWriter creates a new BlankLineStrippingWriter.
func NewBlankLineStrippingWriter(wrapped io.Writer) *BlankLineStrippingWriter {
return &BlankLineStrippingWriter{
output: wrapped,
buf: new(bytes.Buffer),
stripping: true,
}
}
func isBlank(line string) bool {
blank := true
for _, ch := range line {
if !unicode.IsSpace(ch) && ch != '/' {
blank = false
break
}
}
return blank
}
// Write appends the contents of p to the BlankLineStrippingWriter.
// The return values are the length of p and the error of the underlaying io.Writer.
func (w *BlankLineStrippingWriter) Write(p []byte) (int, error) {
// Buffer the current write.
// Error is always nil.
w.buf.Write(p)
n := len(p)
for {
line, err := w.buf.ReadString('\n')
if err != nil {
// Did not have a whole line to read, rebuffer the unconsumed data.
// Error is always nil.
w.buf.Write([]byte(line))
return n, nil
}
// Enable/disable blank line stripping based on comment-based
// annotations.
cleanLine := strings.TrimSpace(line)
if cleanLine == "//glow:keepspace" {
w.stripping = false
continue
} else if cleanLine == "//glow:rmspace" {
w.stripping = true
continue
}
// Write non-empty lines from the buffer.
if !w.stripping || !isBlank(line) {
if _, err := w.output.Write([]byte(line)); err != nil {
return n, err
}
}
}
}