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

Eike Rathke erack at redhat.com
Wed Apr 8 11:46:28 PDT 2015


 sc/source/core/tool/compiler.cxx |  200 +++++++++++++++++++++++++++++++++------
 1 file changed, 171 insertions(+), 29 deletions(-)

New commits:
commit e94ad965f877ad6a860273c5fed94416998678cf
Author: Eike Rathke <erack at redhat.com>
Date:   Wed Apr 8 20:44:04 2015 +0200

    TableRef: add pointers to documentation
    
    Change-Id: I248ac1d116ffabc8346fd000c2ae4b0b9c6bd89b

diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx
index 0970d01..d580bb9 100644
--- a/sc/source/core/tool/compiler.cxx
+++ b/sc/source/core/tool/compiler.cxx
@@ -4762,6 +4762,14 @@ bool ScCompiler::HandleDbData()
     return true;
 }
 
+
+/* Documentation on MS-Excel Table structured references:
+ * https://support.office.com/en-us/article/Use-structured-references-in-Excel-table-formulas-75fb07d3-826a-449c-b76f-363057e3d16f
+ * * as of Excel 2013
+ * [MS-XLSX]: Formulas https://msdn.microsoft.com/en-us/library/dd906358.aspx
+ * * look for structure-reference
+ */
+
 bool ScCompiler::HandleTableRef()
 {
     ScTableRefToken* pTR = dynamic_cast<ScTableRefToken*>(mpToken.get());
commit 7940dabb8a93784a85db10160a8b20fb53b97474
Author: Eike Rathke <erack at redhat.com>
Date:   Wed Apr 8 20:37:09 2015 +0200

    TableRef: table name without items references data only
    
    Change-Id: I2d4e534444678ddf8243db7b3fb6fe66af9fa24f

diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx
index f5b122b..0970d01 100644
--- a/sc/source/core/tool/compiler.cxx
+++ b/sc/source/core/tool/compiler.cxx
@@ -4789,6 +4789,15 @@ bool ScCompiler::HandleTableRef()
         {
             case ScTableRefToken::TABLE:
                 {
+                    // The table name without items references the table data,
+                    // without headers or totals.
+                    if (pDBData->HasHeader())
+                        aRange.aStart.IncRow();
+                    if (pDBData->HasTotals())
+                        aRange.aEnd.IncRow(-1);
+                    if (aRange.aEnd.Row() < aRange.aStart.Row())
+                        bAddRange = false;
+
                     // Optional [] may follow.
                     if ((bGotToken = GetToken()) && mpToken->GetOpCode() == ocTableRefOpen)
                     {
commit 024a5d98324c101dc46c54c972df498741e23f2b
Author: Eike Rathke <erack at redhat.com>
Date:   Wed Apr 8 20:16:56 2015 +0200

    TableRef: match column header rows against DBrange first row
    
    Change-Id: I10f7806288f817e599876f95af4998ff6f539fc3

diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx
index 30f1c5a..f5b122b 100644
--- a/sc/source/core/tool/compiler.cxx
+++ b/sc/source/core/tool/compiler.cxx
@@ -4776,9 +4776,10 @@ bool ScCompiler::HandleTableRef()
         SetError(errNoName);
     else if (mbJumpCommandReorder)
     {
-        ScRange aRange;
-        pDBData->GetArea(aRange);
-        aRange.aEnd.SetTab(aRange.aStart.Tab());
+        ScRange aDBRange;
+        pDBData->GetArea(aDBRange);
+        aDBRange.aEnd.SetTab(aDBRange.aStart.Tab());
+        ScRange aRange( aDBRange);
         ScTokenArray* pNew = new ScTokenArray();
         bool bGotToken = false;
         bool bAddRange = true;
@@ -4954,7 +4955,7 @@ bool ScCompiler::HandleTableRef()
                     default:
                         ;   // nothing
                 }
-                if (aColRange.aStart.Row() != aRange.aStart.Row() || aColRange.aEnd.Row() != aRange.aStart.Row())
+                if (aColRange.aStart.Row() != aDBRange.aStart.Row() || aColRange.aEnd.Row() != aDBRange.aStart.Row())
                     aRange = ScRange( ScAddress::INITIALIZE_INVALID);
                 else
                 {
commit ab060c294ec1f2bf7c59e6ea5edc4b78e006ac10
Author: Eike Rathke <erack at redhat.com>
Date:   Wed Apr 8 19:51:49 2015 +0200

    TableRef: handle column range
    
    Change-Id: Iab87cc3fb2b21b53303e46a227f3a1ae35a3ab6d

diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx
index 791a9a3..30f1c5a 100644
--- a/sc/source/core/tool/compiler.cxx
+++ b/sc/source/core/tool/compiler.cxx
@@ -4922,14 +4922,28 @@ bool ScCompiler::HandleTableRef()
         {
             if (bColumnRange)
             {
+                bGotToken = false;  // obtain at least a close hereafter
                 // Limit range to specified columns.
                 ScRange aColRange( ScAddress::INITIALIZE_INVALID );
                 switch (mpToken->GetType())
                 {
                     case svSingleRef:
                         {
-                            ScAddress aRef( mpToken->GetSingleRef()->toAbs( aPos));
-                            aColRange.aStart = aColRange.aEnd = aRef;
+                            aColRange.aStart = aColRange.aEnd = mpToken->GetSingleRef()->toAbs( aPos);
+                            if (    (bGotToken = GetToken()) && mpToken->GetOpCode() == ocTableRefClose &&
+                                    (bGotToken = GetToken()) && mpToken->GetOpCode() == ocRange &&
+                                    (bGotToken = GetToken()) && mpToken->GetOpCode() == ocTableRefOpen &&
+                                    (bGotToken = GetToken()) && mpToken->GetOpCode() == ocPush)
+                            {
+                                if (mpToken->GetType() != svSingleRef)
+                                    aColRange = ScRange( ScAddress::INITIALIZE_INVALID);
+                                else
+                                {
+                                    bGotToken = false;  // obtain at least a close hereafter
+                                    aColRange.aEnd = mpToken->GetSingleRef()->toAbs( aPos);
+                                    aColRange.Justify();
+                                }
+                            }
                         }
                         break;
                     case svDoubleRef:
@@ -4959,7 +4973,7 @@ bool ScCompiler::HandleTableRef()
             {
                 SetError( errNoRef);
             }
-            if (bColumnRange)
+            if (bColumnRange && !bGotToken)
             {
                 if ((bGotToken = GetToken()) && mpToken->GetOpCode() == ocTableRefClose)
                 {
commit a83c3227919ea6467cd4eee5464d73b24120a440
Author: Eike Rathke <erack at redhat.com>
Date:   Wed Apr 8 19:07:50 2015 +0200

    TableRef: both column range rows must be table range top row
    
    Change-Id: I82fcb95c972defde4a854d4c4cce80e6e561bc92

diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx
index f3c1155..791a9a3 100644
--- a/sc/source/core/tool/compiler.cxx
+++ b/sc/source/core/tool/compiler.cxx
@@ -4940,7 +4940,7 @@ bool ScCompiler::HandleTableRef()
                     default:
                         ;   // nothing
                 }
-                if (aColRange.aStart.Row() != aRange.aStart.Row() && aColRange.aEnd.Row() != aRange.aStart.Row())
+                if (aColRange.aStart.Row() != aRange.aStart.Row() || aColRange.aEnd.Row() != aRange.aStart.Row())
                     aRange = ScRange( ScAddress::INITIALIZE_INVALID);
                 else
                 {
commit 706727932e73a6899bfd820bf56aa691c956bd84
Author: Eike Rathke <erack at redhat.com>
Date:   Wed Apr 8 19:04:22 2015 +0200

    TableRef: push ref only valid after open
    
    Change-Id: I3ea00ddec1a740cbcff9eb22727b1f8ce32bb373

diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx
index b838e32..f3c1155 100644
--- a/sc/source/core/tool/compiler.cxx
+++ b/sc/source/core/tool/compiler.cxx
@@ -4905,7 +4905,8 @@ bool ScCompiler::HandleTableRef()
                             eState = ((eState == sClose) ? sSep : sStop);
                             break;
                         case ocPush:
-                            if (mpToken->GetType() == svSingleRef || mpToken->GetType() == svDoubleRef)
+                            if (eState == sOpen &&
+                                    (mpToken->GetType() == svSingleRef || mpToken->GetType() == svDoubleRef))
                                 bColumnRange = true;
                             eState = sStop;
                             break;
commit 5590bfe72bc086dcdb56eb0a998a1a52e6224097
Author: Eike Rathke <erack at redhat.com>
Date:   Wed Apr 8 19:00:09 2015 +0200

    TableRef: limit to specified columns
    
    Change-Id: I389a0640d6ffefa1b98a9feff86c73775a7771dc

diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx
index ea752c3..b838e32 100644
--- a/sc/source/core/tool/compiler.cxx
+++ b/sc/source/core/tool/compiler.cxx
@@ -4921,12 +4921,56 @@ bool ScCompiler::HandleTableRef()
         {
             if (bColumnRange)
             {
-                /* TODO: limit range to specified columns */
+                // Limit range to specified columns.
+                ScRange aColRange( ScAddress::INITIALIZE_INVALID );
+                switch (mpToken->GetType())
+                {
+                    case svSingleRef:
+                        {
+                            ScAddress aRef( mpToken->GetSingleRef()->toAbs( aPos));
+                            aColRange.aStart = aColRange.aEnd = aRef;
+                        }
+                        break;
+                    case svDoubleRef:
+                        {
+                            aColRange = mpToken->GetDoubleRef()->toAbs( aPos);
+                        }
+                        break;
+                    default:
+                        ;   // nothing
+                }
+                if (aColRange.aStart.Row() != aRange.aStart.Row() && aColRange.aEnd.Row() != aRange.aStart.Row())
+                    aRange = ScRange( ScAddress::INITIALIZE_INVALID);
+                else
+                {
+                    aColRange.aEnd.SetRow( aRange.aEnd.Row());
+                    aRange = aRange.Intersection( aColRange);
+                }
+            }
+            if (aRange.IsValid())
+            {
+                ScComplexRefData aRefData;
+                aRefData.InitFlags();
+                aRefData.SetRange( aRange, aPos);
+                pNew->AddDoubleReference( aRefData );
+            }
+            else
+            {
+                SetError( errNoRef);
+            }
+            if (bColumnRange)
+            {
+                if ((bGotToken = GetToken()) && mpToken->GetOpCode() == ocTableRefClose)
+                {
+                    if ((bGotToken = GetToken()) && mpToken->GetOpCode() == ocTableRefClose)
+                        bGotToken = false;  // get next token below in return
+                }
+                else
+                {
+                    SetError( errPair);
+                    bGotToken = false;  // get next token below in return
+                }
             }
-            ScComplexRefData aRefData;
-            aRefData.InitFlags();
-            aRefData.SetRange( aRange, aPos);
-            pNew->AddDoubleReference( aRefData );
         }
         else
         {
commit 315e1cace3c1384fc37b1a36f48150f7d8afd43c
Author: Eike Rathke <erack at redhat.com>
Date:   Wed Apr 8 18:06:44 2015 +0200

    TableRef: keywords come with extra brackets each
    
    Change-Id: Ie12264c02d178be9bc5752e7ea20b4feff409e68

diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx
index 400be9a..ea752c3 100644
--- a/sc/source/core/tool/compiler.cxx
+++ b/sc/source/core/tool/compiler.cxx
@@ -1986,7 +1986,7 @@ Label_MaskStateMachine:
                 else if( nMask & SC_COMPILER_C_CHAR_ERRCONST )
                 {
                     *pSym++ = c;
-                    if (!maTableRefs.empty() && maTableRefs.back().mnLevel)
+                    if (!maTableRefs.empty() && maTableRefs.back().mnLevel == 2)
                         eState = ssGetTableRefItem;
                     else
                         eState = ssGetErrorConstant;
@@ -3664,7 +3664,7 @@ bool ScCompiler::NextNewToken( bool bInArray )
             if (cSymbol[0] == '#')
             {
                 // Check for TableRef item specifiers first.
-                if (!maTableRefs.empty())
+                if (!maTableRefs.empty() && maTableRefs.back().mnLevel == 2)
                 {
                     if (IsTableRefItem( aUpper ))
                         return true;
@@ -4859,8 +4859,70 @@ bool ScCompiler::HandleTableRef()
                 }
                 break;
         }
+        bool bColumnRange = false;
+        if (bForwardToClose && (bGotToken = GetToken()) && mpToken->GetOpCode() == ocTableRefOpen)
+        {
+            int nLevel = 1;
+            enum
+            {
+                sOpen,
+                sItem,
+                sClose,
+                sSep,
+                sStop
+            } eState = sOpen;
+            do
+            {
+                if ((bGotToken = GetToken()))
+                {
+                    switch (mpToken->GetOpCode())
+                    {
+                        case ocTableRefOpen:
+                            eState = ((eState == sOpen || eState == sSep) ? sOpen : sStop);
+                            if (++nLevel > 2)
+                            {
+                                SetError( errPair);
+                                eState = sStop;
+                            }
+                            break;
+                        case ocTableRefItemAll:
+                        case ocTableRefItemHeaders:
+                        case ocTableRefItemData:
+                        case ocTableRefItemTotals:
+                        case ocTableRefItemThisRow:
+                            eState = ((eState == sOpen) ? sItem : sStop);
+                            break;
+                        case ocTableRefClose:
+                            eState = ((eState == sItem || eState == sClose) ? sClose : sStop);
+                            if (--nLevel <= 0)
+                            {
+                                if (nLevel < 0)
+                                    SetError( errPair);
+                                eState = sStop;
+                            }
+                            break;
+                        case ocSep:
+                            eState = ((eState == sClose) ? sSep : sStop);
+                            break;
+                        case ocPush:
+                            if (mpToken->GetType() == svSingleRef || mpToken->GetType() == svDoubleRef)
+                                bColumnRange = true;
+                            eState = sStop;
+                            break;
+                        default:
+                            eState = sStop;
+                    }
+                }
+            } while (bGotToken && eState != sStop);
+            if (bGotToken && mpToken->GetOpCode() == ocTableRefClose)
+                bGotToken = false;  // get next token below in return
+        }
         if (bAddRange)
         {
+            if (bColumnRange)
+            {
+                /* TODO: limit range to specified columns */
+            }
             ScComplexRefData aRefData;
             aRefData.InitFlags();
             aRefData.SetRange( aRange, aPos);
@@ -4870,12 +4932,6 @@ bool ScCompiler::HandleTableRef()
         {
             SetError( errNoRef);
         }
-        if (bForwardToClose)
-        {
-            while ((bGotToken = GetToken()) && mpToken->GetOpCode() != ocTableRefClose)
-                ;
-            bGotToken = false;  // get next token below
-        }
         PushTokenArray( pNew, true );
         pNew->Reset();
         return bGotToken ? true : GetToken();
commit 2a176c2f658f30cf8b33d9338e931ebf01fd0f3d
Author: Eike Rathke <erack at redhat.com>
Date:   Wed Apr 8 16:03:29 2015 +0200

    TableRef: simplify logic a little
    
    The #All keyword can be prefixing a column range anyway, so needs to be
    treated like all other keywords.
    
    Change-Id: Ic64a5caeff1c6b2d116b21c0c855c7207d649a8d

diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx
index 7295dcc..400be9a 100644
--- a/sc/source/core/tool/compiler.cxx
+++ b/sc/source/core/tool/compiler.cxx
@@ -4787,17 +4787,23 @@ bool ScCompiler::HandleTableRef()
         switch (eItem)
         {
             case ScTableRefToken::TABLE:
-            case ScTableRefToken::ALL:
                 {
-                    // Optional [] (or [#All]) may follow.
+                    // Optional [] may follow.
                     if ((bGotToken = GetToken()) && mpToken->GetOpCode() == ocTableRefOpen)
                     {
-                        bool bAll = ((bGotToken = GetToken()) && mpToken->GetOpCode() == ocTableRefItemAll);
-                        if (bGotToken && (!bAll || (bGotToken = GetToken())) && mpToken->GetOpCode() == ocTableRefClose)
-                            bGotToken = false;  // get next token below
+                        if ((bGotToken = GetToken()))
+                        {
+                            if (mpToken->GetOpCode() == ocTableRefClose)
+                                bGotToken = false;  // get next token below
+                        }
                     }
                 }
                 break;
+            case ScTableRefToken::ALL:
+                {
+                    bForwardToClose = true;
+                }
+                break;
             case ScTableRefToken::HEADERS:
                 {
                     if (pDBData->HasHeader())
commit a01356af7f53b1cfa648ac3085f9a78cb6de4e0e
Author: Eike Rathke <erack at redhat.com>
Date:   Wed Apr 8 13:07:02 2015 +0200

    TableRef: set errNoRef is there is no resulting range
    
    Change-Id: I19ec176abf3291b2d4ad5baff06f66518680b378

diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx
index a561b05..7295dcc 100644
--- a/sc/source/core/tool/compiler.cxx
+++ b/sc/source/core/tool/compiler.cxx
@@ -4818,11 +4818,7 @@ bool ScCompiler::HandleTableRef()
                     if (pDBData->HasTotals())
                         aRange.aEnd.IncRow(-1);
                     if (aRange.aEnd.Row() < aRange.aStart.Row())
-                    {
-                        /* TODO: add RefData with deleted rows to generate
-                         * #REF! error? */
                         bAddRange = false;
-                    }
                     bForwardToClose = true;
                 }
                 break;
@@ -4840,11 +4836,7 @@ bool ScCompiler::HandleTableRef()
                     if (pDBData->HasHeader())
                         aRange.aStart.IncRow();
                     if (aRange.aEnd.Row() < aRange.aStart.Row())
-                    {
-                        /* TODO: add RefData with deleted rows to generate
-                         * #REF! error? */
                         bAddRange = false;
-                    }
                     bForwardToClose = true;
                 }
                 break;
@@ -4856,11 +4848,7 @@ bool ScCompiler::HandleTableRef()
                         aRange.aEnd.SetRow( aPos.Row());
                     }
                     else
-                    {
-                        /* TODO: add RefData with deleted rows to generate
-                         * #REF! error? */
                         bAddRange = false;
-                    }
                     bForwardToClose = true;
                 }
                 break;
@@ -4872,6 +4860,10 @@ bool ScCompiler::HandleTableRef()
             aRefData.SetRange( aRange, aPos);
             pNew->AddDoubleReference( aRefData );
         }
+        else
+        {
+            SetError( errNoRef);
+        }
         if (bForwardToClose)
         {
             while ((bGotToken = GetToken()) && mpToken->GetOpCode() != ocTableRefClose)
commit 54d35353ed76f3c84c9d9eaac4d762da484c5c25
Author: Eike Rathke <erack at redhat.com>
Date:   Wed Apr 8 11:39:13 2015 +0200

    TableRef: handle #ThisRow
    
    Change-Id: I5009df42fcb640ae6e2808900d7d42bd6dcc8677

diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx
index f3b68f5..a561b05 100644
--- a/sc/source/core/tool/compiler.cxx
+++ b/sc/source/core/tool/compiler.cxx
@@ -4849,9 +4849,20 @@ bool ScCompiler::HandleTableRef()
                 }
                 break;
             case ScTableRefToken::THIS_ROW:
-                /* TODO: implement this. */
-                SetError(errUnknownToken);
-                bAddRange = false;
+                {
+                    if (aRange.aStart.Row() <= aPos.Row() && aPos.Row() <= aRange.aEnd.Row())
+                    {
+                        aRange.aStart.SetRow( aPos.Row());
+                        aRange.aEnd.SetRow( aPos.Row());
+                    }
+                    else
+                    {
+                        /* TODO: add RefData with deleted rows to generate
+                         * #REF! error? */
+                        bAddRange = false;
+                    }
+                    bForwardToClose = true;
+                }
                 break;
         }
         if (bAddRange)


More information about the Libreoffice-commits mailing list