sc/source/core/tool/compiler.cxx | 200 +++++++++++++++++++++++++++++++++------ 1 file changed, 171 insertions(+), 29 deletions(-)
New commits: commit e94ad965f877ad6a860273c5fed94416998678cf Author: Eike Rathke <er...@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 <er...@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 <er...@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 <er...@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 <er...@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 <er...@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 <er...@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 <er...@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 <er...@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 <er...@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 <er...@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) _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits