Implement returning errors from the scanner
This commit is contained in:
parent
c6deba77e0
commit
06ae052c32
2
dns.go
2
dns.go
|
@ -154,7 +154,7 @@ func (s RRset) Ok() bool {
|
|||
type Exchange struct {
|
||||
Request *Msg // The question sent.
|
||||
Reply *Msg // The answer to the question that was sent.
|
||||
Error error // If something when wrong, this contains the error.
|
||||
ErrorMsg error // If something when wrong, this contains the error.
|
||||
}
|
||||
|
||||
// DNS resource records.
|
||||
|
|
|
@ -122,7 +122,7 @@ func TestParse(t *testing.T) {
|
|||
t.Logf("`%s' should be equal to\n`%s', but is `%s'\n", i, o, rr.String())
|
||||
t.Fail()
|
||||
} else {
|
||||
t.Logf("RR is %s", rr.String())
|
||||
t.Logf("RR is OK: `%s'", rr.String())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
82
zscan.go
82
zscan.go
|
@ -61,26 +61,34 @@ type Lex struct {
|
|||
column int // column in the fil
|
||||
}
|
||||
|
||||
type Token struct {
|
||||
Rr RR // the scanned resource record
|
||||
Err *ParseError // when an error occured, this is the specifics
|
||||
}
|
||||
|
||||
// NewRR parses the string s and returns the RR contained in there. If the string
|
||||
// contains more than one RR, only the first is returned. If an error is detected
|
||||
// an error is returned.
|
||||
// that error error is returned.
|
||||
// If the class is not specified, the IN class is assumed. If the TTL is not
|
||||
// specified DefaultTtl is assumed.
|
||||
func NewRR(s string) (RR, error) {
|
||||
cr := make(chan RR)
|
||||
t := make(chan Token)
|
||||
if s[len(s)-1] != '\n' { // We need a closing newline
|
||||
go ParseZone(strings.NewReader(s+"\n"), cr)
|
||||
go ParseZone(strings.NewReader(s+"\n"), t)
|
||||
} else {
|
||||
go ParseZone(strings.NewReader(s), cr)
|
||||
go ParseZone(strings.NewReader(s), t)
|
||||
}
|
||||
r := <-cr // There are no error send as of yet
|
||||
return r, nil // Todo: errors
|
||||
r := <-t
|
||||
if r.Err != nil {
|
||||
return nil, r.Err
|
||||
}
|
||||
return r.Rr, nil
|
||||
}
|
||||
|
||||
// ParseZone reads a RFC 1035 zone from r. It returns each parsed RR on the
|
||||
// channel cr. The channel cr is closed by ParseZone when the end of r is reached.
|
||||
func ParseZone(r io.Reader, cr chan RR) {
|
||||
defer close(cr)
|
||||
// ParseZone reads a RFC 1035 zone from r. It returns each parsed RR or on error
|
||||
// on the channel t. The channel t is closed by ParseZone when the end of r is reached.
|
||||
func ParseZone(r io.Reader, t chan Token) {
|
||||
defer close(t)
|
||||
var s scanner.Scanner
|
||||
c := make(chan Lex)
|
||||
s.Init(r)
|
||||
|
@ -105,9 +113,9 @@ func ParseZone(r io.Reader, cr chan RR) {
|
|||
}
|
||||
switch st {
|
||||
case _EXPECT_OWNER:
|
||||
// Set the defaults here
|
||||
h.Ttl = DefaultTtl
|
||||
h.Class = ClassINET
|
||||
// Set the defaults here
|
||||
h.Ttl = DefaultTtl
|
||||
h.Class = ClassINET
|
||||
switch l.value {
|
||||
case _NEWLINE: // Empty line
|
||||
st = _EXPECT_OWNER
|
||||
|
@ -115,12 +123,14 @@ func ParseZone(r io.Reader, cr chan RR) {
|
|||
h.Name = l.token
|
||||
st = _EXPECT_OWNER_BL
|
||||
default:
|
||||
fmt.Printf("%s\n", &ParseError{"Error at the start", l})
|
||||
st = _EXPECT_OWNER
|
||||
t <- Token{Err: &ParseError{"Error at the start", l}}
|
||||
return
|
||||
//st = _EXPECT_OWNER
|
||||
}
|
||||
case _EXPECT_OWNER_BL:
|
||||
if l.value != _BLANK {
|
||||
fmt.Printf("%s\n", &ParseError{"No blank after owner", l})
|
||||
t <- Token{Err: &ParseError{"No blank after owner", l}}
|
||||
return
|
||||
}
|
||||
st = _EXPECT_ANY
|
||||
case _EXPECT_ANY:
|
||||
|
@ -131,28 +141,33 @@ func ParseZone(r io.Reader, cr chan RR) {
|
|||
case _CLASS:
|
||||
h.Class, ok = Str_class[strings.ToUpper(l.token)]
|
||||
if !ok {
|
||||
fmt.Printf("%s\n", &ParseError{"Unknown class", l})
|
||||
t <- Token{Err: &ParseError{"Unknown class", l}}
|
||||
return
|
||||
}
|
||||
st = _EXPECT_ANY_NOCLASS_BL
|
||||
case _STRING: // TTL is this case
|
||||
ttl, ok := strconv.Atoi(l.token)
|
||||
if ok != nil {
|
||||
fmt.Printf("%s\n", &ParseError{"Not a TTL", l})
|
||||
t <- Token{Err: &ParseError{"Not a TTL", l}}
|
||||
return
|
||||
} else {
|
||||
h.Ttl = uint32(ttl)
|
||||
}
|
||||
st = _EXPECT_ANY_NOTTL_BL
|
||||
default:
|
||||
fmt.Printf("%s\n", &ParseError{"Expecting RR type, TTL or class, not this...", l})
|
||||
t <- Token{Err: &ParseError{"Expecting RR type, TTL or class, not this...", l}}
|
||||
return
|
||||
}
|
||||
case _EXPECT_ANY_NOCLASS_BL:
|
||||
if l.value != _BLANK {
|
||||
fmt.Printf("%s\n", &ParseError{"No blank before NOCLASS", l})
|
||||
t <- Token{Err: &ParseError{"No blank before NOCLASS", l}}
|
||||
return
|
||||
}
|
||||
st = _EXPECT_ANY_NOCLASS
|
||||
case _EXPECT_ANY_NOTTL_BL:
|
||||
if l.value != _BLANK {
|
||||
fmt.Printf("%s\n", &ParseError{"No blank before NOTTL", l})
|
||||
t <- Token{Err: &ParseError{"No blank before NOTTL", l}}
|
||||
return
|
||||
}
|
||||
st = _EXPECT_ANY_NOTTL
|
||||
case _EXPECT_ANY_NOTTL:
|
||||
|
@ -160,7 +175,8 @@ func ParseZone(r io.Reader, cr chan RR) {
|
|||
case _CLASS:
|
||||
h.Class, ok = Str_class[strings.ToUpper(l.token)]
|
||||
if !ok {
|
||||
fmt.Printf("%s\n", &ParseError{"Unknown class", l})
|
||||
t <- Token{Err: &ParseError{"Unknown class", l}}
|
||||
return
|
||||
}
|
||||
st = _EXPECT_RRTYPE_BL
|
||||
case _RRTYPE:
|
||||
|
@ -172,7 +188,8 @@ func ParseZone(r io.Reader, cr chan RR) {
|
|||
case _STRING: // TTL
|
||||
ttl, ok := strconv.Atoi(l.token)
|
||||
if ok != nil {
|
||||
fmt.Printf("%s\n", &ParseError{"Not a TTL", l})
|
||||
t <- Token{Err: &ParseError{"Not a TTL", l}}
|
||||
return
|
||||
} else {
|
||||
h.Ttl = uint32(ttl)
|
||||
}
|
||||
|
@ -181,25 +198,30 @@ func ParseZone(r io.Reader, cr chan RR) {
|
|||
h.Rrtype, _ = Str_rr[strings.ToUpper(l.token)]
|
||||
st = _EXPECT_RDATA
|
||||
default:
|
||||
fmt.Printf("%s\n", &ParseError{"Expecting RR type or TTL, not this...", l})
|
||||
t <- Token{Err: &ParseError{"Expecting RR type or TTL, not this...", l}}
|
||||
return
|
||||
}
|
||||
case _EXPECT_RRTYPE_BL:
|
||||
if l.value != _BLANK {
|
||||
fmt.Printf("%s\n", &ParseError{"No blank after", l})
|
||||
t <- Token{Err: &ParseError{"No blank after", l}}
|
||||
return
|
||||
}
|
||||
st = _EXPECT_RRTYPE
|
||||
case _EXPECT_RRTYPE:
|
||||
if l.value != _RRTYPE {
|
||||
fmt.Printf("%s\n", &ParseError{"Unknown RR type", l})
|
||||
t <- Token{Err: &ParseError{"Unknown RR type", l}}
|
||||
return
|
||||
}
|
||||
h.Rrtype, _ = Str_rr[strings.ToUpper(l.token)]
|
||||
st = _EXPECT_RDATA
|
||||
case _EXPECT_RDATA:
|
||||
// I could save my token here...? l
|
||||
r, e := setRR(h, c)
|
||||
if e != nil {
|
||||
fmt.Printf("%v\n", e)
|
||||
t <- Token{Err: e}
|
||||
return
|
||||
}
|
||||
cr <- r
|
||||
t <- Token{Rr: r}
|
||||
st = _EXPECT_OWNER
|
||||
}
|
||||
}
|
||||
|
@ -330,7 +352,7 @@ func zlexer(s scanner.Scanner, c chan Lex) {
|
|||
}
|
||||
brace--
|
||||
if brace < 0 {
|
||||
fmt.Printf("Error\n")
|
||||
fmt.Printf("%s\n", &ParseError{"Extra closing brace", l})
|
||||
}
|
||||
default:
|
||||
if commt {
|
||||
|
@ -341,6 +363,4 @@ func zlexer(s scanner.Scanner, c chan Lex) {
|
|||
}
|
||||
tok = s.Scan()
|
||||
}
|
||||
// Hmm
|
||||
// fmt.Printf("XX %s XXX", str)
|
||||
}
|
||||
|
|
46
zscan_rr.go
46
zscan_rr.go
|
@ -11,13 +11,11 @@ import (
|
|||
// All data from the channel c is either _STRING or _BLANK.
|
||||
// After the rdata there may come 1 _BLANK and then a _NEWLINE
|
||||
// or immediately a _NEWLINE. If this is not the case we flag
|
||||
// an error: garbage after rdata.
|
||||
// an *ParseError: garbage after rdata.
|
||||
|
||||
func setRR(h RR_Header, c chan Lex) (RR, error) {
|
||||
var (
|
||||
r RR
|
||||
e error
|
||||
)
|
||||
func setRR(h RR_Header, c chan Lex) (RR, *ParseError) {
|
||||
var r RR
|
||||
e := new(ParseError)
|
||||
switch h.Rrtype {
|
||||
case TypeA:
|
||||
r, e = setA(h, c)
|
||||
|
@ -87,7 +85,7 @@ func setRR(h RR_Header, c chan Lex) (RR, error) {
|
|||
return r, e
|
||||
}
|
||||
|
||||
func slurpRemainder(c chan Lex) error {
|
||||
func slurpRemainder(c chan Lex) *ParseError {
|
||||
l := <-c
|
||||
if DEBUG {
|
||||
fmt.Printf("%\v", l)
|
||||
|
@ -112,7 +110,7 @@ func slurpRemainder(c chan Lex) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func setA(h RR_Header, c chan Lex) (RR, error) {
|
||||
func setA(h RR_Header, c chan Lex) (RR, *ParseError) {
|
||||
rr := new(RR_A)
|
||||
rr.Hdr = h
|
||||
|
||||
|
@ -124,7 +122,7 @@ func setA(h RR_Header, c chan Lex) (RR, error) {
|
|||
return rr, nil
|
||||
}
|
||||
|
||||
func setAAAA(h RR_Header, c chan Lex) (RR, error) {
|
||||
func setAAAA(h RR_Header, c chan Lex) (RR, *ParseError) {
|
||||
rr := new(RR_AAAA)
|
||||
rr.Hdr = h
|
||||
|
||||
|
@ -136,7 +134,7 @@ func setAAAA(h RR_Header, c chan Lex) (RR, error) {
|
|||
return rr, nil
|
||||
}
|
||||
|
||||
func setNS(h RR_Header, c chan Lex) (RR, error) {
|
||||
func setNS(h RR_Header, c chan Lex) (RR, *ParseError) {
|
||||
rr := new(RR_NS)
|
||||
rr.Hdr = h
|
||||
|
||||
|
@ -148,7 +146,7 @@ func setNS(h RR_Header, c chan Lex) (RR, error) {
|
|||
return rr, nil
|
||||
}
|
||||
|
||||
func setMX(h RR_Header, c chan Lex) (RR, error) {
|
||||
func setMX(h RR_Header, c chan Lex) (RR, *ParseError) {
|
||||
rr := new(RR_MX)
|
||||
rr.Hdr = h
|
||||
|
||||
|
@ -167,7 +165,7 @@ func setMX(h RR_Header, c chan Lex) (RR, error) {
|
|||
return rr, nil
|
||||
}
|
||||
|
||||
func setCNAME(h RR_Header, c chan Lex) (RR, error) {
|
||||
func setCNAME(h RR_Header, c chan Lex) (RR, *ParseError) {
|
||||
rr := new(RR_CNAME)
|
||||
rr.Hdr = h
|
||||
|
||||
|
@ -179,7 +177,7 @@ func setCNAME(h RR_Header, c chan Lex) (RR, error) {
|
|||
return rr, nil
|
||||
}
|
||||
|
||||
func setSOA(h RR_Header, c chan Lex) (RR, error) {
|
||||
func setSOA(h RR_Header, c chan Lex) (RR, *ParseError) {
|
||||
rr := new(RR_SOA)
|
||||
rr.Hdr = h
|
||||
|
||||
|
@ -198,7 +196,7 @@ func setSOA(h RR_Header, c chan Lex) (RR, error) {
|
|||
<-c // _BLANK
|
||||
|
||||
var j int
|
||||
var e error
|
||||
var e error
|
||||
for i := 0; i < 5; i++ {
|
||||
l = <-c
|
||||
if j, e = strconv.Atoi(l.token); e != nil {
|
||||
|
@ -221,7 +219,7 @@ func setSOA(h RR_Header, c chan Lex) (RR, error) {
|
|||
return rr, nil
|
||||
}
|
||||
|
||||
func setRRSIG(h RR_Header, c chan Lex) (RR, error) {
|
||||
func setRRSIG(h RR_Header, c chan Lex) (RR, *ParseError) {
|
||||
rr := new(RR_RRSIG)
|
||||
rr.Hdr = h
|
||||
l := <-c
|
||||
|
@ -297,7 +295,7 @@ func setRRSIG(h RR_Header, c chan Lex) (RR, error) {
|
|||
return rr, nil
|
||||
}
|
||||
|
||||
func setNSEC(h RR_Header, c chan Lex) (RR, error) {
|
||||
func setNSEC(h RR_Header, c chan Lex) (RR, *ParseError) {
|
||||
rr := new(RR_NSEC)
|
||||
rr.Hdr = h
|
||||
|
||||
|
@ -328,7 +326,7 @@ func setNSEC(h RR_Header, c chan Lex) (RR, error) {
|
|||
return rr, nil
|
||||
}
|
||||
|
||||
func setNSEC3(h RR_Header, c chan Lex) (RR, error) {
|
||||
func setNSEC3(h RR_Header, c chan Lex) (RR, *ParseError) {
|
||||
rr := new(RR_NSEC3)
|
||||
rr.Hdr = h
|
||||
|
||||
|
@ -382,7 +380,7 @@ func setNSEC3(h RR_Header, c chan Lex) (RR, error) {
|
|||
return rr, nil
|
||||
}
|
||||
|
||||
func setDNSKEY(h RR_Header, c chan Lex) (RR, error) {
|
||||
func setDNSKEY(h RR_Header, c chan Lex) (RR, *ParseError) {
|
||||
rr := new(RR_DNSKEY)
|
||||
rr.Hdr = h
|
||||
|
||||
|
@ -424,7 +422,7 @@ func setDNSKEY(h RR_Header, c chan Lex) (RR, error) {
|
|||
}
|
||||
|
||||
/*
|
||||
func setNSEC3PARAM(h RR_Header, c chan Lex) (RR, error) {
|
||||
func setNSEC3PARAM(h RR_Header, c chan Lex) (RR, *ParseError) {
|
||||
rr := new(RR_NSEC3PARAM)
|
||||
rr.Hdr = h
|
||||
rdf := fields(data[mark:p], 4)
|
||||
|
@ -449,7 +447,7 @@ func setNSEC3PARAM(h RR_Header, c chan Lex) (RR, error) {
|
|||
}
|
||||
*/
|
||||
|
||||
func setTXT(h RR_Header, c chan Lex) (RR, error) {
|
||||
func setTXT(h RR_Header, c chan Lex) (RR, *ParseError) {
|
||||
rr := new(RR_TXT)
|
||||
rr.Hdr = h
|
||||
|
||||
|
@ -472,7 +470,7 @@ func setTXT(h RR_Header, c chan Lex) (RR, error) {
|
|||
}
|
||||
|
||||
/*
|
||||
func setDS(h RR_Header, c chan Lex) (RR, error) {
|
||||
func setDS(h RR_Header, c chan Lex) (RR, *ParseError) {
|
||||
rr := new(RR_DS)
|
||||
rr.Hdr = h
|
||||
action setDS {
|
||||
|
@ -503,7 +501,7 @@ func setDS(h RR_Header, c chan Lex) (RR, error) {
|
|||
zp.RR <- rr
|
||||
}
|
||||
|
||||
func setCNAME(h RR_Header, c chan Lex) (RR, error) {
|
||||
func setCNAME(h RR_Header, c chan Lex) (RR, *ParseError) {
|
||||
rr := new(RR_CNAME)
|
||||
rr.Hdr = h
|
||||
action setDLV {
|
||||
|
@ -534,7 +532,7 @@ func setCNAME(h RR_Header, c chan Lex) (RR, error) {
|
|||
zp.RR <- rr
|
||||
}
|
||||
|
||||
func setCNAME(h RR_Header, c chan Lex) (RR, error) {
|
||||
func setCNAME(h RR_Header, c chan Lex) (RR, *ParseError) {
|
||||
rr := new(RR_CNAME)
|
||||
rr.Hdr = h
|
||||
action setTA {
|
||||
|
@ -566,7 +564,7 @@ func setCNAME(h RR_Header, c chan Lex) (RR, error) {
|
|||
}
|
||||
|
||||
|
||||
func setSSHFP(h RR_Header, c chan Lex) (RR, error) {
|
||||
func setSSHFP(h RR_Header, c chan Lex) (RR, *ParseError) {
|
||||
rr := new(RR_CNAME)
|
||||
rr.Hdr = h
|
||||
var (
|
||||
|
|
Loading…
Reference in New Issue