From fa0d78db9e5f54028972d635b5e7f0865b5219f0 Mon Sep 17 00:00:00 2001 From: Miek Gieben Date: Wed, 4 Jan 2012 21:31:11 +0100 Subject: [PATCH] partially working code --- zscan.go | 171 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 93 insertions(+), 78 deletions(-) diff --git a/zscan.go b/zscan.go index 5f712183..7970656c 100644 --- a/zscan.go +++ b/zscan.go @@ -5,11 +5,10 @@ import ( "io" "strconv" "strings" - "text/scanner" ) // Only used when debugging the parser itself. -var _DEBUG = false +var _DEBUG = true // Tokinize a RFC 1035 zone file. The tokenizer will normalize it: // * Add ownernames if they are left blank; @@ -84,9 +83,9 @@ type Token struct { func NewRR(s string) (RR, error) { t := make(chan Token) if s[len(s)-1] != '\n' { // We need a closing newline - t = ParseZone(strings.NewReader(s+"\n")) + t = ParseZone(strings.NewReader(s + "\n")) } else { - t= ParseZone(strings.NewReader(s)) + t = ParseZone(strings.NewReader(s)) } r := <-t if r.Error != nil { @@ -97,21 +96,17 @@ func NewRR(s string) (RR, error) { // ParseZone reads a RFC 1035 zone from r. It returns each parsed RR or on error // on the returned channel. The channel t is closed by ParseZone when the end of r is reached. -func ParseZone(r io.Reader) (chan Token) { - t := make(chan Token) - go parseZone(r, t) - return t +func ParseZone(r io.Reader) chan Token { + t := make(chan Token) + go parseZone(r, t) + return t } func parseZone(r io.Reader, t chan Token) { defer close(t) - var s scanner.Scanner c := make(chan lex) - s.Init(r) - s.Mode = 0 - s.Whitespace = 0 // Start the lexer - go zlexer(s, c) + go zlexer(r, c) // 5 possible beginnings of a line, _ is a space // 1. _OWNER _ _RRTYPE -> class/ttl omitted // 2. _OWNER _ _STRING _ _RRTYPE -> class omitted @@ -291,9 +286,9 @@ func (l lex) String() string { } // zlexer scans the sourcefile and returns tokens on the channel c. -func zlexer(s scanner.Scanner, c chan lex) { +func zlexer(r io.Reader, c chan lex) { var l lex - str := "" // Hold the current read text + defer close(c) quote := false escape := false space := false @@ -301,35 +296,39 @@ func zlexer(s scanner.Scanner, c chan lex) { rrtype := false owner := true brace := 0 - 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 { - case " ", "\t": - escape = false + p, q := 0, 0 + buf := make([]byte, 4096) + n, err := r.Read(buf) + for err != io.EOF { + l.column = 0 + l.line = 0 + switch buf[q] { + case ' ', '\t': + escape = false if commt { + p++ break } - if str == "" { + if p == q { //l.value = _BLANK //l.token = " " } else if owner { // If we have a string and its the first, make it an owner l.value = _OWNER - l.token = str - // escape $... start with a \ not a $, so this will work - if str == "$TTL" { + println(p, q) + l.token = string(buf[p:q]) + // escape $... start with a \ not a $, so this will work + if l.token == "$TTL" { l.value = _DIRTTL } - if str == "$ORIGIN" { + if l.token == "$ORIGIN" { l.value = _DIRORIGIN } c <- l + p = q + 1 } else { l.value = _STRING - l.token = str + l.token = string(buf[p:q]) if !rrtype { if _, ok := Str_rr[strings.ToUpper(l.token)]; ok { @@ -341,47 +340,52 @@ func zlexer(s scanner.Scanner, c chan lex) { } } c <- l + p = q + 1 } - str = "" if !space && !commt { l.value = _BLANK l.token = " " c <- l + p = q + 1 + } + if space || commt { + p++ } owner = false space = true - case ";": - if escape { - escape = false - str += ";" - break - } - if quote { - // Inside quoted text we allow ; - str += ";" + println("upping", p, q) + case ';': + if escape { + escape = false break } + if quote { + // Inside quoted text we allow ; + break + } + p++ commt = true - case "\n": - // Hmmm, escape newline - escape = false + case '\n': + // Hmmm, escape newline + escape = false if commt { // Reset a comment commt = false rrtype = false - str = "" + p++ // If not in a brace this ends the comment AND the RR if brace == 0 { owner = true l.value = _NEWLINE l.token = "\n" c <- l + p = q + 1 } break } - if str != "" { + if p != q { l.value = _STRING - l.token = str + l.token = string(buf[p:q]) if !rrtype { if _, ok := Str_rr[strings.ToUpper(l.token)]; ok { l.value = _RRTYPE @@ -389,89 +393,100 @@ func zlexer(s scanner.Scanner, c chan lex) { } } c <- l + p = q + 1 } if brace > 0 { l.value = _BLANK - l.token = " " + p++ if !space { c <- l + p = q + 1 } } else { l.value = _NEWLINE l.token = "\n" c <- l + p = q + 1 } if l.value == _BLANK { space = true } - str = "" + p = q + 1 + println("hallo") commt = false rrtype = false owner = true - case "\\": + case '\\': if commt { + p++ + break + } + if escape { + escape = false break } - if escape { - str += "\\" - escape = false - break - } escape = true - case "\"": + case '"': if commt { + p++ + break + } + if escape { + escape = false break } - if escape { - str += "\"" - escape = false - break - } - // str += "\"" don't add quoted quotes quote = !quote - case "(": + case '(': if commt { + p++ + break + } + if escape { + escape = false break } - if escape { - str += "(" - escape = false - break - } brace++ - case ")": + case ')': if commt { + p++ + break + } + if escape { + escape = false break } - if escape { - str += ")" - escape = false - break - } brace-- if brace < 0 { l.err = "Extra closing brace" c <- l + p = q + 1 return } default: if commt { + p++ break } - escape = false - str += x + escape = false space = false } - tok = s.Scan() + // tok, err = r.ReadByte() read extra bytes + q++ + if q > n { + break + } } - // Hmm. - if len(str) > 0 { + println("We crashen gewoon hier", p, q) + // It this need anymore??? + /* + if p != q { // Send remainder - l.token = str + l.token = string(buf[p:q]) l.value = _STRING c <- l } + */ } func stringToTtl(l lex, t chan Token) (uint32, bool) {