[Libreoffice-commits] core.git: sc/source

Eike Rathke (via logerrit) logerrit at kemper.freedesktop.org
Sat Oct 31 10:48:00 UTC 2020


 sc/source/core/tool/interpr1.cxx |   52 ++++++++++++++++++++++++++++++++++++---
 1 file changed, 48 insertions(+), 4 deletions(-)

New commits:
commit 8100e82509b2f5f29dabf24e19461d649f166b4c
Author:     Eike Rathke <erack at redhat.com>
AuthorDate: Sat Oct 31 01:36:18 2020 +0100
Commit:     Eike Rathke <erack at redhat.com>
CommitDate: Sat Oct 31 11:47:20 2020 +0100

    Support external names in INDIRECT()
    
    Works with external global names, external sheet-local names are
    not supported by ScExternalRefManager / ScExternalRefCache.
    
    Change-Id: I59ecc9444268a14eee67439db5ed99181a716151
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/105092
    Tested-by: Jenkins
    Reviewed-by: Eike Rathke <erack at redhat.com>

diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx
index 8e50ae7303c5..1bcc37478eb5 100644
--- a/sc/source/core/tool/interpr1.cxx
+++ b/sc/source/core/tool/interpr1.cxx
@@ -8190,12 +8190,45 @@ void ScInterpreter::ScIndirect()
         }
         while (false);
 
-        // It may be even a TableRef.
+        // It may be even a TableRef or an external name.
         // Anything else that resolves to one reference could be added
         // here, but we don't want to compile every arbitrary string. This
         // is already nasty enough...
-        sal_Int32 nIndex = sRefStr.indexOf('[');
-        if (nIndex >= 0 && sRefStr.indexOf(']',nIndex+1) > nIndex)
+        sal_Int32 nIndex = ScGlobal::FindUnquoted( sRefStr, '[');
+        const bool bTableRef = (nIndex > 0 && ScGlobal::FindUnquoted( sRefStr, ']', nIndex+1) > nIndex);
+        bool bExternalName = false;     // External references would had been consumed above already.
+        if (!bTableRef)
+        {
+            // This is our own file name reference representation centric.. but
+            // would work also for XL '[doc]'!name and also for
+            // '[doc]Sheet1'!name ... sickos.
+            if (sRefStr[0] == '\'')
+            {
+                // Minimum 'a'#name or 'a'!name
+                // bTryXlA1 means try both, first our own.
+                if (bTryXlA1 || eConv == FormulaGrammar::CONV_OOO)
+                {
+                    nIndex = ScGlobal::FindUnquoted( sRefStr, '#');
+                    if (nIndex >= 3 && sRefStr[nIndex-1] == '\'')
+                    {
+                        bExternalName = true;
+                        eConv = FormulaGrammar::CONV_OOO;
+                    }
+                }
+                if (!bExternalName && (bTryXlA1 || eConv != FormulaGrammar::CONV_OOO))
+                {
+                    nIndex = ScGlobal::FindUnquoted( sRefStr, '!');
+                    if (nIndex >= 3 && sRefStr[nIndex-1] == '\'')
+                    {
+                        bExternalName = true;
+                        if (eConv == FormulaGrammar::CONV_OOO)
+                            eConv = FormulaGrammar::CONV_XL_A1;
+                    }
+                }
+            }
+
+        }
+        if (bExternalName || bTableRef)
         {
             do
             {
@@ -8203,8 +8236,17 @@ void ScInterpreter::ScIndirect()
                 aComp.SetRefConvention( eConv);     // must be after grammar
                 std::unique_ptr<ScTokenArray> pTokArr( aComp.CompileString( sRefStr));
 
+                if (pTokArr->GetCodeError() != FormulaError::NONE || !pTokArr->GetLen())
+                    break;
+
                 // Whatever... use only the specific case.
-                if (!pTokArr->HasOpCode( ocTableRef))
+                if (bExternalName)
+                {
+                    const formula::FormulaToken* pTok = pTokArr->FirstToken();
+                    if (!pTok || pTok->GetType() != svExternalName)
+                        break;
+                }
+                else if (!pTokArr->HasOpCode( ocTableRef))
                     break;
 
                 aComp.CompileTokenArray();
@@ -8223,6 +8265,8 @@ void ScInterpreter::ScIndirect()
                 {
                     case svSingleRef:
                     case svDoubleRef:
+                    case svExternalSingleRef:
+                    case svExternalDoubleRef:
                     case svError:
                         PushTokenRef( xTok);
                         // success!


More information about the Libreoffice-commits mailing list