diff options
author | Kohei Yoshida <kyoshida@novell.com> | 2009-09-09 10:57:16 -0400 |
---|---|---|
committer | Kohei Yoshida <kyoshida@novell.com> | 2009-09-09 10:57:16 -0400 |
commit | 5a9783e305852ab2cd3ef81b04df6d552fec7730 (patch) | |
tree | 9cd37a34def8e195f582169a9c0b30895524e9ba /sc/source/core/tool | |
parent | 7cc7de904e47f2d0b5c68171b27fc66fc1415158 (diff) |
#i102750# initial refactoring in an effort to support external references in DSUM, DGET etc. Not finished yet.
Diffstat (limited to 'sc/source/core/tool')
-rw-r--r-- | sc/source/core/tool/dbcolect.cxx | 1 | ||||
-rw-r--r-- | sc/source/core/tool/doubleref.cxx | 236 | ||||
-rw-r--r-- | sc/source/core/tool/interpr1.cxx | 226 | ||||
-rw-r--r-- | sc/source/core/tool/interpr4.cxx | 89 | ||||
-rw-r--r-- | sc/source/core/tool/makefile.mk | 4 | ||||
-rw-r--r-- | sc/source/core/tool/queryparam.cxx | 296 |
6 files changed, 749 insertions, 103 deletions
diff --git a/sc/source/core/tool/dbcolect.cxx b/sc/source/core/tool/dbcolect.cxx index 51120a106..7bf0a108b 100644 --- a/sc/source/core/tool/dbcolect.cxx +++ b/sc/source/core/tool/dbcolect.cxx @@ -40,6 +40,7 @@ #include "refupdat.hxx" #include "rechead.hxx" #include "document.hxx" +#include "queryparam.hxx" #include "globstr.hrc" diff --git a/sc/source/core/tool/doubleref.cxx b/sc/source/core/tool/doubleref.cxx new file mode 100644 index 000000000..218931ffe --- /dev/null +++ b/sc/source/core/tool/doubleref.cxx @@ -0,0 +1,236 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: interpre.hxx,v $ + * $Revision: 1.35.44.2 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" + +// INCLUDE --------------------------------------------------------------- + +#include "doubleref.hxx" +#include "cell.hxx" +#include "global.hxx" +#include "document.hxx" +#include "queryparam.hxx" + +using ::rtl::OUString; + +// ============================================================================ + +ScDoubleRefBase::ScDoubleRefBase(ScDocument* pDoc, RefType eType) : + mpDoc(pDoc), meType(eType) +{ +} + +ScDoubleRefBase::~ScDoubleRefBase() +{ +} + +ScDoubleRefBase::RefType ScDoubleRefBase::getType() const +{ + return meType; +} + +ScDocument* ScDoubleRefBase::getDoc() +{ + return mpDoc; +} + +// ============================================================================ + +ScInternalDoubleRef::ScInternalDoubleRef(ScDocument* pDoc, const ScRange& rRange) : + ScDoubleRefBase(pDoc, INTERNAL), maRange(rRange) +{ +} + +ScInternalDoubleRef::~ScInternalDoubleRef() +{ +} + +const ScRange& ScInternalDoubleRef::getRange() const +{ + return maRange; +} + +SCCOL ScInternalDoubleRef::getFirstFieldColumn() +{ + return getRange().aStart.Col(); +} + +SCCOL ScInternalDoubleRef::findFieldColumn(SCCOL nColIndex) +{ + const ScRange& rRange = getRange(); + const ScAddress& s = rRange.aStart; + const ScAddress& e = rRange.aEnd; + + SCCOL nDBCol1 = s.Col(); + SCCOL nDBCol2 = e.Col(); + + if ( nColIndex <= 0 || nColIndex > (nDBCol2 - nDBCol1 + 1) ) + return nDBCol1; + + return Min(nDBCol2, static_cast<SCCOL>(nDBCol1 + nColIndex - 1)); +} + +sal_uInt16 ScInternalDoubleRef::getCellString(String& rStr, ScBaseCell* pCell) +{ + sal_uInt16 nErr = 0; + if (pCell) + { + SvNumberFormatter* pFormatter = getDoc()->GetFormatTable(); + switch (pCell->GetCellType()) + { + case CELLTYPE_STRING: + ((ScStringCell*) pCell)->GetString(rStr); + break; + case CELLTYPE_EDIT: + ((ScEditCell*) pCell)->GetString(rStr); + break; + case CELLTYPE_FORMULA: + { + ScFormulaCell* pFCell = (ScFormulaCell*) pCell; + nErr = pFCell->GetErrCode(); + if (pFCell->IsValue()) + { + double fVal = pFCell->GetValue(); + ULONG nIndex = pFormatter->GetStandardFormat( + NUMBERFORMAT_NUMBER, + ScGlobal::eLnge); + pFormatter->GetInputLineString(fVal, nIndex, rStr); + } + else + pFCell->GetString(rStr); + } + break; + case CELLTYPE_VALUE: + { + double fVal = ((ScValueCell*) pCell)->GetValue(); + ULONG nIndex = pFormatter->GetStandardFormat( + NUMBERFORMAT_NUMBER, + ScGlobal::eLnge); + pFormatter->GetInputLineString(fVal, nIndex, rStr); + } + break; + default: + rStr = ScGlobal::GetEmptyString(); + break; + } + } + else + rStr = ScGlobal::GetEmptyString(); + + return nErr; +} + +SCCOL ScInternalDoubleRef::findFieldColumn(const OUString& rStr, sal_uInt16& rErr) +{ + const ScRange& rRange = getRange(); + const ScAddress& s = rRange.aStart; + const ScAddress& e = rRange.aEnd; + + SCCOL nDBCol1 = s.Col(); + SCROW nDBRow1 = s.Row(); + SCTAB nDBTab1 = s.Tab(); + SCCOL nDBCol2 = e.Col(); + + SCCOL nField = nDBCol1; + BOOL bFound = TRUE; + + bFound = FALSE; + String aCellStr; + ScAddress aLook( nDBCol1, nDBRow1, nDBTab1 ); + while (!bFound && (aLook.Col() <= nDBCol2)) + { + ScBaseCell* pCell = getDoc()->GetCell( aLook ); + rErr = getCellString( aCellStr, pCell ); + bFound = ScGlobal::pTransliteration->isEqual(aCellStr, rStr); + if (!bFound) + aLook.IncCol(); + } + nField = aLook.Col(); + + return bFound ? nField : -1; +} + +void ScInternalDoubleRef::initQueryParam(ScQueryParam& rParam) const +{ + const ScAddress& s = maRange.aStart; + const ScAddress& e = maRange.aEnd; + rParam.nCol1 = s.Col(); + rParam.nRow1 = s.Row(); + rParam.nCol2 = e.Col(); + rParam.nRow2 = e.Row(); + rParam.nTab = s.Tab(); + rParam.bHasHeader = TRUE; + rParam.bByRow = TRUE; + rParam.bInplace = TRUE; + rParam.bCaseSens = FALSE; + rParam.bRegExp = FALSE; + rParam.bDuplicate = TRUE; +} + +bool ScInternalDoubleRef::isRangeEqual(const ScRange& rRange) const +{ + return maRange == rRange; +} + +// ============================================================================ + +ScExternalDoubleRef::ScExternalDoubleRef(ScDocument* pDoc) : + ScDoubleRefBase(pDoc, EXTERNAL) +{ +} + +ScExternalDoubleRef::~ScExternalDoubleRef() +{ +} + +SCCOL ScExternalDoubleRef::getFirstFieldColumn() +{ + return -1; +} + +SCCOL ScExternalDoubleRef::findFieldColumn(SCCOL nColIndex) +{ + return -1; +} + +SCCOL ScExternalDoubleRef::findFieldColumn(const OUString& rStr, sal_uInt16& rErr) +{ + return -1; +} + +void ScExternalDoubleRef::initQueryParam(ScQueryParam& rParam) const +{ +} + +bool ScExternalDoubleRef::isRangeEqual(const ScRange& /*rRange*/) const +{ + return false; +} diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx index 1007f7ed3..1e45a973e 100644 --- a/sc/source/core/tool/interpr1.cxx +++ b/sc/source/core/tool/interpr1.cxx @@ -67,14 +67,54 @@ #include <string.h> #include <math.h> #include <vector> +#include <memory> #include "cellkeytranslator.hxx" #include "lookupcache.hxx" #include "rangenam.hxx" #include "compiler.hxx" #include "externalrefmgr.hxx" +#include "doubleref.hxx" +#include "queryparam.hxx" #define SC_DOUBLE_MAXVALUE 1.7e307 + +#include <stdio.h> +#include <string> +#include <sys/time.h> + +namespace { + +class StackPrinter +{ +public: + explicit StackPrinter(const char* msg) : + msMsg(msg) + { + fprintf(stdout, "%s: --begin\n", msMsg.c_str()); + mfStartTime = getTime(); + } + + ~StackPrinter() + { + double fEndTime = getTime(); + fprintf(stdout, "%s: --end (duration: %g sec)\n", msMsg.c_str(), (fEndTime-mfStartTime)); + } + +private: + double getTime() const + { + timeval tv; + gettimeofday(&tv, NULL); + return tv.tv_sec + tv.tv_usec / 1000000.0; + } + + ::std::string msMsg; + double mfStartTime; +}; + +} + IMPL_FIXEDMEMPOOL_NEWDEL( ScTokenStack, 8, 4 ) IMPL_FIXEDMEMPOOL_NEWDEL( ScInterpreter, 32, 16 ) @@ -5618,9 +5658,9 @@ void ScInterpreter::ScSubTotal() #endif -BOOL ScInterpreter::GetDBParams(SCTAB& rTab, ScQueryParam& rParam, - BOOL& rMissingField ) +BOOL ScInterpreter::GetDBParams( ScQueryParam& rParam, BOOL& rMissingField ) { + StackPrinter __stack_printer__("ScInterpreter::GetDBParams"); RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::GetDBParams" ); BOOL bRet = FALSE; BOOL bAllowMissingField = FALSE; @@ -5631,14 +5671,10 @@ BOOL ScInterpreter::GetDBParams(SCTAB& rTab, ScQueryParam& rParam, } if ( GetByte() == 3 ) { - - SCCOL nQCol1; - SCROW nQRow1; - SCTAB nQTab1; - SCCOL nQCol2; - SCROW nQRow2; - SCTAB nQTab2; - PopDoubleRef(nQCol1, nQRow1, nQTab1, nQCol2, nQRow2, nQTab2); + // First, get the query criteria range. + ::std::auto_ptr<ScDoubleRefBase> pQueryRef( PopDoubleRef() ); + if (!pQueryRef.get()) + return false; BOOL bByVal = TRUE; double nVal = 0.0; @@ -5648,16 +5684,20 @@ BOOL ScInterpreter::GetDBParams(SCTAB& rTab, ScQueryParam& rParam, switch (GetStackType()) { case svDouble : + fprintf(stdout, "ScInterpreter::GetDBParams: double\n"); nVal = ::rtl::math::approxFloor( GetDouble() ); + fprintf(stdout, "ScInterpreter::GetDBParams: value = %g\n", nVal); if ( bAllowMissingField && nVal == 0.0 ) rMissingField = TRUE; // fake missing parameter break; case svString : bByVal = FALSE; aStr = GetString(); + fprintf(stdout, "ScInterpreter::GetDBParams: str = '%s'\n", rtl::OUStringToOString(aStr, RTL_TEXTENCODING_UTF8).getStr()); break; case svSingleRef : { + fprintf(stdout, "ScInterpreter::GetDBParams: single ref\n"); ScAddress aAdr; PopSingleRef( aAdr ); ScBaseCell* pCell = GetCell( aAdr ); @@ -5671,6 +5711,7 @@ BOOL ScInterpreter::GetDBParams(SCTAB& rTab, ScQueryParam& rParam, } break; case svDoubleRef : + fprintf(stdout, "ScInterpreter::GetDBParams: double ref\n"); if ( bAllowMissingField ) { // fake missing parameter for old SO compatibility bRangeFake = TRUE; @@ -5683,6 +5724,7 @@ BOOL ScInterpreter::GetDBParams(SCTAB& rTab, ScQueryParam& rParam, } break; case svMissing : + fprintf(stdout, "ScInterpreter::GetDBParams: missing\n"); PopError(); if ( bAllowMissingField ) rMissingField = TRUE; @@ -5690,98 +5732,74 @@ BOOL ScInterpreter::GetDBParams(SCTAB& rTab, ScQueryParam& rParam, SetError( errIllegalParameter ); break; default: + fprintf(stdout, "ScInterpreter::GetDBParams: pop error (%d)\n", __LINE__); PopError(); SetError( errIllegalParameter ); } - SCCOL nDBCol1; - SCROW nDBRow1; - SCTAB nDBTab1; - SCCOL nDBCol2; - SCROW nDBRow2; - SCTAB nDBTab2; - PopDoubleRef(nDBCol1, nDBRow1, nDBTab1, nDBCol2, nDBRow2, nDBTab2); + ::std::auto_ptr<ScDoubleRefBase> pDBRef( PopDoubleRef() ); - if ( nGlobalError == 0 && bRangeFake ) + if (nGlobalError || !pDBRef.get()) + return false; + + if ( bRangeFake ) { // range parameter must match entire database range - if ( aMissingRange == ScRange( nDBCol1, nDBRow1, nDBTab1, nDBCol2, - nDBRow2, nDBTab2) ) + if (pDBRef->isRangeEqual(aMissingRange)) rMissingField = TRUE; else SetError( errIllegalParameter ); } - if (nGlobalError == 0) + if (nGlobalError) + return false; + + SCCOL nField = pDBRef->getFirstFieldColumn(); + if (rMissingField) + ; // special case + else if (bByVal) + nField = pDBRef->findFieldColumn(static_cast<SCCOL>(nVal)); + else { - SCCOL nField = nDBCol1; - BOOL bFound = TRUE; + sal_uInt16 nErr = 0; + nField = pDBRef->findFieldColumn(aStr, nErr); + SetError(nErr); + } + + if (!ValidCol(nField)) + return false; + + pDBRef->initQueryParam(rParam); + bool bCreated = pDok->CreateQueryParam(pQueryRef.get(), rParam); + + if (bCreated) + { + fprintf(stdout, "ScInterpreter::GetDBParams: query param created\n"); + // An allowed missing field parameter sets the result field + // to any of the query fields, just to be able to return + // some cell from the iterator. if ( rMissingField ) - ; // special case - else if ( bByVal ) - { - if ( nVal <= 0 || nVal > (nDBCol2 - nDBCol1 + 1) ) - bFound = FALSE; - else - nField = Min(nDBCol2, (SCCOL)(nDBCol1 + (SCCOL)nVal - 1)); - } - else + nField = static_cast<SCCOL>(rParam.GetEntry(0).nField); + + rParam.nCol1 = nField; + rParam.nCol2 = nField; + + SCSIZE nCount = rParam.GetEntryCount(); + for ( SCSIZE i=0; i < nCount; i++ ) { - bFound = FALSE; - String aCellStr; - ScAddress aLook( nDBCol1, nDBRow1, nDBTab1 ); - while (!bFound && (aLook.Col() <= nDBCol2)) - { - ScBaseCell* pCell = GetCell( aLook ); - GetCellString( aCellStr, pCell ); - bFound = ScGlobal::pTransliteration->isEqual( aCellStr, aStr ); - if (!bFound) - aLook.IncCol(); - } - nField = aLook.Col(); - } - if (bFound) - { - rParam.nCol1 = nDBCol1; - rParam.nRow1 = nDBRow1; - rParam.nCol2 = nDBCol2; - rParam.nRow2 = nDBRow2; - rParam.nTab = nDBTab1; - rParam.bHasHeader = TRUE; - rParam.bByRow = TRUE; - rParam.bInplace = TRUE; - rParam.bCaseSens = FALSE; - rParam.bRegExp = FALSE; - rParam.bDuplicate = TRUE; - if (pDok->CreateQueryParam(nQCol1, nQRow1, nQCol2, nQRow2, nQTab1, rParam)) - { - // An allowed missing field parameter sets the result field - // to any of the query fields, just to be able to return - // some cell from the iterator. - if ( rMissingField ) - nField = static_cast<SCCOL>(rParam.GetEntry(0).nField); - - rParam.nCol1 = nField; - rParam.nCol2 = nField; - rTab = nDBTab1; - bRet = TRUE; - SCSIZE nCount = rParam.GetEntryCount(); - for ( SCSIZE i=0; i < nCount; i++ ) - { - ScQueryEntry& rEntry = rParam.GetEntry(i); - if ( rEntry.bDoQuery ) - { - sal_uInt32 nIndex = 0; - rEntry.bQueryByString = !pFormatter->IsNumberFormat( - *rEntry.pStr, nIndex, rEntry.nVal ); - if ( rEntry.bQueryByString && !rParam.bRegExp ) - rParam.bRegExp = MayBeRegExp( *rEntry.pStr, pDok ); - } - else - break; // for - } + ScQueryEntry& rEntry = rParam.GetEntry(i); + if ( rEntry.bDoQuery ) + { + sal_uInt32 nIndex = 0; + rEntry.bQueryByString = !pFormatter->IsNumberFormat( + *rEntry.pStr, nIndex, rEntry.nVal ); + if ( rEntry.bQueryByString && !rParam.bRegExp ) + rParam.bRegExp = MayBeRegExp( *rEntry.pStr, pDok ); } + else + break; // for } + bRet = true; } } return bRet; @@ -5790,19 +5808,21 @@ BOOL ScInterpreter::GetDBParams(SCTAB& rTab, ScQueryParam& rParam, void ScInterpreter::DBIterator( ScIterFunc eFunc ) { + StackPrinter __stack_printer__("ScInterpreter::DBIterator"); + RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::DBIterator" ); - SCTAB nTab1; double nErg = 0.0; double fMem = 0.0; BOOL bNull = TRUE; ULONG nCount = 0; - ScQueryParam aQueryParam; + ::std::auto_ptr<ScQueryParam> pQueryParam(new ScQueryParam); BOOL bMissingField = FALSE; - if ( GetDBParams( nTab1, aQueryParam, bMissingField) ) + if ( GetDBParams( *pQueryParam, bMissingField) ) { + fprintf(stdout, "ScInterpreter::DBIterator: dp param is good\n"); double nVal; USHORT nErr; - ScQueryValueIterator aValIter(pDok, nTab1, aQueryParam); + ScQueryValueIterator aValIter(pDok, pQueryParam.release()); if ( aValIter.GetFirst(nVal, nErr) && !nErr ) { switch( eFunc ) @@ -5836,10 +5856,14 @@ void ScInterpreter::DBIterator( ScIterFunc eFunc ) } while ( aValIter.GetNext(nVal, nErr) && !nErr ); } + fprintf(stdout, "ScInterpreter::DBIterator: error = %d\n", nErr); SetError(nErr); } else + { + fprintf(stdout, "ScInterpreter::DBIterator: dp params failed!\n"); SetError( errIllegalParameter); + } switch( eFunc ) { case ifCOUNT: nErg = nCount; break; @@ -5853,6 +5877,7 @@ void ScInterpreter::DBIterator( ScIterFunc eFunc ) void ScInterpreter::ScDBSum() { + StackPrinter __stack_printer__("ScInterpreter::ScDBSum"); RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScDBSum" ); DBIterator( ifSUM ); } @@ -5861,13 +5886,12 @@ void ScInterpreter::ScDBSum() void ScInterpreter::ScDBCount() { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScDBCount" ); - SCTAB nTab; - ScQueryParam aQueryParam; + ::std::auto_ptr<ScQueryParam> pQueryParam(new ScQueryParam); BOOL bMissingField = TRUE; - if ( GetDBParams( nTab, aQueryParam, bMissingField) ) + if ( GetDBParams(*pQueryParam, bMissingField) ) { ULONG nCount = 0; - if ( bMissingField ) + if ( bMissingField && pQueryParam->GetType() == ScQueryParamBase::INTERNAL ) { // count all matching records // TODO: currently the QueryIterators only return cell pointers of // existing cells, so if a query matches an empty cell there's @@ -5877,7 +5901,8 @@ void ScInterpreter::ScDBCount() // have to live with it until we reimplement the iterators to also // return empty cells, which would mean to adapt all callers of // iterators. - ScQueryCellIterator aCellIter( pDok, nTab, aQueryParam); + SCTAB nTab = pQueryParam->nTab; + ScQueryCellIterator aCellIter( pDok, nTab, *pQueryParam); if ( aCellIter.GetFirst() ) { do @@ -5890,7 +5915,7 @@ void ScInterpreter::ScDBCount() { // count only matching records with a value in the "result" field double nVal; USHORT nErr = 0; - ScQueryValueIterator aValIter( pDok, nTab, aQueryParam); + ScQueryValueIterator aValIter( pDok, pQueryParam.release()); if ( aValIter.GetFirst( nVal, nErr) && !nErr ) { do @@ -5910,11 +5935,11 @@ void ScInterpreter::ScDBCount() void ScInterpreter::ScDBCount2() { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScDBCount2" ); - SCTAB nTab; ScQueryParam aQueryParam; BOOL bMissingField = TRUE; - if (GetDBParams( nTab, aQueryParam, bMissingField)) + if (GetDBParams(aQueryParam, bMissingField)) { + SCTAB nTab = aQueryParam.nTab; ULONG nCount = 0; ScQueryCellIterator aCellIter(pDok, nTab, aQueryParam); if ( aCellIter.GetFirst() ) @@ -5968,14 +5993,13 @@ void ScInterpreter::GetDBStVarParams( double& rVal, double& rValCount ) rValCount = 0.0; double fSum = 0.0; - SCTAB nTab; - ScQueryParam aQueryParam; + ::std::auto_ptr<ScQueryParam> pQueryParam(new ScQueryParam); BOOL bMissingField = FALSE; - if (GetDBParams( nTab, aQueryParam, bMissingField)) + if (GetDBParams(*pQueryParam, bMissingField)) { double fVal; USHORT nErr; - ScQueryValueIterator aValIter(pDok, nTab, aQueryParam); + ScQueryValueIterator aValIter(pDok, pQueryParam.release()); if (aValIter.GetFirst(fVal, nErr) && !nErr) { do diff --git a/sc/source/core/tool/interpr4.cxx b/sc/source/core/tool/interpr4.cxx index cf8dc7e2c..12f8006c2 100644 --- a/sc/source/core/tool/interpr4.cxx +++ b/sc/source/core/tool/interpr4.cxx @@ -68,6 +68,7 @@ #include "jumpmatrix.hxx" #include "parclass.hxx" #include "externalrefmgr.hxx" +#include "doubleref.hxx" #include <math.h> #include <float.h> @@ -80,6 +81,42 @@ using namespace formula; #define ADDIN_MAXSTRLEN 256 +#include <stdio.h> +#include <string> +#include <sys/time.h> + +namespace { + +class StackPrinter +{ +public: + explicit StackPrinter(const char* msg) : + msMsg(msg) + { + fprintf(stdout, "%s: --begin\n", msMsg.c_str()); + mfStartTime = getTime(); + } + + ~StackPrinter() + { + double fEndTime = getTime(); + fprintf(stdout, "%s: --end (duration: %g sec)\n", msMsg.c_str(), (fEndTime-mfStartTime)); + } + +private: + double getTime() const + { + timeval tv; + gettimeofday(&tv, NULL); + return tv.tv_sec + tv.tv_usec / 1000000.0; + } + + ::std::string msMsg; + double mfStartTime; +}; + +} + // Implementiert in ui\miscdlgs\teamdlg.cxx extern void ShowTheTeam(); @@ -1021,6 +1058,46 @@ void ScInterpreter::DoubleRefToVars( const ScToken* p, } } +ScDoubleRefBase* ScInterpreter::PopDoubleRef() +{ + if (!sp) + { + SetError(errUnknownStackVariable); + return NULL; + } + + --sp; + FormulaToken* p = pStack[sp]; + switch (p->GetType()) + { + case svError: + fprintf(stdout, "ScInterpreter::PopDoubleRef: error\n"); + nGlobalError = p->GetError(); + break; + case svDoubleRef: + { + fprintf(stdout, "ScInterpreter::PopDoubleRef: double ref\n"); + SCCOL nCol1, nCol2; + SCROW nRow1, nRow2; + SCTAB nTab1, nTab2; + DoubleRefToVars(static_cast<ScToken*>(p), + nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, false); + + return new ScInternalDoubleRef(pDok, + ScRange(nCol1, nRow1, nTab1, nCol2, nRow2, nTab2)); + } + break; + case svMatrix: + { + fprintf(stdout, "ScInterpreter::PopDoubleRef: matrix\n"); + } + break; + default: + fprintf(stdout, "ScInterpreter::PopDoubleRef: other\n"); + SetError( errIllegalParameter); + } + return NULL; +} void ScInterpreter::PopDoubleRef(SCCOL& rCol1, SCROW &rRow1, SCTAB& rTab1, SCCOL& rCol2, SCROW &rRow2, SCTAB& rTab2, @@ -1034,13 +1111,16 @@ void ScInterpreter::PopDoubleRef(SCCOL& rCol1, SCROW &rRow1, SCTAB& rTab1, switch (p->GetType()) { case svError: + fprintf(stdout, "ScInterpreter::PopDoubleRef: error\n"); nGlobalError = p->GetError(); break; case svDoubleRef: + fprintf(stdout, "ScInterpreter::PopDoubleRef: double ref\n"); DoubleRefToVars( static_cast<ScToken*>(p), rCol1, rRow1, rTab1, rCol2, rRow2, rTab2, bDontCheckForTableOp); break; default: + fprintf(stdout, "ScInterpreter::PopDoubleRef: other\n"); SetError( errIllegalParameter); } } @@ -1860,11 +1940,11 @@ ScMatValType ScInterpreter::GetDoubleOrStringFromMatrix( double& rDouble, void ScInterpreter::ScDBGet() { RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "Eike.Rathke@sun.com", "ScInterpreter::ScDBGet" ); - SCTAB nTab; ScQueryParam aQueryParam; BOOL bMissingField = FALSE; - if (GetDBParams( nTab, aQueryParam, bMissingField)) + if (GetDBParams(aQueryParam, bMissingField)) { + SCTAB nTab = aQueryParam.nTab; ScBaseCell* pCell; ScQueryCellIterator aCellIter(pDok, nTab, aQueryParam); if ( (pCell = aCellIter.GetFirst()) != NULL ) @@ -2986,6 +3066,7 @@ void ScInterpreter::ScColRowNameAuto() void ScInterpreter::ScExternalRef() { + StackPrinter __stack_printer__("ScInterpreter::ScExternalRef"); ScExternalRefManager* pRefMgr = pDok->GetExternalRefManager(); const String* pFile = pRefMgr->getExternalFileName(pCur->GetIndex()); if (!pFile) @@ -2995,6 +3076,7 @@ void ScInterpreter::ScExternalRef() { case svExternalSingleRef: { + fprintf(stdout, "ScInterpreter::ScExternalRef: single ref\n"); ScSingleRefData aData(static_cast<const ScToken*>(pCur)->GetSingleRef()); if (aData.IsTabRel()) { @@ -3012,6 +3094,7 @@ void ScInterpreter::ScExternalRef() break; PushTempToken( *xNew); // push a clone + fprintf(stdout, "ScInterpreter::ScExternalRef: token pushed\n"); if (aFmt.mbIsSet) { @@ -3023,6 +3106,7 @@ void ScInterpreter::ScExternalRef() //break; // unreachable, prevent compiler warning case svExternalDoubleRef: { + fprintf(stdout, "ScInterpreter::ScExternalRef: double ref\n"); ScComplexRefData aData(static_cast<const ScToken*>(pCur)->GetDoubleRef()); if (aData.Ref1.IsTabRel() || aData.Ref2.IsTabRel()) { @@ -3051,6 +3135,7 @@ void ScInterpreter::ScExternalRef() } PushMatrix(p->GetMatrix()); + fprintf(stdout, "ScInterpreter::ScExternalRef: matrix pushed\n"); return; } //break; // unreachable, prevent compiler warning diff --git a/sc/source/core/tool/makefile.mk b/sc/source/core/tool/makefile.mk index ac0aa23fc..e8a2e0fb7 100644 --- a/sc/source/core/tool/makefile.mk +++ b/sc/source/core/tool/makefile.mk @@ -76,6 +76,7 @@ SLOFILES = \ $(SLO)$/detdata.obj \ $(SLO)$/detfunc.obj \ $(SLO)$/docoptio.obj \ + $(SLO)$/doubleref.obj \ $(SLO)$/editutil.obj \ $(SLO)$/filtopt.obj \ $(SLO)$/formulaparserpool.obj \ @@ -96,6 +97,7 @@ SLOFILES = \ $(SLO)$/printopt.obj \ $(SLO)$/prnsave.obj \ $(SLO)$/progress.obj \ + $(SLO)$/queryparam.obj \ $(SLO)$/rangelst.obj \ $(SLO)$/rangenam.obj \ $(SLO)$/rangeseq.obj \ @@ -123,6 +125,7 @@ EXCEPTIONSFILES= \ $(SLO)$/chartlock.obj \ $(SLO)$/chgtrack.obj \ $(SLO)$/compiler.obj \ + $(SLO)$/doubleref.obj \ $(SLO)$/formulaparserpool.obj \ $(SLO)$/interpr1.obj \ $(SLO)$/interpr2.obj \ @@ -131,6 +134,7 @@ EXCEPTIONSFILES= \ $(SLO)$/interpr5.obj \ $(SLO)$/lookupcache.obj \ $(SLO)$/prnsave.obj \ + $(SLO)$/queryparam.obj \ $(SLO)$/reftokenhelper.obj \ $(SLO)$/token.obj diff --git a/sc/source/core/tool/queryparam.cxx b/sc/source/core/tool/queryparam.cxx new file mode 100644 index 000000000..089e707a8 --- /dev/null +++ b/sc/source/core/tool/queryparam.cxx @@ -0,0 +1,296 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: interpr4.cxx,v $ + * $Revision: 1.57.92.5 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_sc.hxx" + +// INCLUDE --------------------------------------------------------------- + +#include "queryparam.hxx" + +// ============================================================================ + +ScQueryParamBase::ScQueryParamBase(DataType eType) : + nEntryCount(0), meType(eType) +{ +} + +ScQueryParamBase::ScQueryParamBase(const ScQueryParamBase& r) : + bHasHeader(r.bHasHeader), bByRow(r.bByRow), bInplace(r.bInplace), bCaseSens(r.bCaseSens), + bRegExp(r.bRegExp), bDuplicate(r.bDuplicate), + meType(r.meType) +{ +} + +ScQueryParamBase::~ScQueryParamBase() +{ + delete[] pEntries; +} + +void ScQueryParamBase::Resize(SCSIZE nNew) +{ + if ( nNew < MAXQUERY ) + nNew = MAXQUERY; // nie weniger als MAXQUERY + + ScQueryEntry* pNewEntries = NULL; + if ( nNew ) + pNewEntries = new ScQueryEntry[nNew]; + + SCSIZE nCopy = Min( nEntryCount, nNew ); + for (SCSIZE i=0; i<nCopy; i++) + pNewEntries[i] = pEntries[i]; + + if ( nEntryCount ) + delete[] pEntries; + nEntryCount = nNew; + pEntries = pNewEntries; +} + +void ScQueryParamBase::DeleteQuery( SCSIZE nPos ) +{ + if (nPos<nEntryCount) + { + for (SCSIZE i=nPos; i+1<nEntryCount; i++) + pEntries[i] = pEntries[i+1]; + + pEntries[nEntryCount-1].Clear(); + } + else + { + DBG_ERROR("Falscher Parameter bei ScQueryParam2::DeleteQuery"); + } +} + +void ScQueryParamBase::FillInExcelSyntax(String& aCellStr, SCSIZE nIndex) +{ + if (aCellStr.Len() > 0) + { + if ( nIndex >= nEntryCount ) + Resize( nIndex+1 ); + + ScQueryEntry& rEntry = pEntries[nIndex]; + + rEntry.bDoQuery = TRUE; + // Operatoren herausfiltern + if (aCellStr.GetChar(0) == '<') + { + if (aCellStr.GetChar(1) == '>') + { + *rEntry.pStr = aCellStr.Copy(2); + rEntry.eOp = SC_NOT_EQUAL; + } + else if (aCellStr.GetChar(1) == '=') + { + *rEntry.pStr = aCellStr.Copy(2); + rEntry.eOp = SC_LESS_EQUAL; + } + else + { + *rEntry.pStr = aCellStr.Copy(1); + rEntry.eOp = SC_LESS; + } + } + else if (aCellStr.GetChar(0) == '>') + { + if (aCellStr.GetChar(1) == '=') + { + *rEntry.pStr = aCellStr.Copy(2); + rEntry.eOp = SC_GREATER_EQUAL; + } + else + { + *rEntry.pStr = aCellStr.Copy(1); + rEntry.eOp = SC_GREATER; + } + } + else + { + if (aCellStr.GetChar(0) == '=') + *rEntry.pStr = aCellStr.Copy(1); + else + *rEntry.pStr = aCellStr; + rEntry.eOp = SC_EQUAL; + } + } +} + +ScQueryParamBase::DataType ScQueryParamBase::GetType() const +{ + return meType; +} + +// ============================================================================ + +ScQueryParam::ScQueryParam() : + ScQueryParamBase(ScQueryParamBase::INTERNAL) +{ + Clear(); +} + +//------------------------------------------------------------------------ + +ScQueryParam::ScQueryParam( const ScQueryParam& r ) : + ScQueryParamBase(r), + nCol1(r.nCol1),nRow1(r.nRow1),nCol2(r.nCol2),nRow2(r.nRow2),nTab(r.nTab), + bMixedComparison(r.bMixedComparison), bDestPers(r.bDestPers), + nDestTab(r.nDestTab), nDestCol(r.nDestCol), nDestRow(r.nDestRow) +{ + nEntryCount = 0; + + Resize( r.nEntryCount ); + for (USHORT i=0; i<nEntryCount; i++) + pEntries[i] = r.pEntries[i]; +} + +//------------------------------------------------------------------------ + +ScQueryParam::~ScQueryParam() +{ +} + +//------------------------------------------------------------------------ + +void ScQueryParam::Clear() +{ + nCol1=nCol2=nDestCol = 0; + nRow1=nRow2=nDestRow = 0; + nDestTab = 0; + nTab = SCTAB_MAX; + bHasHeader = bCaseSens = bRegExp = bMixedComparison = FALSE; + bInplace = bByRow = bDuplicate = bDestPers = TRUE; + + Resize( MAXQUERY ); + for (USHORT i=0; i<MAXQUERY; i++) + pEntries[i].Clear(); +} + +//------------------------------------------------------------------------ + +ScQueryParam& ScQueryParam::operator=( const ScQueryParam& r ) +{ + nCol1 = r.nCol1; + nRow1 = r.nRow1; + nCol2 = r.nCol2; + nRow2 = r.nRow2; + nTab = r.nTab; + nDestTab = r.nDestTab; + nDestCol = r.nDestCol; + nDestRow = r.nDestRow; + bHasHeader = r.bHasHeader; + bInplace = r.bInplace; + bCaseSens = r.bCaseSens; + bRegExp = r.bRegExp; + bMixedComparison = r.bMixedComparison; + bDuplicate = r.bDuplicate; + bByRow = r.bByRow; + bDestPers = r.bDestPers; + + Resize( r.nEntryCount ); + for (USHORT i=0; i<nEntryCount; i++) + pEntries[i] = r.pEntries[i]; + + return *this; +} + +//------------------------------------------------------------------------ + +BOOL ScQueryParam::operator==( const ScQueryParam& rOther ) const +{ + BOOL bEqual = FALSE; + + // Anzahl der Queries gleich? + USHORT nUsed = 0; + USHORT nOtherUsed = 0; + while ( nUsed<nEntryCount && pEntries[nUsed].bDoQuery ) ++nUsed; + while ( nOtherUsed<rOther.nEntryCount && rOther.pEntries[nOtherUsed].bDoQuery ) + ++nOtherUsed; + + if ( (nUsed == nOtherUsed) + && (nCol1 == rOther.nCol1) + && (nRow1 == rOther.nRow1) + && (nCol2 == rOther.nCol2) + && (nRow2 == rOther.nRow2) + && (nTab == rOther.nTab) + && (bHasHeader == rOther.bHasHeader) + && (bByRow == rOther.bByRow) + && (bInplace == rOther.bInplace) + && (bCaseSens == rOther.bCaseSens) + && (bRegExp == rOther.bRegExp) + && (bMixedComparison == rOther.bMixedComparison) + && (bDuplicate == rOther.bDuplicate) + && (bDestPers == rOther.bDestPers) + && (nDestTab == rOther.nDestTab) + && (nDestCol == rOther.nDestCol) + && (nDestRow == rOther.nDestRow) ) + { + bEqual = TRUE; + for ( USHORT i=0; i<nUsed && bEqual; i++ ) + bEqual = pEntries[i] == rOther.pEntries[i]; + } + return bEqual; +} + +//------------------------------------------------------------------------ + +void ScQueryParam::MoveToDest() +{ + if (!bInplace) + { + SCsCOL nDifX = ((SCsCOL) nDestCol) - ((SCsCOL) nCol1); + SCsROW nDifY = ((SCsROW) nDestRow) - ((SCsROW) nRow1); + SCsTAB nDifZ = ((SCsTAB) nDestTab) - ((SCsTAB) nTab); + + nCol1 = sal::static_int_cast<SCCOL>( nCol1 + nDifX ); + nRow1 = sal::static_int_cast<SCROW>( nRow1 + nDifY ); + nCol2 = sal::static_int_cast<SCCOL>( nCol2 + nDifX ); + nRow2 = sal::static_int_cast<SCROW>( nRow2 + nDifY ); + nTab = sal::static_int_cast<SCTAB>( nTab + nDifZ ); + for (USHORT i=0; i<nEntryCount; i++) + pEntries[i].nField += nDifX; + + bInplace = TRUE; + } + else + { + DBG_ERROR("MoveToDest, bInplace == TRUE"); + } +} + +// ============================================================================ + +ScQueryParamMatrix::ScQueryParamMatrix() : + ScQueryParamBase(ScQueryParamBase::MATRIX) +{ +} + +ScQueryParamMatrix::~ScQueryParamMatrix() +{ +} + |