[Libreoffice-commits] .: Branch 'libreoffice-3-4' - 2 commits - sc/inc sc/source

Kohei Yoshida kohei at kemper.freedesktop.org
Wed Feb 8 07:48:11 PST 2012


 sc/inc/compiler.hxx               |   12 ++-
 sc/inc/rangenam.hxx               |   25 +++++--
 sc/source/core/data/conditio.cxx  |   12 +--
 sc/source/core/data/document.cxx  |    3 
 sc/source/core/data/table2.cxx    |    3 
 sc/source/core/tool/compiler.cxx  |   15 +---
 sc/source/core/tool/rangenam.cxx  |  131 +++++++++++++++++++++++++-------------
 sc/source/ui/docshell/docfunc.cxx |    4 -
 sc/source/ui/view/viewfunc.cxx    |    2 
 9 files changed, 137 insertions(+), 70 deletions(-)

New commits:
commit e8a321db4419be43c693d5b5d06bfda25709d2f5
Author: Eike Rathke <erack at erack.de>
Date:   Wed Feb 8 10:42:04 2012 -0500

    fix fdo#40590 stop abusing regular string token for XML import
    
    During XML import formulas of defined names and conditional formatting
    were remembered as regular svString tokens that then later were
    retrieved without quotes for compilation. This didn't go along with the
    new ScRangeData::CompileUnresolvedXML() that recreates the formula
    string from an already tokenized form of the formula.
    
    Introduced FormulaToken::AddStringXML() with ocStringXML to sort those
    out and removed the IsImportingXML() hack from
    FormulaCompiler::AppendString(), the ocStringXML case is handled in
    FormulaCompiler::CreateStringFromToken().
    
    Signed-off-by: Kohei Yoshida <kohei.yoshida at suse.com>

diff --git a/sc/inc/compiler.hxx b/sc/inc/compiler.hxx
index 6947460..d317150 100644
--- a/sc/inc/compiler.hxx
+++ b/sc/inc/compiler.hxx
@@ -542,7 +542,6 @@ private:
     virtual void CreateStringFromMatrix( rtl::OUStringBuffer& rBuffer, formula::FormulaToken* _pTokenP);
     virtual void CreateStringFromIndex(rtl::OUStringBuffer& rBuffer,formula::FormulaToken* _pTokenP);
     virtual void LocalizeString( String& rName );	// modify rName - input: exact name
-    virtual sal_Bool IsImportingXML() const;
 
     /// Access the CharTable flags
     inline sal_uLong GetCharTableFlags( sal_Unicode c, sal_Unicode cLast )
