[ast] improved polynomial display with unicode superscripts
[scilab.git] / scilab / modules / ast / src / cpp / types / singlepoly.cpp
index d0bc009..04a15cf 100644 (file)
@@ -2,15 +2,18 @@
 *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
 *  Copyright (C) 2008-2008 - DIGITEO - Antoine ELIAS
 *
-*  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.
 *
 */
 #include <sstream>
-#include <math.h>
+#include <cmath>
 #include "singlepoly.hxx"
 #include "double.hxx"
 #include "tostring_common.hxx"
@@ -24,8 +27,6 @@ extern "C"
 #include "elem_common.h"
 }
 
-using namespace std;
-
 namespace types
 {
 SinglePoly::SinglePoly()
@@ -106,9 +107,7 @@ double* SinglePoly::allocData(int _iSize)
             m_pImgData = NULL;
             char message[bsiz];
             os_sprintf(message, _("Can not allocate negative size (%d).\n"),  _iSize);
-            ast::ScilabError se(message);
-            se.SetErrorNumber(999);
-            throw (se);
+            throw ast::InternalError(message);
         }
         else
         {
@@ -118,10 +117,10 @@ double* SinglePoly::allocData(int _iSize)
     catch (std::bad_alloc &/*e*/)
     {
         char message[bsiz];
-        os_sprintf(message, _("Can not allocate %.2f MB memory.\n"),  (double) (_iSize * sizeof(double)) / 1.e6);
-        ast::ScilabError se(message);
-        se.SetErrorNumber(999);
-        throw (se);
+        char byteString[9];
+        humanReadableByteCount(((size_t) m_iSize) * sizeof(double), byteString);
+        os_sprintf(message, _("Can not allocate %s memory.\n"), byteString);
+        throw ast::InternalError(message);
     }
 
     return pDbl;
@@ -137,6 +136,11 @@ int SinglePoly::getRank()
     return m_iSize - 1;
 }
 
