/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_svtools.hxx"

#include <svtools/syntaxhighlight.hxx>

#include <unotools/charclass.hxx>
#include <tools/debug.hxx>


// ##########################################################################
// ATTENTION: all these words needs to be in small caps
// ##########################################################################
static const char* strListBasicKeyWords[] = {
	"access",
	"alias",
	"and",
	"any",
	"append",
	"as",
	"base",
	"binary",
	"boolean",
	"byref",
	"byte",
	"byval",
	"call",
	"case",
	"cdecl",
	"classmodule",
	"close",
	"compare",
	"compatible",
	"const",
	"currency",
	"date",
	"declare",
	"defbool",
	"defcur",
	"defdate",
	"defdbl",
	"deferr",
	"defint",
	"deflng",
	"defobj",
	"defsng",
	"defstr",
	"defvar",
	"dim",
	"do",
	"double",
	"each",
	"else",
	"elseif",
	"end",
	"end enum",
	"end function",
	"end if",
	"end select",
	"end sub",
	"end type",
	"endif",
	"enum",
	"eqv",
	"erase",
	"error",
	"exit",
	"explicit",
	"for",
	"function",
	"get",
	"global",
	"gosub",
	"goto",
	"if",
	"imp",
	"implements",
	"in",
	"input",
	"integer",
	"is",
	"let",
	"lib",
	"like",
	"line",
	"line input",
	"local",
	"lock",
	"long",
	"loop",
	"lprint",
	"lset",
	"mod",
	"name",
	"new",
	"next",
	"not",
	"object",
	"on",
	"open",
	"option",
	"optional",
	"or",
	"output",
	"preserve",
	"print",
	"private",
	"property",
	"public",
	"random",
	"read",
	"redim",
	"rem",
	"resume",
	"return",
	"rset",
	"select",
	"set",
	"shared",
	"single",
	"static",
	"step",
	"stop",
	"string",
	"sub",
	"system",
	"text",
	"then",
	"to",
	"type",
	"typeof",
	"until",
	"variant",
	"wend",
	"while",
	"with",
	"write",
	"xor"
};


static const char* strListSqlKeyWords[] = {
	"all",
	"and",
	"any",
	"as",
	"asc",
	"avg",
	"between",
	"by",
	"cast",
	"corresponding",
	"count",
	"create",
	"cross",
	"delete",
	"desc",
	"distinct",
	"drop",
	"escape",
	"except",
	"exists",	
	"false",
	"from",	
	"full",
	"global",
	"group",
	"having",
	"in",
	"inner",
	"insert",
	"intersect",
	"into",
	"is",
	"join",
	"left",
	"like",
	"local",
	"match",
	"max",
	"min",
	"natural",
	"not",
	"null",
	"on",
	"or",
	"order",
	"outer",
	"right",
	"select",
	"set",
	"some",
	"sum",
	"table",
	"temporary",
	"true",
	"union",
	"unique",
	"unknown",
	"update",
	"using",
	"values",
	"where"
};


extern "C" int CDECL compare_strings( const void *arg1, const void *arg2 )
{
	return strcmp( (char *)arg1, *(char **)arg2 );
}


class LetterTable
{
	bool		IsLetterTab[256];

public:
	LetterTable( void );

	inline bool isLetter( sal_Unicode c )
	{
		bool bRet = (c < 256) ? IsLetterTab[c] : isLetterUnicode( c );
		return bRet;
	}
	bool isLetterUnicode( sal_Unicode c );
};

