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

Tor Lillqvist tml at collabora.com
Tue Feb 17 05:19:12 PST 2015


 sc/inc/formulagroup.hxx                  |   11 
 sc/inc/scmatrix.hxx                      |    9 
 sc/source/core/opencl/formulagroupcl.cxx |  580 ++++++++++++++++---------------
 sc/source/core/opencl/opbase.cxx         |    8 
 sc/source/core/opencl/opbase.hxx         |    7 
 sc/source/core/tool/formulagroup.cxx     |    6 
 sc/source/core/tool/interpr4.cxx         |   10 
 sc/source/core/tool/scmatrix.cxx         |   23 +
 8 files changed, 360 insertions(+), 294 deletions(-)

New commits:
commit ad3ef2fc00c0b5d665702ed1aa1119ef804c21c9
Author: Tor Lillqvist <tml at collabora.com>
Date:   Sat Feb 7 15:38:55 2015 +0200

    Handle (or not) string arguments better when using OpenCL for math ops
    
    This is a combination of four commits from master.
    
    9429cf24675ae6b3a954db560ca567c9413d0ab6: We need ScCalcConfig also for formula groups
    
    The settings for interpretation of text (string) cells as numbers affect
    whether OpenCL can be used or not to get expected results, when operating on
    vectors that contain also text cells.
    
    6dd1025ccf2bcbd2035ab141054950263c638747: Add ScCalcConfig field to DynamicKernelArgument
    
    It is needed to be able to adapt OpenCL code generation to the text-to-number
    conversion settings.
    
    To get the document-specific ScCalcConfig into the DynamicKernelArgument, we
    have to pass it along in lots of places to constructors of various
    DynamicKernelArgument subclasses. Originally it comes from the maCalcConfig
    field of FormulaGroupInterpreterOpenCL, inherited from
    FormulaGroupInterpreter.
    
    dcee6c01206cedf035db175c481cc5fe378bee3f: If a function/operator that takes
    numeric arguments but not string arguments is passed string arguments anyway,
    handle that with OpenCL only if the (document-specific!) setting for text-to
    number conversion is ZERO (treat strings as zero, which is how our OpenCL code
    for such functions/operators works). Otherwise let the code fall back to the
    traditional interpreter.
    
    867cd1de71c774066e72fd30b4d6cde56c598d36: If a function takes numeric
    arguments but there are only string arguments, but the settings say strings
    are to be treated as zero anyway, we can go the OpenCL path.
    
    Also add a few informative comments.
    
    Change-Id: I2c5769c4ae157561c0a3b267d8e1c92795963732
    Reviewed-on: https://gerrit.libreoffice.org/14405
    Reviewed-by: Markus Mohrhard <markus.mohrhard at googlemail.com>
    Tested-by: Markus Mohrhard <markus.mohrhard at googlemail.com>
    Reviewed-on: https://gerrit.libreoffice.org/14408
    Reviewed-by: Eike Rathke <erack at redhat.com>
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/sc/inc/formulagroup.hxx b/sc/inc/formulagroup.hxx
index 9ac9335..8ce3ef5 100644
--- a/sc/inc/formulagroup.hxx
+++ b/sc/inc/formulagroup.hxx
@@ -13,6 +13,7 @@
 #include <config_features.h>
 
 #include "address.hxx"
+#include "calcconfig.hxx"
 #include "types.hxx"
 #include "stlalgorithm.hxx"
 
