1e1f63238SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3e1f63238SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4e1f63238SAndrew Rist * or more contributor license agreements. See the NOTICE file 5e1f63238SAndrew Rist * distributed with this work for additional information 6e1f63238SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7e1f63238SAndrew Rist * to you under the Apache License, Version 2.0 (the 8e1f63238SAndrew Rist * "License"); you may not use this file except in compliance 9e1f63238SAndrew Rist * with the License. You may obtain a copy of the License at 10cdf0e10cSrcweir * 11e1f63238SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 13e1f63238SAndrew Rist * Unless required by applicable law or agreed to in writing, 14e1f63238SAndrew Rist * software distributed under the License is distributed on an 15e1f63238SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16e1f63238SAndrew Rist * KIND, either express or implied. See the License for the 17e1f63238SAndrew Rist * specific language governing permissions and limitations 18e1f63238SAndrew Rist * under the License. 19cdf0e10cSrcweir * 20e1f63238SAndrew Rist *************************************************************/ 21e1f63238SAndrew Rist 22cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 23cdf0e10cSrcweir #include "precompiled_basic.hxx" 24cdf0e10cSrcweir 25cdf0e10cSrcweir #include "sbcomp.hxx" 26cdf0e10cSrcweir #include <stdio.h> 27cdf0e10cSrcweir #include <string.h> 28cdf0e10cSrcweir #include <ctype.h> 29cdf0e10cSrcweir #if defined UNX 30cdf0e10cSrcweir #include <stdlib.h> 31cdf0e10cSrcweir #else 32cdf0e10cSrcweir #include <math.h> // atof() 33cdf0e10cSrcweir #endif 34cdf0e10cSrcweir #include <rtl/math.hxx> 35cdf0e10cSrcweir #include <vcl/svapp.hxx> 36cdf0e10cSrcweir #include <unotools/charclass.hxx> 37cdf0e10cSrcweir 38cdf0e10cSrcweir #include <runtime.hxx> 39cdf0e10cSrcweir 40cdf0e10cSrcweir SbiScanner::SbiScanner( const ::rtl::OUString& rBuf, StarBASIC* p ) : aBuf( rBuf ) 41cdf0e10cSrcweir { 42cdf0e10cSrcweir pBasic = p; 43cdf0e10cSrcweir pLine = NULL; 44cdf0e10cSrcweir nVal = 0; 45cdf0e10cSrcweir eScanType = SbxVARIANT; 46cdf0e10cSrcweir nErrors = 0; 47cdf0e10cSrcweir nBufPos = 0; 48cdf0e10cSrcweir nCurCol1 = 0; 49cdf0e10cSrcweir nSavedCol1 = 0; 50cdf0e10cSrcweir nColLock = 0; 51cdf0e10cSrcweir nLine = 0; 52cdf0e10cSrcweir nCol1 = 0; 53cdf0e10cSrcweir nCol2 = 0; 54cdf0e10cSrcweir nCol = 0; 55cdf0e10cSrcweir bError = 56cdf0e10cSrcweir bAbort = 57cdf0e10cSrcweir bSpaces = 58cdf0e10cSrcweir bNumber = 59cdf0e10cSrcweir bSymbol = 60cdf0e10cSrcweir bUsedForHilite = 61cdf0e10cSrcweir bCompatible = 62cdf0e10cSrcweir bVBASupportOn = 63cdf0e10cSrcweir bPrevLineExtentsComment = sal_False; 64cdf0e10cSrcweir bHash = 65cdf0e10cSrcweir bErrors = sal_True; 66cdf0e10cSrcweir } 67cdf0e10cSrcweir 68cdf0e10cSrcweir SbiScanner::~SbiScanner() 69cdf0e10cSrcweir {} 70cdf0e10cSrcweir 71cdf0e10cSrcweir void SbiScanner::LockColumn() 72cdf0e10cSrcweir { 73cdf0e10cSrcweir if( !nColLock++ ) 74cdf0e10cSrcweir nSavedCol1 = nCol1; 75cdf0e10cSrcweir } 76cdf0e10cSrcweir 77cdf0e10cSrcweir void SbiScanner::UnlockColumn() 78cdf0e10cSrcweir { 79cdf0e10cSrcweir if( nColLock ) 80cdf0e10cSrcweir nColLock--; 81cdf0e10cSrcweir } 82cdf0e10cSrcweir 83cdf0e10cSrcweir void SbiScanner::GenError( SbError code ) 84cdf0e10cSrcweir { 85cdf0e10cSrcweir if( GetSbData()->bBlockCompilerError ) 86cdf0e10cSrcweir { 87cdf0e10cSrcweir bAbort = sal_True; 88cdf0e10cSrcweir return; 89cdf0e10cSrcweir } 90cdf0e10cSrcweir if( !bError && bErrors ) 91cdf0e10cSrcweir { 92cdf0e10cSrcweir sal_Bool bRes = sal_True; 93cdf0e10cSrcweir // Nur einen Fehler pro Statement reporten 94cdf0e10cSrcweir bError = sal_True; 95cdf0e10cSrcweir if( pBasic ) 96cdf0e10cSrcweir { 97cdf0e10cSrcweir // Falls EXPECTED oder UNEXPECTED kommen sollte, bezieht es sich 98*29d7882dSmseidel // immer auf das letzte Token, also die Col1 übernehmen 99cdf0e10cSrcweir sal_uInt16 nc = nColLock ? nSavedCol1 : nCol1; 100cdf0e10cSrcweir switch( code ) 101cdf0e10cSrcweir { 102cdf0e10cSrcweir case SbERR_EXPECTED: 103cdf0e10cSrcweir case SbERR_UNEXPECTED: 104cdf0e10cSrcweir case SbERR_SYMBOL_EXPECTED: 105cdf0e10cSrcweir case SbERR_LABEL_EXPECTED: 106cdf0e10cSrcweir nc = nCol1; 107cdf0e10cSrcweir if( nc > nCol2 ) nCol2 = nc; 108cdf0e10cSrcweir break; 109cdf0e10cSrcweir } 110cdf0e10cSrcweir bRes = pBasic->CError( code, aError, nLine, nc, nCol2 ); 111cdf0e10cSrcweir } 112cdf0e10cSrcweir bAbort |= !bRes | 113cdf0e10cSrcweir ( code == SbERR_NO_MEMORY || code == SbERR_PROG_TOO_LARGE ); 114cdf0e10cSrcweir } 115cdf0e10cSrcweir if( bErrors ) 116cdf0e10cSrcweir nErrors++; 117cdf0e10cSrcweir } 118cdf0e10cSrcweir 119*29d7882dSmseidel // Falls sofort ein Doppelpunkt folgt, wird sal_True zurückgeliefert. 120cdf0e10cSrcweir // Wird von SbiTokenizer::MayBeLabel() verwendet, um einen Label zu erkennen 121cdf0e10cSrcweir 122cdf0e10cSrcweir sal_Bool SbiScanner::DoesColonFollow() 123cdf0e10cSrcweir { 124cdf0e10cSrcweir if( pLine && *pLine == ':' ) 125cdf0e10cSrcweir { 126cdf0e10cSrcweir pLine++; nCol++; return sal_True; 127cdf0e10cSrcweir } 128cdf0e10cSrcweir else return sal_False; 129cdf0e10cSrcweir } 130cdf0e10cSrcweir 131cdf0e10cSrcweir // Testen auf ein legales Suffix 132cdf0e10cSrcweir 133cdf0e10cSrcweir static SbxDataType GetSuffixType( sal_Unicode c ) 134cdf0e10cSrcweir { 135cdf0e10cSrcweir static String aSuffixesStr = String::CreateFromAscii( "%&!#@ $" ); 136cdf0e10cSrcweir if( c ) 137cdf0e10cSrcweir { 138cdf0e10cSrcweir sal_uInt32 n = aSuffixesStr.Search( c ); 139cdf0e10cSrcweir if( STRING_NOTFOUND != n && c != ' ' ) 140cdf0e10cSrcweir return SbxDataType( (sal_uInt16) n + SbxINTEGER ); 141cdf0e10cSrcweir } 142cdf0e10cSrcweir return SbxVARIANT; 143cdf0e10cSrcweir } 144cdf0e10cSrcweir 145*29d7882dSmseidel // Einlesen des nächsten Symbols in die Variablen aSym, nVal und eType 146cdf0e10cSrcweir // Returnwert ist sal_False bei EOF oder Fehlern 147cdf0e10cSrcweir #define BUF_SIZE 80 148cdf0e10cSrcweir 149cdf0e10cSrcweir namespace { 150cdf0e10cSrcweir 151cdf0e10cSrcweir /** Returns true, if the passed character is a white space character. */ 152cdf0e10cSrcweir inline bool lclIsWhitespace( sal_Unicode cChar ) 153cdf0e10cSrcweir { 154cdf0e10cSrcweir return (cChar == ' ') || (cChar == '\t') || (cChar == '\f'); 155cdf0e10cSrcweir } 156cdf0e10cSrcweir 157cdf0e10cSrcweir } // namespace 158cdf0e10cSrcweir 159cdf0e10cSrcweir sal_Bool SbiScanner::NextSym() 160cdf0e10cSrcweir { 161*29d7882dSmseidel // Für den EOLN-Fall merken 162cdf0e10cSrcweir sal_uInt16 nOldLine = nLine; 163cdf0e10cSrcweir sal_uInt16 nOldCol1 = nCol1; 164cdf0e10cSrcweir sal_uInt16 nOldCol2 = nCol2; 165cdf0e10cSrcweir sal_Unicode buf[ BUF_SIZE ], *p = buf; 166cdf0e10cSrcweir bHash = sal_False; 167cdf0e10cSrcweir 168cdf0e10cSrcweir eScanType = SbxVARIANT; 169cdf0e10cSrcweir aSym.Erase(); 170cdf0e10cSrcweir bSymbol = 171cdf0e10cSrcweir bNumber = bSpaces = sal_False; 172cdf0e10cSrcweir 173cdf0e10cSrcweir // Zeile einlesen? 174cdf0e10cSrcweir if( !pLine ) 175cdf0e10cSrcweir { 176cdf0e10cSrcweir sal_Int32 n = nBufPos; 177cdf0e10cSrcweir sal_Int32 nLen = aBuf.getLength(); 178cdf0e10cSrcweir if( nBufPos >= nLen ) 179cdf0e10cSrcweir return sal_False; 180cdf0e10cSrcweir const sal_Unicode* p2 = aBuf.getStr(); 181cdf0e10cSrcweir p2 += n; 182cdf0e10cSrcweir while( ( n < nLen ) && ( *p2 != '\n' ) && ( *p2 != '\r' ) ) 183cdf0e10cSrcweir p2++, n++; 184cdf0e10cSrcweir // #163944# ignore trailing whitespace 185cdf0e10cSrcweir sal_Int32 nCopyEndPos = n; 186cdf0e10cSrcweir while( (nBufPos < nCopyEndPos) && lclIsWhitespace( aBuf[ nCopyEndPos - 1 ] ) ) 187cdf0e10cSrcweir --nCopyEndPos; 188cdf0e10cSrcweir aLine = aBuf.copy( nBufPos, nCopyEndPos - nBufPos ); 189cdf0e10cSrcweir if( n < nLen ) 190cdf0e10cSrcweir { 191cdf0e10cSrcweir if( *p2 == '\r' && *( p2+1 ) == '\n' ) 192cdf0e10cSrcweir n += 2; 193cdf0e10cSrcweir else 194cdf0e10cSrcweir n++; 195cdf0e10cSrcweir } 196cdf0e10cSrcweir nBufPos = n; 197cdf0e10cSrcweir pLine = aLine.getStr(); 198cdf0e10cSrcweir nOldLine = ++nLine; 199cdf0e10cSrcweir nCol = nCol1 = nCol2 = nOldCol1 = nOldCol2 = 0; 200cdf0e10cSrcweir nColLock = 0; 201cdf0e10cSrcweir } 202cdf0e10cSrcweir 203cdf0e10cSrcweir // Leerstellen weg: 204cdf0e10cSrcweir while( lclIsWhitespace( *pLine ) ) 205cdf0e10cSrcweir pLine++, nCol++, bSpaces = sal_True; 206cdf0e10cSrcweir 207cdf0e10cSrcweir nCol1 = nCol; 208cdf0e10cSrcweir 209cdf0e10cSrcweir // nur Leerzeile? 210cdf0e10cSrcweir if( !*pLine ) 211cdf0e10cSrcweir goto eoln; 212cdf0e10cSrcweir 213cdf0e10cSrcweir if( bPrevLineExtentsComment ) 214cdf0e10cSrcweir goto PrevLineCommentLbl; 215cdf0e10cSrcweir 216cdf0e10cSrcweir if( *pLine == '#' ) 217cdf0e10cSrcweir { 218cdf0e10cSrcweir pLine++; 219cdf0e10cSrcweir nCol++; 220cdf0e10cSrcweir bHash = sal_True; 221cdf0e10cSrcweir } 222cdf0e10cSrcweir 223cdf0e10cSrcweir // Symbol? Dann Zeichen kopieren. 224cdf0e10cSrcweir if( BasicSimpleCharClass::isAlpha( *pLine, bCompatible ) || *pLine == '_' ) 225cdf0e10cSrcweir { 226cdf0e10cSrcweir // Wenn nach '_' nichts kommt, ist es ein Zeilenabschluss! 227cdf0e10cSrcweir if( *pLine == '_' && !*(pLine+1) ) 228cdf0e10cSrcweir { pLine++; 229cdf0e10cSrcweir goto eoln; } 230cdf0e10cSrcweir bSymbol = sal_True; 231cdf0e10cSrcweir short n = nCol; 232cdf0e10cSrcweir for ( ; (BasicSimpleCharClass::isAlphaNumeric( *pLine, bCompatible ) || ( *pLine == '_' ) ); pLine++ ) 233cdf0e10cSrcweir nCol++; 234cdf0e10cSrcweir aSym = aLine.copy( n, nCol - n ); 235cdf0e10cSrcweir 236cdf0e10cSrcweir // Special handling for "go to" 237cdf0e10cSrcweir if( bCompatible && *pLine && aSym.EqualsIgnoreCaseAscii( "go" ) ) 238cdf0e10cSrcweir { 239cdf0e10cSrcweir const sal_Unicode* pTestLine = pLine; 240cdf0e10cSrcweir short nTestCol = nCol; 241cdf0e10cSrcweir while( lclIsWhitespace( *pTestLine ) ) 242cdf0e10cSrcweir { 243cdf0e10cSrcweir pTestLine++; 244cdf0e10cSrcweir nTestCol++; 245cdf0e10cSrcweir } 246cdf0e10cSrcweir 247cdf0e10cSrcweir if( *pTestLine && *(pTestLine + 1) ) 248cdf0e10cSrcweir { 249cdf0e10cSrcweir String aTestSym = aLine.copy( nTestCol, 2 ); 250cdf0e10cSrcweir if( aTestSym.EqualsIgnoreCaseAscii( "to" ) ) 251cdf0e10cSrcweir { 252cdf0e10cSrcweir aSym = String::CreateFromAscii( "goto" ); 253cdf0e10cSrcweir pLine = pTestLine + 2; 254cdf0e10cSrcweir nCol = nTestCol + 2; 255cdf0e10cSrcweir } 256cdf0e10cSrcweir } 257cdf0e10cSrcweir } 258cdf0e10cSrcweir 259cdf0e10cSrcweir // Abschliessendes '_' durch Space ersetzen, wenn Zeilenende folgt 260cdf0e10cSrcweir // (sonst falsche Zeilenfortsetzung) 261cdf0e10cSrcweir if( !bUsedForHilite && !*pLine && *(pLine-1) == '_' ) 262cdf0e10cSrcweir { 263cdf0e10cSrcweir aSym.GetBufferAccess(); // #109693 force copy if necessary 264cdf0e10cSrcweir *((sal_Unicode*)(pLine-1)) = ' '; // cast wegen const 265cdf0e10cSrcweir } 266cdf0e10cSrcweir // Typkennung? 267cdf0e10cSrcweir // Das Ausrufezeichen bitte nicht testen, wenn 268cdf0e10cSrcweir // danach noch ein Symbol anschliesst 269cdf0e10cSrcweir else if( *pLine != '!' || !BasicSimpleCharClass::isAlpha( pLine[ 1 ], bCompatible ) ) 270cdf0e10cSrcweir { 271cdf0e10cSrcweir SbxDataType t = GetSuffixType( *pLine ); 272cdf0e10cSrcweir if( t != SbxVARIANT ) 273cdf0e10cSrcweir { 274cdf0e10cSrcweir eScanType = t; 275cdf0e10cSrcweir pLine++; 276cdf0e10cSrcweir nCol++; 277cdf0e10cSrcweir } 278cdf0e10cSrcweir } 279cdf0e10cSrcweir } 280cdf0e10cSrcweir 281cdf0e10cSrcweir // Zahl? Dann einlesen und konvertieren. 282cdf0e10cSrcweir else if( BasicSimpleCharClass::isDigit( *pLine & 0xFF ) 283cdf0e10cSrcweir || ( *pLine == '.' && BasicSimpleCharClass::isDigit( *(pLine+1) & 0xFF ) ) ) 284cdf0e10cSrcweir { 285cdf0e10cSrcweir short exp = 0; 286cdf0e10cSrcweir short comma = 0; 287cdf0e10cSrcweir short ndig = 0; 288cdf0e10cSrcweir short ncdig = 0; 289cdf0e10cSrcweir eScanType = SbxDOUBLE; 290cdf0e10cSrcweir sal_Bool bBufOverflow = sal_False; 291cdf0e10cSrcweir while( strchr( "0123456789.DEde", *pLine ) && *pLine ) 292cdf0e10cSrcweir { 293cdf0e10cSrcweir // AB 4.1.1996: Buffer voll? -> leer weiter scannen 294cdf0e10cSrcweir if( (p-buf) == (BUF_SIZE-1) ) 295cdf0e10cSrcweir { 296cdf0e10cSrcweir bBufOverflow = sal_True; 297cdf0e10cSrcweir pLine++, nCol++; 298cdf0e10cSrcweir continue; 299cdf0e10cSrcweir } 300cdf0e10cSrcweir // Komma oder Exponent? 301cdf0e10cSrcweir if( *pLine == '.' ) 302cdf0e10cSrcweir { 303cdf0e10cSrcweir if( ++comma > 1 ) 304cdf0e10cSrcweir { 305cdf0e10cSrcweir pLine++; nCol++; continue; 306cdf0e10cSrcweir } 307cdf0e10cSrcweir else *p++ = *pLine++, nCol++; 308cdf0e10cSrcweir } 309cdf0e10cSrcweir else if( strchr( "DdEe", *pLine ) ) 310cdf0e10cSrcweir { 311cdf0e10cSrcweir if (++exp > 1) 312cdf0e10cSrcweir { 313cdf0e10cSrcweir pLine++; nCol++; continue; 314cdf0e10cSrcweir } 315cdf0e10cSrcweir // if( toupper( *pLine ) == 'D' ) 316cdf0e10cSrcweir // eScanType = SbxDOUBLE; 317cdf0e10cSrcweir *p++ = 'E'; pLine++; nCol++; 318cdf0e10cSrcweir // Vorzeichen hinter Exponent? 319cdf0e10cSrcweir if( *pLine == '+' ) 320cdf0e10cSrcweir pLine++, nCol++; 321cdf0e10cSrcweir else 322cdf0e10cSrcweir if( *pLine == '-' ) 323cdf0e10cSrcweir *p++ = *pLine++, nCol++; 324cdf0e10cSrcweir } 325cdf0e10cSrcweir else 326cdf0e10cSrcweir { 327cdf0e10cSrcweir *p++ = *pLine++, nCol++; 328cdf0e10cSrcweir if( comma && !exp ) ncdig++; 329cdf0e10cSrcweir } 330cdf0e10cSrcweir if (!exp) ndig++; 331cdf0e10cSrcweir } 332cdf0e10cSrcweir *p = 0; 333cdf0e10cSrcweir aSym = p; bNumber = sal_True; 334cdf0e10cSrcweir // Komma, Exponent mehrfach vorhanden? 335cdf0e10cSrcweir if( comma > 1 || exp > 1 ) 336cdf0e10cSrcweir { aError = '.'; 337cdf0e10cSrcweir GenError( SbERR_BAD_CHAR_IN_NUMBER ); } 338cdf0e10cSrcweir 339cdf0e10cSrcweir // #57844 Lokalisierte Funktion benutzen 340cdf0e10cSrcweir nVal = rtl_math_uStringToDouble( buf, buf+(p-buf), '.', ',', NULL, NULL ); 341cdf0e10cSrcweir // ALT: nVal = atof( buf ); 342cdf0e10cSrcweir 343cdf0e10cSrcweir ndig = ndig - comma; 344cdf0e10cSrcweir if( !comma && !exp ) 345cdf0e10cSrcweir { 346cdf0e10cSrcweir if( nVal >= SbxMININT && nVal <= SbxMAXINT ) 347cdf0e10cSrcweir eScanType = SbxINTEGER; 348cdf0e10cSrcweir else 349cdf0e10cSrcweir if( nVal >= SbxMINLNG && nVal <= SbxMAXLNG ) 350cdf0e10cSrcweir eScanType = SbxLONG; 351cdf0e10cSrcweir } 352cdf0e10cSrcweir if( bBufOverflow ) 353cdf0e10cSrcweir GenError( SbERR_MATH_OVERFLOW ); 354*29d7882dSmseidel // zu viele Zahlen für SINGLE? 355cdf0e10cSrcweir // if (ndig > 15 || ncdig > 6) 356cdf0e10cSrcweir // eScanType = SbxDOUBLE; 357cdf0e10cSrcweir // else 358cdf0e10cSrcweir // if( nVal > SbxMAXSNG || nVal < SbxMINSNG ) 359cdf0e10cSrcweir // eScanType = SbxDOUBLE; 360cdf0e10cSrcweir 361cdf0e10cSrcweir // Typkennung? 362cdf0e10cSrcweir SbxDataType t = GetSuffixType( *pLine ); 363cdf0e10cSrcweir if( t != SbxVARIANT ) 364cdf0e10cSrcweir { 365cdf0e10cSrcweir eScanType = t; 366cdf0e10cSrcweir pLine++; 367cdf0e10cSrcweir nCol++; 368cdf0e10cSrcweir } 369cdf0e10cSrcweir } 370cdf0e10cSrcweir 371cdf0e10cSrcweir // Hex/Oktalzahl? Einlesen und konvertieren: 372cdf0e10cSrcweir else if( *pLine == '&' ) 373cdf0e10cSrcweir { 374cdf0e10cSrcweir pLine++; nCol++; 375cdf0e10cSrcweir sal_Unicode cmp1[] = { '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F', 0 }; 376cdf0e10cSrcweir sal_Unicode cmp2[] = { '0', '1', '2', '3', '4', '5', '6', '7', 0 }; 377cdf0e10cSrcweir sal_Unicode *cmp = cmp1; 378cdf0e10cSrcweir //char *cmp = "0123456789ABCDEF"; 379cdf0e10cSrcweir sal_Unicode base = 16; 380cdf0e10cSrcweir sal_Unicode ndig = 8; 381cdf0e10cSrcweir sal_Unicode xch = *pLine++ & 0xFF; nCol++; 382cdf0e10cSrcweir switch( toupper( xch ) ) 383cdf0e10cSrcweir { 384cdf0e10cSrcweir case 'O': 385cdf0e10cSrcweir cmp = cmp2; base = 8; ndig = 11; break; 386cdf0e10cSrcweir //cmp = "01234567"; base = 8; ndig = 11; break; 387cdf0e10cSrcweir case 'H': 388cdf0e10cSrcweir break; 389cdf0e10cSrcweir default : 390cdf0e10cSrcweir // Wird als Operator angesehen 391cdf0e10cSrcweir pLine--; nCol--; nCol1 = nCol-1; aSym = '&'; return SYMBOL; 392cdf0e10cSrcweir } 393cdf0e10cSrcweir bNumber = sal_True; 394cdf0e10cSrcweir long l = 0; 395cdf0e10cSrcweir int i; 396cdf0e10cSrcweir sal_Bool bBufOverflow = sal_False; 397cdf0e10cSrcweir while( BasicSimpleCharClass::isAlphaNumeric( *pLine & 0xFF, bCompatible ) ) 398cdf0e10cSrcweir { 399cdf0e10cSrcweir sal_Unicode ch = sal::static_int_cast< sal_Unicode >( 400cdf0e10cSrcweir toupper( *pLine & 0xFF ) ); 401cdf0e10cSrcweir pLine++; nCol++; 402cdf0e10cSrcweir // AB 4.1.1996: Buffer voll, leer weiter scannen 403cdf0e10cSrcweir if( (p-buf) == (BUF_SIZE-1) ) 404cdf0e10cSrcweir bBufOverflow = sal_True; 405cdf0e10cSrcweir else if( String( cmp ).Search( ch ) != STRING_NOTFOUND ) 406cdf0e10cSrcweir //else if( strchr( cmp, ch ) ) 407cdf0e10cSrcweir *p++ = ch; 408cdf0e10cSrcweir else 409cdf0e10cSrcweir { 410cdf0e10cSrcweir aError = ch; 411cdf0e10cSrcweir GenError( SbERR_BAD_CHAR_IN_NUMBER ); 412cdf0e10cSrcweir } 413cdf0e10cSrcweir } 414cdf0e10cSrcweir *p = 0; 415cdf0e10cSrcweir for( p = buf; *p; p++ ) 416cdf0e10cSrcweir { 417cdf0e10cSrcweir i = (*p & 0xFF) - '0'; 418cdf0e10cSrcweir if( i > 9 ) i -= 7; 419cdf0e10cSrcweir l = ( l * base ) + i; 420cdf0e10cSrcweir if( !ndig-- ) 421cdf0e10cSrcweir { 422cdf0e10cSrcweir GenError( SbERR_MATH_OVERFLOW ); break; 423cdf0e10cSrcweir } 424cdf0e10cSrcweir } 425cdf0e10cSrcweir if( *pLine == '&' ) pLine++, nCol++; 426cdf0e10cSrcweir nVal = (double) l; 427cdf0e10cSrcweir eScanType = ( l >= SbxMININT && l <= SbxMAXINT ) ? SbxINTEGER : SbxLONG; 428cdf0e10cSrcweir if( bBufOverflow ) 429cdf0e10cSrcweir GenError( SbERR_MATH_OVERFLOW ); 430cdf0e10cSrcweir } 431cdf0e10cSrcweir 432cdf0e10cSrcweir // Strings: 433cdf0e10cSrcweir else if( *pLine == '"' || *pLine == '[' ) 434cdf0e10cSrcweir { 435cdf0e10cSrcweir sal_Unicode cSep = *pLine; 436cdf0e10cSrcweir if( cSep == '[' ) 437cdf0e10cSrcweir bSymbol = sal_True, cSep = ']'; 438cdf0e10cSrcweir short n = nCol+1; 439cdf0e10cSrcweir while( *pLine ) 440cdf0e10cSrcweir { 441cdf0e10cSrcweir do pLine++, nCol++; 442cdf0e10cSrcweir while( *pLine && ( *pLine != cSep ) ); 443cdf0e10cSrcweir if( *pLine == cSep ) 444cdf0e10cSrcweir { 445cdf0e10cSrcweir pLine++; nCol++; 446cdf0e10cSrcweir if( *pLine != cSep || cSep == ']' ) break; 447cdf0e10cSrcweir } else aError = cSep, GenError( SbERR_EXPECTED ); 448cdf0e10cSrcweir } 449*29d7882dSmseidel // If VBA Interop then doesn't eat the [] chars 450cdf0e10cSrcweir if ( cSep == ']' && bVBASupportOn ) 451cdf0e10cSrcweir aSym = aLine.copy( n - 1, nCol - n + 1); 452cdf0e10cSrcweir else 453cdf0e10cSrcweir aSym = aLine.copy( n, nCol - n - 1 ); 454cdf0e10cSrcweir // Doppelte Stringbegrenzer raus 455cdf0e10cSrcweir String s( cSep ); 456cdf0e10cSrcweir s += cSep; 457cdf0e10cSrcweir sal_uInt16 nIdx = 0; 458cdf0e10cSrcweir do 459cdf0e10cSrcweir { 460cdf0e10cSrcweir nIdx = aSym.Search( s, nIdx ); 461cdf0e10cSrcweir if( nIdx == STRING_NOTFOUND ) 462cdf0e10cSrcweir break; 463cdf0e10cSrcweir aSym.Erase( nIdx, 1 ); 464cdf0e10cSrcweir nIdx++; 465cdf0e10cSrcweir } 466cdf0e10cSrcweir while( true ); 467cdf0e10cSrcweir if( cSep != ']' ) 468cdf0e10cSrcweir eScanType = ( cSep == '#' ) ? SbxDATE : SbxSTRING; 469cdf0e10cSrcweir } 470cdf0e10cSrcweir // ungueltige Zeichen: 471cdf0e10cSrcweir else if( ( *pLine & 0xFF ) >= 0x7F ) 472cdf0e10cSrcweir { 473cdf0e10cSrcweir GenError( SbERR_SYNTAX ); pLine++; nCol++; 474cdf0e10cSrcweir } 475cdf0e10cSrcweir // andere Gruppen: 476cdf0e10cSrcweir else 477cdf0e10cSrcweir { 478cdf0e10cSrcweir short n = 1; 479cdf0e10cSrcweir switch( *pLine++ ) 480cdf0e10cSrcweir { 481cdf0e10cSrcweir case '<': if( *pLine == '>' || *pLine == '=' ) n = 2; break; 482cdf0e10cSrcweir case '>': if( *pLine == '=' ) n = 2; break; 483cdf0e10cSrcweir case ':': if( *pLine == '=' ) n = 2; break; 484cdf0e10cSrcweir } 485cdf0e10cSrcweir aSym = aLine.copy( nCol, n ); 486cdf0e10cSrcweir pLine += n-1; nCol = nCol + n; 487cdf0e10cSrcweir } 488cdf0e10cSrcweir 489cdf0e10cSrcweir nCol2 = nCol-1; 490cdf0e10cSrcweir 491cdf0e10cSrcweir PrevLineCommentLbl: 492cdf0e10cSrcweir // Kommentar? 493cdf0e10cSrcweir if( bPrevLineExtentsComment || (eScanType != SbxSTRING && 494cdf0e10cSrcweir ( aSym.GetBuffer()[0] == '\'' || aSym.EqualsIgnoreCaseAscii( "REM" ) ) ) ) 495cdf0e10cSrcweir { 496cdf0e10cSrcweir bPrevLineExtentsComment = sal_False; 497cdf0e10cSrcweir aSym = String::CreateFromAscii( "REM" ); 498cdf0e10cSrcweir sal_uInt16 nLen = String( pLine ).Len(); 499cdf0e10cSrcweir if( bCompatible && pLine[ nLen - 1 ] == '_' && pLine[ nLen - 2 ] == ' ' ) 500cdf0e10cSrcweir bPrevLineExtentsComment = sal_True; 501cdf0e10cSrcweir nCol2 = nCol2 + nLen; 502cdf0e10cSrcweir pLine = NULL; 503cdf0e10cSrcweir } 504cdf0e10cSrcweir return sal_True; 505cdf0e10cSrcweir 506cdf0e10cSrcweir // Sonst Zeilen-Ende: aber bitte auf '_' testen, ob die 507cdf0e10cSrcweir // Zeile nicht weitergeht! 508cdf0e10cSrcweir eoln: 509cdf0e10cSrcweir if( nCol && *--pLine == '_' ) 510cdf0e10cSrcweir { 511cdf0e10cSrcweir pLine = NULL; 512cdf0e10cSrcweir bool bRes = NextSym(); 513cdf0e10cSrcweir if( bVBASupportOn && aSym.GetBuffer()[0] == '.' ) 514cdf0e10cSrcweir { 515cdf0e10cSrcweir // object _ 516cdf0e10cSrcweir // .Method 517cdf0e10cSrcweir // ^^^ <- spaces is legal in MSO VBA 518cdf0e10cSrcweir OSL_TRACE("*** resetting bSpaces***"); 519cdf0e10cSrcweir bSpaces = sal_False; 520cdf0e10cSrcweir } 521cdf0e10cSrcweir return bRes; 522cdf0e10cSrcweir } 523cdf0e10cSrcweir else 524cdf0e10cSrcweir { 525cdf0e10cSrcweir pLine = NULL; 526cdf0e10cSrcweir nLine = nOldLine; 527cdf0e10cSrcweir nCol1 = nOldCol1; 528cdf0e10cSrcweir nCol2 = nOldCol2; 529cdf0e10cSrcweir aSym = '\n'; 530cdf0e10cSrcweir nColLock = 0; 531cdf0e10cSrcweir return sal_True; 532cdf0e10cSrcweir } 533cdf0e10cSrcweir } 534cdf0e10cSrcweir 535cdf0e10cSrcweir LetterTable BasicSimpleCharClass::aLetterTable; 536cdf0e10cSrcweir 537cdf0e10cSrcweir LetterTable::LetterTable( void ) 538cdf0e10cSrcweir { 539cdf0e10cSrcweir for( int i = 0 ; i < 256 ; ++i ) 540cdf0e10cSrcweir IsLetterTab[i] = false; 541cdf0e10cSrcweir 542*29d7882dSmseidel IsLetterTab[0xC0] = true; // À , CAPITAL LETTER A WITH GRAVE ACCENT 543*29d7882dSmseidel IsLetterTab[0xC1] = true; // Á , CAPITAL LETTER A WITH ACUTE ACCENT 544*29d7882dSmseidel IsLetterTab[0xC2] = true; // Â , CAPITAL LETTER A WITH CIRCUMFLEX ACCENT 545*29d7882dSmseidel IsLetterTab[0xC3] = true; // Ã , CAPITAL LETTER A WITH TILDE 546*29d7882dSmseidel IsLetterTab[0xC4] = true; // Ä , CAPITAL LETTER A WITH DIAERESIS 547*29d7882dSmseidel IsLetterTab[0xC5] = true; // Å , CAPITAL LETTER A WITH RING ABOVE 548*29d7882dSmseidel IsLetterTab[0xC6] = true; // Æ , CAPITAL LIGATURE AE 549*29d7882dSmseidel IsLetterTab[0xC7] = true; // Ç , CAPITAL LETTER C WITH CEDILLA 550*29d7882dSmseidel IsLetterTab[0xC8] = true; // È , CAPITAL LETTER E WITH GRAVE ACCENT 551*29d7882dSmseidel IsLetterTab[0xC9] = true; // É , CAPITAL LETTER E WITH ACUTE ACCENT 552*29d7882dSmseidel IsLetterTab[0xCA] = true; // Ê , CAPITAL LETTER E WITH CIRCUMFLEX ACCENT 553*29d7882dSmseidel IsLetterTab[0xCB] = true; // Ë , CAPITAL LETTER E WITH DIAERESIS 554*29d7882dSmseidel IsLetterTab[0xCC] = true; // Ì , CAPITAL LETTER I WITH GRAVE ACCENT 555*29d7882dSmseidel IsLetterTab[0xCD] = true; // Í , CAPITAL LETTER I WITH ACUTE ACCENT 556*29d7882dSmseidel IsLetterTab[0xCE] = true; // Î , CAPITAL LETTER I WITH CIRCUMFLEX ACCENT 557*29d7882dSmseidel IsLetterTab[0xCF] = true; // Ï , CAPITAL LETTER I WITH DIAERESIS 558*29d7882dSmseidel IsLetterTab[0xD0] = true; // Ð , CAPITAL LETTER ETH 559*29d7882dSmseidel IsLetterTab[0xD1] = true; // Ñ , CAPITAL LETTER N WITH TILDE 560*29d7882dSmseidel IsLetterTab[0xD2] = true; // Ò , CAPITAL LETTER O WITH GRAVE ACCENT 561*29d7882dSmseidel IsLetterTab[0xD3] = true; // Ó , CAPITAL LETTER O WITH ACUTE ACCENT 562*29d7882dSmseidel IsLetterTab[0xD4] = true; // Ô , CAPITAL LETTER O WITH CIRCUMFLEX ACCENT 563*29d7882dSmseidel IsLetterTab[0xD5] = true; // Õ , CAPITAL LETTER O WITH TILDE 564*29d7882dSmseidel IsLetterTab[0xD6] = true; // Ö , CAPITAL LETTER O WITH DIAERESIS 565*29d7882dSmseidel IsLetterTab[0xD8] = true; // Ø , CAPITAL LETTER O WITH STROKE 566*29d7882dSmseidel IsLetterTab[0xD9] = true; // Ù , CAPITAL LETTER U WITH GRAVE ACCENT 567*29d7882dSmseidel IsLetterTab[0xDA] = true; // Ú , CAPITAL LETTER U WITH ACUTE ACCENT 568*29d7882dSmseidel IsLetterTab[0xDB] = true; // Û , CAPITAL LETTER U WITH CIRCUMFLEX ACCENT 569*29d7882dSmseidel IsLetterTab[0xDC] = true; // Ü , CAPITAL LETTER U WITH DIAERESIS 570*29d7882dSmseidel IsLetterTab[0xDD] = true; // Ý , CAPITAL LETTER Y WITH ACUTE ACCENT 571*29d7882dSmseidel IsLetterTab[0xDE] = true; // Þ , CAPITAL LETTER THORN 572*29d7882dSmseidel IsLetterTab[0xDF] = true; // ß , SMALL LETTER SHARP S 573*29d7882dSmseidel IsLetterTab[0xE0] = true; // à , SMALL LETTER A WITH GRAVE ACCENT 574*29d7882dSmseidel IsLetterTab[0xE1] = true; // á , SMALL LETTER A WITH ACUTE ACCENT 575*29d7882dSmseidel IsLetterTab[0xE2] = true; // â , SMALL LETTER A WITH CIRCUMFLEX ACCENT 576*29d7882dSmseidel IsLetterTab[0xE3] = true; // ã , SMALL LETTER A WITH TILDE 577*29d7882dSmseidel IsLetterTab[0xE4] = true; // ä , SMALL LETTER A WITH DIAERESIS 578*29d7882dSmseidel IsLetterTab[0xE5] = true; // å , SMALL LETTER A WITH RING ABOVE 579*29d7882dSmseidel IsLetterTab[0xE6] = true; // æ , SMALL LIGATURE AE 580*29d7882dSmseidel IsLetterTab[0xE7] = true; // ç , SMALL LETTER C WITH CEDILLA 581*29d7882dSmseidel IsLetterTab[0xE8] = true; // è , SMALL LETTER E WITH GRAVE ACCENT 582*29d7882dSmseidel IsLetterTab[0xE9] = true; // é , SMALL LETTER E WITH ACUTE ACCENT 583*29d7882dSmseidel IsLetterTab[0xEA] = true; // ê , SMALL LETTER E WITH CIRCUMFLEX ACCENT 584*29d7882dSmseidel IsLetterTab[0xEB] = true; // ë , SMALL LETTER E WITH DIAERESIS 585*29d7882dSmseidel IsLetterTab[0xEC] = true; // ì , SMALL LETTER I WITH GRAVE ACCENT 586*29d7882dSmseidel IsLetterTab[0xED] = true; // í , SMALL LETTER I WITH ACUTE ACCENT 587*29d7882dSmseidel IsLetterTab[0xEE] = true; // î , SMALL LETTER I WITH CIRCUMFLEX ACCENT 588*29d7882dSmseidel IsLetterTab[0xEF] = true; // ï , SMALL LETTER I WITH DIAERESIS 589*29d7882dSmseidel IsLetterTab[0xF0] = true; // ð , SMALL LETTER ETH 590*29d7882dSmseidel IsLetterTab[0xF1] = true; // ñ , SMALL LETTER N WITH TILDE 591*29d7882dSmseidel IsLetterTab[0xF2] = true; // ò , SMALL LETTER O WITH GRAVE ACCENT 592*29d7882dSmseidel IsLetterTab[0xF3] = true; // ó , SMALL LETTER O WITH ACUTE ACCENT 593*29d7882dSmseidel IsLetterTab[0xF4] = true; // ô , SMALL LETTER O WITH CIRCUMFLEX ACCENT 594*29d7882dSmseidel IsLetterTab[0xF5] = true; // õ , SMALL LETTER O WITH TILDE 595*29d7882dSmseidel IsLetterTab[0xF6] = true; // ö , SMALL LETTER O WITH DIAERESIS 596*29d7882dSmseidel IsLetterTab[0xF8] = true; // ø , SMALL LETTER O WITH OBLIQUE BAR 597*29d7882dSmseidel IsLetterTab[0xF9] = true; // ù , SMALL LETTER U WITH GRAVE ACCENT 598*29d7882dSmseidel IsLetterTab[0xFA] = true; // ú , SMALL LETTER U WITH ACUTE ACCENT 599*29d7882dSmseidel IsLetterTab[0xFB] = true; // û , SMALL LETTER U WITH CIRCUMFLEX ACCENT 600*29d7882dSmseidel IsLetterTab[0xFC] = true; // ü , SMALL LETTER U WITH DIAERESIS 601*29d7882dSmseidel IsLetterTab[0xFD] = true; // ý , SMALL LETTER Y WITH ACUTE ACCENT 602*29d7882dSmseidel IsLetterTab[0xFE] = true; // þ , SMALL LETTER THORN 603*29d7882dSmseidel IsLetterTab[0xFF] = true; // ÿ , SMALL LETTER Y WITH DIAERESIS 604cdf0e10cSrcweir } 605cdf0e10cSrcweir 606cdf0e10cSrcweir bool LetterTable::isLetterUnicode( sal_Unicode c ) 607cdf0e10cSrcweir { 608cdf0e10cSrcweir static CharClass* pCharClass = NULL; 609cdf0e10cSrcweir if( pCharClass == NULL ) 610cdf0e10cSrcweir pCharClass = new CharClass( Application::GetSettings().GetLocale() ); 611cdf0e10cSrcweir String aStr( c ); 612cdf0e10cSrcweir bool bRet = pCharClass->isLetter( aStr, 0 ); 613cdf0e10cSrcweir return bRet; 614cdf0e10cSrcweir } 615*29d7882dSmseidel 616*29d7882dSmseidel /* vim: set noet sw=4 ts=4: */ 617