class BasicSimpleCharClass
{
	static LetterTable aLetterTable;

public:
	static sal_Bool isAlpha( sal_Unicode c, bool bCompatible )
	{
		sal_Bool bRet = (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') 
					|| (bCompatible && aLetterTable.isLetter( c ));
		return bRet;
	}

	static sal_Bool isDigit( sal_Unicode c )
	{
		sal_Bool bRet = (c >= '0' && c <= '9');
		return bRet;
	}

	static sal_Bool isAlphaNumeric( sal_Unicode c, bool bCompatible )
	{
		sal_Bool bRet = isDigit( c ) || isAlpha( c, bCompatible );
		return bRet;
	}
};

LetterTable BasicSimpleCharClass::aLetterTable;

LetterTable::LetterTable( void )
{
	for( int i = 0 ; i < 256 ; ++i )
		IsLetterTab[i] = false;

	IsLetterTab[0xC0] = true;	// ?, CAPITAL LETTER A WITH GRAVE ACCENT
	IsLetterTab[0xC1] = true;	// ?, CAPITAL LETTER A WITH ACUTE ACCENT
	IsLetterTab[0xC2] = true;	// ?, CAPITAL LETTER A WITH CIRCUMFLEX ACCENT
	IsLetterTab[0xC3] = true;	// ?, CAPITAL LETTER A WITH TILDE
	IsLetterTab[0xC4] = true;	// ?, CAPITAL LETTER A WITH DIAERESIS
	IsLetterTab[0xC5] = true;	// ?, CAPITAL LETTER A WITH RING ABOVE
	IsLetterTab[0xC6] = true;	// ?, CAPITAL LIGATURE AE
	IsLetterTab[0xC7] = true;	// ?, CAPITAL LETTER C WITH CEDILLA
	IsLetterTab[0xC8] = true;	// ?, CAPITAL LETTER E WITH GRAVE ACCENT
	IsLetterTab[0xC9] = true;	// ?, CAPITAL LETTER E WITH ACUTE ACCENT
	IsLetterTab[0xCA] = true;	// ?, CAPITAL LETTER E WITH CIRCUMFLEX ACCENT
	IsLetterTab[0xCB] = true;	// ?, CAPITAL LETTER E WITH DIAERESIS
	IsLetterTab[0xCC] = true;	// ?, CAPITAL LETTER I WITH GRAVE ACCENT
	IsLetterTab[0xCD] = true;	// ?, CAPITAL LETTER I WITH ACUTE ACCENT
	IsLetterTab[0xCE] = true;	// ?, CAPITAL LETTER I WITH CIRCUMFLEX ACCENT
	IsLetterTab[0xCF] = true;	// ?, CAPITAL LETTER I WITH DIAERESIS
	IsLetterTab[0xD0] = true;	// ?, CAPITAL LETTER ETH
	IsLetterTab[0xD1] = true;	// ?, CAPITAL LETTER N WITH TILDE
	IsLetterTab[0xD2] = true;	// ?, CAPITAL LETTER O WITH GRAVE ACCENT
	IsLetterTab[0xD3] = true;	// ?, CAPITAL LETTER O WITH ACUTE ACCENT
	IsLetterTab[0xD4] = true;	// ?, CAPITAL LETTER O WITH CIRCUMFLEX ACCENT
	IsLetterTab[0xD5] = true;	// ?, CAPITAL LETTER O WITH TILDE
	IsLetterTab[0xD6] = true;	// ?, CAPITAL LETTER O WITH DIAERESIS
	IsLetterTab[0xD8] = true;	// ?, CAPITAL LETTER O WITH STROKE
	IsLetterTab[0xD9] = true;	// ?, CAPITAL LETTER U WITH GRAVE ACCENT
	IsLetterTab[0xDA] = true;	// ?, CAPITAL LETTER U WITH ACUTE ACCENT
	IsLetterTab[0xDB] = true;	// ?, CAPITAL LETTER U WITH CIRCUMFLEX ACCENT
	IsLetterTab[0xDC] = true;	// ?, CAPITAL LETTER U WITH DIAERESIS
	IsLetterTab[0xDD] = true;	// ?, CAPITAL LETTER Y WITH ACUTE ACCENT
	IsLetterTab[0xDE] = true;	// ?, CAPITAL LETTER THORN
	IsLetterTab[0xDF] = true;	// ?, SMALL LETTER SHARP S
	IsLetterTab[0xE0] = true;	// ?, SMALL LETTER A WITH GRAVE ACCENT
	IsLetterTab[0xE1] = true;	// ?, SMALL LETTER A WITH ACUTE ACCENT
	IsLetterTab[0xE2] = true;	// ?, SMALL LETTER A WITH CIRCUMFLEX ACCENT
	IsLetterTab[0xE3] = true;	// ?, SMALL LETTER A WITH TILDE
	IsLetterTab[0xE4] = true;	// ?, SMALL LETTER A WITH DIAERESIS
	IsLetterTab[0xE5] = true;	// ?, SMALL LETTER A WITH RING ABOVE
	IsLetterTab[0xE6] = true;	// ?, SMALL LIGATURE AE
	IsLetterTab[0xE7] = true;	// ?, SMALL LETTER C WITH CEDILLA
	IsLetterTab[0xE8] = true;	// ?, SMALL LETTER E WITH GRAVE ACCENT
	IsLetterTab[0xE9] = true;	// ?, SMALL LETTER E WITH ACUTE ACCENT
	IsLetterTab[0xEA] = true;	// ?, SMALL LETTER E WITH CIRCUMFLEX ACCENT
	IsLetterTab[0xEB] = true;	// ?, SMALL LETTER E WITH DIAERESIS
	IsLetterTab[0xEC] = true;	// ?, SMALL LETTER I WITH GRAVE ACCENT
	IsLetterTab[0xED] = true;	// ?, SMALL LETTER I WITH ACUTE ACCENT
	IsLetterTab[0xEE] = true;	// ?, SMALL LETTER I WITH CIRCUMFLEX ACCENT
	IsLetterTab[0xEF] = true;	// ?, SMALL LETTER I WITH DIAERESIS
	IsLetterTab[0xF0] = true;	// ?, SMALL LETTER ETH
	IsLetterTab[0xF1] = true;	// ?, SMALL LETTER N WITH TILDE
	IsLetterTab[0xF2] = true;	// ?, SMALL LETTER O WITH GRAVE ACCENT
	IsLetterTab[0xF3] = true;	// ?, SMALL LETTER O WITH ACUTE ACCENT
	IsLetterTab[0xF4] = true;	// ?, SMALL LETTER O WITH CIRCUMFLEX ACCENT
	IsLetterTab[0xF5] = true;	// ?, SMALL LETTER O WITH TILDE
	IsLetterTab[0xF6] = true;	// ?, SMALL LETTER O WITH DIAERESIS
	IsLetterTab[0xF8] = true;	// ?, SMALL LETTER O WITH OBLIQUE BAR
	IsLetterTab[0xF9] = true;	// ?, SMALL LETTER U WITH GRAVE ACCENT
	IsLetterTab[0xFA] = true;	// ?, SMALL LETTER U WITH ACUTE ACCENT
	IsLetterTab[0xFB] = true;	// ?, SMALL LETTER U WITH CIRCUMFLEX ACCENT
	IsLetterTab[0xFC] = true;	// ?, SMALL LETTER U WITH DIAERESIS
	IsLetterTab[0xFD] = true;	// ?, SMALL LETTER Y WITH ACUTE ACCENT
	IsLetterTab[0xFE] = true;	// ?, SMALL LETTER THORN
	IsLetterTab[0xFF] = true;	// � , SMALL LETTER Y WITH DIAERESIS
}

bool LetterTable::isLetterUnicode( sal_Unicode c )
{
	static CharClass* pCharClass = NULL;
	if( pCharClass == NULL )
		pCharClass = new CharClass( Application::GetSettings().GetLocale() );
	String aStr( c );
	bool bRet = pCharClass->isLetter( aStr, 0 );
	return bRet;
}

// Hilfsfunktion: Zeichen-Flag Testen
sal_Bool SimpleTokenizer_Impl::testCharFlags( sal_Unicode c, sal_uInt16 nTestFlags )
{
	bool bRet = false;
	if( c != 0 && c <= 255 )
	{
		bRet = ( (aCharTypeTab[c] & nTestFlags) != 0 );
	}
	else if( c > 255 )
	{
		bRet = (( CHAR_START_IDENTIFIER | CHAR_IN_IDENTIFIER ) & nTestFlags) != 0
			? BasicSimpleCharClass::isAlpha( c, true ) : false;
	}
	return bRet;
}

void SimpleTokenizer_Impl::setKeyWords( const char** ppKeyWords, sal_uInt16 nCount )
{
	ppListKeyWords = ppKeyWords;
	nKeyWordCount = nCount;
}

// Neues Token holen
sal_Bool SimpleTokenizer_Impl::getNextToken( /*out*/TokenTypes& reType,
	/*out*/const sal_Unicode*& rpStartPos, /*out*/const sal_Unicode*& rpEndPos )
{
	reType = TT_UNKNOWN;

	// Position merken
	rpStartPos = mpActualPos;

	// Zeichen untersuchen
	sal_Unicode c = peekChar();
	if( c == CHAR_EOF )
		return sal_False;

	// Zeichen lesen
	getChar();

	//*** Alle Moeglichkeiten durchgehen ***
	// Space?
	if ( (testCharFlags( c, CHAR_SPACE ) == sal_True) )
	{
		while( testCharFlags( peekChar(), CHAR_SPACE ) == sal_True )
			getChar();

		reType = TT_WHITESPACE;
	}

	// Identifier?
	else if ( (testCharFlags( c, CHAR_START_IDENTIFIER ) == sal_True) )
	{
		sal_Bool bIdentifierChar;
		do
		{
			// Naechstes Zeichen holen
			c = peekChar();
			bIdentifierChar = testCharFlags( c, CHAR_IN_IDENTIFIER );
			if( bIdentifierChar )
				getChar();
		}
		while( bIdentifierChar );

		reType = TT_IDENTIFIER;

		// Schluesselwort-Tabelle
		if (ppListKeyWords != NULL)
		{
			int nCount = mpActualPos - rpStartPos;

			// No keyword if string contains char > 255
			bool bCanBeKeyword = true;
			for( int i = 0 ; i < nCount ; i++ )
			{
				if( rpStartPos[i] > 255 )
				{
					bCanBeKeyword = false;
					break;
				}
			}

			if( bCanBeKeyword )
			{
				String aKWString(rpStartPos, sal::static_int_cast< xub_StrLen >(nCount) );
				ByteString aByteStr( aKWString, RTL_TEXTENCODING_ASCII_US );
				aByteStr.ToLowerAscii();
				if ( bsearch( aByteStr.GetBuffer(), ppListKeyWords, nKeyWordCount, sizeof( char* ),
																		compare_strings ) )
				{
					reType = TT_KEYWORDS;

					if ( aByteStr.Equals( "rem" ) )
					{
						// Alle Zeichen bis Zeilen-Ende oder EOF entfernen
						sal_Unicode cPeek = peekChar();
						while( cPeek != CHAR_EOF && testCharFlags( cPeek, CHAR_EOL ) == sal_False )
						{
							c = getChar();
							cPeek = peekChar();
						}

						reType = TT_COMMENT;
					}
				}
			}
		}
	}

	// Operator?								
	// only for BASIC '\'' should be a comment, otherwise it is a normal string and handled there
	else if ( ( testCharFlags( c, CHAR_OPERATOR ) == sal_True ) || ( (c == '\'') && (aLanguage==HIGHLIGHT_BASIC)) )
	{
		// paramters for SQL view
		if ( (c==':') || (c=='?'))
		{
			if (c!='?')
			{
				sal_Bool bIdentifierChar;
				do
				{
					// Naechstes Zeichen holen
					c = peekChar();
					bIdentifierChar =  BasicSimpleCharClass::isAlpha( c, true );
					if( bIdentifierChar )
						getChar();
				}
				while( bIdentifierChar );
			}
			reType = TT_PARAMETER;
		}
		else if ((c=='-'))
		{
			sal_Unicode cPeekNext = peekChar();
			if (cPeekNext=='-')
			{
				// Alle Zeichen bis Zeilen-Ende oder EOF entfernen
				while( cPeekNext != CHAR_EOF && testCharFlags( cPeekNext, CHAR_EOL ) == sal_False )
				{
					getChar();
					cPeekNext = peekChar();
				}
				reType = TT_COMMENT;
			}
		}
       else if (c=='/')
       {
           sal_Unicode cPeekNext = peekChar();
           if (cPeekNext=='/')
           {
               // Alle Zeichen bis Zeilen-Ende oder EOF entfernen
               while( cPeekNext != CHAR_EOF && testCharFlags( cPeekNext, CHAR_EOL ) == sal_False )
               {
                   getChar();
                   cPeekNext = peekChar();
               }
               reType = TT_COMMENT;
           }
       }
		else
		{
			// Kommentar ?
			if ( c == '\'' )
			{
				c = getChar();	// '/' entfernen

				// Alle Zeichen bis Zeilen-Ende oder EOF entfernen
				sal_Unicode cPeek = c;
				while( cPeek != CHAR_EOF && testCharFlags( cPeek, CHAR_EOL ) == sal_False )
				{
					getChar();
					cPeek = peekChar();
				}

				reType = TT_COMMENT;
			}

			// Echter Operator, kann hier einfach behandelt werden,
			// da nicht der wirkliche Operator, wie z.B. += interessiert,
			// sondern nur die Tatsache, dass es sich um einen handelt.
			if( reType != TT_COMMENT )
			{
				reType = TT_OPERATOR;
			}

		}
	}

	// Objekt-Trenner? Muss vor Number abgehandelt werden
	else if( c == '.' && ( peekChar() < '0' || peekChar() > '9' ) )
	{
		reType = TT_OPERATOR;
	}

	// Zahl?
	else if( testCharFlags( c, CHAR_START_NUMBER ) == sal_True )
	{
		reType = TT_NUMBER;

		// Zahlensystem, 10 = normal, wird bei Oct/Hex geaendert
		int nRadix = 10;

		// Ist es eine Hex- oder Oct-Zahl?
		if( c == '&' )
		{
			// Octal?
			if( peekChar() == 'o' || peekChar() == 'O' )
			{
				// o entfernen
				getChar();
				nRadix = 8; 	// Octal-Basis

				// Alle Ziffern einlesen
				while( testCharFlags( peekChar(), CHAR_IN_OCT_NUMBER ) )
					c = getChar();
			}
			// Hex?
			else if( peekChar() == 'h' || peekChar() == 'H' )
			{
				// x entfernen
				getChar();
				nRadix = 16;	 // Hex-Basis

				// Alle Ziffern einlesen und puffern
				while( testCharFlags( peekChar(), CHAR_IN_HEX_NUMBER ) )
					c = getChar();
			}
			else
			{
				reType = TT_OPERATOR;
			}
		}

		// Wenn nicht Oct oder Hex als double ansehen
		if( reType == TT_NUMBER && nRadix == 10 )
		{
			// Flag, ob das letzte Zeichen ein Exponent war
			sal_Bool bAfterExpChar = sal_False;

			// Alle Ziffern einlesen
			while( testCharFlags( peekChar(), CHAR_IN_NUMBER ) ||
					(bAfterExpChar && peekChar() == '+' ) ||
					(bAfterExpChar && peekChar() == '-' ) )
					// Nach Exponent auch +/- OK
			{
				c = getChar();					// Zeichen lesen
				bAfterExpChar = ( c == 'e' || c == 'E' );
			}
		}

		// reType = TT_NUMBER;
	}

	// String?
	else if( testCharFlags( c, CHAR_START_STRING ) == sal_True )
	{
		// Merken, welches Zeichen den String eroeffnet hat
		sal_Unicode cEndString = c;
		if( c == '[' )
			cEndString = ']';

		// Alle Ziffern einlesen und puffern
		while( peekChar() != cEndString )
		{
			// #58846 EOF vor getChar() abfangen, damit EOF micht verloren geht
			if( peekChar() == CHAR_EOF )
			{
				// ERROR: unterminated string literal
				reType = TT_ERROR;
				break;
			}
			c = getChar();
			if( testCharFlags( c, CHAR_EOL ) == sal_True )
			{
				// ERROR: unterminated string literal
				reType = TT_ERROR;
				break;
			}
		}

		//	Zeichen lesen
		if( reType != TT_ERROR )
		{
			getChar();
			if( cEndString == ']' )
				reType = TT_IDENTIFIER;
			else
				reType = TT_STRING;
		}
	}

	// Zeilenende?
	else if( testCharFlags( c, CHAR_EOL ) == sal_True )
	{
		// Falls ein weiteres anderes EOL-Char folgt, weg damit
		sal_Unicode cNext = peekChar();
		if( cNext != c && testCharFlags( cNext, CHAR_EOL ) == sal_True )
			getChar();

		// Positions-Daten auf Zeilen-Beginn setzen
		nCol = 0;
		nLine++;

		reType = TT_EOL;
	}

	// Alles andere bleibt TT_UNKNOWN


	// End-Position eintragen
	rpEndPos = mpActualPos;
	return sal_True;
}

String SimpleTokenizer_Impl::getTokStr
	( /*out*/const sal_Unicode* pStartPos, /*out*/const sal_Unicode* pEndPos )
{
	return String( pStartPos, (sal_uInt16)( pEndPos - pStartPos ) );
}

#ifdef DBG_UTIL
// TEST: Token ausgeben
String SimpleTokenizer_Impl::getFullTokenStr( /*out*/TokenTypes eType,
	/*out*/const sal_Unicode* pStartPos, /*out*/const sal_Unicode* pEndPos )
{
	String aOut;
	switch( eType )
	{
		case TT_UNKNOWN:	aOut = String( RTL_CONSTASCII_USTRINGPARAM("TT_UNKNOWN:") ); break;
		case TT_IDENTIFIER:	aOut = String( RTL_CONSTASCII_USTRINGPARAM("TT_IDENTIFIER:") ); break;
		case TT_WHITESPACE:	aOut = String( RTL_CONSTASCII_USTRINGPARAM("TT_WHITESPACE:") ); break;
		case TT_NUMBER:		aOut = String( RTL_CONSTASCII_USTRINGPARAM("TT_NUMBER:") ); break;
		case TT_STRING:		aOut = String( RTL_CONSTASCII_USTRINGPARAM("TT_STRING:") ); break;
		case TT_EOL:		aOut = String( RTL_CONSTASCII_USTRINGPARAM("TT_EOL:") ); break;
		case TT_COMMENT:	aOut = String( RTL_CONSTASCII_USTRINGPARAM("TT_COMMENT:") ); break;
		case TT_ERROR:		aOut = String( RTL_CONSTASCII_USTRINGPARAM("TT_ERROR:") ); break;
		case TT_OPERATOR:	aOut = String( RTL_CONSTASCII_USTRINGPARAM("TT_OPERATOR:") ); break;
		case TT_KEYWORDS:	aOut = String( RTL_CONSTASCII_USTRINGPARAM("TT_KEYWORD:") ); break;
		case TT_PARAMETER:	aOut = String( RTL_CONSTASCII_USTRINGPARAM("TT_PARAMETER:") ); break;
	}
	if( eType != TT_EOL )
	{
		aOut += String( pStartPos, (sal_uInt16)( pEndPos - pStartPos ) );
	}
	aOut += String( RTL_CONSTASCII_USTRINGPARAM("\n") );
	return aOut;
}
#endif

SimpleTokenizer_Impl::SimpleTokenizer_Impl( HighlighterLanguage aLang ): aLanguage(aLang)
{
	memset( aCharTypeTab, 0, sizeof( aCharTypeTab ) );

	// Zeichen-Tabelle fuellen
	sal_uInt16 i;

	// Zulaessige Zeichen fuer Identifier
	sal_uInt16 nHelpMask = (sal_uInt16)( CHAR_START_IDENTIFIER | CHAR_IN_IDENTIFIER );
	for( i = 'a' ; i <= 'z' ; i++ )
		aCharTypeTab[i] |= nHelpMask;
	for( i = 'A' ; i <= 'Z' ; i++ )
		aCharTypeTab[i] |= nHelpMask;
	// '_' extra eintragen
	aCharTypeTab[(int)'_'] |= nHelpMask;
	// AB 23.6.97: '$' ist auch erlaubt
	aCharTypeTab[(int)'$'] |= nHelpMask;

	// Ziffern (Identifier und Number ist moeglich)
	nHelpMask = (sal_uInt16)( CHAR_IN_IDENTIFIER | CHAR_START_NUMBER |
						 CHAR_IN_NUMBER | CHAR_IN_HEX_NUMBER );
	for( i = '0' ; i <= '9' ; i++ )
		aCharTypeTab[i] |= nHelpMask;

	// e und E sowie . von Hand ergaenzen
	aCharTypeTab[(int)'e'] |= CHAR_IN_NUMBER;
	aCharTypeTab[(int)'E'] |= CHAR_IN_NUMBER;
	aCharTypeTab[(int)'.'] |= (sal_uInt16)( CHAR_IN_NUMBER | CHAR_START_NUMBER );
	aCharTypeTab[(int)'&'] |= CHAR_START_NUMBER;

	// Hex-Ziffern
	for( i = 'a' ; i <= 'f' ; i++ )
		aCharTypeTab[i] |= CHAR_IN_HEX_NUMBER;
	for( i = 'A' ; i <= 'F' ; i++ )
		aCharTypeTab[i] |= CHAR_IN_HEX_NUMBER;

	// Oct-Ziffern
	for( i = '0' ; i <= '7' ; i++ )
		aCharTypeTab[i] |= CHAR_IN_OCT_NUMBER;

	// String-Beginn/End-Zeichen
	aCharTypeTab[(int)'\''] |= CHAR_START_STRING;
	aCharTypeTab[(int)'\"'] |= CHAR_START_STRING;
	aCharTypeTab[(int)'[']  |= CHAR_START_STRING;
	aCharTypeTab[(int)'`']  |= CHAR_START_STRING;

	// Operator-Zeichen
	aCharTypeTab[(int)'!'] |= CHAR_OPERATOR;
	aCharTypeTab[(int)'%'] |= CHAR_OPERATOR;
	// aCharTypeTab[(int)'&'] |= CHAR_OPERATOR;		Removed because of #i14140
	aCharTypeTab[(int)'('] |= CHAR_OPERATOR;
	aCharTypeTab[(int)')'] |= CHAR_OPERATOR;
	aCharTypeTab[(int)'*'] |= CHAR_OPERATOR;
	aCharTypeTab[(int)'+'] |= CHAR_OPERATOR;
	aCharTypeTab[(int)','] |= CHAR_OPERATOR;
	aCharTypeTab[(int)'-'] |= CHAR_OPERATOR;
	aCharTypeTab[(int)'/'] |= CHAR_OPERATOR;
	aCharTypeTab[(int)':'] |= CHAR_OPERATOR;
	aCharTypeTab[(int)'<'] |= CHAR_OPERATOR;
	aCharTypeTab[(int)'='] |= CHAR_OPERATOR;
	aCharTypeTab[(int)'>'] |= CHAR_OPERATOR;
	aCharTypeTab[(int)'?'] |= CHAR_OPERATOR;
	aCharTypeTab[(int)'^'] |= CHAR_OPERATOR;
	aCharTypeTab[(int)'|'] |= CHAR_OPERATOR;
	aCharTypeTab[(int)'~'] |= CHAR_OPERATOR;
	aCharTypeTab[(int)'{'] |= CHAR_OPERATOR;
	aCharTypeTab[(int)'}'] |= CHAR_OPERATOR;
	// aCharTypeTab[(int)'['] |= CHAR_OPERATOR;		Removed because of #i17826
	aCharTypeTab[(int)']'] |= CHAR_OPERATOR;
	aCharTypeTab[(int)';'] |= CHAR_OPERATOR;

	// Space
	aCharTypeTab[(int)' ' ] |= CHAR_SPACE;
	aCharTypeTab[(int)'\t'] |= CHAR_SPACE;

	// Zeilen-Ende-Zeichen
	aCharTypeTab[(int)'\r'] |= CHAR_EOL;
	aCharTypeTab[(int)'\n'] |= CHAR_EOL;

	ppListKeyWords = NULL;
}

SimpleTokenizer_Impl::~SimpleTokenizer_Impl( void )
{
}

SimpleTokenizer_Impl* getSimpleTokenizer( void )
{
	static SimpleTokenizer_Impl* pSimpleTokenizer = NULL;
	if( !pSimpleTokenizer )
		pSimpleTokenizer = new SimpleTokenizer_Impl();
	return pSimpleTokenizer;
}

// Heraussuchen der jeweils naechsten Funktion aus einem JavaScript-Modul
sal_uInt16 SimpleTokenizer_Impl::parseLine( sal_uInt32 nParseLine, const String* aSource )
{
	// Position auf den Anfang des Source-Strings setzen
	mpStringBegin = mpActualPos = aSource->GetBuffer();

	// Zeile und Spalte initialisieren
	nLine = nParseLine;
	nCol = 0L;

	// Variablen fuer die Out-Parameter
	TokenTypes eType;
	const sal_Unicode* pStartPos;
	const sal_Unicode* pEndPos;

	// Schleife ueber alle Tokens
	sal_uInt16 nTokenCount = 0;
	while( getNextToken( eType, pStartPos, pEndPos ) )
		nTokenCount++;

	return nTokenCount;
}

void SimpleTokenizer_Impl::getHighlightPortions( sal_uInt32 nParseLine, const String& rLine,
													/*out*/HighlightPortions& portions  )
{
	// Position auf den Anfang des Source-Strings setzen
	mpStringBegin = mpActualPos = rLine.GetBuffer();

	// Zeile und Spalte initialisieren
	nLine = nParseLine;
	nCol = 0L;

	// Variablen fuer die Out-Parameter
	TokenTypes eType;
	const sal_Unicode* pStartPos;
	const sal_Unicode* pEndPos;

	// Schleife ueber alle Tokens
	while( getNextToken( eType, pStartPos, pEndPos ) )
	{
		HighlightPortion portion;

		portion.nBegin = (sal_uInt16)(pStartPos - mpStringBegin);
		portion.nEnd = (sal_uInt16)(pEndPos - mpStringBegin);
		portion.tokenType = eType;
        
        portions.push_back(portion);
	}
}


//////////////////////////////////////////////////////////////////////////
// Implementierung des SyntaxHighlighter

SyntaxHighlighter::SyntaxHighlighter()
{
	m_pSimpleTokenizer = 0;
	m_pKeyWords = NULL;
	m_nKeyWordCount = 0;
}

SyntaxHighlighter::~SyntaxHighlighter()
{
	delete m_pSimpleTokenizer;
	delete m_pKeyWords;
}

void SyntaxHighlighter::initialize( HighlighterLanguage eLanguage_ )
{
	eLanguage = eLanguage_;
	delete m_pSimpleTokenizer;
	m_pSimpleTokenizer = new SimpleTokenizer_Impl(eLanguage);

	switch (eLanguage)
	{
		case HIGHLIGHT_BASIC:
			m_pSimpleTokenizer->setKeyWords( strListBasicKeyWords,
											sizeof( strListBasicKeyWords ) / sizeof( char* ));
			break;
		case HIGHLIGHT_SQL:
			m_pSimpleTokenizer->setKeyWords( strListSqlKeyWords,
											sizeof( strListSqlKeyWords ) / sizeof( char* ));
			break;
		default:
			m_pSimpleTokenizer->setKeyWords( NULL, 0 );
	}
}

const Range SyntaxHighlighter::notifyChange( sal_uInt32 nLine, sal_Int32 nLineCountDifference,
								const String* pChangedLines, sal_uInt32 nArrayLength)
{
    (void)nLineCountDifference;
    
	for( sal_uInt32 i=0 ; i < nArrayLength ; i++ )
		m_pSimpleTokenizer->parseLine(nLine+i, &pChangedLines[i]);

	return Range( nLine, nLine + nArrayLength-1 );
}

void SyntaxHighlighter::getHighlightPortions( sal_uInt32 nLine, const String& rLine,
											/*out*/HighlightPortions& portions )
{
	m_pSimpleTokenizer->getHighlightPortions( nLine, rLine, portions );
}