@@ -120,11 +121,17 @@ public:
 class SC_DLLPUBLIC FormulaGroupInterpreter
 {
     static FormulaGroupInterpreter *msInstance;
- protected:
+
+protected:
+    ScCalcConfig maCalcConfig;
+
     FormulaGroupInterpreter() {}
     virtual ~FormulaGroupInterpreter() {}
 
- public:
+    /// Merge global and document specific settings.
+    void MergeCalcConfig(const ScDocument& rDoc);
+
+public:
     static FormulaGroupInterpreter *getStatic();
 #if HAVE_FEATURE_OPENCL
     static void fillOpenCLInfo(std::vector<OpenCLPlatformInfo>& rPlatforms);
diff --git a/sc/source/core/opencl/formulagroupcl.cxx b/sc/source/core/opencl/formulagroupcl.cxx
index f4c4d68..afc19d4 100644
--- a/sc/source/core/opencl/formulagroupcl.cxx
+++ b/sc/source/core/opencl/formulagroupcl.cxx
@@ -160,9 +160,9 @@ size_t VectorRef::Marshal( cl_kernel k, int argno, int, cl_program )
 class ConstStringArgument : public DynamicKernelArgument
 {
 public:
-    ConstStringArgument( const std::string& s,
+    ConstStringArgument( const ScCalcConfig& config, const std::string& s,
         FormulaTreeNodeRef ft ) :
-        DynamicKernelArgument(s, ft) { }
+        DynamicKernelArgument(config, s, ft) { }
     /// Generate declaration
     virtual void GenDecl( std::stringstream& ss ) const SAL_OVERRIDE
     {
@@ -219,9 +219,9 @@ public:
 class DynamicKernelConstantArgument : public DynamicKernelArgument
 {
 public:
-    DynamicKernelConstantArgument( const std::string& s,
+    DynamicKernelConstantArgument( const ScCalcConfig& config, const std::string& s,
         FormulaTreeNodeRef ft ) :
-        DynamicKernelArgument(s, ft) { }
+        DynamicKernelArgument(config, s, ft) { }
     /// Generate declaration
     virtual void GenDecl( std::stringstream& ss ) const SAL_OVERRIDE
     {
@@ -268,9 +268,9 @@ public:
 class DynamicKernelPiArgument : public DynamicKernelArgument
 {
 public:
-    DynamicKernelPiArgument( const std::string& s,
+    DynamicKernelPiArgument( const ScCalcConfig& config, const std::string& s,
         FormulaTreeNodeRef ft ) :
-        DynamicKernelArgument(s, ft) { }
+        DynamicKernelArgument(config, s, ft) { }
     /// Generate declaration
     virtual void GenDecl( std::stringstream& ss ) const SAL_OVERRIDE
     {
@@ -307,9 +307,9 @@ public:
 class DynamicKernelRandomArgument : public DynamicKernelArgument
 {
 public:
-    DynamicKernelRandomArgument( const std::string& s,
+    DynamicKernelRandomArgument( const ScCalcConfig& config, const std::string& s,
         FormulaTreeNodeRef ft ) :
-        DynamicKernelArgument(s, ft) { }
+        DynamicKernelArgument(config, s, ft) { }
     /// Generate declaration
     virtual void GenDecl( std::stringstream& ss ) const SAL_OVERRIDE
     {
@@ -672,9 +672,9 @@ threefry2x32 (threefry2x32_ctr_t in, threefry2x32_key_t k)\n\
 class DynamicKernelStringArgument : public VectorRef
 {
 public:
-    DynamicKernelStringArgument( const std::string& s,
+    DynamicKernelStringArgument( const ScCalcConfig& config, const std::string& s,
         FormulaTreeNodeRef ft, int index = 0 ) :
-        VectorRef(s, ft, index) { }
+        VectorRef(config, s, ft, index) { }
 
     virtual void GenSlidingWindowFunction( std::stringstream& ) SAL_OVERRIDE { }
     /// Generate declaration
@@ -779,9 +779,9 @@ size_t DynamicKernelStringArgument::Marshal( cl_kernel k, int argno, int, cl_pro
 class DynamicKernelMixedArgument : public VectorRef
 {
 public:
-    DynamicKernelMixedArgument( const std::string& s,
+    DynamicKernelMixedArgument( const ScCalcConfig& config, const std::string& s,
         FormulaTreeNodeRef ft ) :
-        VectorRef(s, ft), mStringArgument(s + "s", ft) { }
+        VectorRef(config, s, ft), mStringArgument(config, s + "s", ft) { }
     virtual void GenSlidingWindowDecl( std::stringstream& ss ) const SAL_OVERRIDE
     {
         VectorRef::GenSlidingWindowDecl(ss);
@@ -856,10 +856,10 @@ template<class Base>
 class DynamicKernelSlidingArgument : public Base
 {
 public:
-    DynamicKernelSlidingArgument( const std::string& s,
+    DynamicKernelSlidingArgument( const ScCalcConfig& config, const std::string& s,
         FormulaTreeNodeRef ft, boost::shared_ptr<SlidingFunctionBase>& CodeGen,
         int index = 0 ) :
-        Base(s, ft, index), mpCodeGen(CodeGen), mpClmem2(NULL)
+        Base(config, s, ft, index), mpCodeGen(CodeGen), mpClmem2(NULL)
     {
         FormulaToken* t = ft->GetFormulaToken();
         if (t->GetType() != formula::svDoubleVectorRef)
@@ -1089,12 +1089,12 @@ protected:
 class DynamicKernelMixedSlidingArgument : public VectorRef
 {
 public:
-    DynamicKernelMixedSlidingArgument( const std::string& s,
+    DynamicKernelMixedSlidingArgument( const ScCalcConfig& config, const std::string& s,
         FormulaTreeNodeRef ft, boost::shared_ptr<SlidingFunctionBase>& CodeGen,
         int index = 0 ) :
-        VectorRef(s, ft),
-        mDoubleArgument(s, ft, CodeGen, index),
-        mStringArgument(s + "s", ft, CodeGen, index) { }
+        VectorRef(config, s, ft),
+        mDoubleArgument(mCalcConfig, s, ft, CodeGen, index),
+        mStringArgument(mCalcConfig, s + "s", ft, CodeGen, index) { }
     virtual void GenSlidingWindowDecl( std::stringstream& ss ) const SAL_OVERRIDE
     {
         mDoubleArgument.GenSlidingWindowDecl(ss);
@@ -1167,7 +1167,7 @@ public:
     typedef std::list<boost::shared_ptr<DynamicKernelArgument> > ArgumentList;
     SymbolTable() : mCurId(0) { }
     template<class T>
-    const DynamicKernelArgument* DeclRefArg( FormulaTreeNodeRef, SlidingFunctionBase* pCodeGen );
+    const DynamicKernelArgument* DeclRefArg( const ScCalcConfig& config, FormulaTreeNodeRef, SlidingFunctionBase* pCodeGen );
     /// Used to generate sliding window helpers
     void DumpSlidingWindowFunctions( std::stringstream& ss )
     {
@@ -1207,10 +1207,10 @@ template<class Base>
 class ParallelReductionVectorRef : public Base
 {
 public:
-    ParallelReductionVectorRef( const std::string& s,
+    ParallelReductionVectorRef( const ScCalcConfig& config, const std::string& s,
         FormulaTreeNodeRef ft, boost::shared_ptr<SlidingFunctionBase>& CodeGen,
         int index = 0 ) :
-        Base(s, ft, index), mpCodeGen(CodeGen), mpClmem2(NULL)
+        Base(config, s, ft, index), mpCodeGen(CodeGen), mpClmem2(NULL)
     {
         FormulaToken* t = ft->GetFormulaToken();
         if (t->GetType() != formula::svDoubleVectorRef)
@@ -2241,7 +2241,7 @@ public:
     typedef boost::shared_ptr<DynamicKernelArgument> SubArgument;
     typedef std::vector<SubArgument> SubArgumentsType;
 
-    DynamicKernelSoPArguments(
+    DynamicKernelSoPArguments( const ScCalcConfig& config,
         const std::string& s, const FormulaTreeNodeRef& ft, SlidingFunctionBase* pCodeGen );
 
     /// Create buffer and pass the buffer to a given kernel
@@ -2505,14 +2505,14 @@ private:
     cl_mem mpClmem2;
 };
 
-boost::shared_ptr<DynamicKernelArgument> SoPHelper(
+boost::shared_ptr<DynamicKernelArgument> SoPHelper( const ScCalcConfig& config,
     const std::string& ts, const FormulaTreeNodeRef& ft, SlidingFunctionBase* pCodeGen )
 {
-    return boost::shared_ptr<DynamicKernelArgument>(new DynamicKernelSoPArguments(ts, ft, pCodeGen));
+    return boost::shared_ptr<DynamicKernelArgument>(new DynamicKernelSoPArguments(config, ts, ft, pCodeGen));
 }
 
 template<class Base>
-DynamicKernelArgument* VectorRefFactory( const std::string& s,
+DynamicKernelArgument* VectorRefFactory( const ScCalcConfig& config, const std::string& s,
     const FormulaTreeNodeRef& ft,
     boost::shared_ptr<SlidingFunctionBase>& pCodeGen,
     int index )
@@ -2522,29 +2522,29 @@ DynamicKernelArgument* VectorRefFactory( const std::string& s,
     if (dynamic_cast<OpSumIfs*>(pCodeGen.get()))
     {
         if (index == 0) // the first argument of OpSumIfs cannot be strings anyway
-            return new DynamicKernelSlidingArgument<VectorRef>(s, ft, pCodeGen, index);
-        return new DynamicKernelSlidingArgument<Base>(s, ft, pCodeGen, index);
+            return new DynamicKernelSlidingArgument<VectorRef>(config, s, ft, pCodeGen, index);
+        return new DynamicKernelSlidingArgument<Base>(config, s, ft, pCodeGen, index);
     }
     // AVERAGE is not supported yet
     //Average has been supported by reduction kernel
     /*else if (dynamic_cast<OpAverage*>(pCodeGen.get()))
     {
-        return new DynamicKernelSlidingArgument<Base>(s, ft, pCodeGen, index);
+        return new DynamicKernelSlidingArgument<Base>(config, s, ft, pCodeGen, index);
     }*/
     // MUL is not supported yet
     else if (dynamic_cast<OpMul*>(pCodeGen.get()))
     {
-        return new DynamicKernelSlidingArgument<Base>(s, ft, pCodeGen, index);
+        return new DynamicKernelSlidingArgument<Base>(config, s, ft, pCodeGen, index);
     }
     // Sub is not a reduction per se
     else if (dynamic_cast<OpSub*>(pCodeGen.get()))
     {
-        return new DynamicKernelSlidingArgument<Base>(s, ft, pCodeGen, index);
+        return new DynamicKernelSlidingArgument<Base>(config, s, ft, pCodeGen, index);
     }
     // Only child class of Reduction is supported
     else if (!dynamic_cast<Reduction*>(pCodeGen.get()))
     {
-        return new DynamicKernelSlidingArgument<Base>(s, ft, pCodeGen, index);
+        return new DynamicKernelSlidingArgument<Base>(config, s, ft, pCodeGen, index);
     }
 
     const formula::DoubleVectorRefToken* pDVR =
@@ -2552,17 +2552,17 @@ DynamicKernelArgument* VectorRefFactory( const std::string& s,
         ft->GetFormulaToken());
     // Window being too small to justify a parallel reduction
     if (pDVR->GetRefRowSize() < REDUCE_THRESHOLD)
-        return new DynamicKernelSlidingArgument<Base>(s, ft, pCodeGen, index);
+        return new DynamicKernelSlidingArgument<Base>(config, s, ft, pCodeGen, index);
     if ((pDVR->IsStartFixed() && pDVR->IsEndFixed()) ||
         (!pDVR->IsStartFixed() && !pDVR->IsEndFixed()))
-        return new ParallelReductionVectorRef<Base>(s, ft, pCodeGen, index);
+        return new ParallelReductionVectorRef<Base>(config, s, ft, pCodeGen, index);
     else // Other cases are not supported as well
-        return new DynamicKernelSlidingArgument<Base>(s, ft, pCodeGen, index);
+        return new DynamicKernelSlidingArgument<Base>(config, s, ft, pCodeGen, index);
 }
 
-DynamicKernelSoPArguments::DynamicKernelSoPArguments(
+DynamicKernelSoPArguments::DynamicKernelSoPArguments(const ScCalcConfig& config,
     const std::string& s, const FormulaTreeNodeRef& ft, SlidingFunctionBase* pCodeGen ) :
-    DynamicKernelArgument(s, ft), mpCodeGen(pCodeGen), mpClmem2(NULL)
+    DynamicKernelArgument(config, s, ft), mpCodeGen(pCodeGen), mpClmem2(NULL)
 {
     size_t nChildren = ft->Children.size();
 
@@ -2598,20 +2598,20 @@ DynamicKernelSoPArguments::DynamicKernelSoPArguments(
                             {
                                 mvSubArguments.push_back(
                                     SubArgument(
-                                        new DynamicKernelMixedSlidingArgument(
+                                        new DynamicKernelMixedSlidingArgument(mCalcConfig,
                                             ts, ft->Children[i], mpCodeGen, j)));
                             }
                             else
                             {
                                 mvSubArguments.push_back(
-                                    SubArgument(VectorRefFactory<VectorRef>(
+                                    SubArgument(VectorRefFactory<VectorRef>(mCalcConfig,
                                             ts, ft->Children[i], mpCodeGen, j)));
                             }
                         }
                         else
                             mvSubArguments.push_back(
                                 SubArgument(VectorRefFactory
-                                    <DynamicKernelStringArgument>(
+                                    <DynamicKernelStringArgument>(mCalcConfig,
                                         ts, ft->Children[i], mpCodeGen, j)));
                     }
                 }
@@ -2624,30 +2624,50 @@ DynamicKernelSoPArguments::DynamicKernelSoPArguments(
                         pSVR->GetArray().mpStringArray &&
                         pCodeGen->takeString())
                     {
+                        // Function takes numbers or strings, there are both
                         mvSubArguments.push_back(
-                            SubArgument(new DynamicKernelMixedArgument(
+                            SubArgument(new DynamicKernelMixedArgument(mCalcConfig,
                                     ts, ft->Children[i])));
                     }
                     else if (pSVR->GetArray().mpNumericArray &&
-                        pCodeGen->takeNumeric())
+                        pCodeGen->takeNumeric() &&
+                        (pSVR->GetArray().mpStringArray == NULL || mCalcConfig.meStringConversion == ScCalcConfig::STRING_CONVERSION_AS_ZERO))
+                    {
+                        // Function takes numbers, and either there
+                        // are no strings, or there are strings but
+                        // they are to be treated as zero
+                        mvSubArguments.push_back(
+                            SubArgument(new VectorRef(mCalcConfig, ts,
+                                    ft->Children[i])));
+                    }
+                    else if (pSVR->GetArray().mpNumericArray == NULL &&
+                        pCodeGen->takeNumeric() &&
+                        pSVR->GetArray().mpStringArray &&
+                        mCalcConfig.meStringConversion == ScCalcConfig::STRING_CONVERSION_AS_ZERO)
                     {
+                        // Function takes numbers, and there are only
+                        // strings, but they are to be treated as zero
                         mvSubArguments.push_back(
-                            SubArgument(new VectorRef(ts,
+                            SubArgument(new VectorRef(mCalcConfig, ts,
                                     ft->Children[i])));
                     }
                     else if (pSVR->GetArray().mpStringArray &&
                         pCodeGen->takeString())
                     {
+                        // There are strings, and the function takes
+                        // strings.
+
                         mvSubArguments.push_back(
-                            SubArgument(new DynamicKernelStringArgument(
+                            SubArgument(new DynamicKernelStringArgument(mCalcConfig,
                                     ts, ft->Children[i])));
                     }
                     else if (pSVR->GetArray().mpStringArray == NULL &&
                         pSVR->GetArray().mpNumericArray == NULL)
                     {
-                        // Push as an array of NANs
+                        // There are only empty cells. Push as an
+                        // array of NANs
                         mvSubArguments.push_back(
-                            SubArgument(new VectorRef(ts,
+                            SubArgument(new VectorRef(mCalcConfig, ts,
                                     ft->Children[i])));
                     }
                     else
@@ -2657,14 +2677,14 @@ DynamicKernelSoPArguments::DynamicKernelSoPArguments(
                 else if (pChild->GetType() == formula::svDouble)
                 {
                     mvSubArguments.push_back(
-                        SubArgument(new DynamicKernelConstantArgument(ts,
+                        SubArgument(new DynamicKernelConstantArgument(mCalcConfig, ts,
                                 ft->Children[i])));
                 }
                 else if (pChild->GetType() == formula::svString
                     && pCodeGen->takeString())
                 {
                     mvSubArguments.push_back(
-                        SubArgument(new ConstStringArgument(ts,
+                        SubArgument(new ConstStringArgument(mCalcConfig, ts,
                                 ft->Children[i])));
                 }
                 else
@@ -2673,931 +2693,931 @@ DynamicKernelSoPArguments::DynamicKernelSoPArguments(
                 }
                 break;
             case ocDiv:
-                mvSubArguments.push_back(SoPHelper(ts, ft->Children[i], new OpDiv));
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], new OpDiv));
                 break;
             case ocMul:
-                mvSubArguments.push_back(SoPHelper(ts, ft->Children[i], new OpMul));
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], new OpMul));
                 break;
             case ocSub:
-                mvSubArguments.push_back(SoPHelper(ts, ft->Children[i], new OpSub));
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], new OpSub));
                 break;
             case ocAdd:
             case ocSum:
-                mvSubArguments.push_back(SoPHelper(ts, ft->Children[i], new OpSum));
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], new OpSum));
                 break;
             case ocAverage:
-                mvSubArguments.push_back(SoPHelper(ts, ft->Children[i], new OpAverage));
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], new OpAverage));
                 break;
             case ocMin:
-                mvSubArguments.push_back(SoPHelper(ts, ft->Children[i], new OpMin));
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], new OpMin));
                 break;
             case ocMax:
-                mvSubArguments.push_back(SoPHelper(ts, ft->Children[i], new OpMax));
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], new OpMax));
                 break;
             case ocCount:
-                mvSubArguments.push_back(SoPHelper(ts, ft->Children[i], new OpCount));
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], new OpCount));
                 break;
             case ocSumProduct:
-                mvSubArguments.push_back(SoPHelper(ts, ft->Children[i], new OpSumProduct));
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], new OpSumProduct));
                 break;
             case ocIRR:
-                mvSubArguments.push_back(SoPHelper(ts, ft->Children[i], new OpIRR));
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], new OpIRR));
                 break;
             case ocMIRR:
-                mvSubArguments.push_back(SoPHelper(ts, ft->Children[i], new OpMIRR));
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], new OpMIRR));
                 break;
             case ocRMZ:
-                mvSubArguments.push_back(SoPHelper(ts, ft->Children[i], new OpPMT));
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], new OpPMT));
                 break;
             case ocZins:
-                mvSubArguments.push_back(SoPHelper(ts, ft->Children[i], new OpIntrate));
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], new OpIntrate));
                 break;
             case ocZGZ:
-                mvSubArguments.push_back(SoPHelper(ts, ft->Children[i], new OpRRI));
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], new OpRRI));
                 break;
             case ocKapz:
-                mvSubArguments.push_back(SoPHelper(ts, ft->Children[i], new OpPPMT));
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], new OpPPMT));
                 break;
             case ocFisher:
-                mvSubArguments.push_back(SoPHelper(ts, ft->Children[i], new OpFisher));
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], new OpFisher));
                 break;
             case ocFisherInv:
