Move scanner comment handling out of scanRR (#877)

* Add comment getter to zlexer

* Use zlexer.Comment instead of lex.comment

* Move comment handling out of setRR code

* Move comment field from lex to zlexer

* Eliminate ZoneParser.com field

* Return empty string from zlexer.Comment on error

* Only reset zlexer.comment field once per Next

* Remove zlexer merge TODO

I'm pretty sure these have to remain separate which is okay.
This commit is contained in:
Tom Thorogood 2018-12-31 19:50:26 +10:30 committed by Miek Gieben
parent ac5c421c48
commit 2533d75276
3 changed files with 469 additions and 461 deletions

View File

@ -109,7 +109,7 @@ func PrivateHandle(rtypestr string, rtype uint16, generator func() PrivateRdata)
return rr, off, err return rr, off, err
} }
setPrivateRR := func(h RR_Header, c *zlexer, o, f string) (RR, *ParseError, string) { setPrivateRR := func(h RR_Header, c *zlexer, o, f string) (RR, *ParseError) {
rr := mkPrivateRR(h.Rrtype) rr := mkPrivateRR(h.Rrtype)
rr.Hdr = h rr.Hdr = h
@ -129,10 +129,10 @@ func PrivateHandle(rtypestr string, rtype uint16, generator func() PrivateRdata)
err := rr.Data.Parse(text) err := rr.Data.Parse(text)
if err != nil { if err != nil {
return nil, &ParseError{f, err.Error(), l}, "" return nil, &ParseError{f, err.Error(), l}
} }
return rr, nil, "" return rr, nil
} }
typeToparserFunc[rtype] = parserFunc{setPrivateRR, true} typeToparserFunc[rtype] = parserFunc{setPrivateRR, true}

83
scan.go
View File

