...
Source file src/pkg/go/build/read.go
1
2
3
4
5 package build
6
7 import (
8 "bufio"
9 "errors"
10 "io"
11 "unicode/utf8"
12 )
13
14 type importReader struct {
15 b *bufio.Reader
16 buf []byte
17 peek byte
18 err error
19 eof bool
20 nerr int
21 }
22
23 func isIdent(c byte) bool {
24 return 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || '0' <= c && c <= '9' || c == '_' || c >= utf8.RuneSelf
25 }
26
27 var (
28 errSyntax = errors.New("syntax error")
29 errNUL = errors.New("unexpected NUL in input")
30 )
31
32
33 func (r *importReader) syntaxError() {
34 if r.err == nil {
35 r.err = errSyntax
36 }
37 }
38
39
40
41 func (r *importReader) readByte() byte {
42 c, err := r.b.ReadByte()
43 if err == nil {
44 r.buf = append(r.buf, c)
45 if c == 0 {
46 err = errNUL
47 }
48 }
49 if err != nil {
50 if err == io.EOF {
51 r.eof = true
52 } else if r.err == nil {
53 r.err = err
54 }
55 c = 0
56 }
57 return c
58 }
59
60
61
62 func (r *importReader) peekByte(skipSpace bool) byte {
63 if r.err != nil {
64 if r.nerr++; r.nerr > 10000 {
65 panic("go/build: import reader looping")
66 }
67 return 0
68 }
69
70
71
72
73 c := r.peek
74 if c == 0 {
75 c = r.readByte()
76 }
77 for r.err == nil && !r.eof {
78 if skipSpace {
79
80
81 switch c {
82 case ' ', '\f', '\t', '\r', '\n', ';':
83 c = r.readByte()
84 continue
85
86 case '/':
87 c = r.readByte()
88 if c == '/' {
89 for c != '\n' && r.err == nil && !r.eof {
90 c = r.readByte()
91 }
92 } else if c == '*' {
93 var c1 byte
94 for (c != '*' || c1 != '/') && r.err == nil {
95 if r.eof {
96 r.syntaxError()
97 }
98 c, c1 = c1, r.readByte()
99 }
100 } else {
101 r.syntaxError()
102 }
103 c = r.readByte()
104 continue
105 }
106 }
107 break
108 }
109 r.peek = c
110 return r.peek
111 }
112
113
114 func (r *importReader) nextByte(skipSpace bool) byte {
115 c := r.peekByte(skipSpace)
116 r.peek = 0
117 return c
118 }
119
120
121
122 func (r *importReader) readKeyword(kw string) {
123 r.peekByte(true)
124 for i := 0; i < len(kw); i++ {
125 if r.nextByte(false) != kw[i] {
126 r.syntaxError()
127 return
128 }
129 }
130 if isIdent(r.peekByte(false)) {
131 r.syntaxError()
132 }
133 }
134
135
136
137 func (r *importReader) readIdent() {
138 c := r.peekByte(true)
139 if !isIdent(c) {
140 r.syntaxError()
141 return
142 }
143 for isIdent(r.peekByte(false)) {
144 r.peek = 0
145 }
146 }
147
148
149
150 func (r *importReader) readString(save *[]string) {
151 switch r.nextByte(true) {
152 case '`':
153 start := len(r.buf) - 1
154 for r.err == nil {
155 if r.nextByte(false) == '`' {
156 if save != nil {
157 *save = append(*save, string(r.buf[start:]))
158 }
159 break
160 }
161 if r.eof {
162 r.syntaxError()
163 }
164 }
165 case '"':
166 start := len(r.buf) - 1
167 for r.err == nil {
168 c := r.nextByte(false)
169 if c == '"' {
170 if save != nil {
171 *save = append(*save, string(r.buf[start:]))
172 }
173 break
174 }
175 if r.eof || c == '\n' {
176 r.syntaxError()
177 }
178 if c == '\\' {
179 r.nextByte(false)
180 }
181 }
182 default:
183 r.syntaxError()
184 }
185 }
186
187
188
189 func (r *importReader) readImport(imports *[]string) {
190 c := r.peekByte(true)
191 if c == '.' {
192 r.peek = 0
193 } else if isIdent(c) {
194 r.readIdent()
195 }
196 r.readString(imports)
197 }
198
199
200
201 func readComments(f io.Reader) ([]byte, error) {
202 r := &importReader{b: bufio.NewReader(f)}
203 r.peekByte(true)
204 if r.err == nil && !r.eof {
205
206 r.buf = r.buf[:len(r.buf)-1]
207 }
208 return r.buf, r.err
209 }
210
211
212
213 func readImports(f io.Reader, reportSyntaxError bool, imports *[]string) ([]byte, error) {
214 r := &importReader{b: bufio.NewReader(f)}
215
216 r.readKeyword("package")
217 r.readIdent()
218 for r.peekByte(true) == 'i' {
219 r.readKeyword("import")
220 if r.peekByte(true) == '(' {
221 r.nextByte(false)
222 for r.peekByte(true) != ')' && r.err == nil {
223 r.readImport(imports)
224 }
225 r.nextByte(false)
226 } else {
227 r.readImport(imports)
228 }
229 }
230
231
232
233 if r.err == nil && !r.eof {
234 return r.buf[:len(r.buf)-1], nil
235 }
236
237
238
239 if r.err == errSyntax && !reportSyntaxError {
240 r.err = nil
241 for r.err == nil && !r.eof {
242 r.readByte()
243 }
244 }
245
246 return r.buf, r.err
247 }
248
View as plain text