summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOliver Bolte <obo@openoffice.org>2007-06-13 08:09:54 +0000
committerOliver Bolte <obo@openoffice.org>2007-06-13 08:09:54 +0000
commitd9de07181992558645261bfcd00976d344d98ea3 (patch)
tree44271b123be4ca3acb154fc30ff91f76cf0563d3
parentf83844de2b536d81bad72e2562449ee00bf07b81 (diff)
INTEGRATION: CWS jgarrays (1.15.52); FILE MERGED
2007/05/14 16:49:36 er 1.15.52.3: help MS and Sun compilers to make their way 2007/05/08 21:16:03 jodygoldberg 1.15.52.2: Issue number: 32342 Submitted by: jodygoldberg Reviewed by: er - Inline boolean support in ScMatrix - parsing for booleans in inline arrays - update ScMatrix to string code to factor out AppendString and AppendDouble 2007/04/26 12:26:05 jodygoldberg 1.15.52.1: Issue number: 32342 Submitted by: jodygoldberg Reviewed by: er,dr Some small updates to the patch in issuezilla, resynced to m210. It still needs the small re-factoring er suggested re: ScCompiler::AppendString
-rw-r--r--sc/source/filter/excel/xeformula.cxx186
1 files changed, 165 insertions, 21 deletions
diff --git a/sc/source/filter/excel/xeformula.cxx b/sc/source/filter/excel/xeformula.cxx
index 3d73d4b45..4c1a29175 100644
--- a/sc/source/filter/excel/xeformula.cxx
+++ b/sc/source/filter/excel/xeformula.cxx
@@ -4,9 +4,9 @@
*
* $RCSfile: xeformula.cxx,v $
*
- * $Revision: 1.15 $
+ * $Revision: 1.16 $
*
- * last change: $Author: vg $ $Date: 2007-02-27 12:24:32 $
+ * last change: $Author: obo $ $Date: 2007-06-13 09:09:54 $
*
* The Contents of this file are made available subject to
* the terms of GNU Lesser General Public License Version 2.1.
@@ -106,6 +106,7 @@ struct XclExpCompConfig
bool mbFromCell; /// True = Any kind of cell formula (cell, array, shared).
bool mb3DRefOnly; /// True = Only 3D references allowed (e.g. names).
bool mbStopAtSep; /// True = Stop compilation at ocSep in root level.
+ bool mbAllowArrays; /// True = Allow inline arrays
};
// ----------------------------------------------------------------------------
@@ -113,6 +114,8 @@ struct XclExpCompConfig
/** Working data of the formula compiler. Used to push onto a stack for recursive calls. */
struct XclExpCompData
{
+ typedef ::std::list< const ScMatrix * > ScMatrixList;
+ typedef ScfRef< ScMatrixList > ScMatrixListRef;
typedef ScfRef< ScTokenArray > ScTokenArrayRef;
XclExpCompConfig maCfg; /// Configuration for current formula type.
@@ -121,6 +124,8 @@ struct XclExpCompData
XclTokenArrayIterator maTokArrIt; /// Iterator in Calc token array.
XclExpLinkManager* mpLinkMgr; /// Link manager for current context (local/global).
XclExpRefLog* mpRefLog; /// Log for external references.
+ ScMatrixListRef maInlineArr; /// List of inline arrays (in reverse order)
+
const ScAddress* mpScBasePos; /// Current cell position of the formula.
// processing data during compilation
@@ -281,8 +286,9 @@ private:
const ScAddress* pScBasePos, XclExpRefLog* pRefLog );
void LeaveRecursive();
- void FinalizeFormula();
- XclTokenArrayRef CreateTokenArray();
+ void FinalizeFormula( ScfUInt8Vec & rExtensionTokens );
+ void AppendInlineArrays( ScfUInt8Vec & rExtensionTokens );
+ XclTokenArrayRef CreateTokenArray( ScfUInt8Vec* pExtensionTokens = NULL );
// compiler ---------------------------------------------------------------
// XclExpTokenData: pass-by-value and return-by-value is intended
@@ -347,6 +353,7 @@ private:
XclExpRefLogEntry* GetNewRefLogEntry();
void ProcessCellRef( const XclExpTokenData& rTokData, sal_uInt8 nExpClass );
void ProcessRangeRef( const XclExpTokenData& rTokData, sal_uInt8 nExpClass );
+ void ProcessMatrix (const XclExpTokenData& rTokData, sal_uInt8 nExpClass );
void ProcessDefinedName( const XclExpTokenData& rTokData, sal_uInt8 nExpClass );
void ProcessDatabaseArea( const XclExpTokenData& rTokData, sal_uInt8 nExpClass );
@@ -375,6 +382,7 @@ private:
void AppendAddress( const XclAddress& rXclPos );
void AppendRange( const XclRange& rXclRange );
+ void AppendMatrixPlaceHolder( const ScMatrix* rMatrix );
void AppendSpaceToken( sal_uInt8 nType, sal_uInt8 nCount );
void AppendIntToken( sal_uInt16 nValue, sal_uInt8 nSpaces = 0 );
@@ -423,17 +431,17 @@ namespace {
/** The table containing configuration data for all formula types. */
static const XclExpCompConfig spConfigTable[] =
{
- // formula type token class type link manager type inCell 3dOnly StopAtSep
- { EXC_FMLATYPE_CELL, EXC_CLASSTYPE_CELL, EXC_LINKMGRTYPE_LOCAL, true, false, true },
- { EXC_FMLATYPE_SHARED, EXC_CLASSTYPE_CELL, EXC_LINKMGRTYPE_LOCAL, true, false, true },
- { EXC_FMLATYPE_MATRIX, EXC_CLASSTYPE_ARRAY, EXC_LINKMGRTYPE_LOCAL, true, false, true },
- { EXC_FMLATYPE_CONDFMT, EXC_CLASSTYPE_ARRAY, EXC_LINKMGRTYPE_NONE, false, false, true },
- { EXC_FMLATYPE_DATAVAL, EXC_CLASSTYPE_ARRAY, EXC_LINKMGRTYPE_NONE, false, false, true },
- { EXC_FMLATYPE_NAME, EXC_CLASSTYPE_NAME, EXC_LINKMGRTYPE_GLOBAL, false, true, false },
- { EXC_FMLATYPE_CHART, EXC_CLASSTYPE_NAME, EXC_LINKMGRTYPE_LOCAL, false, true, false },
- { EXC_FMLATYPE_CONTROL, EXC_CLASSTYPE_NAME, EXC_LINKMGRTYPE_LOCAL, false, false, true },
- { EXC_FMLATYPE_WQUERY, EXC_CLASSTYPE_NAME, EXC_LINKMGRTYPE_LOCAL, false, true, false },
- { EXC_FMLATYPE_LISTVAL, EXC_CLASSTYPE_NAME, EXC_LINKMGRTYPE_NONE, false, false, true }
+ // formula type token class type link manager type inCell 3dOnly StopAtSep allowArray
+ { EXC_FMLATYPE_CELL, EXC_CLASSTYPE_CELL, EXC_LINKMGRTYPE_LOCAL, true, false, true, true },
+ { EXC_FMLATYPE_SHARED, EXC_CLASSTYPE_CELL, EXC_LINKMGRTYPE_LOCAL, true, false, true, true },
+ { EXC_FMLATYPE_MATRIX, EXC_CLASSTYPE_ARRAY, EXC_LINKMGRTYPE_LOCAL, true, false, true, true },
+ { EXC_FMLATYPE_CONDFMT, EXC_CLASSTYPE_ARRAY, EXC_LINKMGRTYPE_NONE, false, false, true, false },
+ { EXC_FMLATYPE_DATAVAL, EXC_CLASSTYPE_ARRAY, EXC_LINKMGRTYPE_NONE, false, false, true, false },
+ { EXC_FMLATYPE_NAME, EXC_CLASSTYPE_NAME, EXC_LINKMGRTYPE_GLOBAL, false, true, false, true },
+ { EXC_FMLATYPE_CHART, EXC_CLASSTYPE_NAME, EXC_LINKMGRTYPE_LOCAL, false, true, false, true },
+ { EXC_FMLATYPE_CONTROL, EXC_CLASSTYPE_NAME, EXC_LINKMGRTYPE_LOCAL, false, false, true, false },
+ { EXC_FMLATYPE_WQUERY, EXC_CLASSTYPE_NAME, EXC_LINKMGRTYPE_LOCAL, false, true, false, false },
+ { EXC_FMLATYPE_LISTVAL, EXC_CLASSTYPE_NAME, EXC_LINKMGRTYPE_NONE, false, false, true, false }
};
} // namespace
@@ -497,10 +505,11 @@ XclTokenArrayRef XclExpFmlaCompImpl::CreateFormula( XclFormulaType eType,
}
}
- // finalizing, e.g. add tAttr-volatile token
- FinalizeFormula();
+ // finalizing, e.g. add tAttr-volatile token, and storing any inline arrays
+ ScfUInt8Vec aExtensionTokens;
+ FinalizeFormula( aExtensionTokens );
- return CreateTokenArray();
+ return CreateTokenArray( &aExtensionTokens );
}
XclTokenArrayRef XclExpFmlaCompImpl::CreateErrorFormula( sal_uInt8 nErrCode )
@@ -570,6 +579,9 @@ void XclExpFmlaCompImpl::Init( XclFormulaType eType )
maTokArrIt.Init();
mpLinkMgr = 0;
mpRefLog = 0;
+
+ maInlineArr.reset( NULL );
+
mpScBasePos = 0;
// init processing data used during compilation
@@ -635,7 +647,101 @@ void XclExpFmlaCompImpl::LeaveRecursive()
}
}
-void XclExpFmlaCompImpl::FinalizeFormula()
+void XclExpFmlaCompImpl::AppendInlineArrays( ScfUInt8Vec & rExtensionTokens )
+{
+ // The const_cast is needed, otherwise MS and Sun compilers can't promote
+ // the non-const iterators obtained via ScMatrixList* to const iterators.
+ const ScMatrixList* pList = const_cast<const ScMatrixList*>(maInlineArr.get());
+ const ScMatrixList::const_reverse_iterator end = pList->rend();
+ ScMatrixList::const_reverse_iterator i = pList->rbegin();
+ for( ; i != end ; i++ )
+ {
+ const ScMatrix *pMatrix = *i;
+ SCSIZE nC, nMaxC, nR, nMaxR;
+
+ pMatrix->GetDimensions( nMaxC, nMaxR);
+
+ if( meBiff == EXC_BIFF8 )
+ {
+ rExtensionTokens.push_back( nMaxC - 1 );
+ rExtensionTokens.resize( rExtensionTokens.size() + 2 );
+ ShortToSVBT16( nMaxR - 1, &*(rExtensionTokens.end() - 2) );
+ }
+ else
+ {
+ rExtensionTokens.push_back( nMaxC == 256 ? 0 : nMaxC );
+ rExtensionTokens.resize( rExtensionTokens.size() + 2 );
+ ShortToSVBT16( nMaxR, &*(rExtensionTokens.end() - 2) );
+ }
+
+ for( nR = 0 ; nR < nMaxR ; nR++)
+ {
+ for( nC = 0 ; nC < nMaxC ; nC++)
+ {
+ if( pMatrix->IsValue( nC, nR ) )
+ {
+ ScMatValType nType;
+ const ScMatrixValue* pVal = pMatrix->Get( nC, nR, nType);
+
+ if( nType == SC_MATVAL_BOOLEAN )
+ {
+ rExtensionTokens.push_back( EXC_CACHEDVAL_BOOL );
+
+ rExtensionTokens.resize( rExtensionTokens.size() + 8 );
+ const bool bVal = ! ::rtl::math::approxEqual( pVal->fVal, 0. );
+ UInt32ToSVBT32( bVal ? 1 : 0, &*(rExtensionTokens.end() - 8) );
+ UInt32ToSVBT32( 0, &*(rExtensionTokens.end() - 4) );
+ }
+ else
+ {
+ USHORT nErr = pVal->GetError();
+ if( nErr )
+ {
+ rExtensionTokens.push_back( EXC_CACHEDVAL_ERROR );
+
+ rExtensionTokens.resize( rExtensionTokens.size() + 8 );
+ UInt32ToSVBT32( XclTools::GetXclErrorCode ( nErr ),
+ &*(rExtensionTokens.end() - 8) );
+ UInt32ToSVBT32( 0, &*(rExtensionTokens.end() - 4) );
+ }
+ else
+ {
+ rExtensionTokens.push_back( EXC_CACHEDVAL_DOUBLE );
+
+ const double nVal = pMatrix->GetDouble( nC, nR );
+ rExtensionTokens.resize( rExtensionTokens.size() + 8 );
+ DoubleToSVBT64( nVal, &*(rExtensionTokens.end() - 8) );
+ }
+ }
+ }
+ else if( pMatrix->IsEmpty( nC, nR ) )
+ {
+ rExtensionTokens.push_back( EXC_CACHEDVAL_EMPTY );
+
+ rExtensionTokens.resize( rExtensionTokens.size() + 8 );
+ UInt32ToSVBT32( 0, &*(rExtensionTokens.end() - 8) );
+ UInt32ToSVBT32( 0, &*(rExtensionTokens.end() - 4) );
+ }
+ else if( pMatrix->IsString( nC, nR ) )
+ {
+ rExtensionTokens.push_back( EXC_CACHEDVAL_STRING );
+
+ const String & rString = pMatrix->GetString( nC, nR );
+ XclExpStringRef xXclStr = XclExpStringHelper::CreateString(
+ GetRoot(), rString,
+ ((meBiff == EXC_BIFF8) ? EXC_STR_DEFAULT : EXC_STR_8BITLENGTH),
+ EXC_TOK_STR_MAXLEN );
+ size_t nSize = rExtensionTokens.size();
+ rExtensionTokens.resize( nSize + xXclStr->GetSize() );
+ xXclStr->WriteToMem( &rExtensionTokens[ nSize ] );
+ }
+
+ }
+ }
+ }
+}
+
+void XclExpFmlaCompImpl::FinalizeFormula( ScfUInt8Vec & rExtensionTokens )
{
if( mbOk )
{
@@ -653,6 +759,12 @@ void XclExpFmlaCompImpl::FinalizeFormula()
// Token array too long? -> error
mbOk = maTokVec.size() <= EXC_TOKARR_MAXLEN;
+
+ // Store any inline arrays
+ if( mbOk && maInlineArr.is() )
+ {
+ AppendInlineArrays( rExtensionTokens );
+ }
}
if( !mbOk )
@@ -664,10 +776,10 @@ void XclExpFmlaCompImpl::FinalizeFormula()
}
}
-XclTokenArrayRef XclExpFmlaCompImpl::CreateTokenArray()
+XclTokenArrayRef XclExpFmlaCompImpl::CreateTokenArray( ScfUInt8Vec* pExtensionTokens )
{
// create the Excel token array object before calling LeaveRecursive()
- XclTokenArrayRef xTokArr( new XclTokenArray( maTokVec, mbVolatile ) );
+ XclTokenArrayRef xTokArr( new XclTokenArray( maTokVec, mbVolatile, pExtensionTokens ) );
// compiler invoked recursively? - restore old working data
LeaveRecursive();
@@ -1042,6 +1154,7 @@ XclExpTokenData XclExpFmlaCompImpl::Factor( XclExpTokenData aTokData, sal_uInt8
case svString: ProcessString( aTokData ); break;
case svSingleRef: ProcessCellRef( aTokData, nExpClass ); break;
case svDoubleRef: ProcessRangeRef( aTokData, nExpClass ); break;
+ case svMatrix: ProcessMatrix (aTokData, nExpClass ); break;
case svExternal: ProcessExternal( aTokData, nExpClass ); break;
default:
@@ -1842,6 +1955,9 @@ void XclExpFmlaCompImpl::UpdateArrExpFlag( sal_uInt8 nParamExpClass, sal_uInt8 n
case EXC_CLASSTYPE_NAME:
bNewIsArrExp = ((nParamExpClass != EXC_TOKCLASS_VAL) || (nFuncRetClass != EXC_TOKCLASS_REF));
break;
+
+ default :
+ break;
}
SetArrExpFlag( mbIsArrExp || bNewIsArrExp );
}
@@ -2018,6 +2134,20 @@ void XclExpFmlaCompImpl::AppendSpaceToken( sal_uInt8 nType, sal_uInt8 nCount )
}
}
+void XclExpFmlaCompImpl::AppendMatrixPlaceHolder( const ScMatrix* pMatrix )
+{
+ SCSIZE cols, rows;
+
+ if( !maInlineArr )
+ maInlineArr.reset( new ScMatrixList );
+ maInlineArr->push_front( pMatrix ); // save it for later
+
+ pMatrix->GetDimensions( cols, rows);
+ Append( static_cast< sal_uInt8 >( cols-1 ) );
+ Append( static_cast< sal_uInt16 >( rows-1 ) );
+ Append( static_cast< sal_uInt32 >( 0 ) ); // undocumented
+}
+
void XclExpFmlaCompImpl::AppendIntToken( sal_uInt16 nValue, sal_uInt8 nSpaces )
{
AppendOpTokenId( EXC_TOKID_INT, EXC_TOKCLASS_NONE, nSpaces );
@@ -2259,6 +2389,20 @@ XclTokenArrayRef XclExpFormulaCompiler::CreateNameXFormula(
{
return mxImpl->CreateNameXFormula( nExtSheet, nExtName );
}
+void XclExpFmlaCompImpl::ProcessMatrix ( const XclExpTokenData& rTokData, sal_uInt8 nExpClass )
+{
+ if( maCfg.mbAllowArrays )
+ {
+ AppendOpTokenId( GetTokenId( EXC_TOKID_ARRAY, EXC_TOKCLASS_ARR ),
+ nExpClass, rTokData.mnSpaces );
+ AppendMatrixPlaceHolder( rTokData.mpScToken->GetMatrix() );
+ }
+ else
+ {
+ // Array in places that do not allow it (cond fmts, data validation)
+ AppendErrorToken( EXC_ERR_NA, rTokData.mnSpaces );
+ }
+}
// ============================================================================