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