diff options
| author | Kyle Consalus <consalus@gmail.com> | 2010-03-23 13:20:16 -0700 | 
|---|---|---|
| committer | Kyle Consalus <consalus@gmail.com> | 2010-03-23 13:20:16 -0700 | 
| commit | 170e3c7485a845ba729e8d158abb3770507958b9 (patch) | |
| tree | d3994a61aefaacee4bf3fff1c0ef9df85786ccfb /src/pkg/xml/xml.go | |
| parent | 55df7f0002cd12a7e9e95ea38b83bdd73443af87 (diff) | |
| download | golang-170e3c7485a845ba729e8d158abb3770507958b9.tar.gz | |
xml: add line numbers to syntax errors.
R=rsc
CC=golang-dev
http://codereview.appspot.com/699041
Committer: Russ Cox <rsc@golang.org>
Diffstat (limited to 'src/pkg/xml/xml.go')
| -rw-r--r-- | src/pkg/xml/xml.go | 55 | 
1 files changed, 32 insertions, 23 deletions
| diff --git a/src/pkg/xml/xml.go b/src/pkg/xml/xml.go index 0d4729dda..796dce582 100644 --- a/src/pkg/xml/xml.go +++ b/src/pkg/xml/xml.go @@ -12,7 +12,6 @@ package xml  // TODO(rsc):  //	Test error handling. -//	Expose parser line number in errors.  import (  	"bufio" @@ -26,9 +25,14 @@ import (  )  // A SyntaxError represents a syntax error in the XML input stream. -type SyntaxError string +type SyntaxError struct { +	Msg  string +	Line int +} -func (e SyntaxError) String() string { return "XML syntax error: " + string(e) } +func (e *SyntaxError) String() string { +	return "XML syntax error on line " + strconv.Itoa(e.Line) + ": " + e.Msg +}  // A Name represents an XML name (Local) annotated  // with a name space identifier (Space). @@ -344,6 +348,11 @@ func (p *Parser) pushNs(local string, url string, ok bool) {  	s.ok = ok  } +// Creates a SyntaxError with the current line number. +func (p *Parser) syntaxError(msg string) os.Error { +	return &SyntaxError{Msg: msg, Line: p.line} +} +  // Record that we are ending an element with the given name.  // The name must match the record at the top of the stack,  // which must be a pushElement record. @@ -355,7 +364,7 @@ func (p *Parser) popElement(t *EndElement) bool {  	name := t.Name  	switch {  	case s == nil || s.kind != stkStart: -		p.err = SyntaxError("unexpected end element </" + name.Local + ">") +		p.err = p.syntaxError("unexpected end element </" + name.Local + ">")  		return false  	case s.name.Local != name.Local:  		if !p.Strict { @@ -364,10 +373,10 @@ func (p *Parser) popElement(t *EndElement) bool {  			t.Name = s.name  			return true  		} -		p.err = SyntaxError("element <" + s.name.Local + "> closed by </" + name.Local + ">") +		p.err = p.syntaxError("element <" + s.name.Local + "> closed by </" + name.Local + ">")  		return false  	case s.name.Space != name.Space: -		p.err = SyntaxError("element <" + s.name.Local + "> in space " + s.name.Space + +		p.err = p.syntaxError("element <" + s.name.Local + "> in space " + s.name.Space +  			"closed by </" + name.Local + "> in space " + name.Space)  		return false  	} @@ -442,7 +451,7 @@ func (p *Parser) RawToken() (Token, os.Error) {  		var name Name  		if name, ok = p.nsname(); !ok {  			if p.err == nil { -				p.err = SyntaxError("expected element name after </") +				p.err = p.syntaxError("expected element name after </")  			}  			return nil, p.err  		} @@ -451,7 +460,7 @@ func (p *Parser) RawToken() (Token, os.Error) {  			return nil, p.err  		}  		if b != '>' { -			p.err = SyntaxError("invalid characters between </" + name.Local + " and >") +			p.err = p.syntaxError("invalid characters between </" + name.Local + " and >")  			return nil, p.err  		}  		return EndElement{name}, nil @@ -463,7 +472,7 @@ func (p *Parser) RawToken() (Token, os.Error) {  		var target string  		if target, ok = p.name(); !ok {  			if p.err == nil { -				p.err = SyntaxError("expected target name after <?") +				p.err = p.syntaxError("expected target name after <?")  			}  			return nil, p.err  		} @@ -496,7 +505,7 @@ func (p *Parser) RawToken() (Token, os.Error) {  				return nil, p.err  			}  			if b != '-' { -				p.err = SyntaxError("invalid sequence <!- not part of <!--") +				p.err = p.syntaxError("invalid sequence <!- not part of <!--")  				return nil, p.err  			}  			// Look for terminator. @@ -523,7 +532,7 @@ func (p *Parser) RawToken() (Token, os.Error) {  					return nil, p.err  				}  				if b != "CDATA["[i] { -					p.err = SyntaxError("invalid <![ sequence") +					p.err = p.syntaxError("invalid <![ sequence")  					return nil, p.err  				}  			} @@ -561,7 +570,7 @@ func (p *Parser) RawToken() (Token, os.Error) {  	)  	if name, ok = p.nsname(); !ok {  		if p.err == nil { -			p.err = SyntaxError("expected element name after <") +			p.err = p.syntaxError("expected element name after <")  		}  		return nil, p.err  	} @@ -578,7 +587,7 @@ func (p *Parser) RawToken() (Token, os.Error) {  				return nil, p.err  			}  			if b != '>' { -				p.err = SyntaxError("expected /> in element") +				p.err = p.syntaxError("expected /> in element")  				return nil, p.err  			}  			break @@ -600,7 +609,7 @@ func (p *Parser) RawToken() (Token, os.Error) {  		a := &attr[n]  		if a.Name, ok = p.nsname(); !ok {  			if p.err == nil { -				p.err = SyntaxError("expected attribute name in element") +				p.err = p.syntaxError("expected attribute name in element")  			}  			return nil, p.err  		} @@ -609,7 +618,7 @@ func (p *Parser) RawToken() (Token, os.Error) {  			return nil, p.err  		}  		if b != '=' { -			p.err = SyntaxError("attribute name without = in element") +			p.err = p.syntaxError("attribute name without = in element")  			return nil, p.err  		}  		p.space() @@ -638,7 +647,7 @@ func (p *Parser) attrval() []byte {  	}  	// Handle unquoted attribute values for strict parsers  	if p.Strict { -		p.err = SyntaxError("unquoted or missing attribute value in element") +		p.err = p.syntaxError("unquoted or missing attribute value in element")  		return nil  	}  	// Handle unquoted attribute values for unstrict parsers @@ -707,7 +716,7 @@ func (p *Parser) getc() (b byte, ok bool) {  func (p *Parser) mustgetc() (b byte, ok bool) {  	if b, ok = p.getc(); !ok {  		if p.err == os.EOF { -			p.err = SyntaxError("unexpected EOF") +			p.err = p.syntaxError("unexpected EOF")  		}  	}  	return @@ -751,14 +760,14 @@ Input:  				trunc = 2  				break Input  			} -			p.err = SyntaxError("unescaped ]]> not in CDATA section") +			p.err = p.syntaxError("unescaped ]]> not in CDATA section")  			return nil  		}  		// Stop reading text if we see a <.  		if b == '<' && !cdata {  			if quote >= 0 { -				p.err = SyntaxError("unescaped < inside quoted string") +				p.err = p.syntaxError("unescaped < inside quoted string")  				return nil  			}  			p.ungetc('<') @@ -779,7 +788,7 @@ Input:  				p.tmp[i], p.err = p.r.ReadByte()  				if p.err != nil {  					if p.err == os.EOF { -						p.err = SyntaxError("unexpected EOF") +						p.err = p.syntaxError("unexpected EOF")  					}  					return nil  				} @@ -804,7 +813,7 @@ Input:  					p.buf.Write(p.tmp[0:i])  					continue Input  				} -				p.err = SyntaxError("character entity expression &" + s + "... too long") +				p.err = p.syntaxError("character entity expression &" + s + "... too long")  				return nil  			}  			var haveText bool @@ -836,7 +845,7 @@ Input:  					p.buf.Write(p.tmp[0:i])  					continue Input  				} -				p.err = SyntaxError("invalid character entity &" + s + ";") +				p.err = p.syntaxError("invalid character entity &" + s + ";")  				return nil  			}  			p.buf.Write([]byte(text)) @@ -913,7 +922,7 @@ func (p *Parser) name() (s string, ok bool) {  	s = p.buf.String()  	for i, c := range s {  		if !unicode.Is(first, c) && (i == 0 || !unicode.Is(second, c)) { -			p.err = SyntaxError("invalid XML name: " + s) +			p.err = p.syntaxError("invalid XML name: " + s)  			return "", false  		}  	} | 
