2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2008-2008 - DIGITEO - Antoine ELIAS
5 * This file must be used under the terms of the CeCILL.
6 * This source file is licensed as described in the file COPYING, which
7 * you should have received as part of this distribution. The terms
8 * are also available at
9 * http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
15 #include "context.hxx"
16 #include "internal.hxx"
17 #include "function.hxx"
19 #include "macrofile.hxx"
20 #include "variables.hxx"
21 #include "configvariable.hxx"
25 #include "getmemory.h"
26 #include "os_string.h"
36 varStack.push(new VarList());
37 globals = new std::list<Symbol>();
42 while (!varStack.empty())
44 VarList * pVL = varStack.top();
55 Context* Context::getInstance(void)
64 void Context::destroyInstance(void)
72 void Context::scope_begin()
75 varStack.push(new VarList());
78 void Context::clearAll()
84 void Context::scope_end()
86 //clear varList of current scope
87 if (varStack.empty() == false)
89 clearCurrentScope(true);
95 bool Context::clearCurrentScope(bool _bClose)
102 VarList* varList = varStack.top();
103 std::list<Symbol> toremove;
104 for (auto var : *varList)
106 if (var.second->empty() == false)
108 ScopedVariable* pSV = var.second->top();
109 if (pSV->m_iLevel == m_iLevel && (_bClose || pSV->protect == false))
111 types::InternalType * pIT = pSV->m_pIT;
112 if (pIT->isLibrary())
114 libraries.remove(var.first, m_iLevel);
124 toremove.push_back(var.first);
136 for (auto var : toremove)
144 Variable* Context::getOrCreate(const Symbol& _key)
146 return variables.getOrCreate(_key);
149 types::InternalType* Context::get(const Symbol& _key)
151 return get(_key, -1);
154 types::InternalType* Context::get(const Variable* _var)
156 types::InternalType* pIT = _var->get();
160 pIT = libraries.get(_var->getSymbol(), -1);
161 if (pIT && pIT->isLibrary() == false)
163 put((Variable*)_var, pIT);
170 types::InternalType* Context::get(const Symbol& _key, int _iLevel)
172 types::InternalType* pIT = NULL;
173 if (_iLevel == m_iLevel || _iLevel == -1)
175 //look for in current VarList
176 VarList::iterator it = varStack.top()->find(_key);
177 if (it != varStack.top()->end())
179 if (it->second->empty() == false)
181 pIT = it->second->get();
188 pIT = variables.get(_key, _iLevel);
192 pIT = libraries.get(_key, _iLevel);
198 types::InternalType* Context::getCurrentLevel(const Symbol& _key)
200 return variables.get(_key, m_iLevel);
203 types::InternalType* Context::getCurrentLevel(Variable* _var)
205 return variables.get(_var, m_iLevel);
208 types::InternalType* Context::getAllButCurrentLevel(const Symbol& _key)
210 return variables.getAllButCurrentLevel(_key, m_iLevel);
213 types::InternalType* Context::getFunction(const Symbol& _key)
218 int Context::getFunctionList(std::list<Symbol>& lst, std::wstring _stModuleName)
220 return variables.getFunctionList(lst, _stModuleName, m_iLevel);
223 int Context::getVarsName(std::list<std::wstring>& lst)
225 variables.getVarsName(lst);
226 libraries.getVarsName(lst);
228 return static_cast<int>(lst.size());
231 int Context::getMacrosName(std::list<std::wstring>& lst)
233 variables.getMacrosName(lst);
234 libraries.getMacrosName(lst);
235 return static_cast<int>(lst.size());
238 int Context::getFunctionsName(std::list<std::wstring>& lst)
240 return variables.getFunctionsName(lst);
243 int Context::getVarsNameForWho(std::list<std::wstring>& lst, bool bSorted)
246 variables.getVarsNameForWho(lst, &iZero, bSorted);
247 return static_cast<int>(lst.size());
250 int Context::getGlobalNameForWho(std::list<std::wstring>& lst, bool bSorted)
253 variables.getGlobalNameForWho(lst, &iZero, bSorted);
254 return static_cast<int>(lst.size());
257 int Context::getWhereIs(std::list<std::wstring>& lst, const std::wstring& _str)
259 return libraries.whereis(lst, Symbol(_str));
262 int Context::getLibrariesList(std::list<std::wstring>& lst)
264 return libraries.librarieslist(lst);
267 void Context::put(Variable* _var, types::InternalType* _pIT)
269 if (_pIT->isLibrary())
271 Library* lib = libraries.getOrCreate(_var->getSymbol());
272 lib->put((types::Library*)_pIT, m_iLevel);
275 _var->put(_pIT, m_iLevel);
276 if (varStack.empty() == false)
278 (*varStack.top())[_var->getSymbol()] = _var;
282 void Context::put(const Symbol& _key, types::InternalType* _pIT)
284 Variable* var = variables.getOrCreate(_key);
288 bool Context::remove(const Symbol& _key)
290 bool ret = variables.remove(_key, m_iLevel);
294 varStack.top()->erase(_key);
297 ret = ret | libraries.remove(_key, m_iLevel);
301 bool Context::removeAll()
303 return clearCurrentScope(false);
306 bool Context::putInPreviousScope(Variable* _var, types::InternalType* _pIT)
308 //add variable in previous scope
309 variables.putInPreviousScope(_var, _pIT, m_iLevel - 1);
311 //add variable in stack of using variables
312 if (varStack.empty() == false)
314 VarList * list = varStack.top();
316 if (varStack.empty() == false)
318 (*varStack.top())[_var->getSymbol()] = _var;
325 bool Context::addFunction(types::Function *_info)
327 Variable* var = variables.getOrCreate(Symbol(_info->getName()));
328 variables.putInPreviousScope(var, _info, 0);
332 bool Context::addMacro(types::Macro *_info)
334 put(Symbol(_info->getName()), _info);
338 bool Context::addMacroFile(types::MacroFile *_info)
340 put(Symbol(_info->getName()), _info);
344 bool Context::isGlobalVisible(const Symbol& _key)
346 return variables.isGlobalVisible(_key, m_iLevel);
349 /*return global variable existance status*/
350 bool Context::isGlobal(const Symbol& _key)
352 return variables.isGlobal(_key, m_iLevel);
355 types::InternalType* Context::getGlobalValue(const Symbol& _key)
357 return variables.getGlobalValue(_key);
360 void Context::setGlobalVisible(const Symbol& _key, bool bVisible)
362 variables.setGlobalVisible(_key, bVisible, m_iLevel);
365 void Context::setGlobal(const Symbol& _key)
367 variables.setGlobal(_key);
368 globals->push_back(_key);
371 void Context::removeGlobal(const Symbol& _key)
373 variables.removeGlobal(_key, m_iLevel);
374 globals->remove(_key);
377 void Context::removeGlobalAll()
379 std::list<Symbol>::iterator it = globals->begin();
380 while (it != globals->end())
383 it = globals->begin();
389 void Context::print(std::wostream& ostr, bool sorted) const
391 std::list<std::wstring> lstVar;
392 std::list<std::wstring> lstGlobal;
393 int iVarLenMax = 10; // initialise to the minimal value of padding
394 int iGlobalLenMax = 10; // initialise to the minimal value of padding
395 variables.getVarsNameForWho(lstVar, &iVarLenMax);
396 variables.getGlobalNameForWho(lstGlobal, &iGlobalLenMax);
397 libraries.getVarsNameForWho(&lstVar, &iVarLenMax);
406 wchar_t wcsVarElem[strSize];
407 wchar_t wcsVarVariable[strSize];
408 wchar_t wcsGlobalElem[strSize];
409 wchar_t wcsGlobalVariable[strSize];
416 MEMORYSTATUSEX statex;
417 statex.dwLength = sizeof(statex);
418 GlobalMemoryStatusEx(&statex);
419 iMemTotal = (int)(statex.ullTotalPhys / (1024 * 1024));
421 iMemTotal = getmemorysize();
424 ostr << _W("Your variables are:") << std::endl << std::endl;
425 std::list<std::wstring>::const_iterator it = lstVar.begin();
426 int iWidth = ConfigVariable::getConsoleWidth();
427 int iCurrentWidth = 0;
428 for (int i = 1; it != lstVar.end(); ++it, i++)
430 if (iCurrentWidth + iVarLenMax + 1 > iWidth)
435 ostr << std::setw(iVarLenMax + 1) << *it;
436 iCurrentWidth += iVarLenMax + 1;
439 os_swprintf(wcsVarElem, strSize, _W(" using %10d elements out of %10d.\n").c_str(), iMemUsed, iMemTotal);
440 ostr << std::endl << wcsVarElem;
442 os_swprintf(wcsVarVariable, strSize, _W(" and %10d variables out of %10d.\n").c_str(), lstVar.size(), nbMaxVar);
443 ostr << wcsVarVariable << std::endl;
445 ostr << std::endl << _W("Your global variables are:") << std::endl << std::endl;
446 it = lstGlobal.begin();
447 for (int i = 1; it != lstGlobal.end(); ++it, i++)
449 ostr << std::setw(iGlobalLenMax + 1) << *it;
458 os_swprintf(wcsGlobalElem, strSize, _W(" using %10d elements out of %10d.\n").c_str(), iMemUsed, iMemTotal);
459 ostr << std::endl << wcsGlobalElem;
461 os_swprintf(wcsGlobalVariable, strSize, _W(" and %10d variables out of %10d.\n").c_str(), lstGlobal.size(), nbMaxVar);
462 ostr << wcsGlobalVariable;
465 int Context::getScopeLevel()
470 bool Context::isValidVariableName(const wchar_t* wcsVarName)
472 static const wchar_t FORBIDDEN_CHARS[] = L" */\\.,;:^@><=+-&|()~\n\t'\"";
473 if (wcslen(wcsVarName) == 0 || std::wcspbrk(wcsVarName, FORBIDDEN_CHARS) || isdigit(wcsVarName[0]))
480 bool Context::isValidVariableName(const char* name)
482 bool isValid = false;
483 wchar_t* wcsname = to_wide_string(name);
486 isValid = isValidVariableName(wcsname);
493 int Context::getLibsToVariableBrowser(std::list<Library*>& lst)
495 libraries.getVarsToVariableBrowser(lst);
497 std::list<Library*> toremove;
498 //list lib that have a variable with the same name
501 Variable* var = getOrCreate(lib->getSymbol());
502 if (var->empty() == false)
504 toremove.push_back(lib);
509 for (auto lib : toremove)
514 return static_cast<int>(lst.size());
517 int Context::getVarsToVariableBrowser(std::list<Variable*>& lst)
519 variables.getVarsToVariableBrowser(lst);
520 return static_cast<int>(lst.size());
523 void Context::updateProtection(bool protect)
525 if (varStack.empty() == false)
527 VarList* lst = varStack.top();
528 for (auto var : *lst)
530 if (var.second->empty() == false)
532 ScopedVariable* pSV = var.second->top();
533 //only for current scope but normally vars in VarStack are in the current scope
534 if (pSV->m_iLevel == m_iLevel)
536 pSV->protect = protect;
540 std::wcerr << L"heu ... " << var.first.getName() << std::endl;
547 void Context::protect()
549 updateProtection(true);
552 void Context::unprotect()
554 updateProtection(false);
557 bool Context::isprotected(const Symbol& key)
559 return isprotected(getOrCreate(key));
562 bool Context::isprotected(Variable* _var)
564 //don't check protection on "ans"
565 if (_var->getSymbol().getName() == L"ans")
570 if (_var->empty() == false)
572 ScopedVariable* pSV = _var->top();
573 if (pSV->m_iLevel == m_iLevel && pSV->protect)
581 int Context::protectedVars(std::list<std::wstring>& vars)
583 return variables.getProtectedVarsName(vars);