add save(filename) to save all variables in context. 57/16857/3
Antoine ELIAS [Fri, 17 Jul 2015 13:47:17 +0000 (15:47 +0200)]
this function save variables in SCOPE_CONSOLE only ( level == 2 )
I change scope opening @ scilab start to ensure .start of modules and/or toolbox does not clear Scilab stuff.
Now we open 3 scopes @ startup,
SCOPE_GATEWAY(0) : with gateways and main variables ( SCI, TMPDIR, SCIHOME, ...)
SCOPE_MACROS(1)  : with execution of scilab.start ( including {modules}.start and {atoms_toolboxes}.start)
SCOPE_CONSOLE(2) : empty scope at the end of Scilab init phase.

Change-Id: I9c2a339bc87729add539a00a1df6e9f56e3c1481

12 files changed:
scilab/modules/ast/includes/symbol/context.hxx
scilab/modules/ast/includes/symbol/libraries.hxx
scilab/modules/ast/includes/symbol/symbol.hxx
scilab/modules/ast/includes/symbol/variables.hxx
scilab/modules/ast/src/cpp/symbol/context.cpp
scilab/modules/core/src/cpp/InitScilab.cpp
scilab/modules/functions_manager/includes/funcmanager.hxx
scilab/modules/functions_manager/includes/functions_manager.h
scilab/modules/functions_manager/src/cpp/funcmanager.cpp
scilab/modules/functions_manager/src/cpp/functions_manager.cpp
scilab/modules/hdf5/sci_gateway/cpp/sci_hdf5_listvar_v3.cpp
scilab/modules/hdf5/sci_gateway/cpp/sci_hdf5_save.cpp

index d1edf51..aa04cb8 100644 (file)
@@ -67,6 +67,7 @@ public:
     /** If key was associated to some Entry_T in the open scopes, return the
     ** most recent insertion DESPITE the current/last one. Otherwise return the empty pointer. */
     types::InternalType* getAllButCurrentLevel(const Symbol& key);
+    types::InternalType* getAtLevel(const Symbol& key, int level = SCOPE_ALL);
 
     /** If key was associated to some Entry_T in the open scopes, return the
     ** most recent insertion. Otherwise return the empty pointer. */
@@ -75,6 +76,7 @@ public:
     /*return function list in the module _stModuleName*/
     int getFunctionList(std::list<Symbol>& lst, std::wstring _stModuleName);
 
+    int getConsoleVarsName(std::list<std::wstring>& lst);
     int getVarsName(std::list<std::wstring>& lst);
     int getMacrosName(std::list<std::wstring>& lst);
     int getFunctionsName(std::list<std::wstring>& lst);
@@ -149,6 +151,7 @@ private:
     VarStack varStack;
     Variables variables;
     Libraries libraries;
+    VarList* console;
     int m_iLevel;
 
     Context();
index 7978814..5df413c 100644 (file)
@@ -158,7 +158,7 @@ struct Libraries
             }
         }
 
-        return -1;
+        return SCOPE_ALL;
     }
 
     void put(const Symbol& _keyLib, types::Library* _pLib, int _iLevel)
