diff options
author | Norbert Thiebaud <nthiebaud@gmail.com> | 2012-09-01 09:49:15 -0500 |
---|---|---|
committer | Norbert Thiebaud <nthiebaud@gmail.com> | 2012-10-16 11:08:16 -0500 |
commit | 87293419e4ceea4db8104197ae001f1a087ea449 (patch) | |
tree | 9a707ff7f6d0c490d8d2b3a89e8e7d441d5b9ea7 /binfilter/bf_sc/source/core/tool/sc_compiler.cxx | |
parent | rename jpeg_filter to prevent the hiding of global jpeg library (diff) | |
download | binfilter-87293419e4ceea4db8104197ae001f1a087ea449.tar.gz binfilter-87293419e4ceea4db8104197ae001f1a087ea449.zip |
move binfilter structure one directory up
Change-Id: I0d6772e8b1206f8bfdb43122a47958fecf586a40
Diffstat (limited to 'binfilter/bf_sc/source/core/tool/sc_compiler.cxx')
-rw-r--r-- | binfilter/bf_sc/source/core/tool/sc_compiler.cxx | 3226 |
1 files changed, 0 insertions, 3226 deletions
diff --git a/binfilter/bf_sc/source/core/tool/sc_compiler.cxx b/binfilter/bf_sc/source/core/tool/sc_compiler.cxx deleted file mode 100644 index 901fad168..000000000 --- a/binfilter/bf_sc/source/core/tool/sc_compiler.cxx +++ /dev/null @@ -1,3226 +0,0 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * This file is part of the LibreOffice project. - * - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at http://mozilla.org/MPL/2.0/. - * - * This file incorporates work covered by the following license notice: - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed - * with this work for additional information regarding copyright - * ownership. The ASF licenses this file to you under the Apache - * License, Version 2.0 (the "License"); you may not use this file - * except in compliance with the License. You may obtain a copy of - * the License at http://www.apache.org/licenses/LICENSE-2.0 . - */ - -#ifdef _MSC_VER -#pragma hdrstop -#endif - - -#include <bf_sfx2/app.hxx> -#include <bf_sfx2/objsh.hxx> -#include "bf_basic/sbmeth.hxx" -#include "bf_basic/sbstar.hxx" -#include <bf_svtools/zforlist.hxx> -#include <tools/rcid.h> -#include <bf_svtools/bf_solar.h> -#include <tools/urlobj.hxx> -#include <rtl/math.hxx> -#include <ctype.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <math.h> - -#include "rangenam.hxx" -#include "dbcolect.hxx" -#include "document.hxx" -#include "callform.hxx" -#include "addincol.hxx" -#include "refupdat.hxx" -#include "scresid.hxx" -#include "bf_sc.hrc" -#include "globstr.hrc" -#include "cell.hxx" -#include "dociter.hxx" -#include "docoptio.hxx" -namespace binfilter { - - -/*N*/ String* ScCompiler::pSymbolTableNative = NULL; -/*N*/ String* ScCompiler::pSymbolTableEnglish = NULL; -/*N*/ USHORT ScCompiler::nAnzStrings = 0; -/*N*/ ULONG* ScCompiler::pCharTable = 0; -/*N*/ ScOpCodeHashMap* ScCompiler::pSymbolHashMapNative = NULL; -/*N*/ ScOpCodeHashMap* ScCompiler::pSymbolHashMapEnglish = NULL; - -/*N*/ enum ScanState -/*N*/ { -/*N*/ ssGetChar, -/*N*/ ssGetBool, -/*N*/ ssGetString, -/*N*/ ssSkipString, -/*N*/ ssGetIdent, -/*N*/ ssStop -/*N*/ }; - -/*N*/ struct ScArrayStack -/*N*/ { -/*N*/ ScArrayStack* pNext; -/*N*/ ScTokenArray* pArr; -/*N*/ BOOL bTemp; -/*N*/ }; - -/*N*/ static const sal_Char* pInternal[ 5 ] = { "GAME", "SPEW", "TTT", "STARCALCTEAM", "ANTWORT" }; - - -///////////////////////////////////////////////////////////////////////// - -/*N*/ short lcl_GetRetFormat( OpCode eOpCode ) -/*N*/ { -/*N*/ switch (eOpCode) -/*N*/ { -/*N*/ case ocEqual: -/*N*/ case ocNotEqual: -/*N*/ case ocLess: -/*N*/ case ocGreater: -/*N*/ case ocLessEqual: -/*N*/ case ocGreaterEqual: -/*N*/ case ocAnd: -/*N*/ case ocOr: -/*N*/ case ocNot: -/*N*/ case ocTrue: -/*N*/ case ocFalse: -/*N*/ case ocIsEmpty: -/*N*/ case ocIsString: -/*N*/ case ocIsNonString: -/*N*/ case ocIsLogical: -/*N*/ case ocIsRef: -/*N*/ case ocIsValue: -/*N*/ case ocIsFormula: -/*N*/ case ocIsNV: -/*N*/ case ocIsErr: -/*N*/ case ocIsError: -/*N*/ case ocIsEven: -/*N*/ case ocIsOdd: -/*N*/ case ocExact: -/*N*/ return NUMBERFORMAT_LOGICAL; -/*N*/ case ocGetActDate: -/*N*/ case ocGetDate: -/*N*/ case ocEasterSunday : -/*N*/ return NUMBERFORMAT_DATE; -/*N*/ case ocGetActTime: -/*N*/ return NUMBERFORMAT_DATETIME; -/*N*/ case ocGetTime: -/*N*/ return NUMBERFORMAT_TIME; -/*N*/ case ocNBW: -/*N*/ case ocBW: -/*N*/ case ocDIA: -/*N*/ case ocGDA: -/*N*/ case ocGDA2: -/*N*/ case ocVBD: -/*N*/ case ocLIA: -/*N*/ case ocRMZ: -/*N*/ case ocZW: -/*N*/ case ocZinsZ: -/*N*/ case ocKapz: -/*N*/ case ocKumZinsZ: -/*N*/ case ocKumKapZ: -/*N*/ return NUMBERFORMAT_CURRENCY; -/*N*/ case ocZins: -/*N*/ case ocIKV: -/*N*/ case ocMIRR: -/*N*/ case ocZGZ: -/*N*/ case ocEffektiv: -/*N*/ case ocNominal: -/*N*/ case ocPercentSign: -/*N*/ return NUMBERFORMAT_PERCENT; -/*N*/ default: -/*N*/ return NUMBERFORMAT_NUMBER; -/*N*/ } -/*N*/ return NUMBERFORMAT_NUMBER; -/*N*/ } - -///////////////////////////////////////////////////////////////////////// - -/*N*/ class ScOpCodeList : public Resource // temp object fuer Resource -/*N*/ { -/*N*/ public: -/*N*/ ScOpCodeList( USHORT, String[], ScOpCodeHashMap& ); -/*N*/ }; - -/*N*/ ScOpCodeList::ScOpCodeList( USHORT nRID, String pSymbolTable[], ScOpCodeHashMap& rHashMap ) -/*N*/ : -/*N*/ Resource( ScResId( nRID ) ) -/*N*/ { -/*N*/ for (USHORT i = 0; i <= SC_OPCODE_LAST_OPCODE_ID; i++) -/*N*/ { -/*N*/ ScResId aRes(i); -/*N*/ aRes.SetRT(RSC_STRING); -/*N*/ if (IsAvailableRes(aRes)) -/*N*/ { -/*N*/ pSymbolTable[i] = aRes.toString(); -/*N*/ rHashMap.insert( ScOpCodeHashMap::value_type( pSymbolTable[i], (OpCode) i ) ); -/*N*/ } -/*N*/ } -/*N*/ FreeResource(); -/*N*/ } - - -/*N*/ class ScCompilerRecursionGuard -/*N*/ { -/*N*/ private: -/*N*/ short& rRecursion; -/*N*/ public: -/*N*/ ScCompilerRecursionGuard( short& rRec ) -/*N*/ : rRecursion( rRec ) { ++rRecursion; } -/*N*/ ~ScCompilerRecursionGuard() { --rRecursion; } -/*N*/ }; - - -/*N*/ void ScCompiler::Init() -/*N*/ { -/*N*/ pSymbolTableNative = new String[SC_OPCODE_LAST_OPCODE_ID+1]; -/*N*/ pSymbolHashMapNative = new ScOpCodeHashMap( SC_OPCODE_LAST_OPCODE_ID+1 ); -/*N*/ ScOpCodeList aOpCodeListNative( RID_SC_FUNCTION_NAMES, pSymbolTableNative, -/*N*/ *pSymbolHashMapNative ); -/*N*/ nAnzStrings = SC_OPCODE_LAST_OPCODE_ID+1; -/*N*/ -/*N*/ pCharTable = new ULONG [128]; -/*N*/ USHORT i; -/*N*/ for (i = 0; i < 128; i++) -/*N*/ pCharTable[i] = SC_COMPILER_C_ILLEGAL; -/*N*/ /* */ pCharTable[32] = SC_COMPILER_C_CHAR_DONTCARE | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP; -/*N*/ /* ! */ pCharTable[33] = SC_COMPILER_C_CHAR | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP; -/*N*/ /* " */ pCharTable[34] = SC_COMPILER_C_CHAR_STRING | SC_COMPILER_C_STRING_SEP; -/*N*/ /* # */ pCharTable[35] = SC_COMPILER_C_WORD_SEP; -/*N*/ /* $ */ pCharTable[36] = SC_COMPILER_C_CHAR_WORD | SC_COMPILER_C_WORD | SC_COMPILER_C_CHAR_IDENT | SC_COMPILER_C_IDENT; -/*N*/ /* % */ pCharTable[37] = SC_COMPILER_C_VALUE; -/*N*/ /* & */ pCharTable[38] = SC_COMPILER_C_CHAR | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP; -/*N*/ /* ' */ pCharTable[39] = SC_COMPILER_C_NAME_SEP; -/*N*/ /* ( */ pCharTable[40] = SC_COMPILER_C_CHAR | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP; -/*N*/ /* ) */ pCharTable[41] = SC_COMPILER_C_CHAR | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP; -/*N*/ /* * */ pCharTable[42] = SC_COMPILER_C_CHAR | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP; -/*N*/ /* + */ pCharTable[43] = SC_COMPILER_C_CHAR | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_EXP | SC_COMPILER_C_VALUE_SIGN; -/*N*/ /* , */ pCharTable[44] = SC_COMPILER_C_CHAR_VALUE | SC_COMPILER_C_VALUE; -/*N*/ /* - */ pCharTable[45] = SC_COMPILER_C_CHAR | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_EXP | SC_COMPILER_C_VALUE_SIGN; -/*N*/ /* . */ pCharTable[46] = SC_COMPILER_C_WORD | SC_COMPILER_C_CHAR_VALUE | SC_COMPILER_C_VALUE | SC_COMPILER_C_IDENT; -/*N*/ /* / */ pCharTable[47] = SC_COMPILER_C_CHAR | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP; -/*N*/ for (i = 48; i < 58; i++) -/*N*/ /* 0-9 */ pCharTable[i] = SC_COMPILER_C_CHAR_VALUE | SC_COMPILER_C_WORD | SC_COMPILER_C_VALUE | SC_COMPILER_C_VALUE_EXP | SC_COMPILER_C_VALUE_VALUE | SC_COMPILER_C_IDENT; -/*N*/ /* : */ pCharTable[58] = SC_COMPILER_C_WORD | SC_COMPILER_C_IDENT; -/*N*/ /* ; */ pCharTable[59] = SC_COMPILER_C_CHAR | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP; -/*N*/ /* < */ pCharTable[60] = SC_COMPILER_C_CHAR_BOOL | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP; -/*N*/ /* = */ pCharTable[61] = SC_COMPILER_C_CHAR | SC_COMPILER_C_BOOL | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP; -/*N*/ /* > */ pCharTable[62] = SC_COMPILER_C_CHAR_BOOL | SC_COMPILER_C_BOOL | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP; -/*N*/ /* ? */ pCharTable[63] = SC_COMPILER_C_CHAR_WORD | SC_COMPILER_C_WORD; -/*N*/ /* @ */ // FREI -/*N*/ for (i = 65; i < 91; i++) -/*N*/ /* A-Z */ pCharTable[i] = SC_COMPILER_C_CHAR_WORD | SC_COMPILER_C_WORD | SC_COMPILER_C_CHAR_IDENT | SC_COMPILER_C_IDENT; -/*N*/ /* [ */ // FREI -/*N*/ /* \ */ // FREI -/*N*/ /* ] */ // FREI -/*N*/ /* ^ */ pCharTable[94] = SC_COMPILER_C_CHAR | SC_COMPILER_C_WORD_SEP | SC_COMPILER_C_VALUE_SEP; -/*N*/ /* _ */ pCharTable[95] = SC_COMPILER_C_CHAR_WORD | SC_COMPILER_C_WORD | SC_COMPILER_C_CHAR_IDENT | SC_COMPILER_C_IDENT; -/*N*/ /* ` */ // FREI -/*N*/ for (i = 97; i < 123; i++) -/*N*/ /* a-z */ pCharTable[i] = SC_COMPILER_C_CHAR_WORD | SC_COMPILER_C_WORD | SC_COMPILER_C_CHAR_IDENT | SC_COMPILER_C_IDENT; -/*N*/ /* { */ // FREI -/*N*/ /* | */ // FREI -/*N*/ /* } */ // FREI -/*N*/ /* ~ */ // FREI -/*N*/ /* 127 */ // FREI -/*N*/ } - -/*N*/ void ScCompiler::DeInit() -/*N*/ { -/*N*/ if (pSymbolTableNative) -/*N*/ { -/*N*/ delete [] pSymbolTableNative; -/*N*/ pSymbolTableNative = NULL; -/*N*/ } -/*N*/ if (pSymbolTableEnglish) -/*N*/ { -/*?*/ delete [] pSymbolTableEnglish; -/*?*/ pSymbolTableEnglish = NULL; -/*N*/ } -/*N*/ if ( pSymbolHashMapNative ) -/*N*/ { -/*?*/ pSymbolHashMapNative->clear(); -/*?*/ delete pSymbolHashMapNative; -/*?*/ pSymbolHashMapNative = NULL; -/*N*/ } -/*N*/ if ( pSymbolHashMapEnglish ) -/*N*/ { -/*?*/ pSymbolHashMapEnglish->clear(); -/*?*/ delete pSymbolHashMapEnglish; -/*?*/ pSymbolHashMapEnglish = NULL; -/*N*/ } -/*N*/ delete [] pCharTable; -/*N*/ pCharTable = NULL; -/*N*/ } - -/*N*/ void ScCompiler::SetCompileEnglish( BOOL bCompileEnglish ) -/*N*/ { -/*N*/ if ( bCompileEnglish ) -/*N*/ { -/*N*/ if ( !pSymbolTableEnglish ) -/*N*/ { -/*N*/ pSymbolTableEnglish = new String[SC_OPCODE_LAST_OPCODE_ID+1]; -/*N*/ pSymbolHashMapEnglish = new ScOpCodeHashMap( SC_OPCODE_LAST_OPCODE_ID+1 ); -/*N*/ ScOpCodeList aOpCodeListEnglish( RID_SC_FUNCTION_NAMES_ENGLISH, -/*N*/ pSymbolTableEnglish, *pSymbolHashMapEnglish ); -/*N*/ } -/*N*/ pSymbolTable = pSymbolTableEnglish; -/*N*/ pSymbolHashMap = pSymbolHashMapEnglish; -/*N*/ } -/*N*/ else -/*N*/ { -/*N*/ pSymbolTable = pSymbolTableNative; -/*N*/ pSymbolHashMap = pSymbolHashMapNative; -/*N*/ } -/*N*/ } - -//-----------------------Funktionen der Klasse ScCompiler---------------------- - -/*N*/ ScCompiler::ScCompiler( ScDocument* pDocument, const ScAddress& rPos, -/*N*/ const ScTokenArray& rArr ) -/*N*/ : -/*N*/ aPos( rPos ), -/*N*/ pSymbolTable( pSymbolTableNative ), -/*N*/ pSymbolHashMap( pSymbolHashMapNative ), -/*N*/ nRecursion(0), -/*N*/ bAutoCorrect( FALSE ), -/*N*/ bCorrected( FALSE ), -/*N*/ bCompileForFAP( FALSE ), -/*N*/ bIgnoreErrors( FALSE ), -/*N*/ bCompileXML( FALSE ), -/*N*/ bImportXML ( FALSE ) -/*N*/ { -/*N*/ if (!nAnzStrings) -/*?*/ Init(); -/*N*/ pArr = (ScTokenArray*) ⇒ -/*N*/ pDoc = pDocument; -/*N*/ nMaxTab = pDoc->GetTableCount() - 1; -/*N*/ pStack = NULL; -/*N*/ nNumFmt = NUMBERFORMAT_UNDEFINED; -/*N*/ } - -/*N*/ ScCompiler::ScCompiler(ScDocument* pDocument, const ScAddress& rPos ) -/*N*/ : -/*N*/ aPos( rPos ), -/*N*/ pSymbolTable( pSymbolTableNative ), -/*N*/ pSymbolHashMap( pSymbolHashMapNative ), -/*N*/ nRecursion(0), -/*N*/ bAutoCorrect( FALSE ), -/*N*/ bCorrected( FALSE ), -/*N*/ bCompileForFAP( FALSE ), -/*N*/ bIgnoreErrors( FALSE ), -/*N*/ bCompileXML( FALSE ), -/*N*/ bImportXML ( FALSE ) -/*N*/ { -/*N*/ if (!nAnzStrings) -/*?*/ Init(); -/*N*/ pDoc = pDocument; -/*N*/ nMaxTab = pDoc->GetTableCount() - 1; -/*N*/ pStack = NULL; -/*N*/ nNumFmt = NUMBERFORMAT_UNDEFINED; -/*N*/ } - - -/*N*/ void ScCompiler::MakeColStr( ::rtl::OUStringBuffer& rBuffer, USHORT nCol ) -/*N*/ { -/*N*/ if ( nCol > MAXCOL ) -/*?*/ rBuffer.append(ScGlobal::GetRscString(STR_NO_REF_TABLE)); -/*N*/ else -/*N*/ { -/*N*/ if (nCol < 26) -/*N*/ rBuffer.append( sal_Unicode('A' + (sal_uChar) nCol)); -/*N*/ else -/*N*/ { -/*?*/ USHORT nLoCol = nCol % 26; -/*?*/ USHORT nHiCol = (nCol / 26) - 1; -/*?*/ rBuffer.append( sal_Unicode('A' + (sal_uChar)nHiCol) ); -/*?*/ rBuffer.append( sal_Unicode('A' + (sal_uChar)nLoCol) ); -/*N*/ } -/*N*/ } -/*N*/ } - -/*N*/ void ScCompiler::MakeRowStr( ::rtl::OUStringBuffer& rBuffer, USHORT nRow ) -/*N*/ { -/*N*/ if ( nRow > MAXROW ) -/*?*/ rBuffer.append(ScGlobal::GetRscString(STR_NO_REF_TABLE)); -/*N*/ else -/*N*/ rBuffer.append(sal_Int32(nRow + 1)); -/*N*/ } - -/*N*/ String ScCompiler::MakeTabStr( USHORT nTab, String& aDoc ) -/*N*/ { -/*N*/ String aString; -/*N*/ if (!pDoc->GetName(nTab, aString)) -/*?*/ aString = ScGlobal::GetRscString(STR_NO_REF_TABLE); -/*N*/ else -/*N*/ { -/*N*/ if ( aString.GetChar(0) == '\'' ) -/*N*/ { // "'Doc'#Tab" -/*N*/ xub_StrLen nPos, nLen = 1; -/*N*/ while( (nPos = aString.Search( '\'', nLen )) != STRING_NOTFOUND ) -/*N*/ nLen = nPos + 1; -/*N*/ if ( aString.GetChar(nLen) == SC_COMPILER_FILE_TAB_SEP ) -/*N*/ { -/*N*/ aDoc = aString.Copy( 0, nLen + 1 ); -/*N*/ aString.Erase( 0, nLen + 1 ); -/*N*/ aDoc = INetURLObject::decode( aDoc, INET_HEX_ESCAPE, -/*N*/ INetURLObject::DECODE_UNAMBIGUOUS ); -/*N*/ } -/*N*/ else -/*?*/ aDoc.Erase(); -/*N*/ } -/*N*/ else -/*N*/ aDoc.Erase(); -/*N*/ CheckTabQuotes( aString ); -/*N*/ } -/*N*/ aString += '.'; -/*N*/ return aString; -/*N*/ } - -/*N*/ void ScCompiler::CheckTabQuotes( String& rString ) -/*N*/ { -/*N*/ register const sal_Unicode* p = rString.GetBuffer(); -/*N*/ register const sal_Unicode* const pEnd = p + rString.Len(); -/*N*/ while ( p < pEnd ) -/*N*/ { -/*N*/ if( !IsWordChar( *p ) ) -/*N*/ { -/*N*/ rString.Insert( '\'', 0 ); -/*N*/ rString += '\''; -/*N*/ return ; -/*N*/ } -/*N*/ p++; -/*N*/ } -/*N*/ if ( CharClass::isAsciiNumeric( rString ) ) -/*N*/ { -/*N*/ rString.Insert( '\'', 0 ); -/*N*/ rString += '\''; -/*N*/ } -/*N*/ } - -/*N*/ void ScCompiler::MakeRefStr( ::rtl::OUStringBuffer& rBuffer, ComplRefData& rRef, BOOL bSingleRef ) -/*N*/ { -/*N*/ if (bCompileXML) -/*N*/ rBuffer.append(sal_Unicode('[')); -/*N*/ ComplRefData aRef( rRef ); -/*N*/ aRef.Ref1.CalcAbsIfRel( aPos ); -/*N*/ if( !bSingleRef ) -/*N*/ aRef.Ref2.CalcAbsIfRel( aPos ); -/*N*/ if( aRef.Ref1.IsFlag3D() ) -/*N*/ { -/*N*/ if (aRef.Ref1.IsTabDeleted()) -/*N*/ { -/*?*/ if (!aRef.Ref1.IsTabRel()) -/*?*/ rBuffer.append(sal_Unicode('$')); -/*?*/ rBuffer.append(ScGlobal::GetRscString(STR_NO_REF_TABLE)); -/*?*/ rBuffer.append(sal_Unicode('.')); -/*N*/ } -/*N*/ else -/*N*/ { -/*N*/ String aDoc; -/*N*/ String aRefStr( MakeTabStr( aRef.Ref1.nTab, aDoc ) ); -/*N*/ rBuffer.append(aDoc); -/*N*/ if (!aRef.Ref1.IsTabRel()) rBuffer.append(sal_Unicode('$')); -/*N*/ rBuffer.append(aRefStr); -/*N*/ } -/*N*/ } -/*N*/ else if (bCompileXML) -/*N*/ rBuffer.append(sal_Unicode('.')); -/*N*/ if (!aRef.Ref1.IsColRel()) -/*N*/ rBuffer.append(sal_Unicode('$')); -/*N*/ if ( aRef.Ref1.IsColDeleted() ) -/*?*/ rBuffer.append(ScGlobal::GetRscString(STR_NO_REF_TABLE)); -/*N*/ else -/*N*/ MakeColStr(rBuffer, aRef.Ref1.nCol ); -/*N*/ if (!aRef.Ref1.IsRowRel()) -/*N*/ rBuffer.append(sal_Unicode('$')); -/*N*/ if ( aRef.Ref1.IsRowDeleted() ) -/*?*/ rBuffer.append(ScGlobal::GetRscString(STR_NO_REF_TABLE)); -/*N*/ else -/*N*/ MakeRowStr( rBuffer, aRef.Ref1.nRow ); -/*N*/ if (!bSingleRef) -/*N*/ { -/*N*/ rBuffer.append(sal_Unicode(':')); -/*N*/ if (aRef.Ref2.IsFlag3D() || aRef.Ref2.nTab != aRef.Ref1.nTab) -/*N*/ { -/*?*/ if (aRef.Ref2.IsTabDeleted()) -/*?*/ { -/*?*/ if (!aRef.Ref2.IsTabRel()) -/*?*/ rBuffer.append(sal_Unicode('$')); -/*?*/ rBuffer.append(ScGlobal::GetRscString(STR_NO_REF_TABLE)); -/*?*/ rBuffer.append(sal_Unicode('.')); -/*?*/ } -/*?*/ else -/*?*/ { -/*?*/ String aDoc; -/*?*/ String aRefStr( MakeTabStr( aRef.Ref2.nTab, aDoc ) ); -/*?*/ rBuffer.append(aDoc); -/*?*/ if (!aRef.Ref2.IsTabRel()) rBuffer.append(sal_Unicode('$')); -/*?*/ rBuffer.append(aRefStr); -/*?*/ } -/*N*/ } -/*N*/ else if (bCompileXML) -/*N*/ rBuffer.append(sal_Unicode('.')); -/*N*/ if (!aRef.Ref2.IsColRel()) -/*N*/ rBuffer.append(sal_Unicode('$')); -/*N*/ if ( aRef.Ref2.IsColDeleted() ) -/*N*/ rBuffer.append(ScGlobal::GetRscString(STR_NO_REF_TABLE)); -/*N*/ else -/*N*/ MakeColStr( rBuffer, aRef.Ref2.nCol ); -/*N*/ if (!aRef.Ref2.IsRowRel()) -/*N*/ rBuffer.append(sal_Unicode('$')); -/*N*/ if ( aRef.Ref2.IsRowDeleted() ) -/*N*/ rBuffer.append(ScGlobal::GetRscString(STR_NO_REF_TABLE)); -/*N*/ else -/*N*/ MakeRowStr( rBuffer, aRef.Ref2.nRow ); -/*N*/ } -/*N*/ if (bCompileXML) -/*N*/ rBuffer.append(sal_Unicode(']')); -/*N*/ } - -//--------------------------------------------------------------------------- - -/*N*/ void ScCompiler::SetError(USHORT nError) -/*N*/ { -/*N*/ if( !pArr->GetError() ) -/*N*/ pArr->nError = nError; -/*N*/ } - - -/*N*/ sal_Unicode* lcl_UnicodeStrNCpy( sal_Unicode* pDst, const sal_Unicode* pSrc, xub_StrLen nMax ) -/*N*/ { -/*N*/ const sal_Unicode* const pStop = pDst + nMax; -/*N*/ while ( *pSrc && pDst < pStop ) -/*N*/ { -/*N*/ *pDst++ = *pSrc++; -/*N*/ } -/*N*/ *pDst = 0; -/*N*/ return pDst; -/*N*/ } - - -//--------------------------------------------------------------------------- -// NextSymbol -//--------------------------------------------------------------------------- -// Zerlegt die Formel in einzelne Symbole fuer die weitere -// Verarbeitung (Turing-Maschine). -//--------------------------------------------------------------------------- -// Ausgangs Zustand = GetChar -//---------------+-------------------+-----------------------+--------------- -// Alter Zustand | gelesenes Zeichen | Aktion | Neuer Zustand -//---------------+-------------------+-----------------------+--------------- -// GetChar | ;()+-*/^=& | Symbol=Zeichen | Stop -// | <> | Symbol=Zeichen | GetBool -// | $ Buchstabe | Symbol=Zeichen | GetWord -// | Ziffer | Symbol=Zeichen | GetValue -// | " | Keine | GetString -// | Sonst | Keine | GetChar -//---------------+-------------------+-----------------------+--------------- -// GetBool | => | Symbol=Symbol+Zeichen | Stop -// | Sonst | Dec(CharPos) | Stop -//---------------+-------------------+-----------------------+--------------- -// GetWord | SepSymbol | Dec(CharPos) | Stop -// | ()+-*/^=<>&~ | | -// | Leerzeichen | Dec(CharPos) | Stop -// | $_:. | | -// | Buchstabe,Ziffer | Symbol=Symbol+Zeichen | GetWord -// | Sonst | Fehler | Stop -//---------------|-------------------+-----------------------+--------------- -// GetValue | ;()*/^=<>& | | -// | Leerzeichen | Dec(CharPos) | Stop -// | Ziffer E+-%,. | Symbol=Symbol+Zeichen | GetValue -// | Sonst | Fehler | Stop -//---------------+-------------------+-----------------------+--------------- -// GetString | " | Keine | Stop -// | Sonst | Symbol=Symbol+Zeichen | GetString -//---------------+-------------------+-----------------------+--------------- - -/*N*/ xub_StrLen ScCompiler::NextSymbol() -/*N*/ { -/*N*/ cSymbol[MAXSTRLEN-1] = 0; // Stopper -/*N*/ sal_Unicode* pSym = cSymbol; -/*N*/ const sal_Unicode* const pStart = aFormula.GetBuffer(); -/*N*/ const sal_Unicode* pSrc = pStart + nSrcPos; -/*N*/ BOOL bi18n = FALSE; -/*N*/ sal_Unicode c = *pSrc; -/*N*/ BOOL bQuote = FALSE; -/*N*/ ScanState eState = ssGetChar; -/*N*/ xub_StrLen nSpaces = 0; -/*N*/ // try to parse simple tokens before calling i18n parser -/*N*/ while ((c != 0) && (eState != ssStop) ) -/*N*/ { -/*N*/ pSrc++; -/*N*/ ULONG nMask = GetCharTableFlags( c ); -/*N*/ switch (eState) -/*N*/ { -/*N*/ case ssGetChar : -/*N*/ { -/*N*/ if( nMask & SC_COMPILER_C_CHAR ) -/*N*/ { -/*N*/ *pSym++ = c; -/*N*/ eState = ssStop; -/*N*/ } -/*N*/ else if( nMask & SC_COMPILER_C_CHAR_BOOL ) -/*N*/ { -/*N*/ *pSym++ = c; -/*N*/ eState = ssGetBool; -/*N*/ } -/*N*/ else if( nMask & SC_COMPILER_C_CHAR_STRING ) -/*N*/ { -/*N*/ *pSym++ = c; -/*N*/ eState = ssGetString; -/*N*/ } -/*N*/ else if( nMask & SC_COMPILER_C_CHAR_DONTCARE ) -/*N*/ { -/*N*/ nSpaces++; -/*N*/ } -/*N*/ else if( nMask & SC_COMPILER_C_CHAR_IDENT ) -/*N*/ { // try to get a simple ASCII identifier before calling -/*N*/ // i18n, to gain performance during import -/*N*/ *pSym++ = c; -/*N*/ eState = ssGetIdent; -/*N*/ } -/*N*/ else -/*N*/ { -/*N*/ bi18n = TRUE; -/*N*/ eState = ssStop; -/*N*/ } -/*N*/ } -/*N*/ break; -/*N*/ case ssGetIdent: -/*N*/ { -/*N*/ if ( nMask & SC_COMPILER_C_IDENT ) -/*N*/ { // this catches also $Sheet1.A1:A$2, for example -/*N*/ *pSym++ = c; -/*N*/ } -/*N*/ else if ( 128 <= c || '\'' == c ) -/*N*/ { // High values need reparsing with i18n, -/*N*/ // single quoted $'sheet' names too (otherwise we'd had to -/*N*/ // implement everything twice). -/*N*/ pSrc = pStart + nSrcPos + nSpaces; -/*N*/ pSym = cSymbol; -/*N*/ c = *pSrc; -/*N*/ bi18n = TRUE; -/*N*/ eState = ssStop; -/*N*/ } -/*N*/ else -/*N*/ { -/*N*/ pSrc--; -/*N*/ eState = ssStop; -/*N*/ } -/*N*/ } -/*N*/ break; -/*N*/ case ssGetBool : -/*N*/ { -/*N*/ if( nMask & SC_COMPILER_C_BOOL ) -/*N*/ { -/*N*/ *pSym++ = c; -/*N*/ eState = ssStop; -/*N*/ } -/*N*/ else -/*N*/ { -/*N*/ pSrc--; -/*N*/ eState = ssStop; -/*N*/ } -/*N*/ } -/*N*/ break; -/*N*/ case ssGetString : -/*N*/ { -/*N*/ if( nMask & SC_COMPILER_C_STRING_SEP ) -/*N*/ { -/*N*/ if ( !bQuote ) -/*N*/ { -/*N*/ if ( *pSrc == '"' ) -/*N*/ bQuote = TRUE; // "" => literal " -/*N*/ else -/*N*/ eState = ssStop; -/*N*/ } -/*N*/ else -/*N*/ bQuote = FALSE; -/*N*/ } -/*N*/ if ( !bQuote ) -/*N*/ { -/*N*/ if( pSym == &cSymbol[ MAXSTRLEN-1 ] ) -/*N*/ { -/*N*/ SetError(errStringOverflow); -/*N*/ eState = ssSkipString; -/*N*/ } -/*N*/ else -/*N*/ *pSym++ = c; -/*N*/ } -/*N*/ } -/*N*/ break; -/*N*/ case ssSkipString: -/*N*/ if( nMask & SC_COMPILER_C_STRING_SEP ) -/*N*/ eState = ssStop; -/*N*/ break; -/*N*/ default: -/*N*/ break; -/*N*/ } -/*N*/ c = *pSrc; -/*N*/ } -/*N*/ if ( bi18n ) -/*N*/ { -/*N*/ using namespace ::com::sun::star::i18n; -/*N*/ nSrcPos += nSpaces; -/*N*/ sal_Int32 nStartFlags = KParseTokens::ANY_LETTER_OR_NUMBER | -/*N*/ KParseTokens::ASC_UNDERSCORE | KParseTokens::ASC_DOLLAR; -/*N*/ sal_Int32 nContFlags = nStartFlags | KParseTokens::ASC_DOT | -/*N*/ KParseTokens::ASC_COLON; -/*N*/ // '?' allowed in range names because of Xcl :-/ -/*N*/ static const String aAddAllowed( '?' ); -/*N*/ String aSymbol; -/*N*/ USHORT nErr = 0; -/*N*/ do -/*N*/ { -/*N*/ bi18n = FALSE; -/*N*/ // special case $'sheetname' -/*N*/ if ( pStart[nSrcPos] == '$' && pStart[nSrcPos+1] == '\'' ) -/*N*/ aSymbol += pStart[nSrcPos++]; -/*N*/ -/*N*/ ParseResult aRes = ScGlobal::pCharClass->parseAnyToken( aFormula, -/*N*/ nSrcPos, nStartFlags, aAddAllowed, nContFlags, aAddAllowed ); -/*N*/ -/*N*/ if ( !aRes.TokenType ) -/*N*/ SetError( nErr = errIllegalChar ); // parsed chars as string -/*N*/ if ( aRes.EndPos <= nSrcPos ) -/*N*/ { // ?!? -/*?*/ SetError( nErr = errIllegalChar ); -/*?*/ nSrcPos = aFormula.Len(); -/*?*/ aSymbol.Erase(); -/*?*/ } -/*N*/ else -/*N*/ { -/*N*/ aSymbol.Append( pStart + nSrcPos, aRes.EndPos - nSrcPos ); -/*N*/ nSrcPos = (xub_StrLen) aRes.EndPos; -/*N*/ if ( aRes.TokenType & KParseType::SINGLE_QUOTE_NAME ) -/*N*/ { // special cases 'sheetname'. 'filename'# -/*N*/ c = pStart[nSrcPos]; -/*N*/ bi18n = (c == '.' || c == SC_COMPILER_FILE_TAB_SEP); -/*N*/ if ( bi18n ) -/*N*/ aSymbol += pStart[nSrcPos++]; -/*N*/ } -/*N*/ else if ( aRes.TokenType & KParseType::IDENTNAME ) -/*N*/ { // special cases reference:[$]'sheetname' -/*N*/ c = aSymbol.GetChar( aSymbol.Len()-1 ); -/*N*/ bi18n = ((c == ':' || c == '$') && pStart[nSrcPos] == '\''); -/*N*/ } -/*N*/ } -/*N*/ } while ( bi18n && !nErr ); -/*N*/ xub_StrLen nLen = aSymbol.Len(); -/*N*/ if ( nLen >= MAXSTRLEN ) -/*N*/ { -/*?*/ SetError( errStringOverflow ); -/*?*/ nLen = MAXSTRLEN-1; -/*N*/ } -/*N*/ lcl_UnicodeStrNCpy( cSymbol, aSymbol.GetBuffer(), nLen ); -/*N*/ } -/*N*/ else -/*N*/ { -/*N*/ nSrcPos = pSrc - pStart; -/*N*/ *pSym = 0; -/*N*/ } -/*N*/ if ( bAutoCorrect ) -/*N*/ aCorrectedSymbol = cSymbol; -/*N*/ return nSpaces; -/*N*/ } - -//--------------------------------------------------------------------------- -// Symbol in Token Umwandeln -//--------------------------------------------------------------------------- - -/*N*/ BOOL ScCompiler::IsOpCode( const String& rName ) -/*N*/ { -/*N*/ ScOpCodeHashMap::const_iterator iLook( pSymbolHashMap->find( rName ) ); -/*N*/ BOOL bFound = (iLook != pSymbolHashMap->end()); -/*N*/ if (bFound) -/*N*/ { -/*N*/ ScRawToken aToken; -/*N*/ aToken.SetOpCode( iLook->second ); -/*N*/ pRawToken = aToken.Clone(); -/*N*/ } -/*N*/ else -/*N*/ { -/*N*/ USHORT nIndex; -/*N*/ bFound = ScGlobal::GetFuncCollection()->SearchFunc(cSymbol, nIndex); -/*N*/ if( bFound ) -/*N*/ { -/*?*/ ScRawToken aToken; -/*N*/ aToken.SetExternal( cSymbol ); -/*N*/ pRawToken = aToken.Clone(); -/*N*/ } -/*N*/ else -/*N*/ { -/*N*/ // bLocalFirst=FALSE for english -/*N*/ String aIntName = ScGlobal::GetAddInCollection()-> -/*N*/ FindFunction( rName, ( pSymbolTable != pSymbolTableEnglish ) ); -/*N*/ if (aIntName.Len()) -/*N*/ { -/*N*/ ScRawToken aToken; -/*N*/ aToken.SetExternal( aIntName.GetBuffer() ); // international name -/*N*/ pRawToken = aToken.Clone(); -/*N*/ bFound = TRUE; -/*N*/ } -/*N*/ } -/*N*/ } -/*N*/ if ( bFound && pRawToken->GetOpCode() == ocSub && -/*N*/ (eLastOp == ocOpen || eLastOp == ocSep || -/*N*/ (eLastOp > ocEndDiv && eLastOp < ocEndBinOp /*ocEndUnOp*/))) -/*N*/ pRawToken->NewOpCode( ocNegSub ); -/*N*/ return bFound; -/*N*/ } - -/*N*/ BOOL ScCompiler::IsOpCode2( const String& rName ) -/*N*/ { -/*N*/ BOOL bFound = FALSE; -/*N*/ -/*N*/ USHORT i = 0; -/*N*/ for( i = ocInternalBegin; i <= ocInternalEnd && !bFound; i++ ) -/*N*/ bFound = rName.EqualsAscii( pInternal[ i-ocInternalBegin ] ); -/*N*/ -/*N*/ if (bFound) -/*N*/ { -/*?*/ ScRawToken aToken; -/*?*/ aToken.SetOpCode( (OpCode) --i ); -/*?*/ pRawToken = aToken.Clone(); -/*N*/ } -/*N*/ return bFound; -/*N*/ } - -/*N*/ BOOL ScCompiler::IsValue( const String& rSym ) -/*N*/ { -/*N*/ double fVal; -/*N*/ sal_uInt32 nIndex = ( pSymbolTable == pSymbolTableEnglish ? -/*N*/ pDoc->GetFormatTable()->GetStandardIndex( LANGUAGE_ENGLISH_US ) : 0 ); -/*N*/ if (pDoc->GetFormatTable()->IsNumberFormat( rSym, nIndex, fVal ) ) -/*N*/ { -/*N*/ USHORT nType = pDoc->GetFormatTable()->GetType(nIndex); -/*N*/ const sal_Unicode* p = aFormula.GetBuffer() + nSrcPos; -/*N*/ while( *p == ' ' ) -/*N*/ p++; -/*N*/ if ( *p == '(' && nType == NUMBERFORMAT_LOGICAL) -/*N*/ return FALSE; -/*N*/ else if( aFormula.GetChar(nSrcPos) == '.' ) -/*N*/ // Numerischer Tabellenname? -/*N*/ return FALSE; -/*N*/ else -/*N*/ { -/*N*/ if( nType == NUMBERFORMAT_TEXT ) -/*N*/ // HACK: Die Zahl ist zu gross! -/*N*/ SetError( errIllegalArgument ); -/*N*/ ScRawToken aToken; -/*N*/ aToken.SetDouble( fVal ); -/*N*/ pRawToken = aToken.Clone(); -/*N*/ return TRUE; -/*N*/ } -/*N*/ } -/*N*/ else -/*N*/ return FALSE; -/*N*/ } - -/*N*/ BOOL ScCompiler::IsString() -/*N*/ { -/*N*/ register const sal_Unicode* p = cSymbol; -/*N*/ while ( *p ) -/*N*/ p++; -/*N*/ xub_StrLen nLen = p - cSymbol - 1; -/*N*/ BOOL bQuote = ((cSymbol[0] == '"') && (cSymbol[nLen] == '"')); -/*N*/ if ((bQuote ? nLen-2 : nLen) > MAXSTRLEN-1) -/*N*/ { -/*?*/ SetError(errStringOverflow); -/*?*/ return FALSE; -/*N*/ } -/*N*/ if ( bQuote ) -/*N*/ { -/*?*/ cSymbol[nLen] = '\0'; -/*?*/ ScRawToken aToken; -/*?*/ aToken.SetString( cSymbol+1 ); -/*?*/ pRawToken = aToken.Clone(); -/*?*/ return TRUE; -/*N*/ } -/*N*/ return FALSE; -/*N*/ } - -/*N*/ BOOL ScCompiler::IsReference( const String& rName ) -/*N*/ { -/*N*/ // Has to be called before IsValue -/*N*/ sal_Unicode ch1 = rName.GetChar(0); -/*N*/ sal_Unicode cDecSep = ( pSymbolTable == pSymbolTableEnglish ? '.' : -/*N*/ ScGlobal::pLocaleData->getNumDecimalSep()[0] ); -/*N*/ if ( ch1 == cDecSep ) -/*N*/ return FALSE; -/*N*/ // Who was that imbecile introducing '.' as the sheet name separator!?! -/*N*/ if ( CharClass::isAsciiNumeric( ch1 ) ) -/*N*/ { // Numerical sheet name is valid. -/*N*/ // But English 1.E2 or 1.E+2 is value 100, 1.E-2 is 0.01 -/*N*/ // Don't create a #REF! of values. -/*N*/ const xub_StrLen nPos = rName.Search( '.' ); -/*N*/ if ( nPos == STRING_NOTFOUND ) -/*N*/ return FALSE; -/*N*/ sal_Unicode const * const pTabSep = rName.GetBuffer() + nPos; -/*N*/ sal_Unicode ch2 = pTabSep[1]; // maybe a column identifier -/*N*/ if ( !(ch2 == '$' || CharClass::isAsciiAlpha( ch2 )) ) -/*N*/ return FALSE; -/*?*/ if ( cDecSep == '.' && (ch2 == 'E' || ch2 == 'e') // E + - digit -/*?*/ && (GetCharTableFlags( pTabSep[2] ) & SC_COMPILER_C_VALUE_EXP) ) -/*?*/ { // #91053# -/*?*/ // If it is an 1.E2 expression check if "1" is an existent sheet -/*?*/ // name. If so, a desired value 1.E2 would have to be entered as -/*?*/ // 1E2 or 1.0E2 or 1.E+2, sorry. Another possibility would be to -/*?*/ // require numerical sheet names always being entered quoted, which -/*?*/ // is not desirable (too many 1999, 2000, 2001 sheets in use). -/*?*/ // Furthermore, XML files created with versions prior to SRC640e -/*?*/ // wouldn't contain the quotes added by MakeTabStr()/CheckTabQuotes() -/*?*/ // and would produce wrong formulas if the conditions here are met. -/*?*/ // If you can live with these restrictions you may remove the -/*?*/ // check and return an unconditional FALSE. -/*?*/ String aTabName( rName.Copy( 0, nPos ) ); -/*?*/ USHORT nTab; -/*?*/ if ( !pDoc->GetTable( aTabName, nTab ) ) -/*?*/ return FALSE; -/*?*/ // If sheet "1" exists and the expression is 1.E+2 continue as -/*?*/ // usual, the ScRange/ScAddress parser will take care of it. -/*?*/ } -/*N*/ } -/*N*/ ScRange aRange( aPos, aPos ); -/*N*/ USHORT nFlags = aRange.Parse( rName, pDoc ); -/*N*/ if( nFlags & SCA_VALID ) -/*N*/ { -/*N*/ ScRawToken aToken; -/*N*/ ComplRefData aRef; -/*N*/ aRef.InitRange( aRange ); -/*N*/ aRef.Ref1.SetColRel( (nFlags & SCA_COL_ABSOLUTE) == 0 ); -/*N*/ aRef.Ref1.SetRowRel( (nFlags & SCA_ROW_ABSOLUTE) == 0 ); -/*N*/ aRef.Ref1.SetTabRel( (nFlags & SCA_TAB_ABSOLUTE) == 0 ); -/*N*/ if ( !(nFlags & SCA_VALID_TAB) ) -/*?*/ aRef.Ref1.SetTabDeleted( TRUE ); // #REF! -/*N*/ aRef.Ref1.SetFlag3D( ( nFlags & SCA_TAB_3D ) != 0 ); -/*N*/ aRef.Ref2.SetColRel( (nFlags & SCA_COL2_ABSOLUTE) == 0 ); -/*N*/ aRef.Ref2.SetRowRel( (nFlags & SCA_ROW2_ABSOLUTE) == 0 ); -/*N*/ aRef.Ref2.SetTabRel( (nFlags & SCA_TAB2_ABSOLUTE) == 0 ); -/*N*/ if ( !(nFlags & SCA_VALID_TAB2) ) -/*?*/ aRef.Ref2.SetTabDeleted( TRUE ); // #REF! -/*N*/ aRef.Ref2.SetFlag3D( ( nFlags & SCA_TAB2_3D ) != 0 ); -/*N*/ aRef.CalcRelFromAbs( aPos ); -/*N*/ aToken.SetDoubleReference( aRef ); -/*N*/ pRawToken = aToken.Clone(); -/*N*/ } -/*N*/ else -/*N*/ { -/*N*/ ScAddress aAddr( aPos ); -/*N*/ nFlags = aAddr.Parse( rName, pDoc ); -/*N*/ // Irgend etwas muss gueltig sein, -/*N*/ // damit Tabelle1.blah oder blah.a1 als (falsche) ref erkannt wird -/*N*/ if( nFlags & ( SCA_VALID_COL|SCA_VALID_ROW|SCA_VALID_TAB ) ) -/*N*/ { -/*N*/ ScRawToken aToken; -/*N*/ SingleRefData aRef; -/*N*/ aRef.InitAddress( aAddr ); -/*N*/ aRef.SetColRel( (nFlags & SCA_COL_ABSOLUTE) == 0 ); -/*N*/ aRef.SetRowRel( (nFlags & SCA_ROW_ABSOLUTE) == 0 ); -/*N*/ aRef.SetTabRel( (nFlags & SCA_TAB_ABSOLUTE) == 0 ); -/*N*/ aRef.SetFlag3D( ( nFlags & SCA_TAB_3D ) != 0 ); -/*N*/ // Die Referenz ist wirklich ungueltig! -/*N*/ if( !( nFlags & SCA_VALID ) ) -/*N*/ { -/*N*/ if( !( nFlags & SCA_VALID_COL ) ) -/*N*/ aRef.nCol = MAXCOL+1; -/*N*/ if( !( nFlags & SCA_VALID_ROW ) ) -/*N*/ aRef.nRow = MAXROW+1; -/*N*/ if( !( nFlags & SCA_VALID_TAB ) ) -/*N*/ aRef.nTab = MAXTAB+3; -/*N*/ nFlags |= SCA_VALID; -/*N*/ } -/*N*/ aRef.CalcRelFromAbs( aPos ); -/*N*/ aToken.SetSingleReference( aRef ); -/*N*/ pRawToken = aToken.Clone(); -/*N*/ } -/*N*/ } -/*N*/ return ( nFlags & SCA_VALID ) != 0; -/*N*/ } - -/*N*/ BOOL ScCompiler::IsMacro( const String& rName ) -/*N*/ { -/*N*/ StarBASIC* pObj = 0; -/*N*/ SfxObjectShell* pDocSh = pDoc->GetDocumentShell(); -/*N*/ -/*N*/ SfxApplication* pSfxApp = SFX_APP(); -/*N*/ pSfxApp->EnterBasicCall(); // Dok-Basic anlegen etc. -/*N*/ -/*N*/ if( pDocSh )//XXX -/*N*/ pObj = pDocSh->GetBasic(); -/*N*/ else -/*?*/ pObj = pSfxApp->GetBasic(); -/*N*/ -/*N*/ SbxMethod* pMeth = (SbxMethod*) pObj->Find( rName, SbxCLASS_METHOD ); -/*N*/ if( !pMeth ) -/*N*/ { -/*N*/ pSfxApp->LeaveBasicCall(); -/*N*/ return FALSE; -/*N*/ } -/*N*/ // Es sollte schon eine BASIC-Function sein! -/*N*/ if( pMeth->GetType() == SbxVOID -/*N*/ || ( pMeth->IsFixed() && pMeth->GetType() == SbxEMPTY ) -/*N*/ || !pMeth->ISA(SbMethod) ) -/*N*/ { -/*N*/ pSfxApp->LeaveBasicCall(); -/*N*/ return FALSE; -/*N*/ } -/*?*/ /*N*/ ScRawToken aToken; -/*N*/ /*?*/ aToken.SetExternal( rName.GetBuffer() ); -/*N*/ /*?*/ aToken.eOp = ocMacro; -/*N*/ /*?*/ pRawToken = aToken.Clone(); -/*N*/ /*?*/ pSfxApp->LeaveBasicCall(); -/*?*/ return TRUE; -/*N*/ } - -/*N*/ BOOL ScCompiler::IsNamedRange( const String& rName ) -/*N*/ { -/*N*/ USHORT n; -/*N*/ ScRangeName* pRangeName = pDoc->GetRangeName(); -/*N*/ if (pRangeName->SearchName( rName, n ) ) -/*N*/ { -/*N*/ ScRangeData* pData = (*pRangeName)[n]; -/*N*/ ScRawToken aToken; -/*N*/ aToken.SetName( pData->GetIndex() ); -/*N*/ pRawToken = aToken.Clone(); -/*N*/ return TRUE; -/*N*/ } -/*N*/ else -/*N*/ return FALSE; -/*N*/ } - -/*N*/ BOOL ScCompiler::IsDBRange( const String& rName ) -/*N*/ { -/*N*/ USHORT n; -/*N*/ ScDBCollection* pDBColl = pDoc->GetDBCollection(); -/*N*/ if (pDBColl->SearchName( rName, n ) ) -/*N*/ { -/*?*/ ScDBData* pData = (*pDBColl)[n]; -/*?*/ ScRawToken aToken; -/*?*/ aToken.SetName( pData->GetIndex() ); -/*?*/ aToken.eOp = ocDBArea; -/*?*/ pRawToken = aToken.Clone(); -/*?*/ return TRUE; -/*N*/ } -/*N*/ else -/*N*/ return FALSE; -/*N*/ } - -/*N*/ BOOL ScCompiler::IsColRowName( const String& rName ) -/*N*/ { -/*N*/ BOOL bInList = FALSE; -/*N*/ BOOL bFound = FALSE; -/*N*/ SingleRefData aRef; -/*N*/ String aName( rName ); -/*N*/ DeQuote( aName ); -/*N*/ USHORT nThisTab = aPos.Tab(); -/*N*/ for ( short jThisTab = 1; jThisTab >= 0 && !bInList; jThisTab-- ) -/*N*/ { // #50300# zuerst Bereiche auf dieser Tabelle pruefen, falls doppelte Namen -/*N*/ for ( short jRow=0; jRow<2 && !bInList; jRow++ ) -/*N*/ { -/*N*/ ScRangePairList* pRL; -/*N*/ if ( !jRow ) -/*N*/ pRL = pDoc->GetColNameRanges(); -/*N*/ else -/*N*/ pRL = pDoc->GetRowNameRanges(); -/*N*/ for ( ScRangePair* pR = pRL->First(); pR && !bInList; pR = pRL->Next() ) -/*N*/ { -/*?*/ const ScRange& rNameRange = pR->GetRange(0); -/*?*/ if ( jThisTab && !(rNameRange.aStart.Tab() <= nThisTab && -/*?*/ nThisTab <= rNameRange.aEnd.Tab()) ) -/*?*/ continue; // for -/*?*/ ScCellIterator aIter( pDoc, rNameRange ); -/*?*/ for ( ScBaseCell* pCell = aIter.GetFirst(); pCell && !bInList; -/*?*/ pCell = aIter.GetNext() ) -/*?*/ { -/*?*/ // GPF wenn Zelle via CompileNameFormula auf Zelle ohne Code -/*?*/ // trifft und HasStringData/Interpret/Compile ausgefuehrt wird -/*?*/ // und das ganze dann auch noch rekursiv.. -/*?*/ // ausserdem wird *diese* Zelle hier nicht angefasst, da noch -/*?*/ // kein RPN existiert -/*?*/ CellType eType = pCell->GetCellType(); -/*?*/ BOOL bOk = (eType == CELLTYPE_FORMULA ? -/*?*/ ((ScFormulaCell*)pCell)->GetCode()->GetCodeLen() > 0 -/*?*/ && ((ScFormulaCell*)pCell)->aPos != aPos // noIter -/*?*/ : TRUE ); -/*?*/ if ( bOk && pCell->HasStringData() ) -/*?*/ { -/*?*/ String aStr; -/*?*/ switch ( eType ) -/*?*/ { -/*?*/ case CELLTYPE_STRING: -/*?*/ ((ScStringCell*)pCell)->GetString( aStr ); -/*?*/ break; -/*?*/ case CELLTYPE_FORMULA: -/*?*/ ((ScFormulaCell*)pCell)->GetString( aStr ); -/*?*/ break; -/*?*/ case CELLTYPE_EDIT: -/*?*/ ((ScEditCell*)pCell)->GetString( aStr ); -/*?*/ break; -/*?*/ default: -/*?*/ break; -/*?*/ } -/*?*/ if ( ScGlobal::pTransliteration->isEqual( aStr, aName ) ) -/*?*/ { -/*?*/ aRef.InitFlags(); -/*?*/ aRef.nCol = aIter.GetCol(); -/*?*/ aRef.nRow = aIter.GetRow(); -/*?*/ aRef.nTab = aIter.GetTab(); -/*?*/ if ( !jRow ) -/*?*/ aRef.SetColRel( TRUE ); // ColName -/*?*/ else -/*?*/ aRef.SetRowRel( TRUE ); // RowName -/*?*/ aRef.CalcRelFromAbs( aPos ); -/*?*/ bInList = bFound = TRUE; -/*?*/ } -/*?*/ } -/*?*/ } -/*N*/ } -/*N*/ } -/*N*/ } -/*N*/ if ( !bInList && pDoc->GetDocOptions().IsLookUpColRowNames() ) -/*N*/ { // in der aktuellen Tabelle suchen -/*N*/ long nDistance(0), nMax(0); -/*N*/ long nMyCol = (long) aPos.Col(); -/*N*/ long nMyRow = (long) aPos.Row(); -/*N*/ BOOL bTwo = FALSE; -/*N*/ ScAddress aOne( 0, 0, aPos.Tab() ); -/*N*/ ScAddress aTwo( MAXCOL, MAXROW, aPos.Tab() ); -/*N*/ ScCellIterator aIter( pDoc, ScRange( aOne, aTwo ) ); -/*N*/ for ( ScBaseCell* pCell = aIter.GetFirst(); pCell; pCell = aIter.GetNext() ) -/*N*/ { -/*N*/ if ( bFound ) -/*N*/ { // aufhoeren wenn alles andere weiter liegt -/*N*/ if ( nMax < (long)aIter.GetCol() ) -/*N*/ break; // aIter -/*N*/ } -/*N*/ CellType eType = pCell->GetCellType(); -/*N*/ BOOL bOk = (eType == CELLTYPE_FORMULA ? -/*N*/ ((ScFormulaCell*)pCell)->GetCode()->GetCodeLen() > 0 -/*N*/ && ((ScFormulaCell*)pCell)->aPos != aPos // noIter -/*N*/ : TRUE ); -/*N*/ if ( bOk && pCell->HasStringData() ) -/*N*/ { -/*N*/ String aStr; -/*N*/ switch ( eType ) -/*N*/ { -/*N*/ case CELLTYPE_STRING: -/*N*/ ((ScStringCell*)pCell)->GetString( aStr ); -/*N*/ break; -/*N*/ case CELLTYPE_FORMULA: -/*N*/ ((ScFormulaCell*)pCell)->GetString( aStr ); -/*N*/ break; -/*N*/ case CELLTYPE_EDIT: -/*N*/ ((ScEditCell*)pCell)->GetString( aStr ); -/*N*/ break; -/*N*/ default: -/*N*/ break; -/*N*/ } -/*N*/ if ( ScGlobal::pTransliteration->isEqual( aStr, aName ) ) -/*N*/ { -/*N*/ USHORT nCol = aIter.GetCol(); -/*N*/ USHORT nRow = aIter.GetRow(); -/*N*/ long nC = nMyCol - nCol; -/*N*/ long nR = nMyRow - nRow; -/*N*/ if ( bFound ) -/*N*/ { -/*?*/ long nD = nC * nC + nR * nR; -/*?*/ if ( nD < nDistance ) -/*?*/ { -/*?*/ if ( nC < 0 || nR < 0 ) -/*?*/ { // rechts oder unterhalb -/*?*/ bTwo = TRUE; -/*?*/ aTwo.Set( nCol, nRow, aIter.GetTab() ); -/*?*/ nMax = Max( nMyCol + Abs( nC ), nMyRow + Abs( nR ) ); -/*?*/ nDistance = nD; -/*?*/ } -/*?*/ else if ( !(nRow < aOne.Row() && nMyRow >= (long)aOne.Row()) ) -/*?*/ { // links oben, nur wenn nicht weiter oberhalb -/*?*/ // des bisherigen und nMyRow darunter -/*?*/ // (CellIter geht spaltenweise!) -/*?*/ bTwo = FALSE; -/*?*/ aOne.Set( nCol, nRow, aIter.GetTab() ); -/*?*/ nMax = Max( nMyCol + nC, nMyRow + nR ); -/*?*/ nDistance = nD; -/*?*/ } -/*?*/ } -/*N*/ } -/*N*/ else -/*N*/ { -/*N*/ aOne.Set( nCol, nRow, aIter.GetTab() ); -/*N*/ nDistance = nC * nC + nR * nR; -/*N*/ nMax = Max( nMyCol + Abs( nC ), nMyRow + Abs( nR ) ); -/*N*/ } -/*N*/ bFound = TRUE; -/*N*/ } -/*N*/ } -/*N*/ } -/*N*/ if ( bFound ) -/*N*/ { -/*N*/ ScAddress aAdr; -/*N*/ if ( bTwo ) -/*N*/ { -/*?*/ if ( nMyCol >= (long)aOne.Col() && nMyRow >= (long)aOne.Row() ) -/*?*/ aAdr = aOne; // links oben hat Vorrang -/*?*/ else -/*?*/ { -/*?*/ if ( nMyCol < (long)aOne.Col() ) -/*?*/ { // zwei rechts -/*?*/ if ( nMyRow >= (long)aTwo.Row() ) -/*?*/ aAdr = aTwo; // direkt rechts -/*?*/ else -/*?*/ aAdr = aOne; -/*?*/ } -/*?*/ else -/*?*/ { // zwei unten oder unten und rechts, der naechstgelegene -/*?*/ long nC1 = nMyCol - aOne.Col(); -/*?*/ long nR1 = nMyRow - aOne.Row(); -/*?*/ long nC2 = nMyCol - aTwo.Col(); -/*?*/ long nR2 = nMyRow - aTwo.Row(); -/*?*/ if ( nC1 * nC1 + nR1 * nR1 <= nC2 * nC2 + nR2 * nR2 ) -/*?*/ aAdr = aOne; -/*?*/ else -/*?*/ aAdr = aTwo; -/*?*/ } -/*?*/ } -/*N*/ } -/*N*/ else -/*N*/ aAdr = aOne; -/*N*/ aRef.InitAddress( aAdr ); -/*N*/ if ( (aRef.nRow != MAXROW && pDoc->HasStringData( -/*N*/ aRef.nCol, aRef.nRow + 1, aRef.nTab )) -/*N*/ || (aRef.nRow != 0 && pDoc->HasStringData( -/*N*/ aRef.nCol, aRef.nRow - 1, aRef.nTab )) ) -/*N*/ aRef.SetRowRel( TRUE ); // RowName -/*N*/ else -/*N*/ aRef.SetColRel( TRUE ); // ColName -/*N*/ aRef.CalcRelFromAbs( aPos ); -/*N*/ } -/*N*/ } -/*N*/ if ( bFound ) -/*N*/ { -/*N*/ ScRawToken aToken; -/*N*/ aToken.SetSingleReference( aRef ); -/*N*/ aToken.eOp = ocColRowName; -/*N*/ pRawToken = aToken.Clone(); -/*N*/ return TRUE; -/*N*/ } -/*N*/ else -/*N*/ return FALSE; -/*N*/ } - -//--------------------------------------------------------------------------- - -/*N*/ void ScCompiler::AutoCorrectParsedSymbol() -/*N*/ { -/*N*/ xub_StrLen nPos = aCorrectedSymbol.Len(); -/*N*/ if ( nPos ) -/*N*/ { -/*N*/ nPos--; -/*N*/ const sal_Unicode cQuote = '\"'; -/*N*/ const sal_Unicode cx = 'x'; -/*N*/ const sal_Unicode cX = 'X'; -/*N*/ sal_Unicode c1 = aCorrectedSymbol.GetChar( 0 ); -/*N*/ sal_Unicode c2 = aCorrectedSymbol.GetChar( nPos ); -/*N*/ if ( c1 == cQuote && c2 != cQuote ) -/*N*/ { // "... -/*N*/ // was kein Wort bildet gehoert nicht dazu. -/*N*/ // Don't be pedantic: c < 128 should be sufficient here. -/*N*/ while ( nPos && ((aCorrectedSymbol.GetChar(nPos) < 128) && -/*N*/ ((GetCharTableFlags( aCorrectedSymbol.GetChar(nPos) ) & -/*N*/ (SC_COMPILER_C_WORD | SC_COMPILER_C_CHAR_DONTCARE)) == 0)) ) -/*N*/ nPos--; -/*N*/ if ( nPos == MAXSTRLEN - 2 ) -/*N*/ aCorrectedSymbol.SetChar( nPos, cQuote ); // '"' als 255. Zeichen -/*N*/ else -/*N*/ aCorrectedSymbol.Insert( cQuote, nPos + 1 ); -/*N*/ bCorrected = TRUE; -/*N*/ } -/*N*/ else if ( c1 != cQuote && c2 == cQuote ) -/*N*/ { // ..." -/*N*/ aCorrectedSymbol.Insert( cQuote, 0 ); -/*N*/ bCorrected = TRUE; -/*N*/ } -/*N*/ else if ( nPos == 0 && (c1 == cx || c1 == cX) ) -/*N*/ { // x => * -/*N*/ aCorrectedSymbol = pSymbolTable[ocMul]; -/*N*/ bCorrected = TRUE; -/*N*/ } -/*N*/ else if ( (GetCharTableFlags( c1 ) & SC_COMPILER_C_CHAR_VALUE) -/*N*/ && (GetCharTableFlags( c2 ) & SC_COMPILER_C_CHAR_VALUE) ) -/*N*/ { -/*N*/ xub_StrLen nXcount; -/*N*/ if ( (nXcount = aCorrectedSymbol.GetTokenCount( cx )) > 1 ) -/*N*/ { // x => * -/*N*/ xub_StrLen nIndex = 0; -/*N*/ sal_Unicode c = pSymbolTable[ocMul].GetChar(0); -/*N*/ while ( (nIndex = aCorrectedSymbol.SearchAndReplace( -/*N*/ cx, c, nIndex )) != STRING_NOTFOUND ) -/*N*/ nIndex++; -/*N*/ bCorrected = TRUE; -/*N*/ } -/*N*/ if ( (nXcount = aCorrectedSymbol.GetTokenCount( cX )) > 1 ) -/*N*/ { // X => * -/*N*/ xub_StrLen nIndex = 0; -/*N*/ sal_Unicode c = pSymbolTable[ocMul].GetChar(0); -/*N*/ while ( (nIndex = aCorrectedSymbol.SearchAndReplace( -/*N*/ cX, c, nIndex )) != STRING_NOTFOUND ) -/*N*/ nIndex++; -/*N*/ bCorrected = TRUE; -/*N*/ } -/*N*/ } -/*N*/ else -/*N*/ { -/*N*/ String aSymbol( aCorrectedSymbol ); -/*N*/ String aDoc; -/*N*/ xub_StrLen nLclPos; -/*N*/ if ( aSymbol.GetChar(0) == '\'' -/*N*/ && ((nLclPos = aSymbol.SearchAscii( "'#" )) != STRING_NOTFOUND) ) -/*N*/ { // 'Doc'# abspalten, kann d:\... und sonstwas sein -/*N*/ aDoc = aSymbol.Copy( 0, nLclPos + 2 ); -/*N*/ aSymbol.Erase( 0, nLclPos + 2 ); -/*N*/ } -/*N*/ xub_StrLen nRefs = aSymbol.GetTokenCount( ':' ); -/*N*/ BOOL bColons; -/*N*/ if ( nRefs > 2 ) -/*N*/ { // doppelte oder zuviele ':'? B:2::C10 => B2:C10 -/*N*/ bColons = TRUE; -/*N*/ xub_StrLen nIndex = 0; -/*N*/ String aTmp1( aSymbol.GetToken( 0, ':', nIndex ) ); -/*N*/ xub_StrLen nLen1 = aTmp1.Len(); -/*N*/ String aSym, aTmp2; -/*N*/ BOOL bLastAlp, bNextNum; -/*N*/ bLastAlp = bNextNum = TRUE; -/*N*/ xub_StrLen nStrip = 0; -/*N*/ xub_StrLen nCount = nRefs; -/*N*/ for ( xub_StrLen j=1; j<nCount; j++ ) -/*N*/ { -/*N*/ aTmp2 = aSymbol.GetToken( 0, ':', nIndex ); -/*N*/ xub_StrLen nLen2 = aTmp2.Len(); -/*N*/ if ( nLen1 || nLen2 ) -/*N*/ { -/*N*/ if ( nLen1 ) -/*N*/ { -/*N*/ aSym += aTmp1; -/*N*/ bLastAlp = CharClass::isAsciiAlpha( aTmp1 ); -/*N*/ } -/*N*/ if ( nLen2 ) -/*N*/ { -/*N*/ bNextNum = CharClass::isAsciiNumeric( aTmp2 ); -/*N*/ if ( bLastAlp == bNextNum && nStrip < 1 ) -/*N*/ { // muss abwechselnd nur Zahl/String sein, -/*N*/ // nur innerhalb einer Ref strippen -/*N*/ nRefs--; -/*N*/ nStrip++; -/*N*/ } -/*N*/ else -/*N*/ { -/*N*/ xub_StrLen nSymLen = aSym.Len(); -/*N*/ if ( nSymLen -/*N*/ && (aSym.GetChar( nSymLen - 1 ) != ':') ) -/*N*/ aSym += ':'; -/*N*/ nStrip = 0; -/*N*/ } -/*N*/ bLastAlp = !bNextNum; -/*N*/ } -/*N*/ else -/*N*/ { // :: -/*N*/ nRefs--; -/*N*/ if ( nLen1 ) -/*N*/ { // B10::C10 ? naechste Runde ':' anhaengen -/*N*/ if ( !bLastAlp && !CharClass::isAsciiNumeric( aTmp1 ) ) -/*N*/ nStrip++; -/*N*/ } -/*N*/ bNextNum = !bLastAlp; -/*N*/ } -/*N*/ aTmp1 = aTmp2; -/*N*/ nLen1 = nLen2; -/*N*/ } -/*N*/ else -/*N*/ nRefs--; -/*N*/ } -/*N*/ aSymbol = aSym; -/*N*/ aSymbol += aTmp1; -/*N*/ } -/*N*/ else -/*N*/ bColons = FALSE; -/*N*/ if ( nRefs && nRefs <= 2 ) -/*N*/ { // Referenzdreher? 4A => A4 etc. -/*N*/ String aTab[2], aRef[2]; -/*N*/ if ( nRefs == 2 ) -/*N*/ { -/*N*/ aRef[0] = aSymbol.GetToken( 0, ':' ); -/*N*/ aRef[1] = aSymbol.GetToken( 1, ':' ); -/*N*/ } -/*N*/ else -/*N*/ aRef[0] = aSymbol; -/*N*/ -/*N*/ BOOL bChanged = FALSE; -/*N*/ BOOL bOk = TRUE; -/*N*/ USHORT nMask = SCA_VALID | SCA_VALID_COL | SCA_VALID_ROW; -/*N*/ for ( int j=0; j<nRefs; j++ ) -/*N*/ { -/*N*/ xub_StrLen nTmp = 0; -/*N*/ xub_StrLen nLclPosB = STRING_NOTFOUND; -/*N*/ while ( (nTmp = aRef[j].Search( '.', nTmp )) != STRING_NOTFOUND ) -/*N*/ nLclPosB = nTmp++; // der letzte zaehlt -/*N*/ if ( nLclPosB != STRING_NOTFOUND ) -/*N*/ { -/*N*/ aTab[j] = aRef[j].Copy( 0, nLclPosB + 1 ); // mit '.' -/*N*/ aRef[j].Erase( 0, nLclPosB + 1 ); -/*N*/ } -/*N*/ String aOld( aRef[j] ); -/*N*/ String aStr2; -/*N*/ const sal_Unicode* p = aRef[j].GetBuffer(); -/*N*/ while ( *p && CharClass::isAsciiNumeric( *p ) ) -/*N*/ aStr2 += *p++; -/*N*/ aRef[j] = String( p ); -/*N*/ aRef[j] += aStr2; -/*N*/ if ( bColons || aRef[j] != aOld ) -/*N*/ { -/*N*/ bChanged = TRUE; -/*N*/ ScAddress aAdr; -/*N*/ bOk &= ((aAdr.Parse( aRef[j], pDoc ) & nMask) == nMask); -/*N*/ } -/*N*/ } -/*N*/ if ( bChanged && bOk ) -/*N*/ { -/*N*/ aCorrectedSymbol = aDoc; -/*N*/ aCorrectedSymbol += aTab[0]; -/*N*/ aCorrectedSymbol += aRef[0]; -/*N*/ if ( nRefs == 2 ) -/*N*/ { -/*N*/ aCorrectedSymbol += ':'; -/*N*/ aCorrectedSymbol += aTab[1]; -/*N*/ aCorrectedSymbol += aRef[1]; -/*N*/ } -/*N*/ bCorrected = TRUE; -/*N*/ } -/*N*/ } -/*N*/ } -/*N*/ } -/*N*/ } - -/*N*/ BOOL ScCompiler::NextNewToken() -/*N*/ { -/*N*/ xub_StrLen nSpaces = NextSymbol(); -/*N*/ ScRawToken aToken; -/*N*/ if( cSymbol[0] ) -/*N*/ { -/*N*/ if( nSpaces ) -/*N*/ { -/*N*/ aToken.SetOpCode( ocSpaces ); -/*N*/ aToken.cByte = (BYTE) ( nSpaces > 255 ? 255 : nSpaces ); -/*N*/ if( !pArr->AddToken( aToken ) ) -/*N*/ { -/*?*/ SetError(errCodeOverflow); return FALSE; -/*N*/ } -/*N*/ } -/*N*/ if ( (cSymbol[0] == '#' || cSymbol[0] == '$') && cSymbol[1] == 0 && -/*N*/ !bAutoCorrect ) -/*N*/ { // #101100# special case to speed up broken [$]#REF documents -/*N*/ String aBad( aFormula.Copy( nSrcPos-1 ) ); -/*N*/ eLastOp = pArr->AddBad( aBad )->GetOpCode(); -/*N*/ return FALSE; -/*N*/ } -/*N*/ if( !IsString() ) -/*N*/ { -/*N*/ BOOL bMayBeFuncName; -/*N*/ if ( cSymbol[0] < 128 ) -/*N*/ bMayBeFuncName = CharClass::isAsciiAlpha( cSymbol[0] ); -/*N*/ else -/*N*/ { -/*N*/ String aTmpStr( cSymbol[0] ); -/*N*/ bMayBeFuncName = ScGlobal::pCharClass->isLetter( aTmpStr, 0 ); -/*N*/ } -/*N*/ if ( bMayBeFuncName ) -/*N*/ { // a function name must be followed by a parenthesis -/*N*/ const sal_Unicode* p = aFormula.GetBuffer() + nSrcPos; -/*N*/ while( *p == ' ' ) -/*N*/ p++; -/*N*/ bMayBeFuncName = ( *p == '(' ); -/*N*/ } -/*N*/ else -/*N*/ bMayBeFuncName = TRUE; // operators and other opcodes -/*N*/ -/*N*/ String aOrg( cSymbol ); // evtl. Dateinamen in IsReference erhalten -/*N*/ String aUpper( ScGlobal::pCharClass->uppercase( aOrg ) ); -/*N*/ // Spalte DM konnte nicht referiert werden, IsReference vor IsValue -/*N*/ // #42016# italian ARCTAN.2 gab #REF! => IsOpCode vor IsReference -/*N*/ if ( !(bMayBeFuncName && IsOpCode( aUpper )) -/*N*/ && !IsReference( aOrg ) -/*N*/ && !IsValue( aUpper ) -/*N*/ && !IsNamedRange( aUpper ) -/*N*/ && !IsDBRange( aUpper ) -/*N*/ && !IsColRowName( aUpper ) -/*N*/ && !(bMayBeFuncName && IsMacro( aUpper )) -/*N*/ && !(bMayBeFuncName && IsOpCode2( aUpper )) ) -/*N*/ { -/*N*/ SetError( errNoName ); -/*N*/ if ( bAutoCorrect ) -/*N*/ { // provide single token information and continue -/*?*/ aUpper = ScGlobal::pCharClass->lowercase( aUpper ); -/*?*/ aToken.SetString( aUpper.GetBuffer() ); -/*?*/ aToken.NewOpCode( ocBad ); -/*?*/ pRawToken = aToken.Clone(); -/*?*/ AutoCorrectParsedSymbol(); -/*N*/ } -/*N*/ else -/*N*/ { // we don't need single token information, just a bad formula -/*N*/ String aBad( aFormula.Copy( nSrcPos - aOrg.Len() ) ); -/*N*/ eLastOp = pArr->AddBad( aBad )->GetOpCode(); -/*N*/ return FALSE; -/*N*/ } -/*N*/ } -/*N*/ } -/*N*/ return TRUE; -/*N*/ } -/*N*/ else -/*N*/ return FALSE; -/*N*/ } - -/*N*/ ScTokenArray* ScCompiler::CompileString( const String& rFormula ) -/*N*/ { -/*N*/ ScTokenArray aArr; -/*N*/ pArr = &aArr; -/*N*/ aFormula = rFormula; -/*N*/ aFormula.EraseLeadingChars(); -/*N*/ aFormula.EraseTrailingChars(); -/*N*/ nSrcPos = 0; -/*N*/ bCorrected = FALSE; -/*N*/ if ( bAutoCorrect ) -/*N*/ { -/*?*/ aCorrectedFormula.Erase(); -/*?*/ aCorrectedSymbol.Erase(); -/*N*/ } -/*N*/ BYTE nForced = 0; // ==Formel forciert Recalc auch wenn nicht sichtbar -/*N*/ if( aFormula.GetChar(nSrcPos) == '=' ) -/*N*/ { -/*N*/ nSrcPos++; -/*N*/ nForced++; -/*N*/ if ( bAutoCorrect ) -/*N*/ aCorrectedFormula += '='; -/*N*/ } -/*N*/ if( aFormula.GetChar(nSrcPos) == '=' ) -/*N*/ { -/*N*/ nSrcPos++; -/*N*/ nForced++; -/*N*/ if ( bAutoCorrect ) -/*N*/ aCorrectedFormula += '='; -/*N*/ } -/*N*/ short nBrackets = 0; -/*N*/ eLastOp = ocOpen; -/*N*/ while( NextNewToken() ) -/*N*/ { -/*N*/ if( pRawToken->GetOpCode() == ocOpen ) -/*N*/ nBrackets++; -/*N*/ else if( pRawToken->GetOpCode() == ocClose ) -/*N*/ { -/*N*/ if( !nBrackets ) -/*N*/ { -/*?*/ SetError( errPairExpected ); -/*?*/ if ( bAutoCorrect ) -/*?*/ { -/*?*/ bCorrected = TRUE; -/*?*/ aCorrectedSymbol.Erase(); -/*?*/ } -/*N*/ } -/*N*/ else -/*N*/ nBrackets--; -/*N*/ } -/*N*/ if( !pArr->Add( pRawToken->CreateToken() ) ) -/*N*/ { -/*?*/ SetError(errCodeOverflow); break; -/*N*/ } -/*N*/ eLastOp = pRawToken->GetOpCode(); -/*N*/ if ( bAutoCorrect ) -/*N*/ aCorrectedFormula += aCorrectedSymbol; -/*N*/ } -/*N*/ if ( eLastOp != ocBad ) -/*N*/ { // bei ocBad ist der Rest der Formel String, es wuerden zuviele -/*N*/ // Klammern erscheinen -/*N*/ ScByteToken aToken( ocClose ); -/*N*/ while( nBrackets-- ) -/*N*/ { -/*?*/ /*N*/ if( !pArr->AddToken( aToken ) ) -/*N*/ /*?*/ { -/*N*/ /*?*/ SetError(errCodeOverflow); break; -/*N*/ /*?*/ } -/*N*/ /*?*/ if ( bAutoCorrect ) -/*N*/ /*?*/ aCorrectedFormula += pSymbolTable[ocClose]; -/*N*/ } -/*N*/ } -/*N*/ if ( nForced >= 2 ) -/*?*/ pArr->SetRecalcModeForced(); -/*N*/ // pArr merken, falls danach CompileTokenArray() kommt -/*N*/ return pArr = new ScTokenArray( aArr ); -/*N*/ } - -/*N*/ void ScCompiler::PushTokenArray( ScTokenArray* pa, BOOL bTemp ) -/*N*/ { -/*N*/ if ( bAutoCorrect && !pStack ) -/*N*/ { // #61426# don't merge stacked subroutine code into entered formula -/*?*/ aCorrectedFormula += aCorrectedSymbol; -/*?*/ aCorrectedSymbol.Erase(); -/*N*/ } -/*N*/ ScArrayStack* p = new ScArrayStack; -/*N*/ p->pNext = pStack; -/*N*/ p->pArr = pArr; -/*N*/ p->bTemp = bTemp; -/*N*/ pStack = p; -/*N*/ pArr = pa; -/*N*/ } - -/*N*/ void ScCompiler::PopTokenArray() -/*N*/ { -/*N*/ if( pStack ) -/*N*/ { -/*N*/ ScArrayStack* p = pStack; -/*N*/ pStack = p->pNext; -/*N*/ p->pArr->nRefs += pArr->nRefs; -/*N*/ // special RecalcMode aus SharedFormula uebernehmen -/*N*/ if ( pArr->IsRecalcModeAlways() ) -/*?*/ p->pArr->SetRecalcModeAlways(); -/*N*/ else if ( !pArr->IsRecalcModeNormal() && p->pArr->IsRecalcModeNormal() ) -/*?*/ p->pArr->SetMaskedRecalcMode( pArr->GetRecalcMode() ); -/*N*/ p->pArr->SetCombinedBitsRecalcMode( pArr->GetRecalcMode() ); -/*N*/ if( p->bTemp ) -/*N*/ delete pArr; -/*N*/ pArr = p->pArr; -/*N*/ delete p; -/*N*/ } -/*N*/ } - -/*N*/ BOOL ScCompiler::GetToken() -/*N*/ { -/*N*/ static const short nRecursionMax = 42; -/*N*/ ScCompilerRecursionGuard aRecursionGuard( nRecursion ); -/*N*/ if ( nRecursion > nRecursionMax ) -/*N*/ { -/*?*/ SetError( errStackOverflow ); -/*?*/ pToken = new ScByteToken( ocStop ); -/*?*/ return FALSE; -/*N*/ } -/*N*/ if ( bAutoCorrect && !pStack ) -/*N*/ { // #61426# don't merge stacked subroutine code into entered formula -/*?*/ aCorrectedFormula += aCorrectedSymbol; -/*?*/ aCorrectedSymbol.Erase(); -/*N*/ } -/*N*/ BOOL bStop = FALSE; -/*N*/ if( pArr->GetError() && !bIgnoreErrors ) -/*N*/ bStop = TRUE; -/*N*/ else -/*N*/ { -/*N*/ short nWasColRowName; -/*N*/ if ( pArr->nIndex -/*N*/ && pArr->pCode[ pArr->nIndex-1 ]->GetOpCode() == ocColRowName ) -/*N*/ nWasColRowName = 1; -/*N*/ else -/*N*/ nWasColRowName = 0; -/*N*/ pToken = pArr->Next(); -/*N*/ while( pToken && pToken->GetOpCode() == ocSpaces ) -/*N*/ { -/*N*/ if ( nWasColRowName ) -/*N*/ nWasColRowName++; -/*N*/ if ( bAutoCorrect && !pStack ) -/*?*/ CreateStringFromToken( aCorrectedFormula, pToken, FALSE ); -/*N*/ pToken = pArr->Next(); -/*N*/ } -/*N*/ if ( bAutoCorrect && !pStack && pToken ) -/*?*/ CreateStringFromToken( aCorrectedSymbol, pToken, FALSE ); -/*N*/ if( !pToken ) -/*N*/ { -/*N*/ if( pStack ) -/*N*/ { -/*N*/ PopTokenArray(); -/*N*/ return GetToken(); -/*N*/ } -/*N*/ else -/*N*/ bStop = TRUE; -/*N*/ } -/*N*/ else -/*N*/ { -/*N*/ if ( nWasColRowName >= 2 && pToken->GetOpCode() == ocColRowName ) -/*N*/ { // aus einem ocSpaces ein ocIntersect im RPN machen -/*?*/ pToken = new ScByteToken( ocIntersect ); -/*?*/ pArr->nIndex--; // ganz schweinisch.. -/*N*/ } -/*N*/ } -/*N*/ } -/*N*/ if( bStop ) -/*N*/ { -/*N*/ pToken = new ScByteToken( ocStop ); -/*N*/ return FALSE; -/*N*/ } -/*N*/ if( pToken->GetOpCode() == ocSubTotal ) -/*N*/ glSubTotal = TRUE; -/*N*/ else if( pToken->GetOpCode() == ocName ) -/*N*/ { -/*N*/ ScRangeData* pRangeData = pDoc->GetRangeName()->FindIndex( pToken->GetIndex() ); -/*N*/ if (pRangeData) -/*N*/ { -/*N*/ USHORT nErr = pRangeData->GetErrCode(); -/*N*/ if( nErr ) -/*N*/ SetError( errNoName ); -/*N*/ else if ( !bCompileForFAP ) -/*N*/ { -/*N*/ ScTokenArray* pNew; -/*N*/ // #35168# Bereichsformel klammern -/*N*/ // #37680# aber nur wenn nicht schon Klammern da, -/*N*/ // geklammerte ocSep geht nicht, z.B. SUMME((...;...)) -/*N*/ // und wenn nicht direkt zwischen ocSep/Klammer, -/*N*/ // z.B. SUMME(...;(...;...)) nicht, SUMME(...;(...)*3) ja -/*N*/ // kurz: wenn kein eigenstaendiger Ausdruck -/*N*/ ScToken* p1 = pArr->PeekPrevNoSpaces(); -/*N*/ ScToken* p2 = pArr->PeekNextNoSpaces(); -/*N*/ OpCode eOp1 = (p1 ? p1->GetOpCode() : static_cast<OpCode>(ocSep)); -/*N*/ OpCode eOp2 = (p2 ? p2->GetOpCode() : static_cast<OpCode>(ocSep)); -/*N*/ BOOL bBorder1 = (eOp1 == ocSep || eOp1 == ocOpen); -/*N*/ BOOL bBorder2 = (eOp2 == ocSep || eOp2 == ocClose); -/*N*/ BOOL bAddPair = !(bBorder1 && bBorder2); -/*N*/ if ( bAddPair ) -/*N*/ { -/*N*/ pNew = new ScTokenArray; -/*N*/ pNew->AddOpCode( ocClose ); -/*N*/ PushTokenArray( pNew, TRUE ); -/*N*/ pNew->Reset(); -/*N*/ } -/*N*/ pNew = pRangeData->GetCode()->Clone(); -/*N*/ PushTokenArray( pNew, TRUE ); -/*N*/ if( pRangeData->HasReferences() ) -/*N*/ { -/*N*/ SetRelNameReference(); -/*N*/ MoveRelWrap(); -/*N*/ } -/*N*/ pNew->Reset(); -/*N*/ if ( bAddPair ) -/*N*/ { -/*N*/ pNew = new ScTokenArray; -/*N*/ pNew->AddOpCode( ocOpen ); -/*N*/ PushTokenArray( pNew, TRUE ); -/*N*/ pNew->Reset(); -/*N*/ } -/*N*/ return GetToken(); -/*N*/ } -/*N*/ } -/*N*/ else -/*N*/ SetError(errNoName); -/*N*/ } -/*N*/ else if( pToken->GetOpCode() == ocColRowName ) -/*N*/ { -/*N*/ SingleRefData& rRef = pToken->GetSingleRef(); -/*N*/ rRef.CalcAbsIfRel( aPos ); -/*N*/ if ( !rRef.Valid() ) -/*N*/ { -/*N*/ SetError( errNoRef ); -/*N*/ return TRUE; -/*N*/ } -/*N*/ USHORT nCol = rRef.nCol; -/*N*/ USHORT nRow = rRef.nRow; -/*N*/ USHORT nTab = rRef.nTab; -/*N*/ ScAddress aLook( nCol, nRow, nTab ); -/*N*/ BOOL bColName = rRef.IsColRel(); -/*N*/ USHORT nMyCol = aPos.Col(); -/*N*/ USHORT nMyRow = aPos.Row(); -/*N*/ BOOL bInList = FALSE; -/*N*/ BOOL bValidName = FALSE; -/*N*/ ScRangePairList* pRL = (bColName ? -/*N*/ pDoc->GetColNameRanges() : pDoc->GetRowNameRanges()); -/*N*/ ScRange aRange; -/*N*/ for ( ScRangePair* pR = pRL->First(); pR; pR = pRL->Next() ) -/*N*/ { -/*?*/ if ( pR->GetRange(0).In( aLook ) ) -/*?*/ { -/*?*/ bInList = bValidName = TRUE; -/*?*/ aRange = pR->GetRange(1); -/*?*/ if ( bColName ) -/*?*/ { -/*?*/ aRange.aStart.SetCol( nCol ); -/*?*/ aRange.aEnd.SetCol( nCol ); -/*?*/ } -/*?*/ else -/*?*/ { -/*?*/ aRange.aStart.SetRow( nRow ); -/*?*/ aRange.aEnd.SetRow( nRow ); -/*?*/ } -/*?*/ break; // for -/*?*/ } -/*N*/ } -/*N*/ if ( !bInList && pDoc->GetDocOptions().IsLookUpColRowNames() ) -/*N*/ { // automagically oder durch kopieren entstanden und NamePos nicht in Liste -/*N*/ BOOL bString = pDoc->HasStringData( nCol, nRow, nTab ); -/*N*/ if ( !bString && !pDoc->GetCell( aLook ) ) -/*N*/ bString = TRUE; // leere Zelle ist ok -/*N*/ if ( bString ) -/*N*/ { //! korrespondiert mit ScInterpreter::ScColRowNameAuto -/*N*/ bValidName = TRUE; -/*N*/ if ( bColName ) -/*N*/ { // ColName -/*N*/ USHORT nStartRow = nRow + 1; -/*N*/ if ( nStartRow > MAXROW ) -/*N*/ nStartRow = MAXROW; -/*N*/ USHORT nMaxRow = MAXROW; -/*N*/ if ( nMyCol == nCol ) -/*N*/ { // Formelzelle in gleicher Col -/*?*/ if ( nMyRow == nStartRow ) -/*?*/ { // direkt unter dem Namen den Rest nehmen -/*?*/ nStartRow++; -/*?*/ if ( nStartRow > MAXROW ) -/*?*/ nStartRow = MAXROW; -/*?*/ } -/*?*/ else if ( nMyRow > nStartRow ) -/*?*/ { // weiter unten vom Namen bis zur Formelzelle -/*?*/ nMaxRow = nMyRow - 1; -/*?*/ } -/*N*/ } -/*N*/ for ( ScRangePair* pR = pRL->First(); pR; pR = pRL->Next() ) -/*N*/ { // naechster definierter ColNameRange unten ist Row-Begrenzung -/*?*/ const ScRange& rRange = pR->GetRange(1); -/*?*/ if ( rRange.aStart.Col() <= nCol && nCol <= rRange.aEnd.Col() ) -/*?*/ { // gleicher Col Bereich -/*?*/ USHORT nTmp = rRange.aStart.Row(); -/*?*/ if ( nStartRow < nTmp && nTmp <= nMaxRow ) -/*?*/ nMaxRow = nTmp - 1; -/*?*/ } -/*N*/ } -/*N*/ aRange.aStart.Set( nCol, nStartRow, nTab ); -/*N*/ aRange.aEnd.Set( nCol, nMaxRow, nTab ); -/*N*/ } -/*N*/ else -/*N*/ { // RowName -/*N*/ USHORT nStartCol = nCol + 1; -/*N*/ if ( nStartCol > MAXCOL ) -/*N*/ nStartCol = MAXCOL; -/*N*/ USHORT nMaxCol = MAXCOL; -/*N*/ if ( nMyRow == nRow ) -/*N*/ { // Formelzelle in gleicher Row -/*N*/ if ( nMyCol == nStartCol ) -/*N*/ { // direkt neben dem Namen den Rest nehmen -/*N*/ nStartCol++; -/*N*/ if ( nStartCol > MAXCOL ) -/*N*/ nStartCol = MAXCOL; -/*N*/ } -/*N*/ else if ( nMyCol > nStartCol ) -/*N*/ { // weiter rechts vom Namen bis zur Formelzelle -/*N*/ nMaxCol = nMyCol - 1; -/*N*/ } -/*N*/ } -/*N*/ for ( ScRangePair* pR = pRL->First(); pR; pR = pRL->Next() ) -/*N*/ { // naechster definierter RowNameRange rechts ist Col-Begrenzung -/*?*/ const ScRange& rRange = pR->GetRange(1); -/*?*/ if ( rRange.aStart.Row() <= nRow && nRow <= rRange.aEnd.Row() ) -/*?*/ { // gleicher Row Bereich -/*?*/ USHORT nTmp = rRange.aStart.Col(); -/*?*/ if ( nStartCol < nTmp && nTmp <= nMaxCol ) -/*?*/ nMaxCol = nTmp - 1; -/*?*/ } -/*N*/ } -/*N*/ aRange.aStart.Set( nStartCol, nRow, nTab ); -/*N*/ aRange.aEnd.Set( nMaxCol, nRow, nTab ); -/*N*/ } -/*N*/ } -/*N*/ } -/*N*/ if ( bValidName ) -/*N*/ { -/*N*/ // Und nun der Zauber zur Unterscheidung zwischen -/*N*/ // Bereich und einer einzelnen Zelle daraus, die -/*N*/ // positionsabhaengig von der Formelzelle gewaehlt wird. -/*N*/ // Ist ein direkter Nachbar ein binaerer Operator (ocAdd etc.) -/*N*/ // so wird eine SingleRef passend zur Col/Row generiert, -/*N*/ // ocColRowName bzw. ocIntersect als Nachbar => Range. -/*N*/ // Spezialfall: Beschriftung gilt fuer eine einzelne Zelle, -/*N*/ // dann wird eine positionsunabhaengige SingleRef generiert. -/*N*/ BOOL bSingle = (aRange.aStart == aRange.aEnd); -/*N*/ BOOL bFound; -/*N*/ if ( bSingle ) -/*N*/ bFound = TRUE; -/*N*/ else -/*N*/ { -/*N*/ ScToken* p1 = pArr->PeekPrevNoSpaces(); -/*N*/ ScToken* p2 = pArr->PeekNextNoSpaces(); -/*N*/ // Anfang/Ende einer Formel => Single -/*N*/ OpCode eOp1 = p1 ? p1->GetOpCode() : static_cast<OpCode>(ocAdd); -/*N*/ OpCode eOp2 = p2 ? p2->GetOpCode() : static_cast<OpCode>(ocAdd); -/*N*/ if ( eOp1 != ocColRowName && eOp1 != ocIntersect -/*N*/ && eOp2 != ocColRowName && eOp2 != ocIntersect ) -/*N*/ { -/*N*/ if ( (ocEndDiv < eOp1 && eOp1 < ocEndBinOp) -/*N*/ || (ocEndDiv < eOp2 && eOp2 < ocEndBinOp) ) -/*N*/ bSingle = TRUE; -/*N*/ } -/*N*/ if ( bSingle ) -/*N*/ { // Col bzw. Row muss zum Range passen -/*N*/ if ( bColName ) -/*N*/ { -/*N*/ bFound = (aRange.aStart.Row() <= nMyRow -/*N*/ && nMyRow <= aRange.aEnd.Row()); -/*N*/ if ( bFound ) -/*N*/ aRange.aStart.SetRow( nMyRow ); -/*N*/ } -/*N*/ else -/*N*/ { -/*N*/ bFound = (aRange.aStart.Col() <= nMyCol -/*N*/ && nMyCol <= aRange.aEnd.Col()); -/*N*/ if ( bFound ) -/*?*/ aRange.aStart.SetCol( nMyCol ); -/*N*/ } -/*N*/ } -/*N*/ else -/*N*/ bFound = TRUE; -/*N*/ } -/*N*/ if ( !bFound ) -/*N*/ SetError(errNoRef); -/*N*/ else if ( !bCompileForFAP ) -/*N*/ { -/*N*/ ScTokenArray* pNew = new ScTokenArray; -/*N*/ if ( bSingle ) -/*N*/ { -/*N*/ SingleRefData aRefData; -/*N*/ aRefData.InitAddress( aRange.aStart ); -/*N*/ if ( bColName ) -/*N*/ aRefData.SetColRel( TRUE ); -/*N*/ else -/*?*/ aRefData.SetRowRel( TRUE ); -/*N*/ aRefData.CalcRelFromAbs( aPos ); -/*N*/ pNew->AddSingleReference( aRefData ); -/*N*/ } -/*N*/ else -/*N*/ { -/*?*/ ComplRefData aRefData; -/*?*/ aRefData.InitRange( aRange ); -/*?*/ if ( bColName ) -/*?*/ { -/*?*/ aRefData.Ref1.SetColRel( TRUE ); -/*?*/ aRefData.Ref2.SetColRel( TRUE ); -/*?*/ } -/*?*/ else -/*?*/ { -/*?*/ aRefData.Ref1.SetRowRel( TRUE ); -/*?*/ aRefData.Ref2.SetRowRel( TRUE ); -/*?*/ } -/*?*/ aRefData.CalcRelFromAbs( aPos ); -/*?*/ if ( bInList ) -/*?*/ pNew->AddDoubleReference( aRefData ); -/*?*/ else -/*?*/ { // automagically -/*?*/ pNew->Add( new ScDoubleRefToken( ocColRowNameAuto, -/*?*/ aRefData ) ); -/*?*/ } -/*N*/ } -/*N*/ PushTokenArray( pNew, TRUE ); -/*N*/ pNew->Reset(); -/*N*/ return GetToken(); -/*N*/ } -/*N*/ } -/*N*/ else -/*N*/ SetError(errNoName); -/*N*/ } -/*N*/ else if( pToken->GetOpCode() == ocDBArea ) -/*N*/ { -/*?*/ /*N*/ ScDBData* pDBData = pDoc->GetDBCollection()->FindIndex( pToken->GetIndex() ); -/*N*/ /*?*/ if ( !pDBData ) -/*N*/ /*?*/ SetError(errNoName); -/*N*/ /*?*/ else if ( !bCompileForFAP ) -/*N*/ /*?*/ { -/*N*/ /*?*/ ComplRefData aRefData; -/*N*/ /*?*/ aRefData.InitFlags(); -/*N*/ /*?*/ pDBData->GetArea( (USHORT&) aRefData.Ref1.nTab, -/*N*/ /*?*/ (USHORT&) aRefData.Ref1.nCol, -/*N*/ /*?*/ (USHORT&) aRefData.Ref1.nRow, -/*N*/ /*?*/ (USHORT&) aRefData.Ref2.nCol, -/*N*/ /*?*/ (USHORT&) aRefData.Ref2.nRow); -/*N*/ /*?*/ aRefData.Ref2.nTab = aRefData.Ref1.nTab; -/*N*/ /*?*/ aRefData.CalcRelFromAbs( aPos ); -/*N*/ /*?*/ ScTokenArray* pNew = new ScTokenArray; -/*N*/ /*?*/ pNew->AddDoubleReference( aRefData ); -/*N*/ /*?*/ PushTokenArray( pNew, TRUE ); -/*N*/ /*?*/ pNew->Reset(); -/*N*/ /*?*/ return GetToken(); -/*N*/ /*?*/ } -/*N*/ } -/*N*/ else if( pToken->GetType() == svSingleRef ) -/*N*/ { -/*N*/ pArr->nRefs++; -/*N*/ } -/*N*/ else if( pToken->GetType() == svDoubleRef ) -/*N*/ { -/*N*/ pArr->nRefs++; -/*N*/ } -/*N*/ return TRUE; -/*N*/ } - -/*N*/ OpCode ScCompiler::NextToken() -/*N*/ { -/*N*/ if( !GetToken() ) -/*N*/ return ocStop; -/*N*/ OpCode eOp = pToken->GetOpCode(); -/*N*/ // #38815# CompileTokenArray mit zurueckgesetztem Fehler gibt wieder Fehler -/*N*/ if ( eOp == ocBad ) -/*N*/ SetError( errNoName ); -/*N*/ // Vor einem Push muss ein Operator kommen -/*N*/ if ( (eOp == ocPush || eOp == ocColRowNameAuto) && -/*N*/ !( (eLastOp == ocOpen) || (eLastOp == ocSep) || -/*N*/ ((eLastOp > ocEndDiv) && (eLastOp < ocEndUnOp))) ) -/*?*/ SetError(errOperatorExpected); -/*N*/ // Operator und Plus = Operator -/*N*/ BOOL bLastOp = ( eLastOp == ocOpen || eLastOp == ocSep || -/*N*/ (eLastOp > ocEndDiv && eLastOp < ocEndUnOp) -/*N*/ ); -/*N*/ if( bLastOp && eOp == ocAdd ) -/*N*/ eOp = NextToken(); -/*N*/ else -/*N*/ { -/*N*/ // Vor einem Operator darf kein weiterer Operator stehen -/*N*/ // Aber AND, OR ist OK -/*N*/ if ( eOp != ocAnd && eOp != ocOr -/*N*/ && ( eOp > ocEndDiv && eOp < ocEndBinOp ) -/*N*/ && ( eLastOp == ocOpen || eLastOp == ocSep -/*N*/ || (eLastOp > ocEndDiv && eLastOp < ocEndUnOp)) ) -/*N*/ { -/*?*/ SetError(errVariableExpected); -/*?*/ if ( bAutoCorrect && !pStack ) -/*?*/ { -/*?*/ if ( eOp == eLastOp || eLastOp == ocOpen ) -/*?*/ { // doppelten Operator verwerfen -/*?*/ aCorrectedSymbol.Erase(); -/*?*/ bCorrected = TRUE; -/*?*/ } -/*?*/ else -/*?*/ { -/*?*/ xub_StrLen nPos = aCorrectedFormula.Len(); -/*?*/ if ( nPos ) -/*?*/ { -/*?*/ nPos--; -/*?*/ sal_Unicode c = aCorrectedFormula.GetChar( nPos ); -/*?*/ switch ( eOp ) -/*?*/ { // Operatoren vertauschen -/*?*/ case ocGreater: -/*?*/ if ( c == pSymbolTable[ocEqual].GetChar(0) ) -/*?*/ { // >= ist richtig statt => -/*?*/ aCorrectedFormula.SetChar( nPos, -/*?*/ pSymbolTable[ocGreater].GetChar(0) ); -/*?*/ aCorrectedSymbol = c; -/*?*/ bCorrected = TRUE; -/*?*/ } -/*?*/ break; -/*?*/ case ocLess: -/*?*/ if ( c == pSymbolTable[ocEqual].GetChar(0) ) -/*?*/ { // <= ist richtig statt =< -/*?*/ aCorrectedFormula.SetChar( nPos, -/*?*/ pSymbolTable[ocLess].GetChar(0) ); -/*?*/ aCorrectedSymbol = c; -/*?*/ bCorrected = TRUE; -/*?*/ } -/*?*/ else if ( c == pSymbolTable[ocGreater].GetChar(0) ) -/*?*/ { // <> ist richtig statt >< -/*?*/ aCorrectedFormula.SetChar( nPos, -/*?*/ pSymbolTable[ocLess].GetChar(0) ); -/*?*/ aCorrectedSymbol = c; -/*?*/ bCorrected = TRUE; -/*?*/ } -/*?*/ break; -/*?*/ case ocMul: -/*?*/ if ( c == pSymbolTable[ocSub].GetChar(0) ) -/*?*/ { // *- statt -* -/*?*/ aCorrectedFormula.SetChar( nPos, -/*?*/ pSymbolTable[ocMul].GetChar(0) ); -/*?*/ aCorrectedSymbol = c; -/*?*/ bCorrected = TRUE; -/*?*/ } -/*?*/ break; -/*?*/ case ocDiv: -/*?*/ if ( c == pSymbolTable[ocSub].GetChar(0) ) -/*?*/ { // /- statt -/ -/*?*/ aCorrectedFormula.SetChar( nPos, -/*?*/ pSymbolTable[ocDiv].GetChar(0) ); -/*?*/ aCorrectedSymbol = c; -/*?*/ bCorrected = TRUE; -/*?*/ } -/*?*/ break; -/*?*/ default: -/*?*/ break; -/*?*/ } -/*?*/ } -/*?*/ } -/*?*/ } -/*N*/ } -/*N*/ eLastOp = eOp; -/*N*/ } -/*N*/ return eOp; -/*N*/ } - -//--------------------------------------------------------------------------- - -/*N*/ BOOL ScCompiler::CompileTokenArray() -/*N*/ { -/*N*/ glSubTotal = FALSE; -/*N*/ bCorrected = FALSE; -/*N*/ if( !pArr->nError || bIgnoreErrors ) -/*N*/ { -/*N*/ if ( bAutoCorrect ) -/*N*/ { -/*?*/ aCorrectedFormula.Erase(); -/*?*/ aCorrectedSymbol.Erase(); -/*N*/ } -/*N*/ pArr->nRefs = 0; // wird neu gezaehlt -/*N*/ pArr->DelRPN(); -/*N*/ pStack = NULL; -/*N*/ ScToken* pData[ MAXCODE ]; -/*N*/ pCode = pData; -/*N*/ BOOL bWasForced = pArr->IsRecalcModeForced(); -/*N*/ if ( bWasForced ) -/*N*/ { -/*N*/ if ( bAutoCorrect ) -/*N*/ aCorrectedFormula = '='; -/*N*/ } -/*N*/ pArr->ClearRecalcMode(); -/*N*/ pArr->Reset(); -/*N*/ eLastOp = ocOpen; -/*N*/ pc = 0; -/*N*/ NextToken(); -/*N*/ Expression(); -/*N*/ -/*N*/ USHORT nErrorBeforePop = pArr->nError; -/*N*/ -/*N*/ while( pStack ) -/*?*/ PopTokenArray(); -/*N*/ if( pc ) -/*N*/ { -/*N*/ pArr->pRPN = new ScToken*[ pc ]; -/*N*/ pArr->nRPN = pc; -/*N*/ memcpy( pArr->pRPN, pData, pc * sizeof( ScToken* ) ); -/*N*/ } -/*N*/ -/*N*/ if( !pArr->nError && nErrorBeforePop ) -/*N*/ pArr->nError = nErrorBeforePop; // einmal Fehler, immer Fehler -/*N*/ -/*N*/ if( pArr->nError && !bIgnoreErrors ) -/*N*/ pArr->DelRPN(); -/*N*/ -/*N*/ if ( bWasForced ) -/*?*/ pArr->SetRecalcModeForced(); -/*N*/ } -/*N*/ if( nNumFmt == NUMBERFORMAT_UNDEFINED ) -/*N*/ nNumFmt = NUMBERFORMAT_NUMBER; -/*N*/ return glSubTotal; -/*N*/ } - -//--------------------------------------------------------------------------- -// Token in den Code Eintragen -//--------------------------------------------------------------------------- - -/*N*/ void ScCompiler::PutCode( ScToken* p ) -/*N*/ { -/*N*/ if( pc >= MAXCODE-1 ) -/*N*/ { -/*?*/ if ( pc == MAXCODE-1 ) -/*?*/ { -/*?*/ p = new ScByteToken( ocStop ); -/*?*/ *pCode++ = p; -/*?*/ ++pc; -/*?*/ p->IncRef(); -/*?*/ } -/*?*/ SetError(errCodeOverflow); -/*?*/ return; -/*N*/ } -/*N*/ if( pArr->GetError() && !bCompileForFAP ) -/*N*/ return; -/*N*/ *pCode++ = p; pc++; -/*N*/ p->IncRef(); -/*N*/ } - -//--------------------------------------------------------------------------- -// UPN-Erzeugung (durch Rekursion) -//--------------------------------------------------------------------------- - -/*N*/ void ScCompiler::Factor() -/*N*/ { -/*N*/ if ( pArr->GetError() && !bIgnoreErrors ) -/*N*/ return; -/*N*/ ScTokenRef pFacToken; -/*N*/ OpCode eOp = pToken->GetOpCode(); -/*N*/ if( eOp == ocPush || eOp == ocColRowNameAuto || eOp == ocMatRef || -/*N*/ eOp == ocDBArea -/*N*/ || (bCompileForFAP && ((eOp == ocName) || (eOp == ocDBArea) -/*N*/ || (eOp == ocColRowName) || (eOp == ocBad))) -/*N*/ ) -/*N*/ { -/*N*/ PutCode( pToken ); -/*N*/ eOp = NextToken(); -/*N*/ if( eOp == ocOpen ) -/*N*/ { -/*?*/ // PUSH( ist ein Fehler, der durch eine unbekannte -/*?*/ // Funktion hervorgerufen wird. -/*?*/ SetError( -/*?*/ ( pToken->GetType() == svString -/*?*/ || pToken->GetType() == svSingleRef ) -/*?*/ ? errNoName : errOperatorExpected ); -/*?*/ if ( bAutoCorrect && !pStack ) -/*?*/ { // Multiplikation annehmen -/*?*/ aCorrectedFormula += pSymbolTable[ocMul]; -/*?*/ bCorrected = TRUE; -/*?*/ NextToken(); -/*?*/ eOp = Expression(); -/*?*/ if( eOp != ocClose ) -/*?*/ SetError(errPairExpected); -/*?*/ else -/*?*/ eOp = NextToken(); -/*?*/ } -/*N*/ } -/*N*/ } -/*N*/ else if( eOp == ocOpen ) -/*N*/ { -/*N*/ NextToken(); -/*N*/ eOp = Expression(); -/*N*/ if( eOp != ocClose ) -/*N*/ SetError(errPairExpected); -/*N*/ else -/*N*/ eOp = NextToken(); -/*N*/ } -/*N*/ else -/*N*/ { -/*N*/ if( nNumFmt == NUMBERFORMAT_UNDEFINED ) -/*N*/ nNumFmt = lcl_GetRetFormat( eOp ); -/*N*/ if( eOp > ocEndUnOp && eOp < ocEndNoPar) -/*N*/ { -/*N*/ // Diese Funktionen muessen immer neu berechnet werden -/*N*/ switch( eOp ) -/*N*/ { -/*N*/ case ocRandom: -/*N*/ case ocGetActDate: -/*N*/ case ocGetActTime: -/*N*/ pArr->SetRecalcModeAlways(); -/*N*/ break; -/*N*/ default: -/*N*/ break; -/*N*/ } -/*N*/ pFacToken = pToken; -/*N*/ eOp = NextToken(); -/*N*/ if (eOp != ocOpen) -/*N*/ { -/*?*/ SetError(errPairExpected); -/*?*/ PutCode( pFacToken ); -/*N*/ } -/*N*/ else -/*N*/ { -/*N*/ eOp = NextToken(); -/*N*/ if (eOp != ocClose) -/*?*/ SetError(errPairExpected); -/*N*/ PutCode(pFacToken); -/*N*/ eOp = NextToken(); -/*N*/ } -/*N*/ } -/*N*/ // Spezialfall NICHT() und NEG() -/*N*/ else if( eOp == ocNot || eOp == ocNeg -/*N*/ || ( eOp > ocEndNoPar && eOp < ocEnd1Par) ) -/*N*/ { -/*N*/ // Functions that have to be always recalculated -/*N*/ switch( eOp ) -/*N*/ { -/*N*/ case ocFormula: -/*?*/ pArr->SetRecalcModeAlways(); -/*N*/ break; -/*N*/ default: -/*N*/ break; -/*N*/ } -/*N*/ pFacToken = pToken; -/*N*/ eOp = NextToken(); -/*N*/ if( nNumFmt == NUMBERFORMAT_UNDEFINED && eOp == ocNot ) -/*N*/ nNumFmt = NUMBERFORMAT_LOGICAL; -/*N*/ if (eOp == ocOpen) -/*N*/ { -/*N*/ NextToken(); -/*N*/ eOp = Expression(); -/*N*/ } -/*N*/ else -/*N*/ SetError(errPairExpected); -/*N*/ if (eOp != ocClose) -/*N*/ SetError(errPairExpected); -/*N*/ else if ( !pArr->GetError() ) -/*N*/ pFacToken->SetByte( 1 ); -/*N*/ PutCode( pFacToken ); -/*N*/ eOp = NextToken(); -/*N*/ } -/*N*/ else if ((eOp > ocEnd1Par && eOp < ocEnd2Par) -/*N*/ || eOp == ocExternal -/*N*/ || eOp == ocMacro -/*N*/ || eOp == ocAnd -/*N*/ || eOp == ocOr -/*N*/ || ( eOp >= ocInternalBegin && eOp <= ocInternalEnd ) -/*N*/ || (bCompileForFAP && ((eOp == ocIf) || (eOp == ocChose))) -/*N*/ ) -/*N*/ { -/*N*/ OpCode eFuncOp = eOp; -/*N*/ pFacToken = pToken; -/*N*/ eOp = NextToken(); -/*N*/ BOOL bNoParam = FALSE; -/*N*/ BOOL bNoPair = FALSE; -/*N*/ BYTE nMultiAreaSep = 0; -/*N*/ if (eOp == ocOpen) -/*N*/ { -/*N*/ eOp = NextToken(); -/*N*/ if ( eFuncOp == ocIndex && eOp == ocOpen ) -/*N*/ { // Mehrfachbereiche -/*?*/ BYTE SepCount = 0; -/*?*/ do -/*?*/ { -/*?*/ eOp = NextToken(); -/*?*/ if ( eOp != ocClose ) -/*?*/ { -/*?*/ SepCount++; -/*?*/ eOp = Expression(); -/*?*/ } -/*?*/ } while ( (eOp == ocSep) && (!pArr->GetError() || bIgnoreErrors) ); -/*?*/ if ( eOp != ocClose ) -/*?*/ SetError(errPairExpected); -/*?*/ eOp = NextToken(); -/*?*/ if ( eOp == ocSep ) -/*?*/ { -/*?*/ nMultiAreaSep = 1; -/*?*/ eOp = NextToken(); -/*?*/ } -/*?*/ if ( SepCount == 0 ) -/*?*/ { -/*?*/ if ( eOp == ocClose ) -/*?*/ bNoParam = TRUE; -/*?*/ } -/*?*/ else -/*?*/ { -/*?*/ PutCode( new ScByteToken( ocPush, SepCount ) ); -/*?*/ if ( eOp != ocClose ) -/*?*/ eOp = Expression(); -/*?*/ } -/*N*/ } -/*N*/ else -/*N*/ { -/*N*/ if (eOp == ocClose) -/*N*/ bNoParam = TRUE; -/*N*/ else -/*N*/ eOp = Expression(); -/*N*/ } -/*N*/ } -/*N*/ else -/*N*/ { -/*?*/ if (pFacToken->GetOpCode() == ocMultiArea) -/*?*/ { -/*?*/ bNoPair = TRUE; -/*?*/ NextToken(); -/*?*/ eOp = Expression(); -/*?*/ } -/*?*/ else -/*?*/ SetError(errPairExpected); -/*N*/ } -/*N*/ BYTE SepCount = nMultiAreaSep; -/*N*/ if( !bNoParam ) -/*N*/ { -/*N*/ SepCount++; -/*N*/ while ( (eOp == ocSep) && (!pArr->GetError() || bIgnoreErrors) ) -/*N*/ { -/*N*/ SepCount++; -/*N*/ NextToken(); -/*N*/ eOp = Expression(); -/*N*/ } -/*N*/ } -/*N*/ if ((eOp != ocClose) && !bNoPair ) -/*N*/ SetError(errPairExpected); -/*N*/ else -/*N*/ eOp = NextToken(); -/*N*/ // Jumps are just normal functions for the FunctionAutoPilot tree view -/*N*/ if ( bCompileForFAP && pFacToken->GetType() == svJump ) -/*?*/ pFacToken = new ScFAPToken( pFacToken->GetOpCode(), SepCount, pFacToken ); -/*N*/ else -/*N*/ pFacToken->SetByte( SepCount ); -/*N*/ PutCode( pFacToken ); -/*N*/ // Diese Funktionen muessen immer neu berechnet werden -/*N*/ switch( eFuncOp ) -/*N*/ { -/*?*/ // ocIndirect muesste sonst bei jedem Interpret StopListening -/*?*/ // und StartListening fuer ein RefTripel ausfuehren -/*?*/ case ocIndirect: -/*?*/ // ocOffset und ocIndex liefern indirekte Refs -/*?*/ case ocOffset: -/*?*/ case ocIndex: -/*?*/ pArr->SetRecalcModeAlways(); -/*?*/ break; -/*?*/ // Functions recalculated on every document load. -/*?*/ // Don't use SetRecalcModeOnLoad which would override ModeAlways -/*N*/ case ocConvert : -/*N*/ pArr->AddRecalcMode( RECALCMODE_ONLOAD ); -/*N*/ break; -/*?*/ // wird die referierte verschoben, aendert sich der Wert -/*?*/ case ocColumn : -/*?*/ case ocRow : -/*?*/ case ocCell : // CELL needs recalc on move for some possible type values -/*?*/ pArr->SetRecalcModeOnRefMove(); -/*?*/ break; -/*?*/ default: -/*?*/ break; -/*N*/ } -/*N*/ } -/*N*/ else if (eOp == ocIf || eOp == ocChose) -/*N*/ { -/*N*/ // Die PC-Staende sind -1 -/*N*/ pFacToken = pToken; -/*N*/ if ( eOp == ocIf ) -/*N*/ pFacToken->GetJump()[ 0 ] = 3; // if, else, behind -/*N*/ else -/*?*/ pFacToken->GetJump()[ 0 ] = MAXJUMPCOUNT+1; -/*N*/ eOp = NextToken(); -/*N*/ if (eOp == ocOpen) -/*N*/ { -/*N*/ NextToken(); -/*N*/ eOp = Expression(); -/*N*/ } -/*N*/ else -/*N*/ SetError(errPairExpected); -/*N*/ short nJumpCount = 0; -/*N*/ PutCode( pFacToken ); -/*N*/ // #36253# bei AutoCorrect (da pArr->nError ignoriert wird) -/*N*/ // unbegrenztes ocIf gibt GPF weil ScRawToken::Clone den JumpBuffer -/*N*/ // anhand von nJump[0]*2+2 alloziert, was bei ocIf 3*2+2 ist -/*N*/ const short nJumpMax = -/*N*/ (pFacToken->GetOpCode() == ocIf ? 3 : MAXJUMPCOUNT); -/*N*/ while ( (nJumpCount < (MAXJUMPCOUNT - 1)) && (eOp == ocSep) -/*N*/ && (!pArr->GetError() || bIgnoreErrors) ) -/*N*/ { -/*N*/ if ( ++nJumpCount <= nJumpMax ) -/*N*/ pFacToken->GetJump()[nJumpCount] = pc-1; -/*N*/ NextToken(); -/*N*/ eOp = Expression(); -/*N*/ PutCode( pToken ); // Als Terminator des Teilausdrucks -/*N*/ } -/*N*/ if (eOp != ocClose) -/*N*/ SetError(errPairExpected); -/*N*/ else -/*N*/ { -/*N*/ eOp = NextToken(); -/*N*/ // auch ohne AutoCorrect gibt es hier ohne nJumpMax bei -/*N*/ // mehr als 3 Parametern in ocIf einen Ueberschreiber, -/*N*/ // das war auch schon in der 312 so (jaja, die Tester..) -/*N*/ if ( ++nJumpCount <= nJumpMax ) -/*N*/ pFacToken->GetJump()[ nJumpCount ] = pc-1; -/*N*/ if ((pFacToken->GetOpCode() == ocIf && (nJumpCount > 3)) || -/*N*/ (nJumpCount >= MAXJUMPCOUNT)) -/*N*/ SetError(errIllegalParameter); -/*N*/ else -/*N*/ pFacToken->GetJump()[ 0 ] = nJumpCount; -/*N*/ } -/*N*/ } -/*N*/ else if ( eOp == ocBad ) -/*N*/ { -/*?*/ SetError( errNoName ); -/*N*/ } -/*N*/ else if ( eOp == ocClose ) -/*N*/ { -/*?*/ SetError( errParameterExpected ); -/*N*/ } -/*N*/ else if ( eOp == ocMissing ) -/*N*/ { // #84460# May occur if imported from Xcl. -/*?*/ // The real value for missing parameters depends on the function -/*?*/ // where it is used, interpreter would have to handle this. -/*?*/ // If it does remove this error case here, that could also be the -/*?*/ // time to generate ocMissing in between subsequent ocSep. -/*?*/ // Xcl import should map missings to values if possible. -/*?*/ SetError( errParameterExpected ); -/*N*/ } -/*N*/ else if ( eOp == ocSep ) -/*N*/ { // Subsequent ocSep -/*N*/ SetError( errParameterExpected ); -/*N*/ if ( bAutoCorrect && !pStack ) -/*N*/ { -/*?*/ aCorrectedSymbol.Erase(); -/*?*/ bCorrected = TRUE; -/*N*/ } -/*N*/ } -/*N*/ else -/*N*/ { -/*?*/ SetError( errUnknownToken ); -/*?*/ if ( bAutoCorrect && !pStack ) -/*?*/ { -/*?*/ if ( eOp == ocStop ) -/*?*/ { // trailing operator w/o operand -/*?*/ xub_StrLen nLen = aCorrectedFormula.Len(); -/*?*/ if ( nLen ) -/*?*/ aCorrectedFormula.Erase( nLen - 1 ); -/*?*/ aCorrectedSymbol.Erase(); -/*?*/ bCorrected = TRUE; -/*?*/ } -/*?*/ } -/*N*/ } -/*N*/ } -/*N*/ } - -//--------------------------------------------------------------------------- - -/*N*/ void ScCompiler::Unary() -/*N*/ { -/*N*/ if( pToken->GetOpCode() == ocAdd ) -/*?*/ GetToken(); -/*N*/ else if ( pToken->GetOpCode() > ocNot && pToken->GetOpCode() < ocEndUnOp ) -/*N*/ { -/*?*/ ScTokenRef p = pToken; -/*?*/ NextToken(); -/*?*/ Factor(); -/*?*/ PutCode( p ); -/*N*/ } -/*N*/ else -/*N*/ { -/*N*/ Factor(); -/*N*/ while ( pToken->GetOpCode() == ocPercentSign ) -/*N*/ { // this operator _follows_ its operand -/*?*/ PutCode( pToken ); -/*?*/ NextToken(); -/*N*/ } -/*N*/ } -/*N*/ } - -/*N*/ void ScCompiler::PowLine() -/*N*/ { -/*N*/ Unary(); -/*N*/ while (pToken->GetOpCode() == ocPow) -/*N*/ { -/*?*/ ScTokenRef p = pToken; -/*?*/ NextToken(); -/*?*/ Unary(); -/*?*/ PutCode(p); -/*N*/ } -/*N*/ } - -//--------------------------------------------------------------------------- - -/*N*/ void ScCompiler::UnionCutLine() -/*N*/ { -/*N*/ PowLine(); -/*N*/ while (pToken->GetOpCode() == ocIntersect) -/*N*/ { -/*?*/ ScTokenRef p = pToken; -/*?*/ NextToken(); -/*?*/ PowLine(); -/*?*/ PutCode(p); -/*N*/ } -/*N*/ } - -//--------------------------------------------------------------------------- - -/*N*/ void ScCompiler::MulDivLine() -/*N*/ { -/*N*/ UnionCutLine(); -/*N*/ while (pToken->GetOpCode() == ocMul || pToken->GetOpCode() == ocDiv) -/*N*/ { -/*N*/ ScTokenRef p = pToken; -/*N*/ NextToken(); -/*N*/ UnionCutLine(); -/*N*/ PutCode(p); -/*N*/ } -/*N*/ } - -//--------------------------------------------------------------------------- - -/*N*/ void ScCompiler::AddSubLine() -/*N*/ { -/*N*/ MulDivLine(); -/*N*/ while (pToken->GetOpCode() == ocAdd || pToken->GetOpCode() == ocSub) -/*N*/ { -/*N*/ ScTokenRef p = pToken; -/*N*/ NextToken(); -/*N*/ MulDivLine(); -/*N*/ PutCode(p); -/*N*/ } -/*N*/ } - -//--------------------------------------------------------------------------- - -/*N*/ void ScCompiler::ConcatLine() -/*N*/ { -/*N*/ AddSubLine(); -/*N*/ while (pToken->GetOpCode() == ocAmpersand) -/*N*/ { -/*N*/ ScTokenRef p = pToken; -/*N*/ NextToken(); -/*N*/ AddSubLine(); -/*N*/ PutCode(p); -/*N*/ } -/*N*/ } - -//--------------------------------------------------------------------------- - -/*N*/ void ScCompiler::CompareLine() -/*N*/ { -/*N*/ ConcatLine(); -/*N*/ while (pToken->GetOpCode() >= ocEqual && pToken->GetOpCode() <= ocGreaterEqual) -/*N*/ { -/*N*/ ScTokenRef p = pToken; -/*N*/ NextToken(); -/*N*/ ConcatLine(); -/*N*/ PutCode(p); -/*N*/ } -/*N*/ } - -//--------------------------------------------------------------------------- - -/*N*/ void ScCompiler::NotLine() -/*N*/ { -/*N*/ CompareLine(); -/*N*/ while (pToken->GetOpCode() == ocNot) -/*N*/ { -/*?*/ ScTokenRef p = pToken; -/*?*/ NextToken(); -/*?*/ CompareLine(); -/*?*/ PutCode(p); -/*N*/ } -/*N*/ } - -//--------------------------------------------------------------------------- - -/*N*/ OpCode ScCompiler::Expression() -/*N*/ { -/*N*/ static const short nRecursionMax = 42; -/*N*/ ScCompilerRecursionGuard aRecursionGuard( nRecursion ); -/*N*/ if ( nRecursion > nRecursionMax ) -/*N*/ { -/*?*/ SetError( errStackOverflow ); -/*?*/ return ocStop; //! stattdessen Token generieren? -/*N*/ } -/*N*/ NotLine(); -/*N*/ while (pToken->GetOpCode() == ocAnd || pToken->GetOpCode() == ocOr) -/*N*/ { -/*?*/ ScTokenRef p = pToken; -/*?*/ pToken->SetByte( 2 ); // 2 parameters! -/*?*/ NextToken(); -/*?*/ NotLine(); -/*?*/ PutCode(p); -/*N*/ } -/*N*/ return pToken->GetOpCode(); -/*N*/ } - -// Referenz aus benanntem Bereich mit relativen Angaben - -/*N*/ void ScCompiler::SetRelNameReference() -/*N*/ { -/*N*/ pArr->Reset(); -/*N*/ for( ScToken* t = pArr->GetNextReference(); t; -/*N*/ t = pArr->GetNextReference() ) -/*N*/ { -/*N*/ SingleRefData& rRef1 = t->GetSingleRef(); -/*N*/ if ( rRef1.IsColRel() || rRef1.IsRowRel() || rRef1.IsTabRel() ) -/*?*/ rRef1.SetRelName( TRUE ); -/*N*/ if ( t->GetType() == svDoubleRef ) -/*N*/ { -/*?*/ SingleRefData& rRef2 = t->GetDoubleRef().Ref2; -/*?*/ if ( rRef2.IsColRel() || rRef2.IsRowRel() || rRef2.IsTabRel() ) -/*?*/ rRef2.SetRelName( TRUE ); -/*N*/ } -/*N*/ } -/*N*/ } - -// nur relative aus RangeName mit Wrap an Position anpassen -/*N*/ void ScCompiler::MoveRelWrap() -/*N*/ { -/*N*/ pArr->Reset(); -/*N*/ for( ScToken* t = pArr->GetNextReference(); t; -/*N*/ t = pArr->GetNextReference() ) -/*N*/ { -/*N*/ if ( t->GetType() == svSingleRef ) -/*N*/ ScRefUpdate::MoveRelWrap( pDoc, aPos, SingleDoubleRefModifier( t->GetSingleRef() ).Ref() ); -/*N*/ else -/*?*/ ScRefUpdate::MoveRelWrap( pDoc, aPos, t->GetDoubleRef() ); -/*N*/ } -/*N*/ } - -/*N*/ BOOL ScCompiler::UpdateNameReference(UpdateRefMode eUpdateRefMode, -/*N*/ const ScRange& r, -/*N*/ short nDx, short nDy, short nDz, -/*N*/ BOOL& rChanged) -/*N*/ { -/*N*/ BOOL bRet = FALSE; // wird gesetzt, wenn rel-Ref -/*N*/ rChanged = FALSE; -/*N*/ pArr->Reset(); -/*N*/ for( ScToken* t = pArr->GetNextReference(); t; -/*N*/ t = pArr->GetNextReference() ) -/*N*/ { -/*N*/ SingleDoubleRefModifier aMod( *t ); -/*N*/ ComplRefData& rRef = aMod.Ref(); -/*N*/ if (!rRef.Ref1.IsColRel() && !rRef.Ref1.IsRowRel() && -/*N*/ (!rRef.Ref1.IsFlag3D() || !rRef.Ref1.IsTabRel()) && -/*N*/ ( t->GetType() == svSingleRef || -/*N*/ (!rRef.Ref2.IsColRel() && !rRef.Ref2.IsRowRel() && -/*N*/ (!rRef.Ref2.IsFlag3D() || !rRef.Ref2.IsTabRel())))) -/*N*/ { -/*?*/ /*N*/ if (ScRefUpdate::Update( pDoc, eUpdateRefMode, aPos, -/*N*/ /*?*/ r, nDx, nDy, nDz, rRef ) != UR_NOTHING ) -/*N*/ /*?*/ rChanged = TRUE; -/*N*/ } -/*N*/ else -/*N*/ bRet = TRUE; -/*N*/ } -/*N*/ return bRet; -/*N*/ } - - -/*N*/ ScRangeData* ScCompiler::UpdateInsertTab( USHORT nTable, BOOL bIsName ) -/*N*/ { -/*N*/ ScRangeData* pRangeData = NULL; -/*N*/ short nTab; -/*N*/ USHORT nPosTab = aPos.Tab(); // _nach_ evtl. Increment! -/*N*/ USHORT nOldPosTab = ((nPosTab > nTable) ? (nPosTab - 1) : nPosTab); -/*N*/ BOOL bIsRel = FALSE; -/*N*/ ScToken* t; -/*N*/ pArr->Reset(); -/*N*/ if (bIsName) -/*?*/ t = pArr->GetNextReference(); -/*N*/ else -/*N*/ t = pArr->GetNextReferenceOrName(); -/*N*/ while( t ) -/*N*/ { -/*N*/ if( t->GetOpCode() == ocName ) -/*N*/ { -/*?*/ if (!bIsName) -/*?*/ { -/*?*/ ScRangeData* pName = pDoc->GetRangeName()->FindIndex(t->GetIndex()); -/*?*/ if (pName && pName->HasType(RT_SHAREDMOD)) -/*?*/ pRangeData = pName; -/*?*/ } -/*N*/ } -/*N*/ else if( t->GetType() != svIndex ) // es kann ein DB-Bereich sein !!! -/*N*/ { -/*N*/ if ( !(bIsName && t->GetSingleRef().IsTabRel()) ) -/*N*/ { // Namen nur absolute anpassen -/*N*/ SingleRefData& rRef = t->GetSingleRef(); -/*N*/ if ( rRef.IsTabRel() ) -/*N*/ { -/*N*/ nTab = rRef.nRelTab + nOldPosTab; -/*N*/ if ( nTab < 0 ) -/*?*/ nTab += pDoc->GetTableCount(); // was a wrap -/*N*/ } -/*N*/ else -/*N*/ nTab = rRef.nTab; -/*N*/ if ( nTable <= nTab ) -/*N*/ rRef.nTab = nTab + 1; -/*N*/ rRef.nRelTab = rRef.nTab - nPosTab; -/*N*/ } -/*N*/ else -/*N*/ bIsRel = TRUE; -/*N*/ if ( t->GetType() == svDoubleRef ) -/*N*/ { -/*N*/ if ( !(bIsName && t->GetDoubleRef().Ref2.IsTabRel()) ) -/*N*/ { // Namen nur absolute anpassen -/*N*/ SingleRefData& rRef = t->GetDoubleRef().Ref2; -/*N*/ if ( rRef.IsTabRel() ) -/*N*/ { -/*N*/ nTab = rRef.nRelTab + nOldPosTab; -/*N*/ if ( nTab < 0 ) -/*?*/ nTab += pDoc->GetTableCount(); // was a wrap -/*N*/ } -/*N*/ else -/*N*/ nTab = rRef.nTab; -/*N*/ if ( nTable <= nTab ) -/*N*/ rRef.nTab = nTab + 1; -/*N*/ rRef.nRelTab = rRef.nTab - nPosTab; -/*N*/ } -/*N*/ else -/*N*/ bIsRel = TRUE; -/*N*/ } -/*N*/ if ( bIsName && bIsRel ) -/*N*/ pRangeData = (ScRangeData*) this; // wird in rangenam nicht dereferenziert -/*N*/ } -/*N*/ if (bIsName) -/*?*/ t = pArr->GetNextReference(); -/*N*/ else -/*N*/ t = pArr->GetNextReferenceOrName(); -/*N*/ } -/*N*/ if ( !bIsName ) -/*N*/ { -/*N*/ pArr->Reset(); -/*N*/ for ( t = pArr->GetNextReferenceRPN(); t; -/*N*/ t = pArr->GetNextReferenceRPN() ) -/*N*/ { -/*N*/ if ( t->GetRef() == 1 ) -/*N*/ { -/*N*/ SingleRefData& rRef1 = t->GetSingleRef(); -/*N*/ if ( !(rRef1.IsRelName() && rRef1.IsTabRel()) ) -/*N*/ { // Namen nur absolute anpassen -/*N*/ if ( rRef1.IsTabRel() ) -/*N*/ { -/*?*/ nTab = rRef1.nRelTab + nOldPosTab; -/*?*/ if ( nTab < 0 ) -/*?*/ nTab += pDoc->GetTableCount(); // was a wrap -/*N*/ } -/*N*/ else -/*N*/ nTab = rRef1.nTab; -/*N*/ if ( nTable <= nTab ) -/*N*/ rRef1.nTab = nTab + 1; -/*N*/ rRef1.nRelTab = rRef1.nTab - nPosTab; -/*N*/ } -/*N*/ if ( t->GetType() == svDoubleRef ) -/*N*/ { -/*?*/ SingleRefData& rRef2 = t->GetDoubleRef().Ref2; -/*?*/ if ( !(rRef2.IsRelName() && rRef2.IsTabRel()) ) -/*?*/ { // Namen nur absolute anpassen -/*?*/ if ( rRef2.IsTabRel() ) -/*?*/ { -/*?*/ nTab = rRef2.nRelTab + nOldPosTab; -/*?*/ if ( nTab < 0 ) -/*?*/ nTab += pDoc->GetTableCount(); // was a wrap -/*?*/ } -/*?*/ else -/*?*/ nTab = rRef2.nTab; -/*?*/ if ( nTable <= nTab ) -/*?*/ rRef2.nTab = nTab + 1; -/*?*/ rRef2.nRelTab = rRef2.nTab - nPosTab; -/*?*/ } -/*N*/ } -/*N*/ } -/*N*/ } -/*N*/ } -/*N*/ return pRangeData; -/*N*/ } - -/*N*/ ScRangeData* ScCompiler::UpdateDeleteTab(USHORT nTable, BOOL /*bIsMove*/, BOOL bIsName, -/*N*/ BOOL& rChanged) -/*N*/ { -/*N*/ ScRangeData* pRangeData = NULL; -/*N*/ USHORT nTab, nTab2; -/*N*/ USHORT nPosTab = aPos.Tab(); // _nach_ evtl. Decrement! -/*N*/ USHORT nOldPosTab = ((nPosTab >= nTable) ? (nPosTab + 1) : nPosTab); -/*N*/ rChanged = FALSE; -/*N*/ BOOL bIsRel = FALSE; -/*N*/ ScToken* t; -/*N*/ pArr->Reset(); -/*N*/ if (bIsName) -/*N*/ t = pArr->GetNextReference(); -/*N*/ else -/*N*/ t = pArr->GetNextReferenceOrName(); -/*N*/ while( t ) -/*N*/ { -/*N*/ if( t->GetOpCode() == ocName ) -/*N*/ { -/*N*/ if (!bIsName) -/*N*/ { -/*N*/ ScRangeData* pName = pDoc->GetRangeName()->FindIndex(t->GetIndex()); -/*N*/ if (pName && pName->HasType(RT_SHAREDMOD)) -/*N*/ pRangeData = pName; -/*N*/ } -/*N*/ rChanged = TRUE; -/*N*/ } -/*N*/ else if( t->GetType() != svIndex ) // es kann ein DB-Bereich sein !!! -/*N*/ { -/*N*/ if ( !(bIsName && t->GetSingleRef().IsTabRel()) ) -/*N*/ { // Namen nur absolute anpassen -/*N*/ SingleRefData& rRef = t->GetSingleRef(); -/*N*/ if ( rRef.IsTabRel() ) -/*N*/ nTab = rRef.nRelTab + nOldPosTab; -/*N*/ else -/*N*/ nTab = rRef.nTab; -/*N*/ if ( nTable < nTab ) -/*N*/ { -/*N*/ rRef.nTab = nTab - 1; -/*N*/ rChanged = TRUE; -/*N*/ } -/*N*/ else if ( nTable == nTab ) -/*N*/ { -/*N*/ if ( t->GetType() == svDoubleRef ) -/*N*/ { -/*N*/ SingleRefData& rRef2 = t->GetDoubleRef().Ref2; -/*N*/ if ( rRef2.IsTabRel() ) -/*N*/ nTab2 = rRef2.nRelTab + nOldPosTab; -/*N*/ else -/*N*/ nTab2 = rRef2.nTab; -/*N*/ if ( nTab == nTab2 -/*N*/ || (nTab+1) >= pDoc->GetTableCount() ) -/*N*/ { -/*N*/ rRef.nTab = MAXTAB+1; -/*N*/ rRef.SetTabDeleted( TRUE ); -/*N*/ } -/*N*/ // else: nTab zeigt spaeter auf jetziges nTable+1 -/*N*/ // => Bereich verkleinert -/*N*/ } -/*N*/ else -/*N*/ { -/*N*/ rRef.nTab = MAXTAB+1; -/*N*/ rRef.SetTabDeleted( TRUE ); -/*N*/ } -/*N*/ rChanged = TRUE; -/*N*/ } -/*N*/ rRef.nRelTab = rRef.nTab - nPosTab; -/*N*/ } -/*N*/ else -/*N*/ bIsRel = TRUE; -/*N*/ if ( t->GetType() == svDoubleRef ) -/*N*/ { -/*N*/ if ( !(bIsName && t->GetDoubleRef().Ref2.IsTabRel()) ) -/*N*/ { // Namen nur absolute anpassen -/*N*/ SingleRefData& rRef = t->GetDoubleRef().Ref2; -/*N*/ if ( rRef.IsTabRel() ) -/*N*/ nTab = rRef.nRelTab + nOldPosTab; -/*N*/ else -/*N*/ nTab = rRef.nTab; -/*N*/ if ( nTable < nTab ) -/*N*/ { -/*N*/ rRef.nTab = nTab - 1; -/*N*/ rChanged = TRUE; -/*N*/ } -/*N*/ else if ( nTable == nTab ) -/*N*/ { -/*N*/ if ( !t->GetDoubleRef().Ref1.IsTabDeleted() ) -/*N*/ rRef.nTab = nTab - 1; // Bereich verkleinern -/*N*/ else -/*N*/ { -/*N*/ rRef.nTab = MAXTAB+1; -/*N*/ rRef.SetTabDeleted( TRUE ); -/*N*/ } -/*N*/ rChanged = TRUE; -/*N*/ } -/*N*/ rRef.nRelTab = rRef.nTab - nPosTab; -/*N*/ } -/*N*/ else -/*N*/ bIsRel = TRUE; -/*N*/ } -/*N*/ if ( bIsName && bIsRel ) -/*N*/ pRangeData = (ScRangeData*) this; // wird in rangenam nicht dereferenziert -/*N*/ } -/*N*/ if (bIsName) -/*N*/ t = pArr->GetNextReference(); -/*N*/ else -/*N*/ t = pArr->GetNextReferenceOrName(); -/*N*/ } -/*N*/ if ( !bIsName ) -/*N*/ { -/*N*/ pArr->Reset(); -/*N*/ for ( t = pArr->GetNextReferenceRPN(); t; -/*N*/ t = pArr->GetNextReferenceRPN() ) -/*N*/ { -/*N*/ if ( t->GetRef() == 1 ) -/*N*/ { -/*N*/ SingleRefData& rRef1 = t->GetSingleRef(); -/*N*/ if ( !(rRef1.IsRelName() && rRef1.IsTabRel()) ) -/*N*/ { // Namen nur absolute anpassen -/*N*/ if ( rRef1.IsTabRel() ) -/*N*/ nTab = rRef1.nRelTab + nOldPosTab; -/*N*/ else -/*N*/ nTab = rRef1.nTab; -/*N*/ if ( nTable < nTab ) -/*N*/ { -/*N*/ rRef1.nTab = nTab - 1; -/*N*/ rChanged = TRUE; -/*N*/ } -/*N*/ else if ( nTable == nTab ) -/*N*/ { -/*N*/ if ( t->GetType() == svDoubleRef ) -/*N*/ { -/*N*/ SingleRefData& rRef2 = t->GetDoubleRef().Ref2; -/*N*/ if ( rRef2.IsTabRel() ) -/*N*/ nTab2 = rRef2.nRelTab + nOldPosTab; -/*N*/ else -/*N*/ nTab2 = rRef2.nTab; -/*N*/ if ( nTab == nTab2 -/*N*/ || (nTab+1) >= pDoc->GetTableCount() ) -/*N*/ { -/*N*/ rRef1.nTab = MAXTAB+1; -/*N*/ rRef1.SetTabDeleted( TRUE ); -/*N*/ } -/*N*/ // else: nTab zeigt spaeter auf jetziges nTable+1 -/*N*/ // => Bereich verkleinert -/*N*/ } -/*N*/ else -/*N*/ { -/*N*/ rRef1.nTab = MAXTAB+1; -/*N*/ rRef1.SetTabDeleted( TRUE ); -/*N*/ } -/*N*/ rChanged = TRUE; -/*N*/ } -/*N*/ rRef1.nRelTab = rRef1.nTab - nPosTab; -/*N*/ } -/*N*/ if ( t->GetType() == svDoubleRef ) -/*N*/ { -/*N*/ SingleRefData& rRef2 = t->GetDoubleRef().Ref2; -/*N*/ if ( !(rRef2.IsRelName() && rRef2.IsTabRel()) ) -/*N*/ { // Namen nur absolute anpassen -/*N*/ if ( rRef2.IsTabRel() ) -/*N*/ nTab = rRef2.nRelTab + nOldPosTab; -/*N*/ else -/*N*/ nTab = rRef2.nTab; -/*N*/ if ( nTable < nTab ) -/*N*/ { -/*N*/ rRef2.nTab = nTab - 1; -/*N*/ rChanged = TRUE; -/*N*/ } -/*N*/ else if ( nTable == nTab ) -/*N*/ { -/*N*/ if ( !rRef1.IsTabDeleted() ) -/*N*/ rRef2.nTab = nTab - 1; // Bereich verkleinern -/*N*/ else -/*N*/ { -/*N*/ rRef2.nTab = MAXTAB+1; -/*N*/ rRef2.SetTabDeleted( TRUE ); -/*N*/ } -/*N*/ rChanged = TRUE; -/*N*/ } -/*N*/ rRef2.nRelTab = rRef2.nTab - nPosTab; -/*N*/ } -/*N*/ } -/*N*/ } -/*N*/ } -/*N*/ } -/*N*/ return pRangeData; -/*N*/ } - -/*N*/ ScToken* ScCompiler::CreateStringFromToken( String& rFormula, ScToken* pInToken, -/*N*/ BOOL bAllowArrAdvance ) -/*N*/ { -/*N*/ ::rtl::OUStringBuffer aBuffer; -/*N*/ ScToken* p = CreateStringFromToken( aBuffer, pInToken, bAllowArrAdvance ); -/*N*/ rFormula += aBuffer.makeStringAndClear(); -/*N*/ return p; -/*N*/ } - -/*N*/ ScToken* ScCompiler::CreateStringFromToken( ::rtl::OUStringBuffer& rBuffer, ScToken* pInToken, -/*N*/ BOOL bAllowArrAdvance ) -/*N*/ { -/*N*/ BOOL bNext = TRUE; -/*N*/ BOOL bSpaces = FALSE; -/*N*/ ScToken* t = pInToken; -/*N*/ OpCode eOp = t->GetOpCode(); -/*N*/ if( eOp >= ocAnd && eOp <= ocOr ) -/*N*/ { -/*N*/ // AND, OR infix? -/*N*/ if ( bAllowArrAdvance ) -/*N*/ t = pArr->Next(); -/*N*/ else -/*N*/ t = pArr->PeekNext(); -/*N*/ bNext = FALSE; -/*N*/ bSpaces = ( !t || t->GetOpCode() != ocOpen ); -/*N*/ } -/*N*/ if( bSpaces ) -/*?*/ rBuffer.append(sal_Unicode(' ')); -/*N*/ -/*N*/ if( eOp == ocSpaces ) -/*N*/ { // most times it's just one blank -/*N*/ BYTE n = t->GetByte(); -/*N*/ for ( BYTE j=0; j<n; ++j ) -/*N*/ { -/*N*/ rBuffer.append(sal_Unicode(' ')); -/*N*/ } -/*N*/ } -/*N*/ else if( eOp >= ocInternalBegin && eOp <= ocInternalEnd ) -/*?*/ rBuffer.appendAscii( pInternal[ eOp - ocInternalBegin ] ); -/*N*/ else if( (USHORT) eOp < nAnzStrings) // Keyword: -/*N*/ rBuffer.append(pSymbolTable[eOp]); -/*N*/ else -/*N*/ { -/*?*/ OSL_FAIL("Unbekannter OpCode"); -/*?*/ rBuffer.append(ScGlobal::GetRscString(STR_NO_NAME_REF)); -/*N*/ } -/*N*/ if( bNext ) switch( t->GetType() ) -/*N*/ { -/*N*/ case svDouble: -/*N*/ { -/*N*/ if ( pSymbolTable == pSymbolTableEnglish ) -/*N*/ { // Don't go via number formatter, slows down XML export -/*N*/ // significantly because on every formula the number formatter -/*N*/ // has to switch to/from English/native language. -/*N*/ ::rtl::math::doubleToUStringBuffer( rBuffer, t->GetDouble(), -/*N*/ rtl_math_StringFormat_Automatic, -/*N*/ rtl_math_DecimalPlaces_Max, '.', TRUE ); -/*N*/ } -/*N*/ else -/*N*/ { -/*N*/ ::rtl::math::doubleToUStringBuffer( rBuffer, t->GetDouble(), -/*N*/ rtl_math_StringFormat_Automatic, -/*N*/ rtl_math_DecimalPlaces_Max, -/*N*/ ScGlobal::pLocaleData->getNumDecimalSep()[0], -/*N*/ TRUE ); -/*N*/ } -/*N*/ } -/*N*/ break; -/*N*/ case svString: -/*N*/ if( eOp == ocBad ) -/*N*/ rBuffer.append(t->GetString()); -/*N*/ else -/*N*/ { -/*N*/ if (bImportXML) -/*?*/ rBuffer.append(t->GetString()); -/*N*/ else -/*N*/ { -/*N*/ rBuffer.append(sal_Unicode('"')); -/*N*/ if ( ScGlobal::UnicodeStrChr( t->GetString().GetBuffer(), '"' ) == NULL ) -/*N*/ rBuffer.append(t->GetString()); -/*N*/ else -/*N*/ { -/*?*/ String aStr( t->GetString() ); -/*?*/ xub_StrLen nPos = 0; -/*?*/ while ( (nPos = aStr.Search( '"', nPos)) != STRING_NOTFOUND ) -/*?*/ { -/*?*/ aStr.Insert( '"', nPos ); -/*?*/ nPos += 2; -/*?*/ } -/*?*/ rBuffer.append(aStr); -/*N*/ } -/*N*/ rBuffer.append(sal_Unicode('"')); -/*N*/ } -/*N*/ } -/*N*/ break; -/*N*/ case svSingleRef: -/*N*/ { -/*N*/ SingleRefData& rRef = t->GetSingleRef(); -/*N*/ ComplRefData aRef; -/*N*/ aRef.Ref1 = aRef.Ref2 = rRef; -/*N*/ if ( eOp == ocColRowName ) -/*N*/ { -/*N*/ rRef.CalcAbsIfRel( aPos ); -/*N*/ if ( pDoc->HasStringData( rRef.nCol, rRef.nRow, rRef.nTab ) ) -/*N*/ { -/*N*/ String aStr; -/*N*/ pDoc->GetString( rRef.nCol, rRef.nRow, rRef.nTab, aStr ); -/*N*/ EnQuote( aStr ); -/*N*/ rBuffer.append(aStr); -/*N*/ } -/*N*/ else -/*N*/ { -/*?*/ rBuffer.append(ScGlobal::GetRscString(STR_NO_NAME_REF)); -/*?*/ MakeRefStr( rBuffer, aRef, TRUE ); -/*N*/ } -/*N*/ } -/*N*/ else -/*N*/ MakeRefStr( rBuffer, aRef, TRUE ); -/*N*/ } -/*N*/ break; -/*N*/ case svDoubleRef: -/*N*/ MakeRefStr( rBuffer, t->GetDoubleRef(), FALSE ); -/*N*/ break; -/*N*/ case svIndex: -/*N*/ { -/*N*/ ::rtl::OUStringBuffer aBuffer; -/*N*/ switch ( eOp ) -/*N*/ { -/*N*/ case ocName: -/*N*/ { -/*N*/ ScRangeData* pData = pDoc->GetRangeName()->FindIndex(t->GetIndex()); -/*N*/ if (pData) -/*N*/ { -/*N*/ if (pData->HasType(RT_SHARED)) -/*N*/ pData->UpdateSymbol( aBuffer, aPos, -/*N*/ pSymbolTable == pSymbolTableEnglish, -/*N*/ bCompileXML ); -/*N*/ else -/*N*/ aBuffer.append(pData->GetName()); -/*N*/ } -/*N*/ } -/*N*/ break; -/*?*/ case ocDBArea: -/*?*/ { -/*?*/ /*N*/ ScDBData* pDBData = pDoc->GetDBCollection()->FindIndex(t->GetIndex()); -/*N*/ /*?*/ if (pDBData) -/*N*/ /*?*/ aBuffer.append(pDBData->GetName()); -/*?*/ } -/*?*/ break; -/*?*/ default: -/*?*/ break; -/*?*/ } -/*N*/ if ( aBuffer.getLength() ) -/*N*/ rBuffer.append(aBuffer.makeStringAndClear()); -/*N*/ else -/*?*/ rBuffer.append(ScGlobal::GetRscString(STR_NO_NAME_REF)); -/*N*/ break; -/*N*/ } -/*N*/ case svExternal: -/*N*/ { -/*N*/ // show translated name of StarOne AddIns -/*N*/ String aAddIn( t->GetExternal() ); -/*N*/ rBuffer.append(aAddIn); -/*N*/ } -/*N*/ break; -/*N*/ case svByte: -/*N*/ case svJump: -/*N*/ case svFAP: -/*N*/ case svMissing: -/*N*/ break; // Opcodes -/*N*/ default: -/*N*/ OSL_FAIL("ScCompiler:: GetStringFromToken errUnknownVariable"); -/*N*/ } // of switch -/*N*/ if( bSpaces ) -/*?*/ rBuffer.append(sal_Unicode(' ')); -/*N*/ if ( bAllowArrAdvance ) -/*N*/ { -/*N*/ if( bNext ) -/*N*/ t = pArr->Next(); -/*N*/ return t; -/*N*/ } -/*N*/ return pInToken; -/*N*/ } - -/*N*/ void ScCompiler::CreateStringFromTokenArray( String& rFormula ) -/*N*/ { -/*N*/ ::rtl::OUStringBuffer aBuffer( pArr->GetLen() * 2 ); -/*N*/ CreateStringFromTokenArray( aBuffer ); -/*N*/ rFormula = aBuffer.makeStringAndClear(); -/*N*/ } - -/*N*/ void ScCompiler::CreateStringFromTokenArray( ::rtl::OUStringBuffer& rBuffer ) -/*N*/ { -/*N*/ rBuffer.setLength(0); -/*N*/ if( !pArr->GetLen() ) -/*N*/ return; -/*N*/ -/*N*/ // at least one char per token, plus some are references, some are function names -/*N*/ rBuffer.ensureCapacity( pArr->GetLen() * 2 ); -/*N*/ -/*N*/ if ( pArr->IsRecalcModeForced() ) -/*?*/ rBuffer.append(sal_Unicode('=')); -/*N*/ ScToken* t = pArr->First(); -/*N*/ while( t ) -/*N*/ t = CreateStringFromToken( rBuffer, t, TRUE ); -/*N*/ } - -/*N*/ BOOL ScCompiler::EnQuote( String& rStr ) -/*N*/ { -/*N*/ sal_Int32 nType = ScGlobal::pCharClass->getStringType( rStr, 0, rStr.Len() ); -/*N*/ if ( !CharClass::isNumericType( nType ) -/*N*/ && CharClass::isAlphaNumericType( nType ) ) -/*N*/ return FALSE; -/*N*/ xub_StrLen nPos = 0; -/*N*/ while ( (nPos = rStr.Search( '\'', nPos)) != STRING_NOTFOUND ) -/*N*/ { -/*N*/ rStr.Insert( '\\', nPos ); -/*N*/ nPos += 2; -/*N*/ } -/*N*/ rStr.Insert( '\'', 0 ); -/*N*/ rStr += '\''; -/*N*/ return TRUE; -/*N*/ } - - -/*N*/ BOOL ScCompiler::DeQuote( String& rStr ) -/*N*/ { -/*N*/ xub_StrLen nLen = rStr.Len(); -/*N*/ if ( nLen > 1 && rStr.GetChar(0) == '\'' && rStr.GetChar( nLen-1 ) == '\'' ) -/*N*/ { -/*N*/ rStr.Erase( nLen-1, 1 ); -/*N*/ rStr.Erase( 0, 1 ); -/*N*/ xub_StrLen nPos = 0; -/*N*/ while ( (nPos = rStr.SearchAscii( "\\\'", nPos)) != STRING_NOTFOUND ) -/*N*/ { -/*N*/ rStr.Erase( nPos, 1 ); -/*N*/ ++nPos; -/*N*/ } -/*N*/ return TRUE; -/*N*/ } -/*N*/ return FALSE; -/*N*/ } - - -} - -/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |