b2a2e5f389471cb439cad2f5d70b936ade918c94
[scilab.git] / scilab / modules / ast / includes / symbol / libraries.hxx
1 /*
2 *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 *  Copyright (C) 2014 - 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 #ifndef __LIBRARIES_HXX__
14 #define __LIBRARIES_HXX__
15
16 #include <stack>
17 #include "symbol.hxx"
18 #include "types.hxx"
19 #include "library.hxx"
20
21 namespace symbol
22 {
23 struct ScopedLibrary
24 {
25     ScopedLibrary(int _iLevel, types::Library* _pLib) : m_iLevel(_iLevel), m_pLib(_pLib) {};
26
27     types::MacroFile* getMacroFile(const Symbol& _key)
28     {
29         return m_pLib->get(_key.getName());
30     }
31
32     int m_iLevel;
33     types::Library* m_pLib;
34 };
35
36 struct Library
37 {
38     typedef std::stack<ScopedLibrary*> StackLib;
39
40     Library(const Symbol& _name) : name(_name), m_global(false) {};
41
42     void put(types::Library* _pLib, int _iLevel)
43     {
44         if (empty() || top()->m_iLevel < _iLevel)
45         {
46             //create a new level
47             stack.push(new ScopedLibrary(_iLevel, _pLib));
48             _pLib->IncreaseRef();
49         }
50         else
51         {
52             //update current level
53             types::Library* pLib = top()->m_pLib;
54             if (pLib != _pLib)
55             {
56                 pLib->DecreaseRef();
57                 pLib->killMe();
58                 top()->m_pLib = _pLib;
59                 _pLib->IncreaseRef();
60             }
61         }
62     }
63
64     types::MacroFile* get(const Symbol& _keyMacro) const
65     {
66         if (empty() == false)
67         {
68             return top()->getMacroFile(_keyMacro);
69         }
70
71         return NULL;
72     }
73
74     int getMacrosName(std::list<std::wstring>& lst)
75     {
76         if (empty() == false)
77         {
78             top()->m_pLib->getMacrosName(lst);
79         }
80
81         return static_cast<int>(lst.size());
82     }
83
84     bool empty() const
85     {
86         return stack.empty();
87     }
88
89     ScopedLibrary* top() const
90     {
91         return stack.top();
92     }
93
94     void pop()
95     {
96         stack.pop();
97     }
98
99     inline Symbol getSymbol() const
100     {
101         return name;
102     }
103
104 private :
105     StackLib stack;
106     Symbol name;
107     bool m_global;
108 };
109
110 struct Libraries
111 {
112     typedef std::map<Symbol, Library*> MapLibs;
113
114     Libraries() {};
115
116     Library* getOrCreate(const Symbol& _key)
117     {
118         MapLibs::const_iterator it = libs.find(_key);
119         if (it == libs.end())
120         {
121             //create an empty StackedValues
122             Library* lib = new Library(_key);
123             libs[_key] = lib;
124             return lib;
125         }
126
127         return it->second;
128     }
129
130     void put(const Symbol& _keyLib, types::Library* _pLib, int _iLevel)
131     {
132         Library* lib = getOrCreate(_keyLib);
133         lib->put(_pLib, _iLevel);
134     }
135
136     types::InternalType* 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 == -1 || 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 == -1 || 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
172     bool 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                     types::Library* pIT = pSL->m_pLib;
183                     pIT->DecreaseRef();
184                     pIT->killMe();
185                     it->second->pop();
186                     delete pSL;
187                     return true;
188                 }
189             }
190         }
191
192         return false;
193     }
194
195     int getMacrosName(std::list<std::wstring>& lst)
196     {
197         MapLibs::iterator it = libs.begin();
198         MapLibs::iterator itEnd = libs.end();
199         for (auto it : libs)
200         {
201             it.second->getMacrosName(lst);
202         }
203
204         return static_cast<int>(lst.size());
205     }
206
207     int getVarsName(std::list<std::wstring>& lst)
208     {
209         for (auto it : libs)
210         {
211             if (it.second->empty() == false)
212             {
213                 lst.push_back(it.first.getName().c_str());
214             }
215         }
216
217         return static_cast<int>(lst.size());
218     }
219
220     int getVarsToVariableBrowser(std::list<Library*>& lst)
221     {
222         for (auto lib : libs)
223         {
224             if (lib.second->empty() == false)
225             {
226                 lst.push_back(lib.second);
227             }
228         }
229
230         return static_cast<int>(lst.size());
231     }
232
233     void clearAll()
234     {
235         for (auto lib : libs)
236         {
237             while (!lib.second->empty())
238             {
239                 ScopedLibrary * pSL = lib.second->top();
240                 types::InternalType * pIT = pSL->m_pLib;
241                 pIT->DecreaseRef();
242                 pIT->killMe();
243                 lib.second->pop();
244                 delete pSL;
245             }
246
247             delete lib.second;
248         }
249     }
250
251     bool getVarsNameForWho(std::list<std::wstring>* lstVarName, int* iVarLenMax, bool bSorted = false) const
252     {
253         for (auto it = libs.begin(), itEnd = libs.end(); it != itEnd; ++it)
254         {
255             std::wstring wstrVarName(it->first.getName().c_str());
256             if (lstVarName && it->second->empty() == false)
257             {
258                 lstVarName->push_back(wstrVarName);
259                 *iVarLenMax = std::max(*iVarLenMax, (int)wstrVarName.size());
260             }
261         }
262
263         if (bSorted)
264         {
265             if (lstVarName)
266             {
267                 lstVarName->sort();
268             }
269         }
270
271         return true;
272     }
273
274     int whereis(std::list<std::wstring>& lst, const Symbol& _key)
275     {
276         for (auto lib : libs)
277         {
278             if (lib.second->get(_key) != NULL)
279             {
280                 lst.push_back(lib.first.getName());
281             }
282         }
283         return static_cast<int>(lst.size());
284     }
285
286     int librarieslist(std::list<std::wstring>& lst)
287     {
288         for (auto lib : libs)
289         {
290             lst.push_back(lib.first.getName());
291         }
292
293         return static_cast<int>(lst.size());
294     }
295
296 private:
297     MapLibs libs;
298 };
299 }
300 #endif /* !__LIBRARIES_HXX__ */