@ -79,13 +79,12 @@ func (e *ParseError) Error() (s string) {
} }
type lex struct { type lex struct {
token string // text of the token token string // text of the token
err bool // when true, token text has lexer error err bool // when true, token text has lexer error
value uint8 // value: zString, _BLANK, etc. value uint8 // value: zString, _BLANK, etc.
torc uint16 // type or class as parsed in the lexer, we only need to look this up in the grammar torc uint16 // type or class as parsed in the lexer, we only need to look this up in the grammar
line int // line in the file line int // line in the file
column int // column in the file column int // column in the file
comment string // any comment text seen
} }
// Token holds the token that are returned when a zone file is parsed. // Token holds the token that are returned when a zone file is parsed.
@ -244,8 +243,6 @@ type ZoneParser struct {
sub *ZoneParser sub *ZoneParser
osFile *os.File osFile *os.File
com string
includeDepth uint8 includeDepth uint8
includeAllowed bool includeAllowed bool
@ -318,12 +315,19 @@ func (zp *ZoneParser) setParseError(err string, l lex) (RR, bool) {
// Comment returns an optional text comment that occurred alongside // Comment returns an optional text comment that occurred alongside
// the RR. // the RR.
func (zp *ZoneParser) Comment() string { func (zp *ZoneParser) Comment() string {
return zp.com if zp.parseErr != nil {
return ""
}
if zp.sub != nil {
return zp.sub.Comment()
}
return zp.c.Comment()
} }
func (zp *ZoneParser) subNext() (RR, bool) { func (zp *ZoneParser) subNext() (RR, bool) {
if rr, ok := zp.sub.Next(); ok { if rr, ok := zp.sub.Next(); ok {
zp.com = zp.sub.com
return rr, true return rr, true
} }
@ -347,8 +351,6 @@ func (zp *ZoneParser) subNext() (RR, bool) {
// error. After Next returns (nil, false), the Err method will return // error. After Next returns (nil, false), the Err method will return
// any error that occurred during parsing. // any error that occurred during parsing.
func (zp *ZoneParser) Next() (RR, bool) { func (zp *ZoneParser) Next() (RR, bool) {
zp.com = ""
if zp.parseErr != nil { if zp.parseErr != nil {
return nil, false return nil, false
} }
@ -501,7 +503,7 @@ func (zp *ZoneParser) Next() (RR, bool) {
return zp.setParseError("expecting $TTL value, not this...", l) return zp.setParseError("expecting $TTL value, not this...", l)
} }
if e, _ := slurpRemainder(zp.c, zp.file); e != nil { if e := slurpRemainder(zp.c, zp.file); e != nil {
zp.parseErr = e zp.parseErr = e
return nil, false return nil, false
} }
@ -525,7 +527,7 @@ func (zp *ZoneParser) Next() (RR, bool) {
return zp.setParseError("expecting $ORIGIN value, not this...", l) return zp.setParseError("expecting $ORIGIN value, not this...", l)
} }
if e, _ := slurpRemainder(zp.c, zp.file); e != nil { if e := slurpRemainder(zp.c, zp.file); e != nil {
zp.parseErr = e zp.parseErr = e
return nil, false return nil, false
} }
@ -648,7 +650,7 @@ func (zp *ZoneParser) Next() (RR, bool) {
st = zExpectRdata st = zExpectRdata
case zExpectRdata: case zExpectRdata:
r, e, c1 := setRR(*h, zp.c, zp.origin, zp.file) r, e := setRR(*h, zp.c, zp.origin, zp.file)
if e != nil { if e != nil {
// If e.lex is nil than we have encounter a unknown RR type // If e.lex is nil than we have encounter a unknown RR type
// in that case we substitute our current lex token // in that case we substitute our current lex token
@ -660,7 +662,6 @@ func (zp *ZoneParser) Next() (RR, bool) {
return nil, false return nil, false
} }
zp.com = c1
return r, true return r, true
} }
} }
@ -678,7 +679,8 @@ type zlexer struct {
line int line int
column int column int
com string comBuf string
comment string
l lex l lex
@ -767,14 +769,15 @@ func (zl *zlexer) Next() (lex, bool) {
escape bool escape bool
) )
if zl.com != "" { if zl.comBuf != "" {
comi = copy(com[:], zl.com) comi = copy(com[:], zl.comBuf)
zl.com = "" zl.comBuf = ""
} }
zl.comment = ""
for x, ok := zl.readByte(); ok; x, ok = zl.readByte() { for x, ok := zl.readByte(); ok; x, ok = zl.readByte() {
l.line, l.column = zl.line, zl.column l.line, l.column = zl.line, zl.column
l.comment = ""
if stri >= len(str) { if stri >= len(str) {
l.token = "token length insufficient for parsing" l.token = "token length insufficient for parsing"
@ -898,7 +901,7 @@ func (zl *zlexer) Next() (lex, bool) {
} }
zl.commt = true zl.commt = true
zl.com = "" zl.comBuf = ""
if comi > 1 { if comi > 1 {
// A newline was previously seen inside a comment that // A newline was previously seen inside a comment that
@ -911,7 +914,7 @@ func (zl *zlexer) Next() (lex, bool) {
comi++ comi++
if stri > 0 { if stri > 0 {
zl.com = string(com[:comi]) zl.comBuf = string(com[:comi])
l.value = zString l.value = zString
l.token = string(str[:stri]) l.token = string(str[:stri])
@ -947,11 +950,11 @@ func (zl *zlexer) Next() (lex, bool) {
l.value = zNewline l.value = zNewline
l.token = "\n" l.token = "\n"
l.comment = string(com[:comi]) zl.comment = string(com[:comi])
return *l, true return *l, true
} }
zl.com = string(com[:comi]) zl.comBuf = string(com[:comi])
break break
} }
@ -977,9 +980,9 @@ func (zl *zlexer) Next() (lex, bool) {
l.value = zNewline l.value = zNewline
l.token = "\n" l.token = "\n"
l.comment = zl.com
zl.com = "" zl.comment = zl.comBuf
zl.comBuf = ""
zl.rrtype = false zl.rrtype = false
zl.owner = true zl.owner = true
@ -1115,7 +1118,7 @@ func (zl *zlexer) Next() (lex, bool) {
// Send remainder of com // Send remainder of com
l.value = zNewline l.value = zNewline
l.token = "\n" l.token = "\n"
l.comment = string(com[:comi]) zl.comment = string(com[:comi])
if retL != (lex{}) { if retL != (lex{}) {
zl.nextL = true zl.nextL = true
@ -1126,7 +1129,6 @@ func (zl *zlexer) Next() (lex, bool) {
} }
if zl.brace != 0 { if zl.brace != 0 {
l.comment = "" // in case there was left over string and comment
l.token = "unbalanced brace" l.token = "unbalanced brace"
l.err = true l.err = true
return *l, true return *l, true
@ -1135,6 +1137,14 @@ func (zl *zlexer) Next() (lex, bool) {
return lex{value: zEOF}, false return lex{value: zEOF}, false
} }
func (zl *zlexer) Comment() string {
if zl.l.err {
return ""
}
return zl.comment
}
// Extract the class number from CLASSxx // Extract the class number from CLASSxx
func classToInt(token string) (uint16, bool) { func classToInt(token string) (uint16, bool) {
offset := 5 offset := 5
@ -1292,24 +1302,21 @@ func locCheckEast(token string, longitude uint32) (uint32, bool) {
return longitude, false return longitude, false
} }
// "Eat" the rest of the "line". Return potential comments // "Eat" the rest of the "line"
func slurpRemainder(c *zlexer, f string) (*ParseError, string) { func slurpRemainder(c *zlexer, f string) *ParseError {
l, _ := c.Next() l, _ := c.Next()
com := ""
switch l.value { switch l.value {
case zBlank: case zBlank:
l, _ = c.Next() l, _ = c.Next()
com = l.comment
if l.value != zNewline && l.value != zEOF { if l.value != zNewline && l.value != zEOF {
return &ParseError{f, "garbage after rdata", l}, "" return &ParseError{f, "garbage after rdata", l}
} }
case zNewline: case zNewline:
com = l.comment
case zEOF: case zEOF:
default: default:
return &ParseError{f, "garbage after rdata", l}, "" return &ParseError{f, "garbage after rdata", l}
} }
return nil, com return nil
} }
// Parse a 64 bit-like ipv6 address: "0014:4fff:ff20:ee64" // Parse a 64 bit-like ipv6 address: "0014:4fff:ff20:ee64"

File diff suppressed because it is too large Load Diff