@@ -200,7 +200,7 @@ struct Libraries
         {
             if (lib->second->empty() == false)
             {
-                if (_iLevel == -1 || lib->second->top()->m_iLevel == _iLevel)
+                if (_iLevel == SCOPE_ALL || lib->second->top()->m_iLevel == _iLevel)
                 {
                     return lib->second->top()->m_pLib;
                 }
@@ -214,7 +214,7 @@ struct Libraries
             Library* lib = it->second;
             if (it->second->empty() == false)
             {
-                if (_iLevel == -1 || it->second->top()->m_iLevel == _iLevel)
+                if (_iLevel == SCOPE_ALL || it->second->top()->m_iLevel == _iLevel)
                 {
                     types::MacroFile* pMF = it->second->get(_key);
                     if (pMF)
index 6caf3ed..4f97321 100644 (file)
@@ -31,6 +31,11 @@ extern "C"
 #include "dynlib_ast.h"
 }
 
+#define SCOPE_ALL       -1
+#define SCOPE_GATEWAY   0
+#define SCOPE_MACRO     1
+#define SCOPE_CONSOLE   2
+
 namespace symbol
 {
 
index daca338..b0e4483 100644 (file)
@@ -233,7 +233,7 @@ struct Variables
             return it->second->top()->m_iLevel;
         }
 
-        return -1;
+        return SCOPE_ALL;
     }
 
     void put(const Symbol& _key, types::InternalType* _pIT, int _iLevel)
@@ -247,7 +247,7 @@ struct Variables
         MapVars::const_iterator it = vars.find(_key);
         if (it != vars.end() && it->second->empty() == false)
         {
-            if (_iLevel == -1 || it->second->top()->m_iLevel == _iLevel)
+            if (_iLevel == SCOPE_ALL || it->second->top()->m_iLevel == _iLevel)
             {
                 return it->second->get();
             }
@@ -260,7 +260,7 @@ struct Variables
     {
         if (_var != NULL && _var->empty() == false)
         {
-            if (_iLevel == -1 || _var->top()->m_iLevel == _iLevel)
+            if (_iLevel == SCOPE_ALL || _var->top()->m_iLevel == _iLevel)
             {
                 return _var->get();
             }
index bbb7f02..e2f1a53 100644 (file)
@@ -28,13 +28,13 @@ extern "C"
 
 namespace symbol
 {
-Context* Context::me;
+Context* Context::me = nullptr;
 
 Context::Context()
 {
-    m_iLevel = 0;
-    varStack.push(new VarList());
+    m_iLevel = SCOPE_ALL;
     globals = new std::list<Symbol>();
+    console = nullptr;
 }
 
 Context::~Context()
@@ -54,7 +54,7 @@ Context::~Context()
 
 Context* Context::getInstance(void)
 {
-    if (me == 0)
+    if (me == nullptr)
     {
         me = new Context();
     }
@@ -66,13 +66,22 @@ void Context::destroyInstance(void)
     if (me)
     {
         delete me;
+        me = nullptr;
     }
 }
 
 void Context::scope_begin()
 {
     m_iLevel++;
-    varStack.push(new VarList());
+    if (m_iLevel == SCOPE_CONSOLE)
+    {
+        console = new VarList();
+        varStack.push(console);
+    }
+    else
+    {
+        varStack.push(new VarList());
+    }
 }
 
 void Context::clearAll()
@@ -90,6 +99,11 @@ void Context::scope_end()
     }
 
     m_iLevel--;
+
+    if (m_iLevel < SCOPE_CONSOLE)
+    {
+        console = nullptr;
+    }
 }
 
 bool Context::clearCurrentScope(bool _bClose)
@@ -161,7 +175,7 @@ int Context::getLevel(const Symbol & _key) const
     else
     {
         const int ret = variables.getLevel(_key);
-        if (ret == -1)
+        if (ret == SCOPE_ALL)
         {
             return libraries.getLevel(_key);
         }
@@ -171,12 +185,12 @@ int Context::getLevel(const Symbol & _key) const
         }
     }
 
-    return -1;
+    return SCOPE_ALL;
 }
 
 types::InternalType* Context::get(const Symbol& _key)
 {
-    return get(_key, -1);
+    return get(_key, SCOPE_ALL);
 }
 
 types::InternalType* Context::get(const Variable* _var)
@@ -185,7 +199,7 @@ types::InternalType* Context::get(const Variable* _var)
     if (pIT == NULL)
     {
         //look in libraries
-        pIT = libraries.get(_var->getSymbol(), -1);
+        pIT = libraries.get(_var->getSymbol(), SCOPE_ALL);
         if (pIT && pIT->isLibrary() == false)
         {
             put((Variable*)_var, pIT);
@@ -198,7 +212,7 @@ types::InternalType* Context::get(const Variable* _var)
 types::InternalType* Context::get(const Symbol& _key, int _iLevel)
 {
     types::InternalType* pIT = NULL;
-    if (_iLevel == m_iLevel || _iLevel == -1)
+    if (_iLevel == m_iLevel || _iLevel == SCOPE_ALL)
     {
         //look for in current VarList
         VarList::iterator it = varStack.top()->find(_key);
@@ -238,6 +252,11 @@ types::InternalType* Context::getAllButCurrentLevel(const Symbol& _key)
     return variables.getAllButCurrentLevel(_key, m_iLevel);
 }
 
+types::InternalType* Context::getAtLevel(const Symbol& _key, int level)
+{
+    return variables.getAllButCurrentLevel(_key, level == SCOPE_ALL ? m_iLevel : level + 1);
+}
+
 types::InternalType* Context::getFunction(const Symbol& _key)
 {
     return get(_key);
@@ -248,6 +267,19 @@ int Context::getFunctionList(std::list<Symbol>& lst, std::wstring _stModuleName)
     return variables.getFunctionList(lst, _stModuleName, m_iLevel);
 }
 
+int Context::getConsoleVarsName(std::list<std::wstring>& lst)
+{
+    if (console)
+    {
+        for (const auto& var : *console)
+        {
+            lst.push_back(var.first.getName());
+        }
+    }
+
+    return static_cast<int>(lst.size());
+}
+
 int Context::getVarsName(std::list<std::wstring>& lst)
 {
     variables.getVarsName(lst);
@@ -358,7 +390,7 @@ bool Context::putInPreviousScope(Variable* _var, types::InternalType* _pIT)
 bool Context::addFunction(types::Function *_info)
 {
     Variable* var = variables.getOrCreate(Symbol(_info->getName()));
-    variables.putInPreviousScope(var, _info, 0);
+    variables.putInPreviousScope(var, _info, SCOPE_GATEWAY);
     return true;
 }
 
index b5b7e12..7582d33 100644 (file)
@@ -195,6 +195,9 @@ int StartScilabEngine(ScilabEngineInfo* _pSEI)
     createInnosetupMutex();
 #endif
 
+    //open scope lvl 0 for gateway from modules and first variables ( SCI, HOME, TMPDIR, ...)
+    symbol::Context::getInstance()->scope_begin();
+
     /* Scilab Startup */
     xmlInitParser();
     InitializeEnvironnement();
@@ -243,18 +246,20 @@ int StartScilabEngine(ScilabEngineInfo* _pSEI)
 #endif
     }
 
-    //open "protection" scope to protect all variables after scilab start
-    symbol::Context::getInstance()->scope_begin();
-
+    //load gateways
     LoadModules();
 
+    //open a scope for macros
+    symbol::Context::getInstance()->scope_begin();
     //execute scilab.start
     if (_pSEI->iNoStart == 0)
     {
-        StartModules();
         execScilabStartTask(_pSEI->iSerialize != 0);
     }
 
+    //open console scope
+    symbol::Context::getInstance()->scope_begin();
+
     ConfigVariable::setStartProcessing(false);
     int pause = 0;
 
@@ -351,7 +356,7 @@ void StopScilabEngine(ScilabEngineInfo* _pSEI)
 
     clearScilabPreferences();
 
-    //close "protection" scope
+    //close console scope
     symbol::Context::getInstance()->scope_end();
 
     //execute scilab.quit
@@ -372,6 +377,12 @@ void StopScilabEngine(ScilabEngineInfo* _pSEI)
         EndModules();
     }
 
+    //close macros scope
+    symbol::Context::getInstance()->scope_end();
+
+    //close gateways scope
+    symbol::Context::getInstance()->scope_end();
+
     //clean context
     symbol::Context::getInstance()->clearAll();
     //destroy context
index 1658de7..e93b927 100644 (file)
@@ -60,7 +60,6 @@ public:
 
     bool LoadModules();
     bool UnloadModules();
-    bool StartModules();
     bool EndModules();
 
 private :
index 4c17d1e..31a2c90 100644 (file)
@@ -18,7 +18,6 @@
 
 FUNCMAN_IMEXP void LoadModules();
 FUNCMAN_IMEXP void UnloadModules();
-FUNCMAN_IMEXP void StartModules();
 FUNCMAN_IMEXP void EndModules();
 FUNCMAN_IMEXP void destroyfunctionManagerInstance(void);
 #endif /* !__FUNCMANAGER_H__ */
\ No newline at end of file
index 9bbdfdb..91c33a7 100644 (file)
@@ -421,19 +421,6 @@ bool FuncManager::LoadModules()
     return true;
 }
 
-bool FuncManager::StartModules()
-{
-    list<wstring>::const_iterator it = m_ModuleName.begin();
-    list<wstring>::const_iterator itEnd = m_ModuleName.end();
-    //excute .start file
-    for (; it != itEnd; ++it)
-    {
-        //ExecuteStartFile(*it);
-    }
-
-    return true;
-}
-
 bool FuncManager::EndModules()
 {
     list<wstring>::const_iterator it = m_ModuleName.begin();
index d0515b2..7bebdd2 100644 (file)
@@ -26,15 +26,6 @@ void LoadModules()
     }
 }
 
-void StartModules()
-{
-    FuncManager* pFM = FuncManager::getInstance();
-    if (pFM)
-    {
-        pFM->StartModules();
-    }
-}
-
 void EndModules()
 {
     FuncManager* pFM = FuncManager::getInstance();
index e6c50c7..85c2fb1 100644 (file)
@@ -59,6 +59,7 @@ static bool read_undefined(int dataset, VarInfo6& info);
 static bool read_struct(int dataset, VarInfo6& info);
 static bool read_cell(int dataset, VarInfo6& info);
 static bool read_handles(int dataset, VarInfo6& info);
+static bool read_macro(int dataset, VarInfo6& info);
 
 static void generateInfo(VarInfo6& info);
 static int getDimsNode(int dataset, int* complex, std::vector<int>& dims);
@@ -411,6 +412,12 @@ static bool read_data(int dataset, VarInfo6& info)
         return read_handles(dataset, info);
     }
 
+    if (type == g_SCILAB_CLASS_MACRO)
+    {
+        info.type = sci_c_function;
+        return read_macro(dataset, info);
+    }
+
     Scierror(999, _("%s: Invalid HDF5 Scilab format.\n"), "listvar_in_hdf5");
     return false;
 }
@@ -759,6 +766,7 @@ static bool read_cell(int dataset, VarInfo6& info)
     generateInfo(info);
     return true;
 }