diff --git a/sc/source/core/data/conditio.cxx b/sc/source/core/data/conditio.cxx
index 642c39b..f3571c5 100644
--- a/sc/source/core/data/conditio.cxx
+++ b/sc/source/core/data/conditio.cxx
@@ -316,10 +316,10 @@ void ScConditionEntry::Compile( const String& rExpr1, const String& rExpr2,
             aComp.SetGrammar( eGrammar1 );
             if ( pDoc->IsImportingXML() && !bTextToReal )
             {
-                //	temporary formula string as string tokens
-                //!	merge with lcl_ScDocFunc_CreateTokenArrayXML
+                //  temporary formula string as string tokens
+                //! merge with lcl_ScDocFunc_CreateTokenArrayXML
                 pFormula1 = new ScTokenArray;
-                pFormula1->AddString( rExpr1 );
+                pFormula1->AddStringXML( rExpr1 );
                 // bRelRef1 is set when the formula is compiled again (CompileXML)
             }
             else
@@ -353,10 +353,10 @@ void ScConditionEntry::Compile( const String& rExpr1, const String& rExpr2,
             aComp.SetGrammar( eGrammar2 );
             if ( pDoc->IsImportingXML() && !bTextToReal )
             {
-                //	temporary formula string as string tokens
-                //!	merge with lcl_ScDocFunc_CreateTokenArrayXML
+                //  temporary formula string as string tokens
+                //! merge with lcl_ScDocFunc_CreateTokenArrayXML
                 pFormula2 = new ScTokenArray;
-                pFormula2->AddString( rExpr2 );
+                pFormula2->AddStringXML( rExpr2 );
                 // bRelRef2 is set when the formula is compiled again (CompileXML)
             }
             else
diff --git a/sc/source/core/tool/compiler.cxx b/sc/source/core/tool/compiler.cxx
index a4938f1..542b1d0 100644
--- a/sc/source/core/tool/compiler.cxx
+++ b/sc/source/core/tool/compiler.cxx
@@ -5123,10 +5123,6 @@ void ScCompiler::LocalizeString( String& rName )
     ScGlobal::GetAddInCollection()->LocalizeString( rName );
 }
 // -----------------------------------------------------------------------------
-sal_Bool ScCompiler::IsImportingXML() const
-{
-    return pDoc->IsImportingXML();
-}
 
 // Put quotes around string if non-alphanumeric characters are contained,
 // quote characters contained within are escaped by '\\'.
diff --git a/sc/source/ui/docshell/docfunc.cxx b/sc/source/ui/docshell/docfunc.cxx
index c4df591..9349da8 100644
--- a/sc/source/ui/docshell/docfunc.cxx
+++ b/sc/source/ui/docshell/docfunc.cxx
@@ -1008,9 +1008,9 @@ sal_Bool ScDocFunc::PutData( const ScAddress& rPos, ScEditEngineDefaulter& rEngi
 ScTokenArray* lcl_ScDocFunc_CreateTokenArrayXML( const String& rText, const String& rFormulaNmsp, const formula::FormulaGrammar::Grammar eGrammar )
 {
     ScTokenArray* pCode = new ScTokenArray;
-    pCode->AddString( rText );
+    pCode->AddStringXML( rText );
     if( (eGrammar == formula::FormulaGrammar::GRAM_EXTERNAL) && (rFormulaNmsp.Len() > 0) )
-        pCode->AddString( rFormulaNmsp );
+        pCode->AddStringXML( rFormulaNmsp );
     return pCode;
 }
 
commit f270d113e354aa608a2efa641691167a504c6539
Author: Eike Rathke <erack at erack.de>
Date:   Wed Feb 8 10:28:46 2012 -0500

    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.
    
    Signed-off-by: Kohei Yoshida <kohei.yoshida at suse.com>

diff --git a/sc/inc/compiler.hxx b/sc/inc/compiler.hxx
index 5fcc6dc..6947460 100644
--- a/sc/inc/compiler.hxx
+++ b/sc/inc/compiler.hxx
@@ -227,6 +227,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;
@@ -327,8 +334,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
 
     sal_Bool   NextNewToken(bool bInArray = false);
@@ -413,7 +420,7 @@ public:
 
     void            CreateStringFromXMLTokenArray( String& rFormula, String& rFormulaNmsp );
 
-    void            SetExtendedErrorDetection( bool bVal ) { mbExtendedErrorDetection = bVal; }
+    void            SetExtendedErrorDetection( ExtendedErrorDetection eVal ) { meExtendedErrorDetection = eVal; }
 
     sal_Bool            IsCorrected() { return bCorrected; }
     const String&   GetCorrectedFormula() { return aCorrectedFormula; }
diff --git a/sc/inc/rangenam.hxx b/sc/inc/rangenam.hxx
index 7417094..56c0544 100644
--- a/sc/inc/rangenam.hxx
+++ b/sc/inc/rangenam.hxx
@@ -75,18 +75,22 @@ private:
     String			aName;
     String          aUpperName;         // #i62977# for faster searching (aName is never modified after ctor)
     ScTokenArray*	pCode;
-    ScAddress   	aPos;
-    RangeType		eType;
-    ScDocument* 	pDoc;
-    sal_uInt16			nIndex;
-    sal_Bool			bModified;			// is set/cleared by UpdateReference
-
-    // max row and column to use for wrapping of references.  If -1 use the 
+    ScAddress       aPos;
+    RangeType       eType;
+    ScDocument*     pDoc;
+    formula::FormulaGrammar::Grammar    eTempGrammar;   // needed for unresolved XML compiles
+    sal_uInt16      nIndex;
+    sal_Bool            bModified;          // is set/cleared by UpdateReference
+
+    // max row and column to use for wrapping of references.  If -1 use the
     // application's default.
     SCROW           mnMaxRow;
     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 sal_Bool ScRangeData::HasType( RangeType nType ) const
@@ -211,6 +217,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 e85ba1f..6f3fec0 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -3154,6 +3154,9 @@ void ScDocument::CompileXML()
     DBG_ASSERT( !pAutoNameCache, "AutoNameCache already set" );
     pAutoNameCache = new ScAutoNameCache( this );
 
+    if (pRangeName)
+        pRangeName->CompileUnresolvedXML();
+
     for (SCTAB i=0; i<=MAXTAB; i++)
         if (pTab[i]) pTab[i]->CompileXML( aProgress );
 
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index 7d7d554..b9c58ce 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -1297,6 +1297,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 9f39358..a4938f1 100644
--- a/sc/source/core/tool/compiler.cxx
+++ b/sc/source/core/tool/compiler.cxx
@@ -1741,8 +1741,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;
@@ -1757,8 +1757,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;
@@ -3623,11 +3623,12 @@ sal_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 b648d1a..2b9ca3b 100644
--- a/sc/source/core/tool/rangenam.cxx
+++ b/sc/source/core/tool/rangenam.cxx
@@ -72,36 +72,19 @@ ScRangeData::ScRangeData( ScDocument* pDok,
                 aName		( rName ),
                 aUpperName  ( ScGlobal::pCharClass->upper( rName ) ),
                 pCode		( NULL ),
-                aPos		( rAddress ),
-                eType		( nType ),
-                pDoc		( pDok ),
-                nIndex		( 0 ),
-                bModified	( false ),
+                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.
@@ -120,11 +103,12 @@ ScRangeData::ScRangeData( ScDocument* pDok,
                 aName		( rName ),
                 aUpperName  ( ScGlobal::pCharClass->upper( rName ) ),
                 pCode		( new ScTokenArray( rArr ) ),
-                aPos		( rAddress ),
-                eType		( nType ),
-                pDoc		( pDok ),
-                nIndex		( 0 ),
-                bModified	( false ),
+                aPos        ( rAddress ),
+                eType       ( nType ),
+                pDoc        ( pDok ),
+                eTempGrammar( FormulaGrammar::GRAM_UNSPECIFIED ),
+                nIndex      ( 0 ),
+                bModified   ( false ),
                 mnMaxRow    (-1),
                 mnMaxCol    (-1)
 {
@@ -148,11 +132,12 @@ ScRangeData::ScRangeData( ScDocument* pDok,
                 aName		( rName ),
                 aUpperName  ( ScGlobal::pCharClass->upper( rName ) ),
                 pCode		( new ScTokenArray() ),
-                aPos		( rTarget ),
-                eType		( RT_NAME ),
-                pDoc		( pDok ),
-                nIndex		( 0 ),
-                bModified	( false ),
+                aPos        ( rTarget ),
+                eType       ( RT_NAME ),
+                pDoc        ( pDok ),
+                eTempGrammar( FormulaGrammar::GRAM_UNSPECIFIED ),
+                nIndex      ( 0 ),
+                bModified   ( false ),
                 mnMaxRow    (-1),
                 mnMaxCol    (-1)
 {
@@ -171,11 +156,12 @@ ScRangeData::ScRangeData(const ScRangeData& rScRangeData) :
     aName 	(rScRangeData.aName),
     aUpperName  (rScRangeData.aUpperName),
     pCode		(rScRangeData.pCode ? rScRangeData.pCode->Clone() : new ScTokenArray()),		// echte Kopie erzeugen (nicht copy-ctor)
-    aPos		(rScRangeData.aPos),
-    eType		(rScRangeData.eType),
-    pDoc		(rScRangeData.pDoc),
-    nIndex   	(rScRangeData.nIndex),
-    bModified	(rScRangeData.bModified),
+    aPos        (rScRangeData.aPos),
+    eType       (rScRangeData.eType),
+    pDoc        (rScRangeData.pDoc),
+    eTempGrammar(rScRangeData.eTempGrammar),
+    nIndex      (rScRangeData.nIndex),
+    bModified   (rScRangeData.bModified),
     mnMaxRow    (rScRangeData.mnMaxRow),
     mnMaxCol    (rScRangeData.mnMaxCol)
 {}
@@ -185,9 +171,63 @@ 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
+    //  setzt eine Position, mit der alle relative Referenzen bei CalcAbsIfRel
     //	ohne Fehler verabsolutiert werden koennen
 
     DBG_ASSERT(aPos == ScAddress(), "die Position geht jetzt verloren");
@@ -802,6 +842,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 f0f05b1..2cb3fe0 100644
--- a/sc/source/ui/view/viewfunc.cxx
+++ b/sc/source/ui/view/viewfunc.cxx
@@ -482,7 +482,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;


More information about the Libreoffice-commits mailing list