2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2015 - Scilab Enterprises - Antoine ELIAS
5 * Copyright (C) 2012 - 2016 - Scilab Enterprises
7 * This file is hereby licensed under the terms of the GNU GPL v2.0,
8 * pursuant to article 5.3.4 of the CeCILL v.2.1.
9 * This file was originally licensed under the terms of the CeCILL v2.1,
10 * and continues to be available under such terms.
11 * For more information, see the COPYING file which you should have received
12 * along with this program.
17 #include "variables.hxx"
18 #include "configvariable.hxx"
20 #include "macrofile.hxx"
21 #include "types_tools.hxx"
34 ScopedVariable * pSV = top();
35 types::InternalType * pIT = pSV->m_pIT;
44 m_GlobalValue->DecreaseRef();
45 m_GlobalValue->killMe();
49 void Variable::setGlobalValue(types::InternalType* _pIT)
51 if (m_GlobalValue != _pIT)
55 m_GlobalValue->DecreaseRef();
56 m_GlobalValue->killMe();
67 void Variable::setGlobalVisible(int _iLevel, bool _bVisible)
69 if (empty() || top()->m_iLevel != _iLevel)
71 last = new ScopedVariable(_iLevel, types::Double::Empty());
75 top()->m_globalVisible = _bVisible;
79 bool Variable::put(types::InternalType* _pIT, int _iLevel)
81 if (isGlobal() && isGlobalVisible(_iLevel))
87 if (empty() || top()->m_iLevel < _iLevel)
90 last = new ScopedVariable(_iLevel, _pIT);
96 //update current level
97 types::InternalType* pIT = top()->m_pIT;
100 //check macro redefinition
103 int iFuncProt = ConfigVariable::getFuncprot();
107 if (pIT && pIT->isCallable())
109 if (pIT->isMacroFile())
111 types::MacroFile* pMF = pIT->getAs<types::MacroFile>();
112 bEquals = *pMF->getMacro() == *_pIT;
114 else if (pIT->isMacro())
116 types::Macro* pM = pIT->getAs<types::Macro>();
117 bEquals = *pM == *_pIT;
121 if (bEquals == false)
128 if (ConfigVariable::getWarningMode())
130 wchar_t pwstFuncName[1024];
131 os_swprintf(pwstFuncName, 1024, L"%-24ls", name.getName().c_str());
132 char* pstFuncName = wide_string_to_UTF8(pwstFuncName);
134 sciprint(_("Warning : redefining function: %s. Use funcprot(0) to avoid this message"), pstFuncName);
142 // _pIT may contained in pIT
143 // so increases ref of _pIT before kill pIT
157 Variable* Variables::getOrCreate(const Symbol& _key)
159 MapVars::const_iterator it = vars.find(_key);
160 if (it == vars.end())
162 //create an empty StackedValues
163 Variable* var = new Variable(_key);
171 int Variables::getLevel(const Symbol& _key) const
173 MapVars::const_iterator it = vars.find(_key);
174 if (it != vars.end() && !it->second->empty())
176 return it->second->top()->m_iLevel;
182 void Variables::put(const Symbol& _key, types::InternalType* _pIT, int _iLevel)
184 Variable* var = getOrCreate(_key);
185 var->put(_pIT, _iLevel);
188 types::InternalType* Variables::get(const Symbol& _key, int _iLevel)
190 MapVars::const_iterator it = vars.find(_key);
191 if (it != vars.end() && it->second->empty() == false)
193 if (_iLevel == SCOPE_ALL || it->second->top()->m_iLevel == _iLevel)
195 return it->second->get();
202 types::InternalType* Variables::get(Variable* _var, int _iLevel)
204 if (_var != NULL && _var->empty() == false)
206 if (_iLevel == SCOPE_ALL || _var->top()->m_iLevel == _iLevel)
215 types::InternalType* Variables::getAllButCurrentLevel(const Symbol& _key, int _iLevel)
217 MapVars::const_iterator it = vars.find(_key);
218 if (it != vars.end() && it->second->empty() == false)
220 if (it->second->top()->m_iLevel < _iLevel)
222 return it->second->get();
226 ScopedVariable* pSave = it->second->top();
228 types::InternalType* pIT = getAllButCurrentLevel(_key, _iLevel);
229 it->second->put(pSave);
237 bool Variables::remove(Variable* _var, int _iLevel)
239 if (_var->empty() == false)
241 if (_var->top()->m_iLevel == _iLevel)
243 ScopedVariable* pSave = _var->top();
244 types::InternalType* pIT = pSave->m_pIT;
256 bool Variables::remove(const Symbol& _key, int _iLevel)
258 MapVars::iterator it = vars.find(_key);
259 if (it != vars.end())
261 Variable* pVar = it->second;
262 return remove(pVar, _iLevel);
268 int Variables::getMacrosName(std::list<std::wstring>& lst)
272 if (it.second->empty() == false)
274 types::InternalType* pIT = it.second->top()->m_pIT;
275 if (pIT && (pIT->isMacro() || pIT->isMacroFile()))
277 lst.push_back(it.first.getName().c_str());
282 return static_cast<int>(lst.size());
285 int Variables::getVarsName(std::list<std::wstring>& lst)
289 if (it.second->empty() == false)
291 types::InternalType* pIT = it.second->top()->m_pIT;
293 pIT->isMacro() == false &&
294 pIT->isMacroFile() == false &&
295 pIT->isFunction() == false)
297 lst.push_back(it.first.getName().c_str());
302 return static_cast<int>(lst.size());
305 bool Variables::getVarsInfoForWho(std::list<std::pair<std::wstring, int>>& lstVar, int* iVarLenMax, bool bSorted) const
309 if (it.second->empty() == false)
311 types::InternalType* pIT = it.second->top()->m_pIT;
312 if (pIT && pIT->isFunction() == false)
314 std::wstring wstrVarName(it.first.getName().c_str());
315 *iVarLenMax = std::max(*iVarLenMax, (int)wstrVarName.size());
316 long long iSize, iSizePlusType;
317 if (pIT->getMemory(&iSize, &iSizePlusType))
319 lstVar.emplace_back(wstrVarName, iSizePlusType);
333 bool Variables::getGlobalInfoForWho(std::list<std::pair<std::wstring, int>>& lstVar, int* iVarLenMax, bool bSorted) const
337 if (it.second->isGlobal())
339 std::wstring wstrVarName(it.first.getName().c_str());
340 *iVarLenMax = std::max(*iVarLenMax, (int)wstrVarName.size());
341 long long iSize, iSizePlusType;
342 types::InternalType* pIT = it.second->empty() ? it.second->getGlobalValue() : it.second->top()->m_pIT;
343 if (pIT->getMemory(&iSize, &iSizePlusType))
345 lstVar.emplace_back(wstrVarName, iSizePlusType);
358 int Variables::getProtectedVarsName(std::list<std::wstring>& lstVarName) const
362 if (it.second->empty() == false)
364 ScopedVariable* pSV = it.second->top();
365 if (pSV->protect && it.first.getName() != L"ans")
367 lstVarName.push_back(it.first.getName());
372 return static_cast<int>(lstVarName.size());
375 int Variables::getFunctionsName(std::list<std::wstring>& lst)
379 if (it.second->empty() == false)
381 types::InternalType* pIT = it.second->top()->m_pIT;
382 if (pIT && pIT->isFunction())
384 lst.push_back(it.first.getName().c_str());
389 return static_cast<int>(lst.size());
392 int Variables::getFunctionList(std::list<Symbol>& lst, std::wstring _stModuleName, int _iLevel)
394 for (auto var : vars)
396 if (var.second->empty())
401 if ((var.second->top()->m_iLevel == _iLevel || _iLevel == 1) && var.second->top()->m_pIT->isCallable())
403 types::Callable* pCall = var.second->top()->m_pIT->getAs<types::Callable>();
404 if (_stModuleName == L"" || _stModuleName == pCall->getModule())
406 lst.push_back(var.first);
411 return static_cast<int>(lst.size());
414 int Variables::getFunctionList(std::list<types::Callable *>& lst, std::wstring _stModuleName, int _iLevel)
416 for (auto var : vars)
418 if (var.second->empty())
423 if ((var.second->top()->m_iLevel == _iLevel || _iLevel == 1) && var.second->top()->m_pIT->isCallable())
425 types::Callable * pCall = var.second->top()->m_pIT->getAs<types::Callable>();
426 if (_stModuleName == L"" || _stModuleName == pCall->getModule())
428 lst.push_back(pCall);
433 return static_cast<int>(lst.size());
436 int Variables::getVarsToVariableBrowser(std::list<Variable*>& lst)
438 for (auto var : vars)
440 if (var.second->empty() == false)
442 types::InternalType* pIT = var.second->top()->m_pIT;
443 if (pIT && pIT->isMacroFile() == false &&
444 pIT->isFunction() == false)
446 lst.push_back(var.second);
451 return static_cast<int>(lst.size());
454 int Variables::getCurrentScope(std::list<std::pair<std::wstring, int>>& lst, int level, bool sorted)
456 for (auto var : vars)
458 if (var.second->empty() == false)
460 if (var.second->top()->m_iLevel == level)
462 std::wstring wstrVarName(var.first.getName());
463 long long iSize, iSizePlusType;
465 types::InternalType* pIT = var.second->top()->m_pIT;
466 if (pIT->getMemory(&iSize, &iSizePlusType))
468 lst.emplace_back(wstrVarName, iSizePlusType);
479 return static_cast<int>(lst.size());
482 bool Variables::putInPreviousScope(Variable* _var, types::InternalType* _pIT, int _iLevel)
486 return _var->put(_pIT, _iLevel);
488 else if (_var->top()->m_iLevel > _iLevel)
490 ScopedVariable* pVar = _var->top();
492 if (putInPreviousScope(_var, _pIT, _iLevel) == false)
496 //decresef ref before, increase it in put
497 //pVar->m_pIT->DecreaseRef();
498 return _var->put(pVar);
502 if (_var->top()->protect == false)
504 return _var->put(_pIT, _iLevel);
513 void Variables::setGlobal(const Symbol& _key)
515 getOrCreate(_key)->setGlobal(true);
518 void Variables::setGlobalVisible(const Symbol& _key, bool _bVisible, int _iLevel)
520 Variable* pVar = getOrCreate(_key);
521 pVar->setGlobalVisible(_iLevel, _bVisible);
524 pVar->setGlobal(true);
528 bool Variables::isGlobalVisible(const Symbol& _key, int _iLevel)
530 return getOrCreate(_key)->isGlobalVisible(_iLevel);
533 bool Variables::isGlobal(const Symbol& _key, int /*_iLevel*/)
535 return getOrCreate(_key)->isGlobal();
538 types::InternalType* Variables::getGlobalValue(const Symbol& _key)
540 return getOrCreate(_key)->getGlobalValue();
543 void Variables::removeGlobal(const Symbol& _key, int _iLevel)
545 Variable* pVar = getOrCreate(_key);
546 if (pVar->isGlobal())
548 pVar->setGlobal(false);
549 pVar->setGlobalValue(NULL);
552 remove(pVar, _iLevel);
555 void Variables::clearAll()
557 for (auto var : vars)