[Libreoffice-commits] .: 2 commits - formula/source sc/inc sc/source

Eike Rathke erack at kemper.freedesktop.org
Fri Aug 26 04:35:12 PDT 2011


 formula/source/core/api/FormulaCompiler.cxx |    4 -
 sc/inc/compiler.hxx                         |   11 ++-
 sc/inc/rangenam.hxx                         |   13 +++-
 sc/source/core/data/document.cxx            |    3 
 sc/source/core/data/table2.cxx              |    3 
 sc/source/core/tool/compiler.cxx            |   11 +--
 sc/source/core/tool/rangenam.cxx            |   89 +++++++++++++++++++++-------
 sc/source/ui/view/viewfunc.cxx              |    2 
 8 files changed, 105 insertions(+), 31 deletions(-)

New commits:
commit 6f42e4d03b04204b7a864f3c5c9c03548f5e2392
Author: Eike Rathke <erack at erack.de>
Date:   Fri Aug 26 13:24:18 2011 +0200

    fdo#40378 compile defined names that had unresolveds during load
    
    Dependencies of defined names must not depend on the order in which they
    are inserted during file load. In a second step compile defined names
    that had unresolved names during load, and only those.

diff --git a/sc/inc/compiler.hxx b/sc/inc/compiler.hxx
index 7f418e3..f7dde6a 100644
--- a/sc/inc/compiler.hxx
+++ b/sc/inc/compiler.hxx
@@ -230,6 +230,13 @@ public:
         ENCODE_NEVER,
     };
 
+    enum ExtendedErrorDetection
+    {
+        EXTENDED_ERROR_DETECTION_NONE = 0,      // no error on unknown symbols, default (interpreter handles it)
+        EXTENDED_ERROR_DETECTION_NAME_BREAK,    // name error on unknown symbols and break, pCode incomplete
+        EXTENDED_ERROR_DETECTION_NAME_NO_BREAK  // name error on unknown symbols, don't break, continue
+    };
+
     struct Convention
     {
         const formula::FormulaGrammar::AddressConvention meConv;
@@ -330,8 +337,8 @@ private:
     sal_Int32   mnRangeOpPosInSymbol;       // if and where a range operator is in symbol
     const Convention *pConv;
     EncodeUrlMode   meEncodeUrlMode;
+    ExtendedErrorDetection  meExtendedErrorDetection;
     bool        mbCloseBrackets;            // whether to close open brackets automatically, default TRUE
-    bool        mbExtendedErrorDetection;
     bool        mbRewind;                   // whether symbol is to be rewound to some step during lexical analysis
 
     bool   NextNewToken(bool bInArray = false);
@@ -417,7 +424,7 @@ public:
 
     void            CreateStringFromXMLTokenArray( String& rFormula, String& rFormulaNmsp );
 
-    void            SetExtendedErrorDetection( bool bVal ) { mbExtendedErrorDetection = bVal; }
+    void            SetExtendedErrorDetection( ExtendedErrorDetection eVal ) { meExtendedErrorDetection = eVal; }
 
     bool            IsCorrected() { return bCorrected; }
     const String&   GetCorrectedFormula() { return aCorrectedFormula; }
diff --git a/sc/inc/rangenam.hxx b/sc/inc/rangenam.hxx
index 2774028..7b50362 100644
--- a/sc/inc/rangenam.hxx
+++ b/sc/inc/rangenam.hxx
@@ -77,7 +77,8 @@ private:
     ScAddress       aPos;
     RangeType       eType;
     ScDocument*     pDoc;
-    sal_uInt16          nIndex;
+    formula::FormulaGrammar::Grammar    eTempGrammar;   // needed for unresolved XML compiles
+    sal_uInt16      nIndex;
     bool            bModified;          // is set/cleared by UpdateReference
 
     // max row and column to use for wrapping of references.  If -1 use the
@@ -86,6 +87,9 @@ private:
     SCCOL           mnMaxCol;
 
     ScRangeData( sal_uInt16 nIndex );
+
+    void CompileRangeData( const String& rSymbol, bool bSetError );
+
 public:
     typedef ::std::map<sal_uInt16, sal_uInt16> IndexMap;
 
@@ -161,6 +165,8 @@ public:
     SCROW GetMaxRow() const;
     SC_DLLPUBLIC void SetMaxCol(SCCOL nCol);
     SCCOL GetMaxCol() const;
+
+    void            CompileUnresolvedXML();
 };
 
 inline bool ScRangeData::HasType( RangeType nType ) const
