2011-12-16 03:38:14 +11:00
|
|
|
package dns
|
|
|
|
|
|
|
|
import (
|
|
|
|
"io"
|
|
|
|
"text/scanner"
|
|
|
|
)
|
|
|
|
|
|
|
|
// 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 ParseKey(r io.Reader) (map[string]string, error) {
|
|
|
|
var s scanner.Scanner
|
2011-12-17 00:48:30 +11:00
|
|
|
m := make(map[string]string)
|
2011-12-16 03:38:14 +11:00
|
|
|
c := make(chan Lex)
|
2011-12-17 00:48:30 +11:00
|
|
|
k := ""
|
2011-12-16 03:38:14 +11:00
|
|
|
s.Init(r)
|
|
|
|
s.Mode = 0
|
|
|
|
s.Whitespace = 0
|
|
|
|
// Start the lexer
|
|
|
|
go klexer(s, c)
|
|
|
|
for l := range c {
|
2011-12-17 00:48:30 +11:00
|
|
|
// It should alternate
|
2011-12-16 03:38:14 +11:00
|
|
|
switch l.value {
|
|
|
|
case _KEY:
|
2011-12-17 00:48:30 +11:00
|
|
|
k = l.token
|
2011-12-16 03:38:14 +11:00
|
|
|
case _VALUE:
|
2011-12-17 01:06:24 +11:00
|
|
|
if k == "" {
|
|
|
|
return nil, &ParseError{"No key seen", l}
|
|
|
|
}
|
2011-12-17 00:48:30 +11:00
|
|
|
m[k] = l.token
|
2011-12-17 01:06:24 +11:00
|
|
|
k = ""
|
2011-12-16 03:38:14 +11:00
|
|
|
}
|
|
|
|
}
|
2011-12-17 00:48:30 +11:00
|
|
|
return m, nil
|
2011-12-16 03:38:14 +11:00
|
|
|
}
|
|
|
|
|
|
|
|
// klexer scans the sourcefile and returns tokens on the channel c.
|
|
|
|
func klexer(s scanner.Scanner, c chan Lex) {
|
|
|
|
var l Lex
|
|
|
|
str := "" // Hold the current read text
|
|
|
|
commt := false
|
2011-12-17 00:48:30 +11:00
|
|
|
key := true
|
2011-12-16 03:38:14 +11:00
|
|
|
tok := s.Scan()
|
|
|
|
defer close(c)
|
|
|
|
for tok != scanner.EOF {
|
|
|
|
l.column = s.Position.Column
|
|
|
|
l.line = s.Position.Line
|
|
|
|
switch x := s.TokenText(); x {
|
2011-12-17 00:48:30 +11:00
|
|
|
case ":":
|
2011-12-16 03:38:14 +11:00
|
|
|
if commt {
|
|
|
|
break
|
|
|
|
}
|
2011-12-17 00:48:30 +11:00
|
|
|
if key {
|
|
|
|
l.value = _KEY
|
|
|
|
c <- l
|
|
|
|
key = false
|
|
|
|
} else {
|
|
|
|
l.value = _VALUE
|
|
|
|
}
|
2011-12-16 03:38:14 +11:00
|
|
|
case ";":
|
|
|
|
commt = true
|
|
|
|
case "\n":
|
|
|
|
if commt {
|
|
|
|
// Reset a comment
|
|
|
|
commt = false
|
|
|
|
}
|
2011-12-17 00:48:30 +11:00
|
|
|
c <- l
|
2011-12-16 03:38:14 +11:00
|
|
|
str = ""
|
|
|
|
commt = false
|
2011-12-17 00:48:30 +11:00
|
|
|
key = true
|
2011-12-16 03:38:14 +11:00
|
|
|
default:
|
|
|
|
if commt {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
str += x
|
|
|
|
}
|
|
|
|
tok = s.Scan()
|
|
|
|
}
|
|
|
|
}
|