who 40/15440/5
Cedric Delamarre [Wed, 29 Oct 2014 15:24:59 +0000 (16:24 +0100)]
Change-Id: I24fe1039637e62916819234727a698d6159a0cde

scilab/modules/ast/includes/symbol/context.hxx
scilab/modules/ast/includes/symbol/libraries.hxx
scilab/modules/ast/includes/symbol/variables.hxx
scilab/modules/ast/src/cpp/symbol/context.cpp
scilab/modules/core/sci_gateway/cpp/sci_who.cpp

index b0f5bcf..b328684 100644 (file)
@@ -77,6 +77,8 @@ public :
     std::list<std::wstring>* getVarsName();
     std::list<std::wstring>* getMacrosName();
     std::list<std::wstring>* getFunctionsName();
+    std::list<std::wstring>* getVarsNameForWho(bool sorted);
+    std::list<std::wstring>* getGlobalNameForWho(bool sorted);
 
     /* global functions */
 
@@ -117,7 +119,7 @@ public :
     bool addFunction(types::Function *_info);
     bool addMacro(types::Macro *_info);
     bool addMacroFile(types::MacroFile *_info);
-    void print(std::wostream& ostr) const;
+    void print(std::wostream& ostr, bool bSorted = false) const;
     int getScopeLevel();
 
 private :
