Date: prev next · Thread: first prev next last
2011 Archives by date, by thread · List index


Hi there,

I'd like to have the attached patch committed for 3.4.  It fixes

https://bugs.freedesktop.org/show_bug.cgi?id=36933

Per rule, I need to have one sign-off in order to commit this to the 3.4
branch.

Review appreciated.

Kohei

-- 
Kohei Yoshida, LibreOffice hacker, Calc
<kyoshida@novell.com>
From b49cc01b9556a434c3c690df3bb6ddad5e0a7802 Mon Sep 17 00:00:00 2001
From: Kohei Yoshida <kyoshida@novell.com>
Date: Mon, 9 May 2011 22:54:59 -0400
Subject: [PATCH] fdo#36933: Fixed array comparison with external references.

---
 sc/source/core/inc/interpre.hxx  |    1 +
 sc/source/core/tool/interpr1.cxx |   32 +++++++++++++++++
 sc/source/core/tool/interpr4.cxx |   71 +++++++++++++++++++++++++++++--------
 3 files changed, 88 insertions(+), 16 deletions(-)

diff --git a/sc/source/core/inc/interpre.hxx b/sc/source/core/inc/interpre.hxx
index ce59c16..7caee75 100644
--- a/sc/source/core/inc/interpre.hxx
+++ b/sc/source/core/inc/interpre.hxx
@@ -316,6 +316,7 @@ void PopExternalSingleRef(ScExternalRefCache::TokenRef& rToken, ScExternalRefCac
 void PopExternalDoubleRef(sal_uInt16& rFileId, String& rTabName, ScComplexRefData& rRef);
 void PopExternalDoubleRef(ScExternalRefCache::TokenArrayRef& rArray);
 void PopExternalDoubleRef(ScMatrixRef& rMat);
+void GetExternalDoubleRef(sal_uInt16 nFileId, const String& rTabName, const ScComplexRefData& 
aData, ScExternalRefCache::TokenArrayRef& rArray);
 sal_Bool PopDoubleRefOrSingleRef( ScAddress& rAdr );
 void PopDoubleRefPushMatrix();
 // If MatrixFormula: convert formula::svDoubleRef to svMatrix, create JumpMatrix.
diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx
index 8beb6f1..1999bff 100644
--- a/sc/source/core/tool/interpr1.cxx
+++ b/sc/source/core/tool/interpr1.cxx
@@ -810,6 +810,38 @@ double ScInterpreter::Compare()
                 }
             }
             break;
+            case svExternalSingleRef:
+            {
+                ScMatrixRef pMat = GetMatrix();
+                if (!pMat)
+                {
+                    SetError( errIllegalParameter);
+                    break;
+                }
+
+                SCSIZE nC, nR;
+                pMat->GetDimensions(nC, nR);
+                if (!nC || !nR)
+                {
+                    SetError( errIllegalParameter);
+                    break;
+                }
+                if (pMat->IsEmpty(0, 0))
+                    aComp.bEmpty[i] = true;
+                else if (pMat->IsString(0, 0))
+                {
+                    *aComp.pVal[i] = pMat->GetString(0, 0);
+                    aComp.bVal[i] = false;
+                }
+                else
+                {
+                    aComp.nVal[i] = pMat->GetDouble(0, 0);
+                    aComp.bVal[i] = true;
+                }
+            }
+            break;
+            case svExternalDoubleRef:
+                // TODO: Find out how to handle this...
             default:
                 SetError( errIllegalParameter);
             break;
