* Bug 15330 fixed: spec.tst was crashing on Linux
[scilab.git] / scilab / modules / linear_algebra / sci_gateway / cpp / sci_spec.cpp
index 10355a7..ca038ab 100644 (file)
@@ -3,11 +3,14 @@
 * Copyright (C) 2009 - DIGITEO - Bernard HUGUENEY
 * Copyright (C) 2011 - DIGITEO - Cedric DELAMARRE
 *
-* This file must be used under the terms of the CeCILL.
-* This source file is licensed as described in the file COPYING, which
-* you should have received as part of this distribution.  The terms
-* are also available at
-* http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
+ * Copyright (C) 2012 - 2016 - Scilab Enterprises
+ *
+ * This file is hereby licensed under the terms of the GNU GPL v2.0,
+ * pursuant to article 5.3.4 of the CeCILL v.2.1.
+ * This file was originally licensed under the terms of the CeCILL v2.1,
+ * and continues to be available under such terms.
+ * For more information, see the COPYING file which you should have received
+ * along with this program.
 *
 */
 /*--------------------------------------------------------------------------*/
@@ -16,7 +19,6 @@
 #include "function.hxx"
 #include "double.hxx"
 #include "overload.hxx"
-#include "execvisitor.hxx"
 
 extern "C"
 {
@@ -38,6 +40,8 @@ types::Function::ReturnValue sci_spec(types::typed_list &in, int _iRetCount, typ
     bool symmetric          = FALSE;
     int iRet                = 0;
 
+    _iRetCount = std::max(1, _iRetCount);
+
     if (in.size() != 1 && in.size() != 2)
     {
         Scierror(77, _("%s: Wrong number of input argument(s): %d to %d expected.\n"), "spec", 1, 2);
@@ -52,9 +56,8 @@ types::Function::ReturnValue sci_spec(types::typed_list &in, int _iRetCount, typ
 
     if (in[0]->isDouble() == false)
     {
-        ast::ExecVisitor exec;
         std::wstring wstFuncName = L"%" + in[0]->getShortTypeStr() + L"_spec";
-        return Overload::call(wstFuncName, in, _iRetCount, out, &exec);
+        return Overload::call(wstFuncName, in, _iRetCount, out);
     }
 
     types::Double* in0 = in[0]->getAs<types::Double>();
@@ -116,7 +119,7 @@ types::Function::ReturnValue sci_spec(types::typed_list &in, int _iRetCount, typ
         }
 
         symmetric = isSymmetric(pDblA->getReal(), pDblA->getImg(), pDblA->isComplex(), pDblA->getRows(), pDblA->getCols()) == 1;
-        int eigenValuesCols = (_iRetCount == 1) ? 1 : pDblA->getCols();
+        int eigenValuesCols = (_iRetCount <= 1) ? 1 : pDblA->getCols();
 
         if (symmetric)
         {
@@ -145,7 +148,7 @@ types::Function::ReturnValue sci_spec(types::typed_list &in, int _iRetCount, typ
                 {
                     vFreeDoubleComplexFromPointer((doublecomplex*)pDataA);
                     pDblA->killMe();
-                    Scierror(998, _("%s: On entry to ZGEEV parameter number  3 had an illegal value (lapack library problem).\n"), "spec", iRet);
+                    Scierror(998, _("%s: On entry to ZGEEV parameter number  3 had an illegal value (lapack library problem).\n"), "spec");
                     return types::Function::Error;
                 }
 
@@ -159,12 +162,13 @@ types::Function::ReturnValue sci_spec(types::typed_list &in, int _iRetCount, typ
 
                 if (_iRetCount == 2)
                 {
-                    vGetPointerFromDoubleComplex((doublecomplex*)pDataA, pDblA->getSize() , pDblEigenVectors->getReal(), pDblEigenVectors->getImg());
-                    vFreeDoubleComplexFromPointer((doublecomplex*)pDataA);
+                    vGetPointerFromDoubleComplex((doublecomplex*)pDataA, pDblA->getSize(), pDblEigenVectors->getReal(), pDblEigenVectors->getImg());
                     expandToDiagonalOfMatrix(pDblEigenValues->getReal(), pDblA->getCols());
                     out.push_back(pDblEigenVectors);
                 }
                 out.push_back(pDblEigenValues);
+                pDblA->killMe();
+                vFreeDoubleComplexFromPointer((doublecomplex*)pDataA);
             }
             else // not symmetric
             {
@@ -175,7 +179,7 @@ types::Function::ReturnValue sci_spec(types::typed_list &in, int _iRetCount, typ
                 if (iRet < 0)
                 {
                     pDblA->killMe();
-                    Scierror(998, _("%s: On entry to ZHEEV parameter number  3 had an illegal value (lapack library problem).\n"), "spec", iRet);
+                    Scierror(998, _("%s: On entry to ZHEEV parameter number  3 had an illegal value (lapack library problem).\n"), "spec");
                     return types::Function::Error;
                 }
 
@@ -211,7 +215,7 @@ types::Function::ReturnValue sci_spec(types::typed_list &in, int _iRetCount, typ
                 if (iRet < 0)
                 {
                     pDblA->killMe();
-                    Scierror(998, _("%s: On entry to ZGEEV parameter number  3 had an illegal value (lapack library problem).\n"), "spec", iRet);
+                    Scierror(998, _("%s: On entry to ZGEEV parameter number  3 had an illegal value (lapack library problem).\n"), "spec");
                     return types::Function::Error;
                 }
 
@@ -224,6 +228,10 @@ types::Function::ReturnValue sci_spec(types::typed_list &in, int _iRetCount, typ
 
                 if (_iRetCount == 2)
                 {
+                    if (pDblEigenVectors)
+                    {
+                        pDblEigenVectors->killMe();
+                    }
                     expandToDiagonalOfMatrix(pDblEigenValues->getReal(), pDblA->getCols());
                     out.push_back(pDblA);
                 }
@@ -241,13 +249,21 @@ types::Function::ReturnValue sci_spec(types::typed_list &in, int _iRetCount, typ
                 if (iRet < 0)
                 {
                     pDblA->killMe();
-                    Scierror(998, _("%s: On entry to ZHEEV parameter number  3 had an illegal value (lapack library problem).\n"), "spec", iRet);
+                    if (pDblEigenVectors)
+                    {
+                        pDblEigenVectors->killMe();
+                    }
+                    Scierror(998, _("%s: On entry to ZHEEV parameter number  3 had an illegal value (lapack library problem).\n"), "spec");
                     return types::Function::Error;
                 }
 
                 if (iRet > 0)
                 {
                     pDblA->killMe();
+                    if (pDblEigenVectors)
+                    {
+                        pDblEigenVectors->killMe();
+                    }
                     Scierror(24, _("%s: The QR algorithm failed to compute all the eigenvalues, and no eigenvectors have been computed. Elements and %d+1:N of WR and WI contain eigenvalues which have converged.\n"), "spec", iRet);
                     return types::Function::Error;
                 }
@@ -281,9 +297,8 @@ types::Function::ReturnValue sci_spec(types::typed_list &in, int _iRetCount, typ
 
         if (in[1]->isDouble() == false)
         {
-            ast::ExecVisitor exec;
             std::wstring wstFuncName = L"%" + in[1]->getShortTypeStr() + L"_spec";
-            return Overload::call(wstFuncName, in, _iRetCount, out, &exec);
+            return Overload::call(wstFuncName, in, _iRetCount, out);
         }
 
         types::Double* in1 = in[1]->getAs<types::Double>();
@@ -328,10 +343,22 @@ types::Function::ReturnValue sci_spec(types::typed_list &in, int _iRetCount, typ
             pDataA = (double*)oGetDoubleComplexFromPointer(pDblA->getReal(), pDblA->getImg(), pDblA->getSize());
             pDataB = (double*)oGetDoubleComplexFromPointer(pDblB->getReal(), pDblB->getImg(), pDblB->getSize());
 
-            if (!pDataA || !pDataB)
+            if (!pDataA && !pDataB)
             {
-                delete pDataA;
-                delete pDataB;
+                Scierror(999, _("%s: Cannot allocate more memory.\n"), "spec");
+                return types::Function::Error;
+            }
+
+            if (!pDataA)
+            {
+                vFreeDoubleComplexFromPointer((doublecomplex*)pDataB);
+                Scierror(999, _("%s: Cannot allocate more memory.\n"), "spec");
+                return types::Function::Error;
+            }
+
+            if (!pDataB)
+            {
+                vFreeDoubleComplexFromPointer((doublecomplex*)pDataA);
                 Scierror(999, _("%s: Cannot allocate more memory.\n"), "spec");
                 return types::Function::Error;
             }
@@ -422,7 +449,7 @@ types::Function::ReturnValue sci_spec(types::typed_list &in, int _iRetCount, typ
         {
             pDblA->killMe();
             pDblB->killMe();
-            Scierror(998, _("%s: On entry to ZHEEV parameter number  3 had an illegal value (lapack library problem).\n"), "spec", iRet);
+            Scierror(998, _("%s: On entry to ZHEEV parameter number  3 had an illegal value (lapack library problem).\n"), "spec");
             return types::Function::Error;
         }
 
@@ -525,7 +552,7 @@ types::Function::ReturnValue sci_spec(types::typed_list &in, int _iRetCount, typ
         {
             vFreeDoubleComplexFromPointer(pR);
         }
-        if (pDblB->isComplex())
+        if (bIsComplex && pDblB->isComplex())
         {
             vFreeDoubleComplexFromPointer((doublecomplex*)pDataB);
         }