X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Ftextparser.cpp;h=f7c830d0030ebcf5428c3c0abf06c63ba043ce60;hb=e26f7e98e5d8a5666192a43348b3ca7a35f6b860;hp=298b7cac363ebd2b75a712b2ea41d18dd17b3801;hpb=27630d44298cb67e075c166f4421288cc8ca117e;p=libs%2Fdatafile.git diff --git a/source/textparser.cpp b/source/textparser.cpp index 298b7ca..f7c830d 100644 --- a/source/textparser.cpp +++ b/source/textparser.cpp @@ -6,6 +6,7 @@ Distributed under the LGPL */ #include +#include #include "input.h" #include "textparser.h" #include "token.h" @@ -103,10 +104,10 @@ Statement TextParser::parse_statement(const Token *t) Token TextParser::parse_token() { int c=0; - unsigned comment=0; + int comment=0; // Skip over comments and whitespace - while(in) + while(in && comment>=0) { c=in.get(); int next=in.peek(); @@ -122,11 +123,13 @@ Token TextParser::parse_token() else if(comment==3) // Skip the second character of block comment end comment=0; else if(!isspace(c) && !comment) - break; + comment=-1; } - if(comment) // Didn't hit any non-whitespace + if(comment>0) // EOF while in comment throw ParseError(src+": Unfinished comment at end of input", src, in.get_line_number()); + else if(comment==0) // Didn't hit any non-whitespace + return Token(Token::SPECIAL, ""); enum ParseState { @@ -166,7 +169,7 @@ Token TextParser::parse_token() string buf; bool escape=false; - while(in) + while(in || state==INIT) { if(state!=INIT) c=in.get(); @@ -266,7 +269,16 @@ Token TextParser::parse_token() if(c=='\\') escape=!escape; else if(c=='"' && !escape) - return Token(Token::STRING, unescape_string(buf)); + { + try + { + return Token(Token::STRING, c_unescape(buf.substr(1, buf.size()-2))); + } + catch(const Exception &e) + { + throw ParseError(format("%s: %s", get_location(), e.what()), src, in.get_line_number()); + } + } else escape=false; break; @@ -297,57 +309,6 @@ bool TextParser::isodigit(int c) return (c>='0' && c<='7'); } -string TextParser::unescape_string(const string &str) -{ - string result; - bool escape=false; - unsigned hexcape=0; - for(string::const_iterator i=str.begin()+1; i!=str.end()-1; ++i) - { - if(escape) - { - if(*i=='n') - result+='\n'; - else if(*i=='t') - result+='\t'; - else if(*i=='\\') - result+='\\'; - else if(*i=='"') - result+='"'; - else if(*i=='x') - hexcape=0x100; - else - throw ParseError(format("%s: Invalid escape sequence '\\%c'", get_location(), *i), src, in.get_line_number()); - escape=false; - } - else if(hexcape) - { - unsigned digit=0; - if(*i>='0' && *i<='9') - digit=*i-'0'; - else if(*i>='a' && *i<='f') - digit=*i-'a'+10; - else if(*i>='A' && *i<='F') - digit=*i-'A'+10; - else - throw ParseError(get_location()+": Invalid hex digit", src, in.get_line_number()); - - hexcape=(hexcape<<4)|digit; - if(hexcape&0x10000) - { - result+=hexcape&0xFF; - hexcape=0; - } - } - else if(*i=='\\') - escape=true; - else - result+=*i; - } - - return result; -} - string TextParser::get_location() { ostringstream ss;