diff --git a/sc/source/core/tool/interpr4.cxx b/sc/source/core/tool/interpr4.cxx
index 551a1c2..bfe5b6b 100644
--- a/sc/source/core/tool/interpr4.cxx
+++ b/sc/source/core/tool/interpr4.cxx
@@ -1519,6 +1519,28 @@ void ScInterpreter::PopExternalDoubleRef(ScExternalRefCache::TokenArrayRef& 
rArr
     if (nGlobalError)
         return;
 
+    GetExternalDoubleRef(nFileId, aTabName, aData, rArray);
+    if (nGlobalError)
+        return;
+}
+
+void ScInterpreter::PopExternalDoubleRef(ScMatrixRef& rMat)
+{
+    ScExternalRefCache::TokenArrayRef pArray;
+    PopExternalDoubleRef(pArray);
+    if (nGlobalError)
+        return;
+
+    // For now, we only support single range data for external
+    // references, which means the array should only contain a
+    // single matrix token.
+    ScToken* p = static_cast<ScToken*>(pArray->First());
+    rMat = p->GetMatrix();
+}
+
+void ScInterpreter::GetExternalDoubleRef(
+    sal_uInt16 nFileId, const String& rTabName, const ScComplexRefData& rData, 
ScExternalRefCache::TokenArrayRef& rArray)
+{
     ScExternalRefManager* pRefMgr = pDok->GetExternalRefManager();
     const String* pFile = pRefMgr->getExternalFileName(nFileId);
     if (!pFile)
@@ -1526,18 +1548,19 @@ void ScInterpreter::PopExternalDoubleRef(ScExternalRefCache::TokenArrayRef& 
rArr
         SetError(errNoName);
         return;
     }
-    if (aData.Ref1.IsTabRel() || aData.Ref2.IsTabRel())
+    if (rData.Ref1.IsTabRel() || rData.Ref2.IsTabRel())
     {
         OSL_FAIL("ScCompiler::GetToken: external double reference must have an absolute table 
reference!");
         SetError(errNoRef);
         return;
     }
 
+    ScComplexRefData aData(rData);
     aData.CalcAbsIfRel(aPos);
     ScRange aRange(aData.Ref1.nCol, aData.Ref1.nRow, aData.Ref1.nTab,
                    aData.Ref2.nCol, aData.Ref2.nRow, aData.Ref2.nTab);
     ScExternalRefCache::TokenArrayRef pArray = pRefMgr->getDoubleRefTokens(
-        nFileId, aTabName, aRange, &aPos);
+        nFileId, rTabName, aRange, &aPos);
 
     if (!pArray)
     {
@@ -1562,20 +1585,6 @@ void ScInterpreter::PopExternalDoubleRef(ScExternalRefCache::TokenArrayRef& 
rArr
     rArray = pArray;
 }
 
-void ScInterpreter::PopExternalDoubleRef(ScMatrixRef& rMat)
-{
-    ScExternalRefCache::TokenArrayRef pArray;
-    PopExternalDoubleRef(pArray);
-    if (nGlobalError)
-        return;
-
-    // For now, we only support single range data for external
-    // references, which means the array should only contain a
-    // single matrix token.
-    ScToken* p = static_cast<ScToken*>(pArray->First());
-    rMat = p->GetMatrix();
-}
-
 sal_Bool ScInterpreter::PopDoubleRefOrSingleRef( ScAddress& rAdr )
 {
     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "sc", "er", "ScInterpreter::PopDoubleRefOrSingleRef" );
@@ -1643,6 +1652,7 @@ bool ScInterpreter::ConvertMatrixParameters()
                 case svDouble:
                 case svString:
                 case svSingleRef:
+                case svExternalSingleRef:
                 case svMissing:
                 case svError:
                 case svEmptyCell:
@@ -1700,6 +1710,35 @@ bool ScInterpreter::ConvertMatrixParameters()
                     }
                 }
                 break;
+                case svExternalDoubleRef:
+                {
+                    ScParameterClassification::Type eType =
+                        ScParameterClassification::GetParameterType( pCur, nParams - i);
+                    if (eType == ScParameterClassification::Array)
+                    {
+                        sal_uInt16 nFileId = p->GetIndex();
+                        const String& rTabName = p->GetString();
+                        const ScComplexRefData& rRef = static_cast<ScToken*>(p)->GetDoubleRef();
+                        ScExternalRefCache::TokenArrayRef pArray;
+                        GetExternalDoubleRef(nFileId, rTabName, rRef, pArray);
+                        if (nGlobalError)
+                            break;
+
+                        ScToken* pTemp = static_cast<ScToken*>(pArray->First());
+                        if (!pTemp)
+                            break;
+
+                        ScMatrixRef pMat = pTemp->GetMatrix();
+                        if (pMat)
+                        {
+                            ScToken* pNew = new ScMatrixToken( pMat);
+                            pNew->IncRef();
+                            pStack[ sp - i ] = pNew;
+                            p->DecRef();    // p may be dead now!
+                        }
+                    }
+                }
+                break;
                 case svRefList:
                 {
                     ScParameterClassification::Type eType =
-- 
1.7.3.4


Context


Privacy Policy | Impressum (Legal Info) | Copyright information: Unless otherwise specified, all text and images on this website are licensed under the Creative Commons Attribution-Share Alike 3.0 License. This does not include the source code of LibreOffice, which is licensed under the Mozilla Public License (MPLv2). "LibreOffice" and "The Document Foundation" are registered trademarks of their corresponding registered owners or are in actual use as trademarks in one or more countries. Their respective logos and icons are also subject to international copyright laws. Use thereof is explained in our trademark policy.