LCOV - code coverage report
Current view: top level - libreoffice/svtools/source/edit - syntaxhighlight.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 317 0.0 %
Date: 2012-12-17 Functions: 0 18 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : 
      21             : #include <svtools/syntaxhighlight.hxx>
      22             : 
      23             : #include <unotools/charclass.hxx>
      24             : #include <comphelper/string.hxx>
      25             : 
      26             : // ##########################################################################
      27             : // ATTENTION: all these words needs to be in small caps
      28             : // ##########################################################################
      29             : static const char* strListBasicKeyWords[] = {
      30             :     "access",
      31             :     "alias",
      32             :     "and",
      33             :     "any",
      34             :     "append",
      35             :     "as",
      36             :     "attribute",
      37             :     "base",
      38             :     "binary",
      39             :     "boolean",
      40             :     "byref",
      41             :     "byte",
      42             :     "byval",
      43             :     "call",
      44             :     "case",
      45             :     "cdecl",
      46             :     "classmodule",
      47             :     "close",
      48             :     "compare",
      49             :     "compatible",
      50             :     "const",
      51             :     "currency",
      52             :     "date",
      53             :     "declare",
      54             :     "defbool",
      55             :     "defcur",
      56             :     "defdate",
      57             :     "defdbl",
      58             :     "deferr",
      59             :     "defint",
      60             :     "deflng",
      61             :     "defobj",
      62             :     "defsng",
      63             :     "defstr",
      64             :     "defvar",
      65             :     "dim",
      66             :     "do",
      67             :     "double",
      68             :     "each",
      69             :     "else",
      70             :     "elseif",
      71             :     "end",
      72             :     "end enum",
      73             :     "end function",
      74             :     "end if",
      75             :     "end property",
      76             :     "end select",
      77             :     "end sub",
      78             :     "end type",
      79             :     "endif",
      80             :     "enum",
      81             :     "eqv",
      82             :     "erase",
      83             :     "error",
      84             :     "exit",
      85             :     "explicit",
      86             :     "for",
      87             :     "function",
      88             :     "get",
      89             :     "global",
      90             :     "gosub",
      91             :     "goto",
      92             :     "if",
      93             :     "imp",
      94             :     "implements",
      95             :     "in",
      96             :     "input",
      97             :     "integer",
      98             :     "is",
      99             :     "let",
     100             :     "lib",
     101             :     "like",
     102             :     "line",
     103             :     "line input",
     104             :     "local",
     105             :     "lock",
     106             :     "long",
     107             :     "loop",
     108             :     "lprint",
     109             :     "lset",
     110             :     "mod",
     111             :     "name",
     112             :     "new",
     113             :     "next",
     114             :     "not",
     115             :     "object",
     116             :     "on",
     117             :     "open",
     118             :     "option",
     119             :     "optional",
     120             :     "or",
     121             :     "output",
     122             :     "paramarray",
     123             :     "preserve",
     124             :     "print",
     125             :     "private",
     126             :     "property",
     127             :     "public",
     128             :     "random",
     129             :     "read",
     130             :     "redim",
     131             :     "rem",
     132             :     "resume",
     133             :     "return",
     134             :     "rset",
     135             :     "select",
     136             :     "set",
     137             :     "shared",
     138             :     "single",
     139             :     "static",
     140             :     "step",
     141             :     "stop",
     142             :     "string",
     143             :     "sub",
     144             :     "system",
     145             :     "text",
     146             :     "then",
     147             :     "to",
     148             :     "type",
     149             :     "typeof",
     150             :     "until",
     151             :     "variant",
     152             :     "vbasupport",
     153             :     "wend",
     154             :     "while",
     155             :     "with",
     156             :     "withevent",
     157             :     "write",
     158             :     "xor"
     159             : };
     160             : 
     161             : 
     162             : static const char* strListSqlKeyWords[] = {
     163             :     "all",
     164             :     "and",
     165             :     "any",
     166             :     "as",
     167             :     "asc",
     168             :     "avg",
     169             :     "between",
     170             :     "by",
     171             :     "cast",
     172             :     "corresponding",
     173             :     "count",
     174             :     "create",
     175             :     "cross",
     176             :     "delete",
     177             :     "desc",
     178             :     "distinct",
     179             :     "drop",
     180             :     "escape",
     181             :     "except",
     182             :     "exists",
     183             :     "false",
     184             :     "from",
     185             :     "full",
     186             :     "global",
     187             :     "group",
     188             :     "having",
     189             :     "in",
     190             :     "inner",
     191             :     "insert",
     192             :     "intersect",
     193             :     "into",
     194             :     "is",
     195             :     "join",
     196             :     "left",
     197             :     "like",
     198             :     "local",
     199             :     "match",
     200             :     "max",
     201             :     "min",
     202             :     "natural",
     203             :     "not",
     204             :     "null",
     205             :     "on",
     206             :     "or",
     207             :     "order",
     208             :     "outer",
     209             :     "right",
     210             :     "select",
     211             :     "set",
     212             :     "some",
     213             :     "sum",
     214             :     "table",
     215             :     "temporary",
     216             :     "true",
     217             :     "union",
     218             :     "unique",
     219             :     "unknown",
     220             :     "update",
     221             :     "using",
     222             :     "values",
     223             :     "where"
     224             : };
     225             : 
     226             : 
     227           0 : extern "C" int CDECL compare_strings( const void *arg1, const void *arg2 )
     228             : {
     229           0 :     return strcmp( (char *)arg1, *(char **)arg2 );
     230             : }
     231             : 
     232             : 
     233             : namespace
     234             : {
     235             : 
     236             :     class LetterTable
     237             :     {
     238             :         bool        IsLetterTab[256];
     239             : 
     240             :     public:
     241             :         LetterTable( void );
     242             : 
     243           0 :         inline bool isLetter( sal_Unicode c )
     244             :         {
     245           0 :             bool bRet = (c < 256) ? IsLetterTab[c] : isLetterUnicode( c );
     246           0 :             return bRet;
     247             :         }
     248             :         bool isLetterUnicode( sal_Unicode c );
     249             :     };
     250             : 
     251           0 :     static bool isAlpha(sal_Unicode c)
     252             :     {
     253           0 :         if (comphelper::string::isalphaAscii(c))
     254           0 :             return true;
     255           0 :         static LetterTable aLetterTable;
     256           0 :         return aLetterTable.isLetter(c);
     257             :     }
     258             : }
     259             : 
     260           0 : LetterTable::LetterTable( void )
     261             : {
     262           0 :     for( int i = 0 ; i < 256 ; ++i )
     263           0 :         IsLetterTab[i] = false;
     264             : 
     265           0 :     IsLetterTab[0xC0] = true;   // ?, CAPITAL LETTER A WITH GRAVE ACCENT
     266           0 :     IsLetterTab[0xC1] = true;   // ?, CAPITAL LETTER A WITH ACUTE ACCENT
     267           0 :     IsLetterTab[0xC2] = true;   // ?, CAPITAL LETTER A WITH CIRCUMFLEX ACCENT
     268           0 :     IsLetterTab[0xC3] = true;   // ?, CAPITAL LETTER A WITH TILDE
     269           0 :     IsLetterTab[0xC4] = true;   // ?, CAPITAL LETTER A WITH DIAERESIS
     270           0 :     IsLetterTab[0xC5] = true;   // ?, CAPITAL LETTER A WITH RING ABOVE
     271           0 :     IsLetterTab[0xC6] = true;   // ?, CAPITAL LIGATURE AE
     272           0 :     IsLetterTab[0xC7] = true;   // ?, CAPITAL LETTER C WITH CEDILLA
     273           0 :     IsLetterTab[0xC8] = true;   // ?, CAPITAL LETTER E WITH GRAVE ACCENT
     274           0 :     IsLetterTab[0xC9] = true;   // ?, CAPITAL LETTER E WITH ACUTE ACCENT
     275           0 :     IsLetterTab[0xCA] = true;   // ?, CAPITAL LETTER E WITH CIRCUMFLEX ACCENT
     276           0 :     IsLetterTab[0xCB] = true;   // ?, CAPITAL LETTER E WITH DIAERESIS
     277           0 :     IsLetterTab[0xCC] = true;   // ?, CAPITAL LETTER I WITH GRAVE ACCENT
     278           0 :     IsLetterTab[0xCD] = true;   // ?, CAPITAL LETTER I WITH ACUTE ACCENT
     279           0 :     IsLetterTab[0xCE] = true;   // ?, CAPITAL LETTER I WITH CIRCUMFLEX ACCENT
     280           0 :     IsLetterTab[0xCF] = true;   // ?, CAPITAL LETTER I WITH DIAERESIS
     281           0 :     IsLetterTab[0xD0] = true;   // ?, CAPITAL LETTER ETH
     282           0 :     IsLetterTab[0xD1] = true;   // ?, CAPITAL LETTER N WITH TILDE
     283           0 :     IsLetterTab[0xD2] = true;   // ?, CAPITAL LETTER O WITH GRAVE ACCENT
     284           0 :     IsLetterTab[0xD3] = true;   // ?, CAPITAL LETTER O WITH ACUTE ACCENT
     285           0 :     IsLetterTab[0xD4] = true;   // ?, CAPITAL LETTER O WITH CIRCUMFLEX ACCENT
     286           0 :     IsLetterTab[0xD5] = true;   // ?, CAPITAL LETTER O WITH TILDE
     287           0 :     IsLetterTab[0xD6] = true;   // ?, CAPITAL LETTER O WITH DIAERESIS
     288           0 :     IsLetterTab[0xD8] = true;   // ?, CAPITAL LETTER O WITH STROKE
     289           0 :     IsLetterTab[0xD9] = true;   // ?, CAPITAL LETTER U WITH GRAVE ACCENT
     290           0 :     IsLetterTab[0xDA] = true;   // ?, CAPITAL LETTER U WITH ACUTE ACCENT
     291           0 :     IsLetterTab[0xDB] = true;   // ?, CAPITAL LETTER U WITH CIRCUMFLEX ACCENT
     292           0 :     IsLetterTab[0xDC] = true;   // ?, CAPITAL LETTER U WITH DIAERESIS
     293           0 :     IsLetterTab[0xDD] = true;   // ?, CAPITAL LETTER Y WITH ACUTE ACCENT
     294           0 :     IsLetterTab[0xDE] = true;   // ?, CAPITAL LETTER THORN
     295           0 :     IsLetterTab[0xDF] = true;   // ?, SMALL LETTER SHARP S
     296           0 :     IsLetterTab[0xE0] = true;   // ?, SMALL LETTER A WITH GRAVE ACCENT
     297           0 :     IsLetterTab[0xE1] = true;   // ?, SMALL LETTER A WITH ACUTE ACCENT
     298           0 :     IsLetterTab[0xE2] = true;   // ?, SMALL LETTER A WITH CIRCUMFLEX ACCENT
     299           0 :     IsLetterTab[0xE3] = true;   // ?, SMALL LETTER A WITH TILDE
     300           0 :     IsLetterTab[0xE4] = true;   // ?, SMALL LETTER A WITH DIAERESIS
     301           0 :     IsLetterTab[0xE5] = true;   // ?, SMALL LETTER A WITH RING ABOVE
     302           0 :     IsLetterTab[0xE6] = true;   // ?, SMALL LIGATURE AE
     303           0 :     IsLetterTab[0xE7] = true;   // ?, SMALL LETTER C WITH CEDILLA
     304           0 :     IsLetterTab[0xE8] = true;   // ?, SMALL LETTER E WITH GRAVE ACCENT
     305           0 :     IsLetterTab[0xE9] = true;   // ?, SMALL LETTER E WITH ACUTE ACCENT
     306           0 :     IsLetterTab[0xEA] = true;   // ?, SMALL LETTER E WITH CIRCUMFLEX ACCENT
     307           0 :     IsLetterTab[0xEB] = true;   // ?, SMALL LETTER E WITH DIAERESIS
     308           0 :     IsLetterTab[0xEC] = true;   // ?, SMALL LETTER I WITH GRAVE ACCENT
     309           0 :     IsLetterTab[0xED] = true;   // ?, SMALL LETTER I WITH ACUTE ACCENT
     310           0 :     IsLetterTab[0xEE] = true;   // ?, SMALL LETTER I WITH CIRCUMFLEX ACCENT
     311           0 :     IsLetterTab[0xEF] = true;   // ?, SMALL LETTER I WITH DIAERESIS
     312           0 :     IsLetterTab[0xF0] = true;   // ?, SMALL LETTER ETH
     313           0 :     IsLetterTab[0xF1] = true;   // ?, SMALL LETTER N WITH TILDE
     314           0 :     IsLetterTab[0xF2] = true;   // ?, SMALL LETTER O WITH GRAVE ACCENT
     315           0 :     IsLetterTab[0xF3] = true;   // ?, SMALL LETTER O WITH ACUTE ACCENT
     316           0 :     IsLetterTab[0xF4] = true;   // ?, SMALL LETTER O WITH CIRCUMFLEX ACCENT
     317           0 :     IsLetterTab[0xF5] = true;   // ?, SMALL LETTER O WITH TILDE
     318           0 :     IsLetterTab[0xF6] = true;   // ?, SMALL LETTER O WITH DIAERESIS
     319           0 :     IsLetterTab[0xF8] = true;   // ?, SMALL LETTER O WITH OBLIQUE BAR
     320           0 :     IsLetterTab[0xF9] = true;   // ?, SMALL LETTER U WITH GRAVE ACCENT
     321           0 :     IsLetterTab[0xFA] = true;   // ?, SMALL LETTER U WITH ACUTE ACCENT
     322           0 :     IsLetterTab[0xFB] = true;   // ?, SMALL LETTER U WITH CIRCUMFLEX ACCENT
     323           0 :     IsLetterTab[0xFC] = true;   // ?, SMALL LETTER U WITH DIAERESIS
     324           0 :     IsLetterTab[0xFD] = true;   // ?, SMALL LETTER Y WITH ACUTE ACCENT
     325           0 :     IsLetterTab[0xFE] = true;   // ?, SMALL LETTER THORN
     326           0 :     IsLetterTab[0xFF] = true;   // � , SMALL LETTER Y WITH DIAERESIS
     327           0 : }
     328             : 
     329           0 : bool LetterTable::isLetterUnicode( sal_Unicode c )
     330             : {
     331             :     static CharClass* pCharClass = NULL;
     332           0 :     if( pCharClass == NULL )
     333           0 :         pCharClass = new CharClass( Application::GetSettings().GetLanguageTag() );
     334           0 :     rtl::OUString aStr( c );
     335           0 :     bool bRet = pCharClass->isLetter( aStr, 0 );
     336           0 :     return bRet;
     337             : }
     338             : 
     339             : // Hilfsfunktion: Zeichen-Flag Testen
     340           0 : sal_Bool SimpleTokenizer_Impl::testCharFlags( sal_Unicode c, sal_uInt16 nTestFlags )
     341             : {
     342           0 :     bool bRet = false;
     343           0 :     if( c != 0 && c <= 255 )
     344             :     {
     345           0 :         bRet = ( (aCharTypeTab[c] & nTestFlags) != 0 );
     346             :     }
     347           0 :     else if( c > 255 )
     348             :     {
     349             :         bRet = (( CHAR_START_IDENTIFIER | CHAR_IN_IDENTIFIER ) & nTestFlags) != 0
     350           0 :             ? isAlpha(c) : false;
     351             :     }
     352           0 :     return bRet;
     353             : }
     354             : 
     355           0 : void SimpleTokenizer_Impl::setKeyWords( const char** ppKeyWords, sal_uInt16 nCount )
     356             : {
     357           0 :     ppListKeyWords = ppKeyWords;
     358           0 :     nKeyWordCount = nCount;
     359           0 : }
     360             : 
     361             : // Neues Token holen
     362           0 : sal_Bool SimpleTokenizer_Impl::getNextToken( /*out*/TokenTypes& reType,
     363             :     /*out*/const sal_Unicode*& rpStartPos, /*out*/const sal_Unicode*& rpEndPos )
     364             : {
     365           0 :     reType = TT_UNKNOWN;
     366             : 
     367             :     // Position merken
     368           0 :     rpStartPos = mpActualPos;
     369             : 
     370             :     // Zeichen untersuchen
     371           0 :     sal_Unicode c = peekChar();
     372           0 :     if( c == CHAR_EOF )
     373           0 :         return sal_False;
     374             : 
     375             :     // Zeichen lesen
     376           0 :     getChar();
     377             : 
     378             :     //*** Alle Moeglichkeiten durchgehen ***
     379             :     // Space?
     380           0 :     if ( (testCharFlags( c, CHAR_SPACE ) == sal_True) )
     381             :     {
     382           0 :         while( testCharFlags( peekChar(), CHAR_SPACE ) == sal_True )
     383           0 :             getChar();
     384             : 
     385           0 :         reType = TT_WHITESPACE;
     386             :     }
     387             : 
     388             :     // Identifier?
     389           0 :     else if ( (testCharFlags( c, CHAR_START_IDENTIFIER ) == sal_True) )
     390             :     {
     391             :         sal_Bool bIdentifierChar;
     392           0 :         do
     393             :         {
     394             :             // Naechstes Zeichen holen
     395           0 :             c = peekChar();
     396           0 :             bIdentifierChar = testCharFlags( c, CHAR_IN_IDENTIFIER );
     397           0 :             if( bIdentifierChar )
     398           0 :                 getChar();
     399             :         }
     400             :         while( bIdentifierChar );
     401             : 
     402           0 :         reType = TT_IDENTIFIER;
     403             : 
     404             :         // Schluesselwort-Tabelle
     405           0 :         if (ppListKeyWords != NULL)
     406             :         {
     407           0 :             int nCount = mpActualPos - rpStartPos;
     408             : 
     409             :             // No keyword if string contains char > 255
     410           0 :             bool bCanBeKeyword = true;
     411           0 :             for( int i = 0 ; i < nCount ; i++ )
     412             :             {
     413           0 :                 if( rpStartPos[i] > 255 )
     414             :                 {
     415           0 :                     bCanBeKeyword = false;
     416           0 :                     break;
     417             :                 }
     418             :             }
     419             : 
     420           0 :             if( bCanBeKeyword )
     421             :             {
     422           0 :                 rtl::OUString aKWString(rpStartPos, nCount);
     423             :                 rtl::OString aByteStr = rtl::OUStringToOString(aKWString,
     424           0 :                     RTL_TEXTENCODING_ASCII_US).toAsciiLowerCase();
     425           0 :                 if ( bsearch( aByteStr.getStr(), ppListKeyWords, nKeyWordCount, sizeof( char* ),
     426           0 :                                                                         compare_strings ) )
     427             :                 {
     428           0 :                     reType = TT_KEYWORDS;
     429             : 
     430           0 :                     if (aByteStr.equalsL(RTL_CONSTASCII_STRINGPARAM("rem")))
     431             :                     {
     432             :                         // Alle Zeichen bis Zeilen-Ende oder EOF entfernen
     433           0 :                         sal_Unicode cPeek = peekChar();
     434           0 :                         while( cPeek != CHAR_EOF && testCharFlags( cPeek, CHAR_EOL ) == sal_False )
     435             :                         {
     436           0 :                             c = getChar();
     437           0 :                             cPeek = peekChar();
     438             :                         }
     439             : 
     440           0 :                         reType = TT_COMMENT;
     441             :                     }
     442           0 :                 }
     443             :             }
     444             :         }
     445             :     }
     446             : 
     447             :     // Operator?
     448             :     // only for BASIC '\'' should be a comment, otherwise it is a normal string and handled there
     449           0 :     else if ( ( testCharFlags( c, CHAR_OPERATOR ) == sal_True ) || ( (c == '\'') && (aLanguage==HIGHLIGHT_BASIC)) )
     450             :     {
     451             :         // parameters for SQL view
     452           0 :         if ( (c==':') || (c=='?'))
     453             :         {
     454           0 :             if (c!='?')
     455             :             {
     456             :                 sal_Bool bIdentifierChar;
     457           0 :                 do
     458             :                 {
     459             :                     // Naechstes Zeichen holen
     460           0 :                     c = peekChar();
     461           0 :                     bIdentifierChar = isAlpha(c);
     462           0 :                     if( bIdentifierChar )
     463           0 :                         getChar();
     464             :                 }
     465             :                 while( bIdentifierChar );
     466             :             }
     467           0 :             reType = TT_PARAMETER;
     468             :         }
     469           0 :         else if (c=='-')
     470             :         {
     471           0 :             sal_Unicode cPeekNext = peekChar();
     472           0 :             if (cPeekNext=='-')
     473             :             {
     474             :                 // Alle Zeichen bis Zeilen-Ende oder EOF entfernen
     475           0 :                 while( cPeekNext != CHAR_EOF && testCharFlags( cPeekNext, CHAR_EOL ) == sal_False )
     476             :                 {
     477           0 :                     getChar();
     478           0 :                     cPeekNext = peekChar();
     479             :                 }
     480           0 :                 reType = TT_COMMENT;
     481             :             }
     482             :         }
     483           0 :        else if (c=='/')
     484             :        {
     485           0 :            sal_Unicode cPeekNext = peekChar();
     486           0 :            if (cPeekNext=='/')
     487             :            {
     488             :                // Alle Zeichen bis Zeilen-Ende oder EOF entfernen
     489           0 :                while( cPeekNext != CHAR_EOF && testCharFlags( cPeekNext, CHAR_EOL ) == sal_False )
     490             :                {
     491           0 :                    getChar();
     492           0 :                    cPeekNext = peekChar();
     493             :                }
     494           0 :                reType = TT_COMMENT;
     495             :            }
     496             :        }
     497             :         else
     498             :         {
     499             :             // Kommentar ?
     500           0 :             if ( c == '\'' )
     501             :             {
     502           0 :                 c = getChar();  // '/' entfernen
     503             : 
     504             :                 // Alle Zeichen bis Zeilen-Ende oder EOF entfernen
     505           0 :                 sal_Unicode cPeek = c;
     506           0 :                 while( cPeek != CHAR_EOF && testCharFlags( cPeek, CHAR_EOL ) == sal_False )
     507             :                 {
     508           0 :                     getChar();
     509           0 :                     cPeek = peekChar();
     510             :                 }
     511             : 
     512           0 :                 reType = TT_COMMENT;
     513             :             }
     514             : 
     515             :             // Echter Operator, kann hier einfach behandelt werden,
     516             :             // da nicht der wirkliche Operator, wie z.B. += interessiert,
     517             :             // sondern nur die Tatsache, dass es sich um einen handelt.
     518           0 :             if( reType != TT_COMMENT )
     519             :             {
     520           0 :                 reType = TT_OPERATOR;
     521             :             }
     522             : 
     523             :         }
     524             :     }
     525             : 
     526             :     // Objekt-Trenner? Muss vor Number abgehandelt werden
     527           0 :     else if( c == '.' && ( peekChar() < '0' || peekChar() > '9' ) )
     528             :     {
     529           0 :         reType = TT_OPERATOR;
     530             :     }
     531             : 
     532             :     // Zahl?
     533           0 :     else if( testCharFlags( c, CHAR_START_NUMBER ) == sal_True )
     534             :     {
     535           0 :         reType = TT_NUMBER;
     536             : 
     537             :         // Zahlensystem, 10 = normal, wird bei Oct/Hex geaendert
     538           0 :         int nRadix = 10;
     539             : 
     540             :         // Ist es eine Hex- oder Oct-Zahl?
     541           0 :         if( c == '&' )
     542             :         {
     543             :             // Octal?
     544           0 :             if( peekChar() == 'o' || peekChar() == 'O' )
     545             :             {
     546             :                 // o entfernen
     547           0 :                 getChar();
     548           0 :                 nRadix = 8;     // Octal-Basis
     549             : 
     550             :                 // Alle Ziffern einlesen
     551           0 :                 while( testCharFlags( peekChar(), CHAR_IN_OCT_NUMBER ) )
     552           0 :                     c = getChar();
     553             :             }
     554             :             // Hex?
     555           0 :             else if( peekChar() == 'h' || peekChar() == 'H' )
     556             :             {
     557             :                 // x entfernen
     558           0 :                 getChar();
     559           0 :                 nRadix = 16;     // Hex-Basis
     560             : 
     561             :                 // Alle Ziffern einlesen und puffern
     562           0 :                 while( testCharFlags( peekChar(), CHAR_IN_HEX_NUMBER ) )
     563           0 :                     c = getChar();
     564             :             }
     565             :             else
     566             :             {
     567           0 :                 reType = TT_OPERATOR;
     568             :             }
     569             :         }
     570             : 
     571             :         // Wenn nicht Oct oder Hex als double ansehen
     572           0 :         if( reType == TT_NUMBER && nRadix == 10 )
     573             :         {
     574             :             // Flag, ob das letzte Zeichen ein Exponent war
     575           0 :             sal_Bool bAfterExpChar = sal_False;
     576             : 
     577             :             // Alle Ziffern einlesen
     578           0 :             while( testCharFlags( peekChar(), CHAR_IN_NUMBER ) ||
     579           0 :                     (bAfterExpChar && peekChar() == '+' ) ||
     580           0 :                     (bAfterExpChar && peekChar() == '-' ) )
     581             :                     // Nach Exponent auch +/- OK
     582             :             {
     583           0 :                 c = getChar();                  // Zeichen lesen
     584           0 :                 bAfterExpChar = ( c == 'e' || c == 'E' );
     585             :             }
     586             :         }
     587             : 
     588             :         // reType = TT_NUMBER;
     589             :     }
     590             : 
     591             :     // String?
     592           0 :     else if( testCharFlags( c, CHAR_START_STRING ) == sal_True )
     593             :     {
     594             :         // Merken, welches Zeichen den String eroeffnet hat
     595           0 :         sal_Unicode cEndString = c;
     596           0 :         if( c == '[' )
     597           0 :             cEndString = ']';
     598             : 
     599             :         // Alle Ziffern einlesen und puffern
     600           0 :         while( peekChar() != cEndString )
     601             :         {
     602             :             // #58846 EOF vor getChar() abfangen, damit EOF micht verloren geht
     603           0 :             if( peekChar() == CHAR_EOF )
     604             :             {
     605             :                 // ERROR: unterminated string literal
     606           0 :                 reType = TT_ERROR;
     607           0 :                 break;
     608             :             }
     609           0 :             c = getChar();
     610           0 :             if( testCharFlags( c, CHAR_EOL ) == sal_True )
     611             :             {
     612             :                 // ERROR: unterminated string literal
     613           0 :                 reType = TT_ERROR;
     614           0 :                 break;
     615             :             }
     616             :         }
     617             : 
     618             :         //  Zeichen lesen
     619           0 :         if( reType != TT_ERROR )
     620             :         {
     621           0 :             getChar();
     622           0 :             if( cEndString == ']' )
     623           0 :                 reType = TT_IDENTIFIER;
     624             :             else
     625           0 :                 reType = TT_STRING;
     626             :         }
     627             :     }
     628             : 
     629             :     // Zeilenende?
     630           0 :     else if( testCharFlags( c, CHAR_EOL ) == sal_True )
     631             :     {
     632             :         // Falls ein weiteres anderes EOL-Char folgt, weg damit
     633           0 :         sal_Unicode cNext = peekChar();
     634           0 :         if( cNext != c && testCharFlags( cNext, CHAR_EOL ) == sal_True )
     635           0 :             getChar();
     636             : 
     637             :         // Positions-Daten auf Zeilen-Beginn setzen
     638           0 :         nCol = 0;
     639           0 :         nLine++;
     640             : 
     641           0 :         reType = TT_EOL;
     642             :     }
     643             : 
     644             :     // Alles andere bleibt TT_UNKNOWN
     645             : 
     646             : 
     647             :     // End-Position eintragen
     648           0 :     rpEndPos = mpActualPos;
     649           0 :     return sal_True;
     650             : }
     651             : 
     652           0 : SimpleTokenizer_Impl::SimpleTokenizer_Impl( HighlighterLanguage aLang ): aLanguage(aLang)
     653             : {
     654           0 :     memset( aCharTypeTab, 0, sizeof( aCharTypeTab ) );
     655             : 
     656             :     // Zeichen-Tabelle fuellen
     657             :     sal_uInt16 i;
     658             : 
     659             :     // Zulaessige Zeichen fuer Identifier
     660           0 :     sal_uInt16 nHelpMask = (sal_uInt16)( CHAR_START_IDENTIFIER | CHAR_IN_IDENTIFIER );
     661           0 :     for( i = 'a' ; i <= 'z' ; i++ )
     662           0 :         aCharTypeTab[i] |= nHelpMask;
     663           0 :     for( i = 'A' ; i <= 'Z' ; i++ )
     664           0 :         aCharTypeTab[i] |= nHelpMask;
     665             :     // '_' extra eintragen
     666           0 :     aCharTypeTab[(int)'_'] |= nHelpMask;
     667             :     // AB 23.6.97: '$' ist auch erlaubt
     668           0 :     aCharTypeTab[(int)'$'] |= nHelpMask;
     669             : 
     670             :     // Ziffern (Identifier und Number ist moeglich)
     671             :     nHelpMask = (sal_uInt16)( CHAR_IN_IDENTIFIER | CHAR_START_NUMBER |
     672           0 :                          CHAR_IN_NUMBER | CHAR_IN_HEX_NUMBER );
     673           0 :     for( i = '0' ; i <= '9' ; i++ )
     674           0 :         aCharTypeTab[i] |= nHelpMask;
     675             : 
     676             :     // e und E sowie . von Hand ergaenzen
     677           0 :     aCharTypeTab[(int)'e'] |= CHAR_IN_NUMBER;
     678           0 :     aCharTypeTab[(int)'E'] |= CHAR_IN_NUMBER;
     679           0 :     aCharTypeTab[(int)'.'] |= (sal_uInt16)( CHAR_IN_NUMBER | CHAR_START_NUMBER );
     680           0 :     aCharTypeTab[(int)'&'] |= CHAR_START_NUMBER;
     681             : 
     682             :     // Hex-Ziffern
     683           0 :     for( i = 'a' ; i <= 'f' ; i++ )
     684           0 :         aCharTypeTab[i] |= CHAR_IN_HEX_NUMBER;
     685           0 :     for( i = 'A' ; i <= 'F' ; i++ )
     686           0 :         aCharTypeTab[i] |= CHAR_IN_HEX_NUMBER;
     687             : 
     688             :     // Oct-Ziffern
     689           0 :     for( i = '0' ; i <= '7' ; i++ )
     690           0 :         aCharTypeTab[i] |= CHAR_IN_OCT_NUMBER;
     691             : 
     692             :     // String-Beginn/End-Zeichen
     693           0 :     aCharTypeTab[(int)'\''] |= CHAR_START_STRING;
     694           0 :     aCharTypeTab[(int)'\"'] |= CHAR_START_STRING;
     695           0 :     aCharTypeTab[(int)'[']  |= CHAR_START_STRING;
     696           0 :     aCharTypeTab[(int)'`']  |= CHAR_START_STRING;
     697             : 
     698             :     // Operator-Zeichen
     699           0 :     aCharTypeTab[(int)'!'] |= CHAR_OPERATOR;
     700           0 :     aCharTypeTab[(int)'%'] |= CHAR_OPERATOR;
     701             :     // aCharTypeTab[(int)'&'] |= CHAR_OPERATOR;     Removed because of #i14140
     702           0 :     aCharTypeTab[(int)'('] |= CHAR_OPERATOR;
     703           0 :     aCharTypeTab[(int)')'] |= CHAR_OPERATOR;
     704           0 :     aCharTypeTab[(int)'*'] |= CHAR_OPERATOR;
     705           0 :     aCharTypeTab[(int)'+'] |= CHAR_OPERATOR;
     706           0 :     aCharTypeTab[(int)','] |= CHAR_OPERATOR;
     707           0 :     aCharTypeTab[(int)'-'] |= CHAR_OPERATOR;
     708           0 :     aCharTypeTab[(int)'/'] |= CHAR_OPERATOR;
     709           0 :     aCharTypeTab[(int)':'] |= CHAR_OPERATOR;
     710           0 :     aCharTypeTab[(int)'<'] |= CHAR_OPERATOR;
     711           0 :     aCharTypeTab[(int)'='] |= CHAR_OPERATOR;
     712           0 :     aCharTypeTab[(int)'>'] |= CHAR_OPERATOR;
     713           0 :     aCharTypeTab[(int)'?'] |= CHAR_OPERATOR;
     714           0 :     aCharTypeTab[(int)'^'] |= CHAR_OPERATOR;
     715           0 :     aCharTypeTab[(int)'|'] |= CHAR_OPERATOR;
     716           0 :     aCharTypeTab[(int)'~'] |= CHAR_OPERATOR;
     717           0 :     aCharTypeTab[(int)'{'] |= CHAR_OPERATOR;
     718           0 :     aCharTypeTab[(int)'}'] |= CHAR_OPERATOR;
     719             :     // aCharTypeTab[(int)'['] |= CHAR_OPERATOR;     Removed because of #i17826
     720           0 :     aCharTypeTab[(int)']'] |= CHAR_OPERATOR;
     721           0 :     aCharTypeTab[(int)';'] |= CHAR_OPERATOR;
     722             : 
     723             :     // Space
     724           0 :     aCharTypeTab[(int)' ' ] |= CHAR_SPACE;
     725           0 :     aCharTypeTab[(int)'\t'] |= CHAR_SPACE;
     726             : 
     727             :     // Zeilen-Ende-Zeichen
     728           0 :     aCharTypeTab[(int)'\r'] |= CHAR_EOL;
     729           0 :     aCharTypeTab[(int)'\n'] |= CHAR_EOL;
     730             : 
     731           0 :     ppListKeyWords = NULL;
     732           0 : }
     733             : 
     734           0 : SimpleTokenizer_Impl::~SimpleTokenizer_Impl( void )
     735             : {
     736           0 : }
     737             : 
     738           0 : SimpleTokenizer_Impl* getSimpleTokenizer( void )
     739             : {
     740             :     static SimpleTokenizer_Impl* pSimpleTokenizer = NULL;
     741           0 :     if( !pSimpleTokenizer )
     742           0 :         pSimpleTokenizer = new SimpleTokenizer_Impl();
     743           0 :     return pSimpleTokenizer;
     744             : }
     745             : 
     746             : // Heraussuchen der jeweils naechsten Funktion aus einem JavaScript-Modul
     747           0 : sal_uInt16 SimpleTokenizer_Impl::parseLine( sal_uInt32 nParseLine, const String* aSource )
     748             : {
     749             :     // Position auf den Anfang des Source-Strings setzen
     750           0 :     mpStringBegin = mpActualPos = aSource->GetBuffer();
     751             : 
     752             :     // Zeile und Spalte initialisieren
     753           0 :     nLine = nParseLine;
     754           0 :     nCol = 0L;
     755             : 
     756             :     // Variablen fuer die Out-Parameter
     757             :     TokenTypes eType;
     758             :     const sal_Unicode* pStartPos;
     759             :     const sal_Unicode* pEndPos;
     760             : 
     761             :     // Schleife ueber alle Tokens
     762           0 :     sal_uInt16 nTokenCount = 0;
     763           0 :     while( getNextToken( eType, pStartPos, pEndPos ) )
     764           0 :         nTokenCount++;
     765             : 
     766           0 :     return nTokenCount;
     767             : }
     768             : 
     769           0 : void SimpleTokenizer_Impl::getHighlightPortions( sal_uInt32 nParseLine, const String& rLine,
     770             :                                                     /*out*/HighlightPortions& portions  )
     771             : {
     772             :     // Position auf den Anfang des Source-Strings setzen
     773           0 :     mpStringBegin = mpActualPos = rLine.GetBuffer();
     774             : 
     775             :     // Zeile und Spalte initialisieren
     776           0 :     nLine = nParseLine;
     777           0 :     nCol = 0L;
     778             : 
     779             :     // Variablen fuer die Out-Parameter
     780             :     TokenTypes eType;
     781             :     const sal_Unicode* pStartPos;
     782             :     const sal_Unicode* pEndPos;
     783             : 
     784             :     // Schleife ueber alle Tokens
     785           0 :     while( getNextToken( eType, pStartPos, pEndPos ) )
     786             :     {
     787             :         HighlightPortion portion;
     788             : 
     789           0 :         portion.nBegin = (sal_uInt16)(pStartPos - mpStringBegin);
     790           0 :         portion.nEnd = (sal_uInt16)(pEndPos - mpStringBegin);
     791           0 :         portion.tokenType = eType;
     792             : 
     793           0 :         portions.push_back(portion);
     794             :     }
     795           0 : }
     796             : 
     797             : 
     798             : //////////////////////////////////////////////////////////////////////////
     799             : // Implementierung des SyntaxHighlighter
     800             : 
     801           0 : SyntaxHighlighter::SyntaxHighlighter()
     802             : {
     803           0 :     m_pSimpleTokenizer = 0;
     804           0 :     m_pKeyWords = NULL;
     805           0 :     m_nKeyWordCount = 0;
     806           0 : }
     807             : 
     808           0 : SyntaxHighlighter::~SyntaxHighlighter()
     809             : {
     810           0 :     delete m_pSimpleTokenizer;
     811           0 :     delete m_pKeyWords;
     812           0 : }
     813             : 
     814           0 : void SyntaxHighlighter::initialize( HighlighterLanguage eLanguage_ )
     815             : {
     816           0 :     eLanguage = eLanguage_;
     817           0 :     delete m_pSimpleTokenizer;
     818           0 :     m_pSimpleTokenizer = new SimpleTokenizer_Impl(eLanguage);
     819             : 
     820           0 :     switch (eLanguage)
     821             :     {
     822             :         case HIGHLIGHT_BASIC:
     823             :             m_pSimpleTokenizer->setKeyWords( strListBasicKeyWords,
     824           0 :                                             sizeof( strListBasicKeyWords ) / sizeof( char* ));
     825           0 :             break;
     826             :         case HIGHLIGHT_SQL:
     827             :             m_pSimpleTokenizer->setKeyWords( strListSqlKeyWords,
     828           0 :                                             sizeof( strListSqlKeyWords ) / sizeof( char* ));
     829           0 :             break;
     830             :         default:
     831           0 :             m_pSimpleTokenizer->setKeyWords( NULL, 0 );
     832             :     }
     833           0 : }
     834             : 
     835           0 : const Range SyntaxHighlighter::notifyChange( sal_uInt32 nLine, sal_Int32 nLineCountDifference,
     836             :                                 const String* pChangedLines, sal_uInt32 nArrayLength)
     837             : {
     838             :     (void)nLineCountDifference;
     839             : 
     840           0 :     for( sal_uInt32 i=0 ; i < nArrayLength ; i++ )
     841           0 :         m_pSimpleTokenizer->parseLine(nLine+i, &pChangedLines[i]);
     842             : 
     843           0 :     return Range( nLine, nLine + nArrayLength-1 );
     844             : }
     845             : 
     846           0 : void SyntaxHighlighter::getHighlightPortions( sal_uInt32 nLine, const String& rLine,
     847             :                                             /*out*/HighlightPortions& portions )
     848             : {
     849           0 :     m_pSimpleTokenizer->getHighlightPortions( nLine, rLine, portions );
     850           0 : }
     851             : 
     852             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10