1 /*
2 *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 *  Copyright (C) 2015 - Scilab Enterprises - Antoine ELIAS
4 *
5  * Copyright (C) 2012 - 2016 - Scilab Enterprises
6  *
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.
13 *
14 */
15 
16 #include <algorithm>
17 #include "libraries.hxx"
18 
19 namespace symbol
20 {
21 
put(types::Library * _pLib,int _iLevel)22 void Library::put(types::Library* _pLib, int _iLevel)
23 {
24     if (empty() || top()->m_iLevel < _iLevel)
25     {
26         //create a new level
27         stack.push(new ScopedLibrary(_iLevel, _pLib));
28     }
29     else
30     {
31         //update current level
32         types::Library* pLib = top()->m_pLib;
33         if (pLib != _pLib)
34         {
35             // data is manage by variables.
36             // So if this library have to be killed
37             // this is alredy done by variables.
38             //pLib->killMe();
39             top()->m_pLib = _pLib;
40         }
41     }
42 }
43 
get(const Symbol & _keyMacro) const44 types::MacroFile* Library::get(const Symbol& _keyMacro) const
45 {
46     if (empty() == false)
47     {
48         return top()->getMacroFile(_keyMacro);
49     }
50 
51     return nullptr;
52 }
53 
getMacrosName(std::list<std::wstring> & lst)54 int Library::getMacrosName(std::list<std::wstring>& lst)
55 {
56     if (empty() == false)
57     {
58         top()->m_pLib->getMacrosName(lst);
59     }
60 
61     return static_cast<int>(lst.size());
62 }
63 
getOrCreate(const Symbol & _key)64 Library* Libraries::getOrCreate(const Symbol& _key)
65 {
66     MapLibs::const_iterator it = libs.find(_key);
67     if (it == libs.end())
68     {
69         //create an empty StackedValues
70         Library* lib = new Library(_key);
71         libs[_key] = lib;
72         return lib;
73     }
74 
75     return it->second;
76 }
77 
getLevel(const Symbol & _key) const78 int Libraries::getLevel(const Symbol& _key) const
79 {
80     MapLibs::const_iterator it = libs.find(_key);
81     if (it != libs.end())
82     {
83         if (!it->second->empty())
84         {
85             return it->second->top()->m_iLevel;
86         }
87     }
88     else
89     {
90         for (auto i = libs.rbegin(), end = libs.rend(); i != end; ++i)
91         {
92             Library * lib = i->second;
93             if (!lib->empty())
94             {
95                 types::MacroFile * pMF = lib->get(_key);
96                 if (pMF)
97                 {
98                     return lib->top()->m_iLevel;
99                 }
100             }
101         }
102     }
103 
104     return SCOPE_ALL;
105 }
106 
put(const Symbol & _keyLib,types::Library * _pLib,int _iLevel)107 void Libraries::put(const Symbol& _keyLib, types::Library* _pLib, int _iLevel)
108 {
109     Library* lib = getOrCreate(_keyLib);
110     lib->put(_pLib, _iLevel);
111 }
112 
putInPreviousScope(const Symbol & _keyLib,types::Library * _pLib,int _iLevel)113 bool Libraries::putInPreviousScope(const Symbol& _keyLib, types::Library* _pLib, int _iLevel)
114 {
115     Library* lib = getOrCreate(_keyLib);
116 
117     if (lib->empty())
118     {
119         lib->put(_pLib, _iLevel);
120     }
121     else if (lib->top()->m_iLevel > _iLevel)
122     {
123         ScopedLibrary* pLib = lib->top();
124         lib->pop();
125         putInPreviousScope(_keyLib, _pLib, _iLevel);
126         lib->put(pLib);
127     }
128     else
129     {
130         lib->put(_pLib, _iLevel);
131     }
132 
133     return true;
134 }
135 
get(const Symbol & _key,int _iLevel)136 types::InternalType* Libraries::get(const Symbol& _key, int _iLevel)
137 {
138     //does _key is a lib name
139     auto lib = libs.find(_key);
140     if (lib != libs.end())
141     {
142         if (lib->second->empty() == false)
143         {
144             if (_iLevel == SCOPE_ALL || lib->second->top()->m_iLevel == _iLevel)
145             {
146                 return lib->second->top()->m_pLib;
147             }
148         }
149     }
150 
151     //does _key is a macro in a lib
152     auto it = libs.rbegin();
153     for (auto it = libs.rbegin(), itEnd = libs.rend(); it != itEnd; ++it)
154     {
155         Library* lib = it->second;
156         if (it->second->empty() == false)
157         {
158             if (_iLevel == SCOPE_ALL || it->second->top()->m_iLevel == _iLevel)
159             {
160                 types::MacroFile* pMF = it->second->get(_key);
161                 if (pMF)
162                 {
163                     return (types::InternalType*)pMF;
164                 }
165             }
166         }
167     }
168 
169     return NULL;
170 }
171 
remove(const Symbol & _key,int _iLevel)172 bool Libraries::remove(const Symbol& _key, int _iLevel)
173 {
174     MapLibs::iterator it = libs.find(_key);
175     if (it != libs.end())
176     {
177         if (it->second->empty() == false)
178         {
179             if (it->second->top()->m_iLevel == _iLevel)
180             {
181                 ScopedLibrary * pSL = it->second->top();
182                 it->second->pop();
183                 delete pSL;
184                 return true;
185             }
186         }
187     }
188 
189     return false;
190 }
191 
getMacrosName(std::list<std::wstring> & lst)192 int Libraries::getMacrosName(std::list<std::wstring>& lst)
193 {
194     MapLibs::iterator it = libs.begin();
195     MapLibs::iterator itEnd = libs.end();
196     for (auto it : libs)
197     {
198         it.second->getMacrosName(lst);
199     }
200 
201     return static_cast<int>(lst.size());
202 }
203 
getVarsName(std::list<std::wstring> & lst)204 int Libraries::getVarsName(std::list<std::wstring>& lst)
205 {
206     for (auto it : libs)
207     {
208         if (it.second->empty() == false)
209         {
210             lst.push_back(it.first.getName().c_str());
211         }
212     }
213 
214     return static_cast<int>(lst.size());
215 }
216 
getVarsToVariableBrowser(std::list<Library * > & lst)217 int Libraries::getVarsToVariableBrowser(std::list<Library*>& lst)
218 {
219     for (auto lib : libs)
220     {
221         if (lib.second->empty() == false)
222         {
223             lst.push_back(lib.second);
224         }
225     }
226 
227     return static_cast<int>(lst.size());
228 }
229 
clearAll()230 void Libraries::clearAll()
231 {
232     for (auto lib : libs)
233     {
234         while (!lib.second->empty())
235         {
236             ScopedLibrary * pSL = lib.second->top();
237             types::InternalType * pIT = pSL->m_pLib;
238             pIT->killMe();
239             lib.second->pop();
240             delete pSL;
241         }
242 
243         delete lib.second;
244     }
245 }
246 
getVarsNameForWho(std::list<std::wstring> * lstVarName,int * iVarLenMax,bool bSorted) const247 bool Libraries::getVarsNameForWho(std::list<std::wstring>* lstVarName, int* iVarLenMax, bool bSorted) const
248 {
249     for (auto it = libs.begin(), itEnd = libs.end(); it != itEnd; ++it)
250     {
251         std::wstring wstrVarName(it->first.getName().c_str());
252         if (lstVarName && it->second->empty() == false)
253         {
254             lstVarName->push_back(wstrVarName);
255             *iVarLenMax = std::max(*iVarLenMax, (int)wstrVarName.size());
256         }
257     }
258 
259     if (bSorted)
260     {
261         if (lstVarName)
262         {
263             lstVarName->sort();
264         }
265     }
266 
267     return true;
268 }
269 
whereis(std::list<std::wstring> & lst,const Symbol & _key)270 int Libraries::whereis(std::list<std::wstring>& lst, const Symbol& _key)
271 {
272     for (auto lib : libs)
273     {
274         if (lib.second->get(_key) != NULL)
275         {
276             lst.push_back(lib.first.getName());
277         }
278     }
279     return static_cast<int>(lst.size());
280 }
281 
librarieslist(std::list<std::wstring> & lst)282 int Libraries::librarieslist(std::list<std::wstring>& lst)
283 {
284     for (auto lib : libs)
285     {
286         if (lib.second->empty() == false)
287         {
288             lst.push_back(lib.first.getName());
289         }
290     }
291 
292     return static_cast<int>(lst.size());
293 }
294 
295 }
296