index 0e1fd47..9647bfd 100644 (file)
@@ -37,7 +37,7 @@ struct Library
 {
     typedef std::stack<ScopedLibrary*> StackLib;
 
-    Library(const Symbol& _name) : name(_name) {};
+    Library(const Symbol& _name) : name(_name), m_global(false) {};
 
     void put(types::Library* _pLib, int _iLevel)
     {
@@ -130,9 +130,24 @@ struct Libraries
 
     types::InternalType* get(const Symbol& _key, int _iLevel)
     {
-        MapLibs::reverse_iterator it = libs.rbegin();
-        for (; it != libs.rend() ; ++it)
+        //does _key is a lib name
+        auto lib = libs.find(_key);
+        if (lib != libs.end())
         {
+            if (lib->second->empty() == false)
+            {
+                if (_iLevel == -1 || lib->second->top()->m_iLevel == _iLevel)
+                {
+                    return lib->second->top()->m_pLib;
+                }
+            }
+        }
+
+        //does _key is a macro in a lib
+        auto it = libs.rbegin();
+        for (auto it = libs.rbegin(), itEnd = libs.rend(); it != itEnd ; ++it)
+        {
+            Library* lib = it->second;
             if (it->second->empty() == false)
             {
                 if (_iLevel == -1 || it->second->top()->m_iLevel == _iLevel)
@@ -187,6 +202,20 @@ struct Libraries
         return names;
     }
 
+    std::list<std::wstring>* getVarsName()
+    {
+        std::list<std::wstring>* plOut = new std::list<std::wstring>();
+        for (auto it = libs.begin(), itEnd = libs.end(); it != itEnd; ++it)
+        {
+            if (it->second->empty() == false)
+            {
+                plOut->push_back(it->first.getName().c_str());
+            }
+        }
+
+        return plOut;
+    }
+
     void clearAll()
     {
         for (MapLibs::iterator it = libs.begin(); it != libs.end() ; ++it)
@@ -205,6 +234,30 @@ struct Libraries
         }
     }
 
+    bool getVarsNameForWho(std::list<std::wstring>* lstVarName, int* iVarLenMax, bool bSorted = false) const
+    {
+        for (auto it = libs.begin(), itEnd = libs.end(); it != itEnd; ++it)
+        {
+            std::wstring wstrVarName(it->first.getName().c_str());
+            if (lstVarName && it->second->empty() == false)
+            {
+                lstVarName->push_back(wstrVarName);
+                *iVarLenMax = std::max(*iVarLenMax, (int)wstrVarName.size());
+            }
+        }
+
+        if (bSorted)
+        {
+            if (lstVarName)
+            {
+                lstVarName->sort();
+            }
+        }
+
+        return true;
+    }
+
+
 private:
     MapLibs libs;
 };
index 96e7c9f..d9e776b 100644 (file)
@@ -335,6 +335,44 @@ struct Variables
         return plOut;
     }
 
+    bool getVarsNameForWho(std::list<std::wstring>* lstVarName, int* iVarLenMax, std::list<std::wstring>* lstGlobalVarName, int* iGlobalLenMax, bool bSorted = false) const
+    {
+        for (auto it = vars.begin(), itEnd = vars.end(); it != itEnd; ++it)
+        {
+            std::wstring wstrVarName(it->first.getName().c_str());
+            if (lstVarName && it->second->empty() == false)
+            {
+                types::InternalType* pIT = it->second->top()->m_pIT;
+                if (pIT && pIT->isFunction() == false)
+                {
+                    lstVarName->push_back(wstrVarName);
+                    *iVarLenMax = std::max(*iVarLenMax, (int)wstrVarName.size());
+                }
+            }
+
+            if (lstGlobalVarName && it->second->isGlobal())
+            {
+                lstGlobalVarName->push_back(wstrVarName);
+                *iGlobalLenMax = std::max(*iGlobalLenMax, (int)wstrVarName.size());
+            }
+        }
+
+        if (bSorted)
+        {
+            if (lstVarName)
+            {
+                lstVarName->sort();
+            }
+
+            if (lstGlobalVarName)
+            {
+                lstGlobalVarName->sort();
+            }
+        }
+
+        return true;
+    }
+
     std::list<std::wstring>* getFunctionsName()
     {
         std::list<std::wstring>* plOut = new std::list<std::wstring>();
index 5f70ba1..f971f85 100644 (file)
@@ -9,12 +9,21 @@
 *  http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
 *
 */
+#include <iomanip>
+
 #include "context.hxx"
 #include "internal.hxx"
 #include "function.hxx"
 #include "macro.hxx"
 #include "macrofile.hxx"
 #include "variables.hxx"
+#include "configvariable.hxx"
+
+extern "C"
+{
+#include "getmemory.h"
+#include "os_swprintf.h"
+}
 
 namespace symbol
 {
@@ -128,15 +137,10 @@ types::InternalType* Context::get(const Symbol& _key)
 types::InternalType* Context::get(const Variable* _var)
 {
     types::InternalType* pIT = _var->get();
-
     if (pIT == NULL)
     {
         //look in libraries
         pIT = libraries.get(_var->getSymbol(), -1);
-        if (pIT)
-        {
-            put((Variable*)_var, pIT);
-        }
     }
 
     return pIT;
@@ -165,11 +169,6 @@ types::InternalType* Context::get(const Symbol& _key, int _iLevel)
         {
             //find in libraries
             pIT = libraries.get(_key, _iLevel);
-            if (pIT)
-            {
-                //add symbol to current scope
-                put(_key, pIT);
-            }
         }
     }
 
@@ -198,7 +197,11 @@ std::list<Symbol>* Context::getFunctionList(std::wstring _stModuleName)
 
 std::list<std::wstring>* Context::getVarsName()
 {
-    return variables.getVarsName();
+    std::list<std::wstring>* vars = variables.getVarsName();
+    std::list<std::wstring>* libs = libraries.getVarsName();
+    vars->insert(vars->end(), libs->begin(), libs->end());
+    delete libs;
+    return vars;
 }
 
 std::list<std::wstring>* Context::getMacrosName()
@@ -215,6 +218,22 @@ std::list<std::wstring>* Context::getFunctionsName()
     return variables.getFunctionsName();
 }
 
+std::list<std::wstring>* Context::getVarsNameForWho(bool bSorted)
+{
+    std::list<std::wstring>* lstVar = new std::list<std::wstring>();
+    int iZero = 0;
+    variables.getVarsNameForWho(lstVar, &iZero, NULL, &iZero, bSorted);
+    return lstVar;
+}
+
+std::list<std::wstring>* Context::getGlobalNameForWho(bool bSorted)
+{
+    std::list<std::wstring>* lstVar = new std::list<std::wstring>();
+    int iZero = 0;
+    variables.getVarsNameForWho(NULL, &iZero, lstVar, &iZero, bSorted);
+    return lstVar;
+}
+
 void Context::put(Variable* _var, types::InternalType* _pIT)
 {
     _var->put(_pIT, m_iLevel);
@@ -334,10 +353,79 @@ void Context::removeGlobalAll()
     globals->clear();
 }
 
-void Context::print(std::wostream& ostr) const
+void Context::print(std::wostream& ostr, bool sorted) const
 {
-    ostr << L"  Environment Variables:" << std::endl;
-    ostr << L"==========================" << std::endl;
+    std::list<std::wstring> lstVar;
+    std::list<std::wstring> lstGlobal;
+    int iVarLenMax = 10; // initialise to the minimal value of padding
+    int iGlobalLenMax = 10; // initialise to the minimal value of padding
+    variables.getVarsNameForWho(&lstVar, &iVarLenMax, &lstGlobal, &iGlobalLenMax);
+    libraries.getVarsNameForWho(&lstVar, &iVarLenMax);
+
+    if (sorted)
+    {
+        lstVar.sort();
+        lstGlobal.sort();
+    }
+
+#define strSize 64
+    wchar_t wcsVarElem[strSize];
+    wchar_t wcsVarVariable[strSize];
+    wchar_t wcsGlobalElem[strSize];
+    wchar_t wcsGlobalVariable[strSize];
+
+    int iMemTotal = 0;
+    int iMemUsed  = 0;
+    int nbMaxVar  = 0;
+
+#ifdef _MSC_VER
+    MEMORYSTATUSEX statex;
+    statex.dwLength = sizeof(statex);
+    GlobalMemoryStatusEx (&statex);
+    iMemTotal = (int)(statex.ullTotalPhys / (1024 * 1024));
+#else
+    iMemTotal = getmemorysize();
+#endif
+
+    ostr << _W("Your variables are:") << std::endl << std::endl;
+    std::list<std::wstring>::const_iterator it = lstVar.begin();
+    int iWidth = ConfigVariable::getConsoleWidth();
+    int iCurrentWidth = 0;
+    for (int i = 1; it != lstVar.end(); ++it, i++)
+    {
+        if (iCurrentWidth + iVarLenMax + 1 > iWidth)
+        {
+            ostr << std::endl;
+            iCurrentWidth = 0;
+        }
+        ostr << std::setw(iVarLenMax + 1) << *it;
+        iCurrentWidth += iVarLenMax + 1;
+    }
+
+    os_swprintf(wcsVarElem, strSize, _W(" using %10d elements out of  %10d.\n").c_str(), iMemUsed, iMemTotal);
+    ostr << std::endl << wcsVarElem;
+
+    os_swprintf(wcsVarVariable, strSize, _W(" and   %10d variables out of %10d.\n").c_str(), lstVar.size(), nbMaxVar);
+    ostr << wcsVarVariable << std::endl;
+
+    ostr << std::endl << _W("Your global variables are:") << std::endl << std::endl;
+    it = lstGlobal.begin();
+    for (int i = 1; it != lstGlobal.end(); ++it, i++)
+    {
+        ostr << std::setw(iGlobalLenMax + 1) << *it;
+        if (i % 4 == 0)
+        {
+            ostr << std::endl;
+        }
+    }
+
+    ostr << std::endl;
+
+    os_swprintf(wcsGlobalElem, strSize, _W(" using %10d elements out of  %10d.\n").c_str(), iMemUsed, iMemTotal);
+    ostr << std::endl << wcsGlobalElem;
+
+    os_swprintf(wcsGlobalVariable, strSize, _W(" and   %10d variables out of %10d.\n").c_str(), lstGlobal.size(), nbMaxVar);
+    ostr << wcsGlobalVariable;
 }
 
 int Context::getScopeLevel()
index 34a4845..55dc1ff 100644 (file)
@@ -1,6 +1,7 @@
 /*
  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
  *  Copyright (C) 2011-2011 - DIGITEO - Bruno JOFRET
+ *  Copyright (C) 2014 - Scilab Enterprises - 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
 #include "function.hxx"
 #include "context.hxx"
 #include "scilabWrite.hxx"
+#include "string.hxx"
 
-using namespace types;
+extern "C"
+{
+#include "Scierror.h"
+#include "localization.h"
+}
 
-Function::ReturnValue sci_who(typed_list& in, int iRetCount, typed_list& out)
+types::Function::ReturnValue sci_who(types::typed_list& in, int _iRetCount, types::typed_list& out)
 {
-    std::wstringstream wstream;
-    wstream << *(symbol::Context::getInstance()) << std::endl;
+    wchar_t* wcsWhat = L"";
+    bool bSorted = false;
+    types::String* pStrOut = NULL;
+    types::Double* pDblOut = NULL;
+    std::list<std::wstring>* lstVar = NULL;
+
+    if (in.size() < 0 || in.size() > 2)
+    {
+        Scierror(77, _("%s: Wrong number of input argument(s): %d to %d expected.\n"), "who", 0, 2);
+        return types::Function::Error;
+    }
+
+    if (_iRetCount > 2)
+    {
+        Scierror(78, _("%s: Wrong number of output argument(s): %d to %d expected.\n"), "who", 0, 2);
+        return types::Function::Error;
+    }
+
+    if (in.size() == 0)
+    {
+        std::wstringstream wstream;
+        symbol::Context::getInstance()->print(wstream, bSorted);
+        wstream << std::endl;
+        scilabForcedWriteW(wstream.str().c_str());
+        return types::Function::OK;
+    }
+
+    if (in.size() == 2)
+    {
+        if (in[1]->isString() == false)
+        {
+            Scierror(999, _("%s: Wrong type for input argument #%d: A string expected.\n"), "who", 2);
+            return types::Function::Error;
+        }
+
+        types::String* pStrSorted = in[1]->getAs<types::String>();
+
+        if (pStrSorted->isScalar() == false)
+        {
+            Scierror(999, _("%s: Wrong type for input argument #%d: A single string expected.\n"), "who", 2);
+            return types::Function::Error;
+        }
+
+        if (wcscmp(pStrSorted->get(0), L"sorted") == 0)
+        {
+            bSorted = true;
+        }
+        else
+        {
+            Scierror(999, _("%s: Wrong value for input argument #%d: 'sorted' expected.\n"), "who", 2);
+            return types::Function::Error;
+        }
+    }
+
+    if (in.size() > 0)
+    {
+        if (in[0]->isString() == false)
+        {
+            Scierror(999, _("%s: Wrong type for input argument #%d: A string expected.\n"), "who", 1);
+            return types::Function::Error;
+        }
+
+        types::String* pStrWhat = in[0]->getAs<types::String>();
+
+        if (pStrWhat->isScalar() == false)
+        {
+            Scierror(999, _("%s: Wrong type for input argument #%d: A single string expected.\n"), "who", 1);
+            return types::Function::Error;
+        }
+
+        wcsWhat = pStrWhat->get(0);
+    }
+
+    if (wcscmp(wcsWhat, L"local") == 0 || wcscmp(wcsWhat, L"get") == 0)
+    {
+        lstVar = symbol::Context::getInstance()->getVarsNameForWho(bSorted);
+    }
+    else if (wcscmp(wcsWhat, L"global") == 0)
+    {
+        lstVar = symbol::Context::getInstance()->getGlobalNameForWho(bSorted);
+    }
+    else if (bSorted == false && wcscmp(wcsWhat, L"sorted") == 0)
+    {
+        bSorted = true;
+        std::wstringstream wstream;
+        symbol::Context::getInstance()->print(wstream, bSorted);
+        wstream << std::endl;
+        scilabForcedWriteW(wstream.str().c_str());
+        return types::Function::OK;
+    }
+    else
+    {
+        if (bSorted)
+        {
+            Scierror(999, _("%s: Wrong value for input argument #%d: 'local', 'get' or 'global' expected.\n"), "who", 1);
+        }
+        else
+        {
+            Scierror(999, _("%s: Wrong value for input argument #%d: 'local', 'get', 'global' or 'sorted' expected.\n"), "who", 1);
+        }
+
+        return types::Function::Error;
+    }
+
+    if (lstVar->empty())
+    {
+        out.push_back(types::Double::Empty());
+        if (_iRetCount == 2)
+        {
+            out.push_back(types::Double::Empty());
+        }
+
+        delete lstVar;
+        return types::Function::OK;
+    }
+
+    pStrOut = new types::String(lstVar->size(), 1);
+    std::list<std::wstring>::const_iterator it = lstVar->begin();
+    for (int i = 0; it != lstVar->end(); ++it, i++)
+    {
+        pStrOut->set(i, (*it).c_str());
+    }
+
+    delete lstVar;
+    out.push_back(pStrOut);
 
-    scilabForcedWriteW(wstream.str().c_str());
+    if (_iRetCount == 2)
+    {
+        pDblOut = new types::Double(pStrOut->getDims(), pStrOut->getDimsArray());
+        memset(pDblOut->get(), 0x00, pDblOut->getSize() * sizeof(double));
+        out.push_back(pDblOut);
+    }
 
-    return Function::OK;
+    return types::Function::OK;
 }