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