+
 static bool read_handles(int dataset, VarInfo6& info)
 {
     //get cell dimensions
@@ -774,28 +782,23 @@ static bool read_handles(int dataset, VarInfo6& info)
         return true;
     }
 
-    ////open __refs__ node
-    //int refs = getDataSetIdFromName(dataset, "__refs__");
-    //for (int i = 0; i < size; ++i)
-    //{
-    //    int ref = getDataSetIdFromName(refs, std::to_string(i).data());
-    //    VarInfo6 info2;
-    //    if (read_data(ref, info2) == false)
-    //    {
-    //        closeList6(refs);
-    //        closeList6(dataset);
-    //        return false;
-    //    }
+    closeList6(dataset);
 
-    //    info.size += info2.size;
-    //}
+    generateInfo(info);
+    return true;
+}
 
-    //closeList6(refs);
+static bool read_macro(int dataset, VarInfo6& info)
+{
+    info.size = 0;
+    info.dims = 2;
+    info.pdims = {1, 1};
     closeList6(dataset);
-
     generateInfo(info);
     return true;
 }
+
+
 static void generateInfo(VarInfo6& info)
 {
     std::ostringstream ostr;
index 0be60a2..5cea475 100644 (file)
@@ -82,7 +82,7 @@ types::Function::ReturnValue sci_hdf5_save(types::typed_list &in, int _iRetCount
     symbol::Context* ctx = symbol::Context::getInstance();
 
     /* Check the number of input argument */
-    if (in.size() < 2)
+    if (in.size() < 1)
     {
         Scierror(999, _("%s: Wrong number of input argument(s): at least %d expected.\n"), fname.data(), 2);
         return types::Function::Error;
@@ -100,36 +100,68 @@ types::Function::ReturnValue sci_hdf5_save(types::typed_list &in, int _iRetCount
     FREE(wfilename);
     FREE(cfilename);
 
-    for (int i = 1; i < rhs; ++i)
+    if (rhs == 1)
     {
-        if (in[i]->getId() != types::InternalType::IdScalarString)
-        {
-            Scierror(999, _("%s: Wrong type for input argument #%d: A String expected.\n"), fname.data(), 1);
-            return types::Function::Error;
-        }
+        //save environment
+        //get variables in scope 1
+        std::list<std::wstring> lst;
+        int size = ctx->getConsoleVarsName(lst);
 
-        wchar_t* wvar = in[i]->getAs<types::String>()->get()[0];
-        if (wcscmp(wvar, L"-append") == 0)
+        if (size == 0)
         {
-            bAppendMode = true;
-            continue;
+            return types::Function::OK;
         }
 
-        types::InternalType* pIT = ctx->get(symbol::Symbol(wvar));
-        if (pIT == NULL)
+        for (const auto& wvar : lst)
         {
-            Scierror(999, _("%s: Wrong value for input argument #%d: Defined variable expected.\n"), fname.data(), i + 1);
-            return types::Function::Error;
-        }
+            types::InternalType* pIT = ctx->getAtLevel(symbol::Symbol(wvar), SCOPE_CONSOLE);
 
-        char* cvar = wide_string_to_UTF8(wvar);
-        std::string var(cvar);
-        FREE(cvar);
+            //do not save macrofile
+            if (pIT->isMacroFile() || pIT->isFunction() || pIT->isLibrary())
+            {
+                continue;
+            }
 
-        //check var exists
-        vars[var] = pIT;
+            char* cvar = wide_string_to_UTF8(wvar.data());
+            std::string var(cvar);
+            FREE(cvar);
+
+            //check var exists
+            vars[var] = pIT;
+        }
     }
+    else
+    {
+        for (int i = 1; i < rhs; ++i)
+        {
+            if (in[i]->getId() != types::InternalType::IdScalarString)
+            {
+                Scierror(999, _("%s: Wrong type for input argument #%d: A String expected.\n"), fname.data(), 1);
+                return types::Function::Error;
+            }
 
+            wchar_t* wvar = in[i]->getAs<types::String>()->get()[0];
+            if (wcscmp(wvar, L"-append") == 0)
+            {
+                bAppendMode = true;
+                continue;
+            }
+
+            types::InternalType* pIT = ctx->get(symbol::Symbol(wvar));
+            if (pIT == NULL)
+            {
+                Scierror(999, _("%s: Wrong value for input argument #%d: Defined variable expected.\n"), fname.data(), i + 1);
+                return types::Function::Error;
+            }
+
+            char* cvar = wide_string_to_UTF8(wvar);
+            std::string var(cvar);
+            FREE(cvar);
+
+            //check var exists
+            vars[var] = pIT;
+        }
+    }
     //check append option
     if (bAppendMode)
     {
@@ -930,4 +962,4 @@ static int export_usertype(int parent, const std::string& name, types::UserType*
     it->DecreaseRef();
 
     return ret;
-}
\ No newline at end of file
+}