+double SinglePoly::getDegree()
+{
+    return m_iSize == 1 && m_pRealData[0] == 0 && (m_pImgData == NULL || m_pImgData[0] == 0) ? -INFINITY : m_iSize - 1;
+}
+
 bool SinglePoly::setRank(int _iRank, bool bSave)
 {
     double *pR = NULL;
@@ -272,15 +276,15 @@ bool SinglePoly::evaluate(double _dblInR, double _dblInI, double *_pdblOutR, dou
     for (int i = 0 ; i < m_iSize ; i++)
     {
         //real part
-        *_pdblOutR += m_pRealData[i] * pow(_dblInR, i);
+        *_pdblOutR += m_pRealData[i] * std::pow(_dblInR, i);
         //only if variable is complex
         if (isComplex())
         {
-            *_pdblOutR -= m_pImgData[i] * pow(_dblInI, i);
+            *_pdblOutR -= m_pImgData[i] * std::pow(_dblInI, i);
             //img part
-            *_pdblOutI += m_pRealData[i] * pow(_dblInR, i);
+            *_pdblOutI += m_pRealData[i] * std::pow(_dblInR, i);
         }
-        *_pdblOutI += m_pRealData[i] * pow(_dblInI, i);
+        *_pdblOutI += m_pRealData[i] * std::pow(_dblInI, i);
     }
 
     return true;
@@ -293,7 +297,7 @@ void SinglePoly::updateRank(void)
     {
         for (int i = getRank(); i > 0 ; i--)
         {
-            if (fabs(m_pRealData[i]) == 0.0 && abs(m_pImgData[i]) == 0.0)
+            if (std::fabs(m_pRealData[i]) == 0.0 && std::fabs(m_pImgData[i]) == 0.0)
             {
                 iNewRank--;
             }
@@ -307,7 +311,7 @@ void SinglePoly::updateRank(void)
     {
         for (int i = getRank(); i > 0 ; i--)
         {
-            if (fabs(m_pRealData[i]) == 0.0)
+            if (std::fabs(m_pRealData[i]) == 0.0)
             {
                 iNewRank--;
             }
@@ -330,38 +334,39 @@ bool SinglePoly::toString(std::wostringstream& ostr)
     return true;
 }
 
-void SinglePoly::toStringReal(wstring _szVar, list<wstring>* _pListExp , list<wstring>* _pListCoef)
+void SinglePoly::toStringReal(const std::wstring& _szVar, std::list<std::wstring>* _pListWstPoly)
 {
-    toStringInternal(m_pRealData, _szVar, _pListExp, _pListCoef);
+    toStringInternal(m_pRealData, _szVar, _pListWstPoly);
 }
 
-void SinglePoly::toStringImg(wstring _szVar, list<wstring>* _pListExp , list<wstring>* _pListCoef)
+void SinglePoly::toStringImg(const std::wstring& _szVar, std::list<std::wstring>* _pListWstPoly)
 {
     if (isComplex() == false)
     {
-        _pListExp->clear();
-        _pListCoef->clear();
+        _pListWstPoly->clear();
         return;
     }
 
-    toStringInternal(m_pImgData, _szVar, _pListExp, _pListCoef);
+    toStringInternal(m_pImgData, _szVar, _pListWstPoly);
 }
 
-bool SinglePoly::subMatrixToString(wostringstream& /*ostr*/, int* /*_piDims*/, int /*_iDims*/)
+bool SinglePoly::subMatrixToString(std::wostringstream& /*ostr*/, int* /*_piDims*/, int /*_iDims*/)
 {
     return false;
 }
 
-void SinglePoly::toStringInternal(double *_pdblVal, wstring _szVar, list<wstring>* _pListExp , list<wstring>* _pListCoef)
+void SinglePoly::toStringInternal(double *_pdblVal, const std::wstring& _szVar, std::list<std::wstring>* _pListWstPoly)
 {
     int iLineLen = ConfigVariable::getConsoleWidth();
 
-    wostringstream ostemp;
-    wostringstream ostemp2;
+    std::wstring strExponentDigits (L"\u2070\u00B9\u00B2\u00B3\u2074\u2075\u2076\u2077\u2078\u2079");
+    std::vector<int> iExponentsDigits = {0};
+    std::wostringstream ostemp;
+    bool bFirst = true;
 
     ostemp << L" ";
-    ostemp2 << L" ";
 
+    int k;
     int iLen = 0;
     int iLastFlush = 2;
     for (int i = 0 ; i < m_iSize ; i++)
@@ -374,45 +379,50 @@ void SinglePoly::toStringInternal(double *_pdblVal, wstring _szVar, list<wstring
             if (iLen + df.iWidth + df.iSignLen >= iLineLen - 1)
             {
                 iLastFlush = i;
-                _pListExp->push_back(ostemp2.str());
-                ostemp2.str(L""); //reset stream
-                addSpaces(&ostemp2, 11); //take from scilab ... why not ...
-
-                _pListCoef->push_back(ostemp.str());
+                _pListWstPoly->push_back(ostemp.str());
                 ostemp.str(L""); //reset stream
-                addSpaces(&ostemp, 11); //take from scilab ... why not ...
+                addSpaces(&ostemp, 1); //take from scilab ... why not ...
             }
 
-            bool bFirst = ostemp.str().size() == 1;
-
             // In scientific notation case bExp == true, so we have to print point (2.000D+10s)
             // In other case don't print point (2s)
             df.bPrintPoint = df.bExp;
             df.bPrintPlusSign = bFirst == false;
             df.bPrintOne = i == 0;
+            bFirst = false;
             addDoubleValue(&ostemp, _pdblVal[i], &df);
-
+            
             if (i == 0)
             {
                 iLen = static_cast<int>(ostemp.str().size());
             }
             else if (i == 1)
             {
-                // add polynom name
+                // add polynomial variable
                 ostemp << _szVar;
                 iLen = static_cast<int>(ostemp.str().size());
             }
             else
             {
-                // add polynom name and exponent
+                // add polynomial variable and exponent
                 ostemp << _szVar;
-                iLen = static_cast<int>(ostemp.str().size());
-                addSpaces(&ostemp2, iLen - static_cast<int>(ostemp2.str().size()));
-                ostemp2 << i;
-                int iSize = static_cast<int>(ostemp2.str().size()) - iLen;
-                addSpaces(&ostemp, iSize);
-            }
+                for (auto it = iExponentsDigits.rbegin(); it != iExponentsDigits.rend(); ++it)
+                {
+                    ostemp << strExponentDigits[*it];
+                }
+                iLen = static_cast<int>(ostemp.str().size());            
+            }            
         }
+
+        for (k=0; k < iExponentsDigits.size() && iExponentsDigits[k] == 9; k++)
+        {
+            iExponentsDigits[k] = 0;
+        }
+        if (k == iExponentsDigits.size())
+        {
+            iExponentsDigits.push_back(0);
+        }
+        iExponentsDigits[k]++;
     }
 
     if (iLastFlush != 0)
@@ -420,17 +430,9 @@ void SinglePoly::toStringInternal(double *_pdblVal, wstring _szVar, list<wstring
         if (ostemp.str() == L" ")
         {
             ostemp << L"  0";
-            addSpaces(&ostemp2, static_cast<int>(ostemp.str().size()));
-        }
-
-        if (ostemp2.str() == L" ")
-        {
-            // -1 because ostemp2 have already a space
-            addSpaces(&ostemp2, static_cast<int>(ostemp.str().size()) - 1);
         }
 
-        _pListExp->push_back(ostemp2.str());
-        _pListCoef->push_back(ostemp.str());
+        _pListWstPoly->push_back(ostemp.str());
     }
 
     return;