@@ -204,6 +210,11 @@ public:
     void UpdateTranspose(const ScRange& rSource, const ScAddress& rDest);
     void UpdateGrow(const ScRange& rArea, SCCOL nGrowX, SCROW nGrowY);
 
+    /** Compile those names that couldn't be resolved during loading and
+        inserting because they may have referred a name that was inserted later.
+     */
+    void CompileUnresolvedXML();
+
     SC_DLLPUBLIC const_iterator begin() const;
     SC_DLLPUBLIC const_iterator end() const;
     SC_DLLPUBLIC iterator begin();
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index 75cb424..e475d8a 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -3425,6 +3425,9 @@ void ScDocument::CompileXML()
     OSL_ENSURE( !pAutoNameCache, "AutoNameCache already set" );
     pAutoNameCache = new ScAutoNameCache( this );
 
+    if (pRangeName)
+        pRangeName->CompileUnresolvedXML();
+
     TableContainer::iterator it = maTabs.begin();
     for (; it != maTabs.end(); ++it)
         if (*it)
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index 10f0e9f..812b07f 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -1302,6 +1302,9 @@ void ScTable::CompileAll()
 
 void ScTable::CompileXML( ScProgress& rProgress )
 {
+    if (mpRangeName)
+        mpRangeName->CompileUnresolvedXML();
+
     for (SCCOL i=0; i <= MAXCOL; i++)
     {
         aCol[i].CompileXML( rProgress );
diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx
index 8d1ad64..22c6c91 100644
--- a/sc/source/core/tool/compiler.cxx
+++ b/sc/source/core/tool/compiler.cxx
@@ -1735,8 +1735,8 @@ ScCompiler::ScCompiler( ScDocument* pDocument, const ScAddress& rPos,ScTokenArra
         mnRangeOpPosInSymbol(-1),
         pConv( pConvOOO_A1 ),
         meEncodeUrlMode( ENCODE_BY_GRAMMAR ),
+        meExtendedErrorDetection( EXTENDED_ERROR_DETECTION_NONE ),
         mbCloseBrackets( true ),
-        mbExtendedErrorDetection( false ),
         mbRewind( false )
 {
     nMaxTab = pDoc ? pDoc->GetTableCount() - 1 : 0;
@@ -1751,8 +1751,8 @@ ScCompiler::ScCompiler( ScDocument* pDocument, const ScAddress& rPos)
         mnRangeOpPosInSymbol(-1),
         pConv( pConvOOO_A1 ),
         meEncodeUrlMode( ENCODE_BY_GRAMMAR ),
+        meExtendedErrorDetection( EXTENDED_ERROR_DETECTION_NONE ),
         mbCloseBrackets( true ),
-        mbExtendedErrorDetection( false ),
         mbRewind( false )
 {
     nMaxTab = pDoc ? pDoc->GetTableCount() - 1 : 0;
@@ -3703,11 +3703,12 @@ bool ScCompiler::NextNewToken( bool bInArray )
 
     } while (mbRewind);
 
-    if ( mbExtendedErrorDetection )
+    if ( meExtendedErrorDetection != EXTENDED_ERROR_DETECTION_NONE )
     {
-        // set an error and end compilation
+        // set an error
         SetError( errNoName );
-        return false;
+        if (meExtendedErrorDetection == EXTENDED_ERROR_DETECTION_NAME_BREAK)
+            return false;   // end compilation
     }
 
     // Provide single token information and continue. Do not set an error, that
diff --git a/sc/source/core/tool/rangenam.cxx b/sc/source/core/tool/rangenam.cxx
index 2437eb4..23e1b2f 100644
--- a/sc/source/core/tool/rangenam.cxx
+++ b/sc/source/core/tool/rangenam.cxx
@@ -75,33 +75,16 @@ ScRangeData::ScRangeData( ScDocument* pDok,
                 aPos        ( rAddress ),
                 eType       ( nType ),
                 pDoc        ( pDok ),
+                eTempGrammar( eGrammar ),
                 nIndex      ( 0 ),
                 bModified   ( false ),
                 mnMaxRow    (-1),
                 mnMaxCol    (-1)
 {
     if (rSymbol.Len() > 0)
-    {
-        ScCompiler aComp( pDoc, aPos );
-        aComp.SetGrammar(eGrammar);
-        pCode = aComp.CompileString( rSymbol );
-        if( !pCode->GetCodeError() )
-        {
-            pCode->Reset();
-            FormulaToken* p = pCode->GetNextReference();
-            if( p )// genau eine Referenz als erstes
-            {
-                if( p->GetType() == svSingleRef )
-                    eType = eType | RT_ABSPOS;
-                else
-                    eType = eType | RT_ABSAREA;
-            }
-            // ggf. den Fehlercode wg. unvollstaendiger Formel setzen!
-            // Dies ist fuer die manuelle Eingabe
-            aComp.CompileTokenArray();
-            pCode->DelRPN();
-        }
-    }
+        CompileRangeData( rSymbol, pDoc->IsImportingXML());
+        // Let the compiler set an error on unknown names for a subsequent
+        // CompileUnresolvedXML().
     else
     {
         // #i63513#/#i65690# don't leave pCode as NULL.
@@ -123,6 +106,7 @@ ScRangeData::ScRangeData( ScDocument* pDok,
                 aPos        ( rAddress ),
                 eType       ( nType ),
                 pDoc        ( pDok ),
+                eTempGrammar( FormulaGrammar::GRAM_UNSPECIFIED ),
                 nIndex      ( 0 ),
                 bModified   ( false ),
                 mnMaxRow    (-1),
@@ -151,6 +135,7 @@ ScRangeData::ScRangeData( ScDocument* pDok,
                 aPos        ( rTarget ),
                 eType       ( RT_NAME ),
                 pDoc        ( pDok ),
+                eTempGrammar( FormulaGrammar::GRAM_UNSPECIFIED ),
                 nIndex      ( 0 ),
                 bModified   ( false ),
                 mnMaxRow    (-1),
@@ -174,6 +159,7 @@ ScRangeData::ScRangeData(const ScRangeData& rScRangeData, ScDocument* pDocument)
     aPos        (rScRangeData.aPos),
     eType       (rScRangeData.eType),
     pDoc        (pDocument ? pDocument : rScRangeData.pDoc),
+    eTempGrammar(rScRangeData.eTempGrammar),
     nIndex      (rScRangeData.nIndex),
     bModified   (rScRangeData.bModified),
     mnMaxRow    (rScRangeData.mnMaxRow),
@@ -185,6 +171,60 @@ ScRangeData::~ScRangeData()
     delete pCode;
 }
 
+void ScRangeData::CompileRangeData( const String& rSymbol, bool bSetError )
+{
+    if (eTempGrammar == FormulaGrammar::GRAM_UNSPECIFIED)
+    {
+        OSL_FAIL( "ScRangeData::CompileRangeData: unspecified grammar");
+        // Anything is almost as bad as this, but we might have the best choice
+        // if not loading documents.
+        eTempGrammar = FormulaGrammar::GRAM_NATIVE;
+    }
+
+    ScCompiler aComp( pDoc, aPos );
+    aComp.SetGrammar( eTempGrammar);
+    if (bSetError)
+        aComp.SetExtendedErrorDetection( ScCompiler::EXTENDED_ERROR_DETECTION_NAME_NO_BREAK);
+    ScTokenArray* pNewCode = aComp.CompileString( rSymbol );
+    ::std::auto_ptr<ScTokenArray> pOldCode( pCode);     // old pCode will be deleted
+    pCode = pNewCode;
+    if( !pCode->GetCodeError() )
+    {
+        pCode->Reset();
+        FormulaToken* p = pCode->GetNextReference();
+        if( p )
+        {
+            // first token is a reference
+            /* FIXME: wouldn't that need a check if it's exactly one reference? */
+            if( p->GetType() == svSingleRef )
+                eType = eType | RT_ABSPOS;
+            else
+                eType = eType | RT_ABSAREA;
+        }
+        // For manual input set an error for an incomplete formula.
+        if (!pDoc->IsImportingXML())
+        {
+            aComp.CompileTokenArray();
+            pCode->DelRPN();
+        }
+    }
+}
+
+void ScRangeData::CompileUnresolvedXML()
+{
+    if (pCode->GetCodeError() == errNoName)
+    {
+        // Reconstruct the symbol/formula and then recompile.
+        String aSymbol;
+        ScCompiler aComp( pDoc, aPos, *pCode);
+        aComp.SetGrammar( eTempGrammar);
+        aComp.CreateStringFromTokenArray( aSymbol);
+        // Don't let the compiler set an error for unknown names on final
+        // compile, errors are handled by the interpreter thereafter.
+        CompileRangeData( aSymbol, false);
+    }
+}
+
 void ScRangeData::GuessPosition()
 {
     //  setzt eine Position, mit der alle relative Referenzen bei CalcAbsIfRel
@@ -815,6 +855,13 @@ void ScRangeName::UpdateGrow(const ScRange& rArea, SCCOL nGrowX, SCROW nGrowY)
         itr->UpdateGrow(rArea, nGrowX, nGrowY);
 }
 
+void ScRangeName::CompileUnresolvedXML()
+{
+    DataType::iterator itr = maData.begin(), itrEnd = maData.end();
+    for (; itr != itrEnd; ++itr)
+        itr->CompileUnresolvedXML();
+}
+
 ScRangeName::const_iterator ScRangeName::begin() const
 {
     return maData.begin();
diff --git a/sc/source/ui/view/viewfunc.cxx b/sc/source/ui/view/viewfunc.cxx
index 2187a73..2186e58 100644
--- a/sc/source/ui/view/viewfunc.cxx
+++ b/sc/source/ui/view/viewfunc.cxx
@@ -480,7 +480,7 @@ void ScViewFunc::EnterData( SCCOL nCol, SCROW nRow, SCTAB nTab, const String& rS
             aComp.SetAutoCorrection( sal_True );
             if ( rString.GetChar(0) == '+' || rString.GetChar(0) == '-' )
             {
-                aComp.SetExtendedErrorDetection( true );
+                aComp.SetExtendedErrorDetection( ScCompiler::EXTENDED_ERROR_DETECTION_NAME_BREAK );
             }
             String aFormula( rString );
             ScTokenArray* pArr;
commit 0e735d61b2601392c2054188166b055bdc061d43
Author: Eike Rathke <erack at erack.de>
Date:   Fri Aug 26 02:40:40 2011 +0200

    ensureCapacity on OUStringBuffer

diff --git a/formula/source/core/api/FormulaCompiler.cxx b/formula/source/core/api/FormulaCompiler.cxx
index 346c8e3..e1122c2 100644
--- a/formula/source/core/api/FormulaCompiler.cxx
+++ b/formula/source/core/api/FormulaCompiler.cxx
@@ -1569,7 +1569,7 @@ void FormulaCompiler::CreateStringFromTokenArray( String& rFormula )
 {
     rtl::OUStringBuffer aBuffer( pArr->GetLen() * 5 );
     CreateStringFromTokenArray( aBuffer );
-    rFormula = aBuffer;
+    rFormula = aBuffer.makeStringAndClear();
 }
 
 void FormulaCompiler::CreateStringFromTokenArray( rtl::OUStringBuffer& rBuffer )
@@ -1578,6 +1578,8 @@ void FormulaCompiler::CreateStringFromTokenArray( rtl::OUStringBuffer& rBuffer )
     if( !pArr->GetLen() )
         return;
 
+    rBuffer.ensureCapacity( pArr->GetLen() * 5 );
+
     FormulaTokenArray* pSaveArr = pArr;
     bool bODFF = FormulaGrammar::isODFF( meGrammar);
     if (bODFF || FormulaGrammar::isPODF( meGrammar) )


More information about the Libreoffice-commits mailing list