-                mvSubArguments.push_back(SoPHelper(ts, ft->Children[i], new OpFisherInv));
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], new OpFisherInv));
                 break;
             case ocGamma:
-                mvSubArguments.push_back(SoPHelper(ts, ft->Children[i], new OpGamma));
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], new OpGamma));
                 break;
             case ocLIA:
-                mvSubArguments.push_back(SoPHelper(ts, ft->Children[i], new OpSLN));
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], new OpSLN));
                 break;
             case ocGammaLn:
-                mvSubArguments.push_back(SoPHelper(ts, ft->Children[i], new OpGammaLn));
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], new OpGammaLn));
                 break;
             case ocGauss:
-                mvSubArguments.push_back(SoPHelper(ts, ft->Children[i], new OpGauss));
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], new OpGauss));
                 break;
             /*case ocGeoMean:
-                mvSubArguments.push_back(SoPHelper(ts, ft->Children[i], new OpGeoMean));
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], new OpGeoMean));
                 break;*/
             case ocHarMean:
-                mvSubArguments.push_back(SoPHelper(ts, ft->Children[i], new OpHarMean));
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], new OpHarMean));
                 break;
             case ocLessEqual:
-                mvSubArguments.push_back(SoPHelper(ts, ft->Children[i], new OpLessEqual));
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], new OpLessEqual));
                 break;
             case ocLess:
