Changeset View
Changeset View
Standalone View
Standalone View
libksieve/parser/lexer.cpp
Show First 20 Lines • Show All 155 Lines • ▼ Show 20 Lines | |||||
#ifndef KDE_USE_FINAL | #ifndef KDE_USE_FINAL | ||||
static inline bool is8Bit( signed char ch ) { | static inline bool is8Bit( signed char ch ) { | ||||
return ch < 0; | return ch < 0; | ||||
} | } | ||||
#endif | #endif | ||||
static QString removeCRLF( const QString & s ) { | static QString removeCRLF( const QString & s ) { | ||||
const bool CRLF = s.endsWith( QLatin1String("\r\n") ); | const bool CRLF = s.endsWith( QLatin1String("\r\n") ); | ||||
const bool LF = !CRLF && s.endsWith( '\n' ); | const bool LF = !CRLF && s.endsWith( QLatin1Char('\n') ); | ||||
const int e = CRLF ? 2 : LF ? 1 : 0 ; // what to chop off at the end | const int e = CRLF ? 2 : LF ? 1 : 0 ; // what to chop off at the end | ||||
return s.left( s.length() - e ); | return s.left( s.length() - e ); | ||||
} | } | ||||
static QString removeDotStuff( const QString & s ) { | static QString removeDotStuff( const QString & s ) { | ||||
return s.startsWith( QLatin1String("..") ) ? s.mid( 1 ) : s ; | return s.startsWith( QLatin1String("..") ) ? s.mid( 1 ) : s ; | ||||
▲ Show 20 Lines • Show All 77 Lines • ▼ Show 20 Lines | Lexer::Token Lexer::Impl::nextToken( QString & result ) { | ||||
case '{': | case '{': | ||||
case '}': | case '}': | ||||
case '[': | case '[': | ||||
case ']': | case ']': | ||||
case '(': | case '(': | ||||
case ')': | case ')': | ||||
case ';': | case ';': | ||||
case ',': // Special | case ',': // Special | ||||
result = *mState.cursor++; | result = QLatin1Char(*mState.cursor++); | ||||
return Special; | return Special; | ||||
case '0': | case '0': | ||||
case '1': | case '1': | ||||
case '2': | case '2': | ||||
case '3': | case '3': | ||||
case '4': | case '4': | ||||
case '5': | case '5': | ||||
case '6': | case '6': | ||||
▲ Show 20 Lines • Show All 129 Lines • ▼ Show 20 Lines | bool Lexer::Impl::parseBracketComment( QString & result, bool reallySave ) { | ||||
const int commentLength = mState.cursor - commentStart - 1; | const int commentLength = mState.cursor - commentStart - 1; | ||||
if ( commentLength > 0 ) { | if ( commentLength > 0 ) { | ||||
if ( !isValidUtf8( commentStart, commentLength ) ) { | if ( !isValidUtf8( commentStart, commentLength ) ) { | ||||
makeError( Error::InvalidUTF8 ); | makeError( Error::InvalidUTF8 ); | ||||
return false; | return false; | ||||
} | } | ||||
if ( reallySave ) { | if ( reallySave ) { | ||||
QString tmp = QString::fromUtf8( commentStart, commentLength ); | QString tmp = QString::fromUtf8( commentStart, commentLength ); | ||||
result += tmp.remove( '\r' ); // get rid of CR in CRLF pairs | result += tmp.remove( QLatin1Char('\r') ); // get rid of CR in CRLF pairs | ||||
} | } | ||||
} | } | ||||
++mState.cursor; // eat '/' | ++mState.cursor; // eat '/' | ||||
return true; | return true; | ||||
} | } | ||||
bool Lexer::Impl::parseComment( QString & result, bool reallySave ) { | bool Lexer::Impl::parseComment( QString & result, bool reallySave ) { | ||||
▲ Show 20 Lines • Show All 87 Lines • ▼ Show 20 Lines | |||||
bool Lexer::Impl::parseNumber( QString & result ) { | bool Lexer::Impl::parseNumber( QString & result ) { | ||||
// number := 1*DIGIT [QUANTIFIER] | // number := 1*DIGIT [QUANTIFIER] | ||||
// QUANTIFIER := "K" / "M" / "G" | // QUANTIFIER := "K" / "M" / "G" | ||||
assert( isdigit( *mState.cursor ) ); | assert( isdigit( *mState.cursor ) ); | ||||
while ( !atEnd() && isdigit( *mState.cursor ) ) | while ( !atEnd() && isdigit( *mState.cursor ) ) | ||||
result += *mState.cursor++; | result += QLatin1Char(*mState.cursor++); | ||||
if ( atEnd() || isDelim( *mState.cursor ) ) | if ( atEnd() || isDelim( *mState.cursor ) ) | ||||
return true; | return true; | ||||
switch ( *mState.cursor ) { | switch ( *mState.cursor ) { | ||||
case 'G': | case 'G': | ||||
case 'g': | case 'g': | ||||
case 'M': | case 'M': | ||||
case 'm': | case 'm': | ||||
case 'K': | case 'K': | ||||
case 'k': | case 'k': | ||||
result += *mState.cursor++; | result += QLatin1Char(*mState.cursor++); | ||||
break; | break; | ||||
default: | default: | ||||
makeIllegalCharError(); | makeIllegalCharError(); | ||||
return false; | return false; | ||||
} | } | ||||
// quantifier found. Check for delimiter: | // quantifier found. Check for delimiter: | ||||
if ( atEnd() || isDelim( *mState.cursor ) ) | if ( atEnd() || isDelim( *mState.cursor ) ) | ||||
▲ Show 20 Lines • Show All 55 Lines • ▼ Show 20 Lines | while ( !atEnd() ) { | ||||
const int lineLength = mState.cursor - oldBeginOfLine; | const int lineLength = mState.cursor - oldBeginOfLine; | ||||
if ( lineLength > 0 ) { | if ( lineLength > 0 ) { | ||||
if ( !isValidUtf8( oldBeginOfLine, lineLength ) ) { | if ( !isValidUtf8( oldBeginOfLine, lineLength ) ) { | ||||
makeError( Error::InvalidUTF8 ); | makeError( Error::InvalidUTF8 ); | ||||
return false; | return false; | ||||
} | } | ||||
const QString line = removeCRLF( QString::fromUtf8( oldBeginOfLine, lineLength ) ); | const QString line = removeCRLF( QString::fromUtf8( oldBeginOfLine, lineLength ) ); | ||||
lines.push_back( removeDotStuff( line ) ); | lines.push_back( removeDotStuff( line ) ); | ||||
if ( line == "." ) | if ( line == QLatin1String(".") ) | ||||
break; | break; | ||||
} else { | } else { | ||||
lines.push_back( QString() ); | lines.push_back( QString() ); | ||||
} | } | ||||
} | } | ||||
if ( lines.back() != "." ) { | if ( lines.back() != QLatin1String(".") ) { | ||||
makeError( Error::PrematureEndOfMultiLine, mlBeginLine, mlBeginCol ); | makeError( Error::PrematureEndOfMultiLine, mlBeginLine, mlBeginCol ); | ||||
return false; | return false; | ||||
} | } | ||||
assert( !lines.empty() ); | assert( !lines.empty() ); | ||||
lines.erase( --lines.end() ); // don't include the lone dot. | lines.erase( --lines.end() ); // don't include the lone dot. | ||||
result = lines.join("\n"); | result = lines.join(QLatin1String("\n")); | ||||
return true; | return true; | ||||
} | } | ||||
bool Lexer::Impl::parseQuotedString( QString & result ) { | bool Lexer::Impl::parseQuotedString( QString & result ) { | ||||
// quoted-string := DQUOTE *CHAR DQUOTE | // quoted-string := DQUOTE *CHAR DQUOTE | ||||
// check that caller plays by the rules: | // check that caller plays by the rules: | ||||
assert( *(mState.cursor-1) == '"' ); | assert( *(mState.cursor-1) == '"' ); | ||||
Show All 10 Lines | while ( !atEnd() ) | ||||
switch ( *mState.cursor ) { | switch ( *mState.cursor ) { | ||||
case '"': | case '"': | ||||
++mState.cursor; | ++mState.cursor; | ||||
return true; | return true; | ||||
case '\r': | case '\r': | ||||
case '\n': | case '\n': | ||||
if ( !eatCRLF() ) | if ( !eatCRLF() ) | ||||
return false; | return false; | ||||
result += '\n'; | result += QLatin1Char('\n'); | ||||
break; | break; | ||||
case '\\': | case '\\': | ||||
++mState.cursor; | ++mState.cursor; | ||||
if ( atEnd() ) | if ( atEnd() ) | ||||
break; | break; | ||||
// else fall through: | // else fall through: | ||||
default: | default: | ||||
if ( !is8Bit( *mState.cursor ) ) | if ( !is8Bit( *mState.cursor ) ) | ||||
result += *mState.cursor++; | result += QLatin1Char(*mState.cursor++); | ||||
else { // probably UTF-8 | else { // probably UTF-8 | ||||
const char * const eightBitBegin = mState.cursor; | const char * const eightBitBegin = mState.cursor; | ||||
skipTo8BitEnd(); | skipTo8BitEnd(); | ||||
const int eightBitLen = mState.cursor - eightBitBegin; | const int eightBitLen = mState.cursor - eightBitBegin; | ||||
assert( eightBitLen > 0 ); | assert( eightBitLen > 0 ); | ||||
if ( isValidUtf8( eightBitBegin, eightBitLen ) ) | if ( isValidUtf8( eightBitBegin, eightBitLen ) ) | ||||
result += dec->toUnicode( eightBitBegin, eightBitLen ); | result += dec->toUnicode( eightBitBegin, eightBitLen ); | ||||
else { | else { | ||||
Show All 16 Lines |