-                mvSubArguments.push_back(SoPHelper(ts, ft->Children[i], new OpLess));
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], new OpLess));
                 break;
             case ocEqual:
-                mvSubArguments.push_back(SoPHelper(ts, ft->Children[i], new OpEqual));
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], new OpEqual));
                 break;
             case ocGreater:
-                mvSubArguments.push_back(SoPHelper(ts, ft->Children[i], new OpGreater));
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], new OpGreater));
                 break;
             case ocDIA:
-                mvSubArguments.push_back(SoPHelper(ts, ft->Children[i], new OpSYD));
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], new OpSYD));
                 break;
             case ocCorrel:
-                mvSubArguments.push_back(SoPHelper(ts, ft->Children[i], new OpCorrel));
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], new OpCorrel));
                 break;
             case ocCos:
-                mvSubArguments.push_back(SoPHelper(ts, ft->Children[i], new OpCos));
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], new OpCos));
                 break;
             case ocNegBinomVert :
-                mvSubArguments.push_back(SoPHelper(ts, ft->Children[i], new OpNegbinomdist));
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], new OpNegbinomdist));
                 break;
             case ocPearson:
-                mvSubArguments.push_back(SoPHelper(ts, ft->Children[i], new OpPearson));
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], new OpPearson));
                 break;
             case ocRSQ:
-                mvSubArguments.push_back(SoPHelper(ts, ft->Children[i], new OpRsq));
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], new OpRsq));
                 break;
             case ocCosecant:
-                mvSubArguments.push_back(SoPHelper(ts, ft->Children[i], new OpCsc));
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], new OpCsc));
                 break;
             case ocISPMT:
-                mvSubArguments.push_back(SoPHelper(ts, ft->Children[i], new OpISPMT));
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], new OpISPMT));
                 break;
             case ocLaufz:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpDuration));
                 break;
             case ocSinHyp:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpSinh));
                 break;
             case ocAbs:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpAbs));
                 break;
             case ocBW:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpPV));
                 break;
             case ocSin:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpSin));
                 break;
             case ocTan:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpTan));
                 break;
             case ocTanHyp:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpTanH));
                 break;
             case ocStandard:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpStandard));
                 break;
             case ocWeibull:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpWeibull));
                 break;
             /*case ocMedian:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                          ft->Children[i],new OpMedian));
                 break;*/
             case ocGDA:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpDDB));
                 break;
             case ocZW:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpFV));
                 break;
             case ocSumIfs:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpSumIfs));
                 break;
                 /*case ocVBD:
-                    mvSubArguments.push_back(SoPHelper(ts,
+                    mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                              ft->Children[i],new OpVDB));
                      break;*/
             case ocKurt:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpKurt));
                 break;
                 /*case ocZZR:
-                    mvSubArguments.push_back(SoPHelper(ts,
+                    mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                             ft->Children[i], new OpNper));
                      break;*/
             case ocNormDist:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpNormdist));
                 break;
             case ocArcCos:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpArcCos));
                 break;
             case ocSqrt:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpSqrt));
                 break;
             case ocArcCosHyp:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpArcCosHyp));
                 break;
             case ocNPV:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpNPV));
                 break;
             case ocStdNormDist:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpNormsdist));
                 break;
             case ocNormInv:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpNorminv));
                 break;
             case ocSNormInv:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpNormsinv));
                 break;
             case ocVariationen:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpVariationen));
                 break;
             case ocVariationen2:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpVariationen2));
                 break;
             case ocPhi:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpPhi));
                 break;
             case ocZinsZ:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpIPMT));
                 break;
             case ocConfidence:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpConfidence));
                 break;
             case ocIntercept:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpIntercept));
                 break;
             case ocGDA2:
-                mvSubArguments.push_back(SoPHelper(ts, ft->Children[i],
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i],
                         new OpDB));
                 break;
             case ocLogInv:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpLogInv));
                 break;
             case ocArcCot:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpArcCot));
                 break;
             case ocCosHyp:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpCosh));
                 break;
             case ocKritBinom:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpCritBinom));
                 break;
             case ocArcCotHyp:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpArcCotHyp));
                 break;
             case ocArcSin:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpArcSin));
                 break;
             case ocArcSinHyp:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpArcSinHyp));
                 break;
             case ocArcTan:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpArcTan));
                 break;
             case ocArcTanHyp:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpArcTanH));
                 break;
             case ocBitAnd:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpBitAnd));
                 break;
             case ocForecast:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpForecast));
                 break;
             case ocLogNormDist:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpLogNormDist));
                 break;
             /*case ocGammaDist:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                          ft->Children[i], new OpGammaDist));
                 break;*/
             case ocLn:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpLn));
                 break;
             case ocRound:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpRound));
                 break;
             case ocCot:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpCot));
                 break;
             case ocCotHyp:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpCoth));
                 break;
             case ocFDist:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpFdist));
                 break;
             case ocVar:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpVar));
                 break;
             /*case ocChiDist:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                          ft->Children[i],new OpChiDist));
                 break;*/
             case ocPow:
             case ocPower:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpPower));
                 break;
             case ocOdd:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpOdd));
                 break;
             /*case ocChiSqDist:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                          ft->Children[i],new OpChiSqDist));
                 break;
             case ocChiSqInv:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                          ft->Children[i],new OpChiSqInv));
                 break;
             case ocGammaInv:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                          ft->Children[i], new OpGammaInv));
                 break;*/
             case ocFloor:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpFloor));
                 break;
             /*case ocFInv:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                          ft->Children[i], new OpFInv));
                 break;*/
             case ocFTest:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpFTest));
                 break;
             case ocB:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpB));
                 break;
             case ocBetaDist:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpBetaDist));
                 break;
             case ocCosecantHyp:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpCscH));
                 break;
             case ocExp:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpExp));
                 break;
             case ocLog10:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpLog10));
                 break;
             case ocExpDist:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpExponDist));
                 break;
             case ocAverageIfs:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpAverageIfs));
                 break;
             case ocCountIfs:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpCountIfs));
                 break;
             case ocKombin2:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpCombina));
                 break;
             case ocEven:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpEven));
                 break;
             case ocLog:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpLog));
                 break;
             case ocMod:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpMod));
                 break;
             case ocTrunc:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpTrunc));
                 break;
             case ocSchiefe:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpSkew));
                 break;
             case ocArcTan2:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpArcTan2));
                 break;
             case ocBitOr:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpBitOr));
                 break;
             case ocBitLshift:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpBitLshift));
                 break;
             case ocBitRshift:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpBitRshift));
                 break;
             case ocBitXor:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpBitXor));
                 break;
             /*case ocChiInv:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                          ft->Children[i],new OpChiInv));
                 break;*/
             case ocPoissonDist:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpPoisson));
                 break;
             case ocSumSQ:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpSumSQ));
                 break;
             case ocSkewp:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpSkewp));
                 break;
             case ocBinomDist:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpBinomdist));
                 break;
             case ocVarP:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpVarP));
                 break;
             case ocCeil:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpCeil));
                 break;
             case ocKombin:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpKombin));
                 break;
             case ocDevSq:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpDevSq));
                 break;
             case ocStDev:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpStDev));
                 break;
             case ocSlope:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpSlope));
                 break;
             case ocSTEYX:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpSTEYX));
                 break;
             case ocZTest:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpZTest));
                 break;
             case ocPi:
                 mvSubArguments.push_back(
-                    SubArgument(new DynamicKernelPiArgument(ts,
+                    SubArgument(new DynamicKernelPiArgument(mCalcConfig, ts,
                             ft->Children[i])));
                 break;
             case ocRandom:
                 mvSubArguments.push_back(
-                    SubArgument(new DynamicKernelRandomArgument(ts,
+                    SubArgument(new DynamicKernelRandomArgument(mCalcConfig, ts,
                             ft->Children[i])));
                 break;
             case ocProduct:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpProduct));
                 break;
             /*case ocHypGeomDist:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                          ft->Children[i],new OpHypGeomDist));
                 break;*/
             case ocSumX2MY2:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpSumX2MY2));
                 break;
             case ocSumX2DY2:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpSumX2PY2));
                 break;
             /*case ocBetaInv:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                          ft->Children[i],new OpBetainv));
                  break;*/
             case ocTTest:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpTTest));
                 break;
             case ocTDist:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpTDist));
                 break;
             /*case ocTInv:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                          ft->Children[i], new OpTInv));
                  break;*/
             case ocSumXMY2:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpSumXMY2));
                 break;
             case ocStDevP:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpStDevP));
                 break;
             case ocCovar:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpCovar));
                 break;
             case ocAnd:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpAnd));
                 break;
             case ocVLookup:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpVLookup));
                 break;
             case ocOr:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpOr));
                 break;
             case ocNot:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpNot));
                 break;
             case ocXor:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpXor));
                 break;
             case ocDBMax:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpDmax));
                 break;
             case ocDBMin:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpDmin));
                 break;
             case ocDBProduct:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpDproduct));
                 break;
             case ocDBAverage:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpDaverage));
                 break;
             case ocDBStdDev:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpDstdev));
                 break;
             case ocDBStdDevP:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpDstdevp));
                 break;
             case ocDBSum:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpDsum));
                 break;
             case ocDBVar:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpDvar));
                 break;
             case ocDBVarP:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpDvarp));
                 break;
             case ocAverageIf:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpAverageIf));
                 break;
             case ocDBCount:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpDcount));
                 break;
             case ocDBCount2:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpDcount2));
                 break;
             case ocDeg:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpDeg));
                 break;
             case ocRoundUp:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpRoundUp));
                 break;
             case ocRoundDown:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpRoundDown));
                 break;
             case ocInt:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpInt));
                 break;
             case ocRad:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpRadians));
                 break;
             case ocCountIf:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpCountIf));
                 break;
             case ocIsEven:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpIsEven));
                 break;
             case ocIsOdd:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpIsOdd));
                 break;
             case ocFact:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpFact));
                 break;
             case ocMinA:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpMinA));
                 break;
             case ocCount2:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpCountA));
                 break;
             case ocMaxA:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpMaxA));
                 break;
             case ocAverageA:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpAverageA));
                 break;
             case ocVarA:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpVarA));
                 break;
             case ocVarPA:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpVarPA));
                 break;
             case ocStDevA:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpStDevA));
                 break;
             case ocStDevPA:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpStDevPA));
                 break;
             case ocSecant:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpSec));
                 break;
             case ocSecantHyp:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpSecH));
                 break;
             case ocSumIf:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpSumIf));
                 break;
             case ocNegSub:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpNegSub));
                 break;
             case ocAveDev:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpAveDev));
                 break;
             case ocIf:
-                mvSubArguments.push_back(SoPHelper(ts,
+                mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                         ft->Children[i], new OpIf));
                 break;
             case ocExternal:
                 if (!(pChild->GetExternal().compareTo(OUString(
                                 "com.sun.star.sheet.addin.Analysis.getEffect"))))
                 {
-                    mvSubArguments.push_back(SoPHelper(ts, ft->Children[i], new OpEffective));
+                    mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], new OpEffective));
                 }
                 else if (!(pChild->GetExternal().compareTo(OUString(
                                 "com.sun.star.sheet.addin.Analysis.getCumipmt"))))
                 {
-                    mvSubArguments.push_back(SoPHelper(ts, ft->Children[i], new OpCumipmt));
+                    mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], new OpCumipmt));
                 }
                 else if (!(pChild->GetExternal().compareTo(OUString(
                                 "com.sun.star.sheet.addin.Analysis.getNominal"))))
                 {
-                    mvSubArguments.push_back(SoPHelper(ts, ft->Children[i], new OpNominal));
+                    mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], new OpNominal));
                 }
                 else if (!(pChild->GetExternal().compareTo(OUString(
                                 "com.sun.star.sheet.addin.Analysis.getCumprinc"))))
                 {
-                    mvSubArguments.push_back(SoPHelper(ts, ft->Children[i], new OpCumprinc));
+                    mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], new OpCumprinc));
                 }
                 else if (!(pChild->GetExternal().compareTo(OUString(
                                 "com.sun.star.sheet.addin.Analysis.getXnpv"))))
                 {
-                    mvSubArguments.push_back(SoPHelper(ts, ft->Children[i], new OpXNPV));
+                    mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], new OpXNPV));
                 }
                 else if (!(pChild->GetExternal().compareTo(OUString(
                                 "com.sun.star.sheet.addin.Analysis.getPricemat"))))
                 {
-                    mvSubArguments.push_back(SoPHelper(ts, ft->Children[i], new OpPriceMat));
+                    mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], new OpPriceMat));
                 }
                 else if (!(pChild->GetExternal().compareTo(OUString(
                                 "com.sun.star.sheet.addin.Analysis.getReceived"))))
                 {
-                    mvSubArguments.push_back(SoPHelper(ts, ft->Children[i], new OpReceived));
+                    mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], new OpReceived));
                 }
                 else if (!(pChild->GetExternal().compareTo(OUString(
                                 "com.sun.star.sheet.addin.Analysis.getTbilleq"))))
                 {
-                    mvSubArguments.push_back(SoPHelper(ts, ft->Children[i], new OpTbilleq));
+                    mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], new OpTbilleq));
                 }
                 else if (!(pChild->GetExternal().compareTo(OUString(
                                 "com.sun.star.sheet.addin.Analysis.getTbillprice"))))
                 {
-                    mvSubArguments.push_back(SoPHelper(ts, ft->Children[i], new OpTbillprice));
+                    mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], new OpTbillprice));
                 }
                 else if (!(pChild->GetExternal().compareTo(OUString(
                                 "com.sun.star.sheet.addin.Analysis.getTbillyield"))))
                 {
-                    mvSubArguments.push_back(SoPHelper(ts, ft->Children[i], new OpTbillyield));
+                    mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], new OpTbillyield));
                 }
                 else if (!(pChild->GetExternal().compareTo(OUString(
                                 "com.sun.star.sheet.addin.Analysis.getFvschedule"))))
                 {
-                    mvSubArguments.push_back(SoPHelper(ts, ft->Children[i], new OpFvschedule));
+                    mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], new OpFvschedule));
                 }
                 /*else if ( !(pChild->GetExternal().compareTo(OUString(
                     "com.sun.star.sheet.addin.Analysis.getYield"))))
                 {
-                    mvSubArguments.push_back(SoPHelper(ts, ft->Children[i], new OpYield));
+                    mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], new OpYield));
                 }*/
                 else if (!(pChild->GetExternal().compareTo(OUString(
                                 "com.sun.star.sheet.addin.Analysis.getYielddisc"))))
                 {
-                    mvSubArguments.push_back(SoPHelper(ts, ft->Children[i], new OpYielddisc));
+                    mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], new OpYielddisc));
                 }
                 else    if (!(pChild->GetExternal().compareTo(OUString(
                                 "com.sun.star.sheet.addin.Analysis.getYieldmat"))))
                 {
-                    mvSubArguments.push_back(SoPHelper(ts, ft->Children[i], new OpYieldmat));
+                    mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], new OpYieldmat));
                 }
                 else if (!(pChild->GetExternal().compareTo(OUString(
                                 "com.sun.star.sheet.addin.Analysis.getAccrintm"))))
                 {
-                    mvSubArguments.push_back(SoPHelper(ts, ft->Children[i], new OpAccrintm));
+                    mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], new OpAccrintm));
                 }
                 else if (!(pChild->GetExternal().compareTo(OUString(
                                 "com.sun.star.sheet.addin.Analysis.getCoupdaybs"))))
                 {
-                    mvSubArguments.push_back(SoPHelper(ts, ft->Children[i], new OpCoupdaybs));
+                    mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], new OpCoupdaybs));
                 }
                 else if (!(pChild->GetExternal().compareTo(OUString(
                                 "com.sun.star.sheet.addin.Analysis.getDollarde"))))
                 {
-                    mvSubArguments.push_back(SoPHelper(ts, ft->Children[i], new OpDollarde));
+                    mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], new OpDollarde));
                 }
                 else if (!(pChild->GetExternal().compareTo(OUString(
                                 "com.sun.star.sheet.addin.Analysis.getDollarfr"))))
                 {
-                    mvSubArguments.push_back(SoPHelper(ts, ft->Children[i], new OpDollarfr));
+                    mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], new OpDollarfr));
                 }
                 else if (!(pChild->GetExternal().compareTo(OUString(
                                 "com.sun.star.sheet.addin.Analysis.getCoupdays"))))
                 {
-                    mvSubArguments.push_back(SoPHelper(ts, ft->Children[i], new OpCoupdays));
+                    mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], new OpCoupdays));
                 }
                 else if (!(pChild->GetExternal().compareTo(OUString(
                                 "com.sun.star.sheet.addin.Analysis.getCoupdaysnc"))))
                 {
-                    mvSubArguments.push_back(SoPHelper(ts, ft->Children[i], new OpCoupdaysnc));
+                    mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], new OpCoupdaysnc));
                 }
                 else if (!(pChild->GetExternal().compareTo(OUString(
                                 "com.sun.star.sheet.addin.Analysis.getDisc"))))
                 {
-                    mvSubArguments.push_back(SoPHelper(ts, ft->Children[i], new OpDISC));
+                    mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], new OpDISC));
                 }
                 else if (!(pChild->GetExternal().compareTo(OUString(
                                 "com.sun.star.sheet.addin.Analysis.getIntrate"))))
                 {
-                    mvSubArguments.push_back(SoPHelper(ts, ft->Children[i], new OpINTRATE));
+                    mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i], new OpINTRATE));
                 }
                 else if (!(pChild->GetExternal().compareTo(OUString(
                                 "com.sun.star.sheet.addin.Analysis.getPrice"))))
                 {
-                    mvSubArguments.push_back(SoPHelper(ts,
+                    mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                             ft->Children[i], new OpPrice));
                 }
                 else if (!(pChild->GetExternal().compareTo(OUString(
                                 "com.sun.star.sheet.addin.Analysis.getCoupnum"))))
                 {
-                    mvSubArguments.push_back(SoPHelper(ts, ft->Children[i],
+                    mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i],
                             new OpCoupnum));
                 }
                 /*else if ( !(pChild->GetExternal().compareTo(OUString(
                    "com.sun.star.sheet.addin.Analysis.getDuration"))))
                 {
                     mvSubArguments.push_back(
-                        SoPHelper(ts, ft->Children[i], new OpDuration_ADD));
+                        SoPHelper(mCalcConfig, ts, ft->Children[i], new OpDuration_ADD));
                 }*/
                 else if (!(pChild->GetExternal().compareTo(OUString(
                                 "com.sun.star.sheet.addin.Analysis.getAmordegrc"))))
                 {
-                    mvSubArguments.push_back(SoPHelper(ts, ft->Children[i],
+                    mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i],
                             new OpAmordegrc));
                 }
                 else if (!(pChild->GetExternal().compareTo(OUString(
                                 "com.sun.star.sheet.addin.Analysis.getAmorlinc"))))
                 {
-                    mvSubArguments.push_back(SoPHelper(ts, ft->Children[i],
+                    mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i],
                             new OpAmorlinc));
                 }
                 else if (!(pChild->GetExternal().compareTo(OUString(
                                 "com.sun.star.sheet.addin.Analysis.getMduration"))))
                 {
-                    mvSubArguments.push_back(SoPHelper(ts, ft->Children[i],
+                    mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i],
                             new OpMDuration));
                 }
                 else if (!(pChild->GetExternal().compareTo(OUString(
                                 "com.sun.star.sheet.addin.Analysis.getXirr"))))
                 {
-                    mvSubArguments.push_back(SoPHelper(ts, ft->Children[i],
+                    mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i],
                             new OpXirr));
                 }
                 else if (!(pChild->GetExternal().compareTo(OUString(
                                 "com.sun.star.sheet.addin.Analysis.getOddlprice"))))
                 {
-                    mvSubArguments.push_back(SoPHelper(ts,
+                    mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                             ft->Children[i], new OpOddlprice));
                 }
                 else if (!(pChild->GetExternal().compareTo(OUString(
                                 "com.sun.star.sheet.addin.Analysis.getOddlyield"))))
                 {
-                    mvSubArguments.push_back(SoPHelper(ts, ft->Children[i],
+                    mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i],
                             new OpOddlyield));
                 }
                 else if (!(pChild->GetExternal().compareTo(OUString(
                                 "com.sun.star.sheet.addin.Analysis.getPricedisc"))))
                 {
-                    mvSubArguments.push_back(SoPHelper(ts,
+                    mvSubArguments.push_back(SoPHelper(mCalcConfig, ts,
                             ft->Children[i], new OpPriceDisc));
                 }
                 else if (!(pChild->GetExternal().compareTo(OUString(
                                 "com.sun.star.sheet.addin.Analysis.getCouppcd"))))
                 {
-                    mvSubArguments.push_back(SoPHelper(ts, ft->Children[i],
+                    mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i],
                             new OpCouppcd));
                 }
                 else if (!(pChild->GetExternal().compareTo(OUString(
                                 "com.sun.star.sheet.addin.Analysis.getCoupncd"))))
                 {
-                    mvSubArguments.push_back(SoPHelper(ts, ft->Children[i],
+                    mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i],
                             new OpCoupncd));
                 }
                 else if (!(pChild->GetExternal().compareTo(OUString(
                                 "com.sun.star.sheet.addin.Analysis.getAccrint"))))
                 {
-                    mvSubArguments.push_back(SoPHelper(ts, ft->Children[i],
+                    mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i],
                             new OpAccrint));
                 }
                 else if (!(pChild->GetExternal().compareTo(OUString(
                                 "com.sun.star.sheet.addin.Analysis.getSqrtpi"))))
                 {
-                    mvSubArguments.push_back(SoPHelper(ts, ft->Children[i],
+                    mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i],
                             new OpSqrtPi));
                 }
                 else if (!(pChild->GetExternal().compareTo(OUString(
                                 "com.sun.star.sheet.addin.Analysis.getConvert"))))
                 {
-                    mvSubArguments.push_back(SoPHelper(ts, ft->Children[i],
+                    mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i],
                             new OpConvert));
                 }
                 else if (!(pChild->GetExternal().compareTo(OUString(
                                 "com.sun.star.sheet.addin.Analysis.getIseven"))))
                 {
-                    mvSubArguments.push_back(SoPHelper(ts, ft->Children[i],
+                    mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i],
                             new OpIsEven));
                 }
                 else if (!(pChild->GetExternal().compareTo(OUString(
                                 "com.sun.star.sheet.addin.Analysis.getIsodd"))))
                 {
-                    mvSubArguments.push_back(SoPHelper(ts, ft->Children[i],
+                    mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i],
                             new OpIsOdd));
                 }
                 else if (!(pChild->GetExternal().compareTo(OUString(
                                 "com.sun.star.sheet.addin.Analysis.getMround"))))
                 {
-                    mvSubArguments.push_back(SoPHelper(ts, ft->Children[i],
+                    mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i],
                             new OpMROUND));
                 }
                 else if (!(pChild->GetExternal().compareTo(OUString(
                                 "com.sun.star.sheet.addin.Analysis.getQuotient"))))
                 {
-                    mvSubArguments.push_back(SoPHelper(ts, ft->Children[i],
+                    mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i],
                             new OpQuotient));
                 }
                 else if (!(pChild->GetExternal().compareTo(OUString(
                                 "com.sun.star.sheet.addin.Analysis.getSeriessum"))))
                 {
-                    mvSubArguments.push_back(SoPHelper(ts, ft->Children[i],
+                    mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i],
                             new OpSeriesSum));
                 }
                 else if (!(pChild->GetExternal().compareTo(OUString(
                                 "com.sun.star.sheet.addin.Analysis.getBesselj"))))
                 {
-                    mvSubArguments.push_back(SoPHelper(ts, ft->Children[i],
+                    mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i],
                             new OpBesselj));
                 }
                 else if (!(pChild->GetExternal().compareTo(OUString(
                                 "com.sun.star.sheet.addin.Analysis.getGestep"))))
                 {
-                    mvSubArguments.push_back(SoPHelper(ts, ft->Children[i],
+                    mvSubArguments.push_back(SoPHelper(mCalcConfig, ts, ft->Children[i],
                             new OpGestep));
                 }
                 else
@@ -3613,9 +3633,9 @@ DynamicKernelSoPArguments::DynamicKernelSoPArguments(
 class DynamicKernel : public CompiledFormula
 {
 public:
-    DynamicKernel( FormulaTreeNodeRef r ) : mpRoot(r),
+    DynamicKernel( const ScCalcConfig& config, FormulaTreeNodeRef r ) : mCalcConfig(config), mpRoot(r),
         mpProgram(NULL), mpKernel(NULL), mpResClmem(NULL) { }
-    static DynamicKernel* create( ScDocument& rDoc,
+    static DynamicKernel* create( const ScCalcConfig& config, ScDocument& rDoc,
         const ScAddress& rTopPos,
         ScTokenArray& rCode );
     /// OpenCL code generation
@@ -3623,7 +3643,7 @@ public:
     {
         // Travese the tree of expression and declare symbols used
         const DynamicKernelArgument* DK = mSyms.DeclRefArg<
-                                                               DynamicKernelSoPArguments>(mpRoot, new OpNop);
+                                                               DynamicKernelSoPArguments>(mCalcConfig, mpRoot, new OpNop);
 
         std::stringstream decl;
         if (::opencl::gpuEnv.mnKhrFp64Flag)
@@ -3725,7 +3745,7 @@ public:
     cl_mem GetResultBuffer() const { return mpResClmem; }
 
 private:
-
+    ScCalcConfig mCalcConfig;
     FormulaTreeNodeRef mpRoot;
     SymbolTable mSyms;
     std::string mKernelSignature, mKernelHash;
@@ -3862,7 +3882,7 @@ void DynamicKernel::CreateKernel()
 // kernel with argument with unique name and return so.
 // The template argument T must be a subclass of DynamicKernelArgument
 template<typename T>
-const DynamicKernelArgument* SymbolTable::DeclRefArg(
+const DynamicKernelArgument* SymbolTable::DeclRefArg( const ScCalcConfig& config,
     FormulaTreeNodeRef t, SlidingFunctionBase* pCodeGen )
 {
     FormulaToken* ref = t->GetFormulaToken();
@@ -3872,7 +3892,7 @@ const DynamicKernelArgument* SymbolTable::DeclRefArg(
         // Allocate new symbols
         std::stringstream ss;
         ss << "tmp" << mCurId++;
-        boost::shared_ptr<DynamicKernelArgument> new_arg(new T(ss.str(), t, pCodeGen));
+        boost::shared_ptr<DynamicKernelArgument> new_arg(new T(config, ss.str(), t, pCodeGen));
         mSymbols[ref] = new_arg;
         mParams.push_back(new_arg);
         return new_arg.get();
@@ -3888,7 +3908,7 @@ ScMatrixRef FormulaGroupInterpreterOpenCL::inverseMatrix( const ScMatrix& )
     return NULL;
 }
 
-DynamicKernel* DynamicKernel::create( ScDocument& /* rDoc */,
+DynamicKernel* DynamicKernel::create( const ScCalcConfig& rConfig, ScDocument& /* rDoc */,
     const ScAddress& /* rTopPos */,
     ScTokenArray& rCode )
 {
@@ -3931,7 +3951,7 @@ DynamicKernel* DynamicKernel::create( ScDocument& /* rDoc */,
     FormulaTreeNodeRef Root = FormulaTreeNodeRef(new FormulaTreeNode(NULL));
     Root->Children.push_back(aHashMap[aTokenList.back()]);
 
-    DynamicKernel* pDynamicKernel = new DynamicKernel(Root);
+    DynamicKernel* pDynamicKernel = new DynamicKernel(rConfig, Root);
 
     if (!pDynamicKernel)
         return NULL;
@@ -3966,13 +3986,15 @@ CompiledFormula* FormulaGroupInterpreterOpenCL::createCompiledFormula( ScDocumen
     ScTokenArray& rCode )
 {
     SymbolTable::nR = rGroup.mnLength;
-    return DynamicKernel::create(rDoc, rTopPos, rCode);
+    return DynamicKernel::create(maCalcConfig, rDoc, rTopPos, rCode);
 }
 
 bool FormulaGroupInterpreterOpenCL::interpret( ScDocument& rDoc,
     const ScAddress& rTopPos, ScFormulaCellGroupRef& xGroup,
     ScTokenArray& rCode )
 {
+    MergeCalcConfig(rDoc);
+
     ScCompiler aComp(&rDoc, rTopPos, rCode);
     aComp.SetGrammar(rDoc.GetGrammar());
     // Disable special ordering for jump commands for the OpenCL interpreter.
diff --git a/sc/source/core/opencl/opbase.cxx b/sc/source/core/opencl/opbase.cxx
index 14ae124..6d32331 100644
--- a/sc/source/core/opencl/opbase.cxx
+++ b/sc/source/core/opencl/opbase.cxx
@@ -84,9 +84,9 @@ const char* OpenCLError::strerror( cl_int i ) const
 Unhandled::Unhandled( const std::string& fn, int ln ) :
     mFile(fn), mLineNumber(ln) {}
 
-DynamicKernelArgument::DynamicKernelArgument( const std::string& s,
+DynamicKernelArgument::DynamicKernelArgument( const ScCalcConfig& config, const std::string& s,
     FormulaTreeNodeRef ft ) :
-    mSymName(s), mFormulaTree(ft) { }
+    mCalcConfig(config), mSymName(s), mFormulaTree(ft) { }
 
 std::string DynamicKernelArgument::GenDoubleSlidingWindowDeclRef( bool ) const
 {
@@ -144,8 +144,8 @@ bool DynamicKernelArgument::NeedParallelReduction() const
     return false;
 }
 
-VectorRef::VectorRef( const std::string& s, FormulaTreeNodeRef ft, int idx ) :
-    DynamicKernelArgument(s, ft), mpClmem(NULL), mnIndex(idx)
+VectorRef::VectorRef( const ScCalcConfig& config, const std::string& s, FormulaTreeNodeRef ft, int idx ) :
+    DynamicKernelArgument(config, s, ft), mpClmem(NULL), mnIndex(idx)
 {
     if (mnIndex)
     {
diff --git a/sc/source/core/opencl/opbase.hxx b/sc/source/core/opencl/opbase.hxx
index c1e47b8..6cdfa87 100644
--- a/sc/source/core/opencl/opbase.hxx
+++ b/sc/source/core/opencl/opbase.hxx
@@ -21,6 +21,8 @@
 #include <set>
 #define ISNAN
 
+#include "calcconfig.hxx"
+
 namespace sc { namespace opencl {
 
 class FormulaTreeNode;
@@ -86,7 +88,7 @@ private:
 class DynamicKernelArgument : boost::noncopyable
 {
 public:
-    DynamicKernelArgument( const std::string& s, FormulaTreeNodeRef ft );
+    DynamicKernelArgument( const ScCalcConfig& config, const std::string& s, FormulaTreeNodeRef ft );
     virtual ~DynamicKernelArgument() {}
 
     /// Generate declaration
@@ -125,6 +127,7 @@ public:
     virtual bool NeedParallelReduction() const;
 
 protected:
+    const ScCalcConfig& mCalcConfig;
     std::string mSymName;
     FormulaTreeNodeRef mFormulaTree;
 };
@@ -137,7 +140,7 @@ protected:
 class VectorRef : public DynamicKernelArgument
 {
 public:
-    VectorRef( const std::string& s, FormulaTreeNodeRef ft, int index = 0 );
+    VectorRef( const ScCalcConfig& config, const std::string& s, FormulaTreeNodeRef ft, int index = 0 );
     virtual ~VectorRef();
 
     /// Generate declaration
diff --git a/sc/source/core/tool/formulagroup.cxx b/sc/source/core/tool/formulagroup.cxx
index 32ee19a..7ca030d 100644
--- a/sc/source/core/tool/formulagroup.cxx
+++ b/sc/source/core/tool/formulagroup.cxx
@@ -510,6 +510,12 @@ public:
 
 FormulaGroupInterpreter *FormulaGroupInterpreter::msInstance = NULL;
 
+void FormulaGroupInterpreter::MergeCalcConfig(const ScDocument& rDoc)
+{
+    maCalcConfig = ScInterpreter::GetGlobalConfig();
+    maCalcConfig.MergeDocumentSpecific(rDoc.GetCalcConfig());
+}
+
 /// load and/or configure the correct formula group interpreter
 FormulaGroupInterpreter *FormulaGroupInterpreter::getStatic()
 {
commit 9ace23338c0a9241895bab05b494c6de7fbfdb6e
Author: Eike Rathke <erack at redhat.com>
Date:   Wed Feb 11 21:47:23 2015 +0100

    Resolves: tdf#39316 add matrix empty cells to ScInterpreter::QueryMatrixType()
    
    (cherry picked from commit eccbc97c7c224269fe261b8924e7866c3758ec91)
    
    add ScMatrix::IsEmptyResult() for tdf#39316 fix preparation
    
    (cherry picked from commit cf3f1d8dfeb45249eb60a30dba3243fe9a4a65e5)
    
    9f2a3e6fa9f4ef43df672661afef996269b90a7a
    
    Change-Id: Ifa5d59e90afcfff66f2e8683fac2a9090ed615da
    Reviewed-on: https://gerrit.libreoffice.org/14429
    Reviewed-by: Markus Mohrhard <markus.mohrhard at googlemail.com>
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/sc/inc/scmatrix.hxx b/sc/inc/scmatrix.hxx
index 6bcd8857..6f8ad91 100644
--- a/sc/inc/scmatrix.hxx
+++ b/sc/inc/scmatrix.hxx
@@ -322,13 +322,16 @@ public:
     /// @return <TRUE/> if string or empty or empty path, in fact non-value.
     bool IsString( SCSIZE nC, SCSIZE nR ) const;
 
-    /// @return <TRUE/> if empty or empty path.
+    /// @return <TRUE/> if empty or empty cell or empty result, not empty path.
     bool IsEmpty( SCSIZE nC, SCSIZE nR ) const;
 
-    /// @return <TRUE/> if empty, not empty result or empty path.
+    /// @return <TRUE/> if empty cell, not empty or empty result or empty path.
     bool IsEmptyCell( SCSIZE nC, SCSIZE nR ) const;
 
-    /// @return <TRUE/> if empty path.
+    /// @return <TRUE/> if empty result, not empty or empty cell or empty path.
+    bool IsEmptyResult( SCSIZE nC, SCSIZE nR ) const;
+
+    /// @return <TRUE/> if empty path, not empty or empty cell or empty result.
     bool IsEmptyPath( SCSIZE nC, SCSIZE nR ) const;
 
     /// @return <TRUE/> if value or boolean.
diff --git a/sc/source/core/tool/interpr4.cxx b/sc/source/core/tool/interpr4.cxx
index bbb77ca..8b5fb73 100644
--- a/sc/source/core/tool/interpr4.cxx
+++ b/sc/source/core/tool/interpr4.cxx
@@ -1849,6 +1849,16 @@ void ScInterpreter::QueryMatrixType(ScMatrixRef& xMat, short& rRetTypeExpr, sal_
                 PushTempToken( new ScMatrixFormulaCellToken(nCols, nRows, xMat, xRes.get()));
                 rRetTypeExpr = NUMBERFORMAT_LOGICAL;
             }
+            else if ( xMat->IsEmptyResult( 0, 0))
+            {   // empty formula result
+                FormulaTokenRef xRes = new ScEmptyCellToken( true, true);   // inherited, display empty
+                PushTempToken( new ScMatrixFormulaCellToken(nCols, nRows, xMat, xRes.get()));
+            }
+            else if ( xMat->IsEmpty( 0, 0))
+            {   // empty or empty cell
+                FormulaTokenRef xRes = new ScEmptyCellToken( false, true);  // not inherited, display empty
+                PushTempToken( new ScMatrixFormulaCellToken(nCols, nRows, xMat, xRes.get()));
+            }
             else
             {
                 svl::SharedString aStr( nMatVal.GetString());
diff --git a/sc/source/core/tool/scmatrix.cxx b/sc/source/core/tool/scmatrix.cxx
index 4402002..998f562 100644
--- a/sc/source/core/tool/scmatrix.cxx
+++ b/sc/source/core/tool/scmatrix.cxx
@@ -254,6 +254,7 @@ public:
     bool IsString( SCSIZE nC, SCSIZE nR ) const;
     bool IsEmpty( SCSIZE nC, SCSIZE nR ) const;
     bool IsEmptyCell( SCSIZE nC, SCSIZE nR ) const;
+    bool IsEmptyResult( SCSIZE nC, SCSIZE nR ) const;
     bool IsEmptyPath( SCSIZE nC, SCSIZE nR ) const;
     bool IsValue( SCSIZE nIndex ) const;
     bool IsValue( SCSIZE nC, SCSIZE nR ) const;
@@ -684,8 +685,8 @@ bool ScMatrixImpl::IsString( SCSIZE nC, SCSIZE nR ) const
 
 bool ScMatrixImpl::IsEmpty( SCSIZE nC, SCSIZE nR ) const
 {
-    // Flag must indicate an empty element instead of an
-    // 'empty path' element.
+    // Flag must indicate an 'empty' or 'empty cell' or 'empty result' element,
+    // but not an 'empty path' element.
     ValidColRowReplicated( nC, nR );
     return maMat.get_type(nR, nC) == mdds::mtm::element_empty &&
         maMatFlag.get<TMatFlag>(nR, nC) != SC_MATFLAG_EMPTYPATH;
@@ -693,13 +694,22 @@ bool ScMatrixImpl::IsEmpty( SCSIZE nC, SCSIZE nR ) const
 
 bool ScMatrixImpl::IsEmptyCell( SCSIZE nC, SCSIZE nR ) const
 {
-    // Flag must indicate an 'empty' element instead of an
-    // 'empty result' or 'empty path' element.
+    // Flag must indicate an 'empty cell' element instead of an
+    // 'empty' or 'empty result' or 'empty path' element.
     ValidColRowReplicated( nC, nR );
     return maMat.get_type(nR, nC) == mdds::mtm::element_empty &&
         maMatFlag.get<TMatFlag>(nR, nC) == SC_MATFLAG_EMPTYCELL;
 }
 
+bool ScMatrixImpl::IsEmptyResult( SCSIZE nC, SCSIZE nR ) const
+{
+    // Flag must indicate an 'empty result' element instead of an
+    // 'empty' or 'empty cell' or 'empty path' element.
+    ValidColRowReplicated( nC, nR );
+    return maMat.get_type(nR, nC) == mdds::mtm::element_empty &&
+        maMatFlag.get<TMatFlag>(nR, nC) == SC_MATFLAG_EMPTYRESULT;
+}
+
 bool ScMatrixImpl::IsEmptyPath( SCSIZE nC, SCSIZE nR ) const
 {
     // Flag must indicate an 'empty path' element.
@@ -2324,6 +2334,11 @@ bool ScMatrix::IsEmptyCell( SCSIZE nC, SCSIZE nR ) const
     return pImpl->IsEmptyCell(nC, nR);
 }
 
+bool ScMatrix::IsEmptyResult( SCSIZE nC, SCSIZE nR ) const
+{
+    return pImpl->IsEmptyResult(nC, nR);
+}
+
 bool ScMatrix::IsEmptyPath( SCSIZE nC, SCSIZE nR ) const
 {
     return pImpl->IsEmptyPath(nC, nR);


More information about the Libreoffice-commits mailing list