add function libraryinfo and librarieslist
[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     std::list<std::wstring>* getMacrosName()
75     {
76         if (empty() == false)
77         {
78             return top()->m_pLib->getMacrosName();
79         }
80
81         return new std::list<std::wstring>();
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 private :
100     StackLib stack;
101     Symbol name;
102     bool m_global;
103 };
104
105 struct Libraries
106 {
107     typedef std::map<Symbol, Library*> MapLibs;
108
109     Libraries() {};
110
111     Library* getOrCreate(const Symbol& _key)
112     {
113         MapLibs::const_iterator it = libs.find(_key);
114         if (it == libs.end())
115         {
116             //create an empty StackedValues
117             Library* lib = new Library(_key);
118             libs[_key] = lib;
119             return lib;
120         }
121
122         return it->second;
123     }
124
125     void put(const Symbol& _keyLib, types::Library* _pLib, int _iLevel)
126     {
127         Library* lib = getOrCreate(_keyLib);
128         lib->put(_pLib, _iLevel);
129     }
130
131     types::InternalType* get(const Symbol& _key, int _iLevel)
132     {
133         //does _key is a lib name
134         auto lib = libs.find(_key);
135         if (lib != libs.end())
136         {
137             if (lib->second->empty() == false)
138             {
139                 if (_iLevel == -1 || lib->second->top()->m_iLevel == _iLevel)
140                 {
141                     return lib->second->top()->m_pLib;
142                 }
143             }
144         }
145
146         //does _key is a macro in a lib
147         auto it = libs.rbegin();
148         for (auto it = libs.rbegin(), itEnd = libs.rend(); it != itEnd ; ++it)
149         {
150             Library* lib = it->second;
151             if (it->second->empty() == false)
152             {
153                 if (_iLevel == -1 || it->second->top()->m_iLevel == _iLevel)
154                 {
155                     types::MacroFile* pMF = it->second->get(_key);
156                     if (pMF)
157                     {
158                         return (types::InternalType*)pMF;
159                     }
160                 }
161             }
162         }
163
164         return NULL;
165     }
166
167     bool remove(const Symbol& _key, int _iLevel)
168     {
169         MapLibs::iterator it = libs.find(_key);
170         if (it != libs.end())
171         {
172             if (it->second->empty() == false)
173             {
174                 if (it->second->top()->m_iLevel == _iLevel)
175                 {
176                     ScopedLibrary * pSL = it->second->top();
177                     types::Library* pIT = pSL->m_pLib;
178                     pIT->DecreaseRef();
179                     pIT->killMe();
180                     it->second->pop();
181                     delete pSL;
182                     return true;
183                 }
184             }
185         }
186
187         return false;
188     }
189
190     std::list<std::wstring>* getMacrosName()
191     {
192         std::list<std::wstring>* names = new std::list<std::wstring>();
193         MapLibs::iterator it = libs.begin();
194         MapLibs::iterator itEnd = libs.end();
195         for (; it != itEnd ; ++it)
196         {
197             std::list<std::wstring>* temp = it->second->getMacrosName();
198             names->insert(names->end(), temp->begin(), temp->end());
199             delete temp;
200         }
201
202         return names;
203     }
204
205     std::list<std::wstring>* getVarsName()
206     {
207         std::list<std::wstring>* plOut = new std::list<std::wstring>();
208         for (auto it = libs.begin(), itEnd = libs.end(); it != itEnd; ++it)
209         {
210             if (it->second->empty() == false)
211             {
212                 plOut->push_back(it->first.getName().c_str());
213             }
214         }
215
216         return plOut;
217     }
218
219     void clearAll()
220     {
221         for (MapLibs::iterator it = libs.begin(); it != libs.end() ; ++it)
222         {
223             while (!it->second->empty())
224             {
225                 ScopedLibrary * pSL = it->second->top();
226                 types::InternalType * pIT = pSL->m_pLib;
227                 pIT->DecreaseRef();
228                 pIT->killMe();
229                 it->second->pop();
230                 delete pSL;
231             }
232
233             delete it->second;
234         }
235     }
236
237     bool getVarsNameForWho(std::list<std::wstring>* lstVarName, int* iVarLenMax, bool bSorted = false) const
238     {
239         for (auto it = libs.begin(), itEnd = libs.end(); it != itEnd; ++it)
240         {
241             std::wstring wstrVarName(it->first.getName().c_str());
242             if (lstVarName && it->second->empty() == false)
243             {
244                 lstVarName->push_back(wstrVarName);
245                 *iVarLenMax = std::max(*iVarLenMax, (int)wstrVarName.size());
246             }
247         }
248
249         if (bSorted)
250         {
251             if (lstVarName)
252             {
253                 lstVarName->sort();
254             }
255         }
256
257         return true;
258     }
259
260     std::list<std::wstring>* whereis(const Symbol& _key)
261     {
262         std::list<std::wstring>* ret = new std::list<std::wstring>();
263
264         for (auto lib : libs)
265         {
266             if (lib.second->get(_key) != NULL)
267             {
268                 ret->push_back(lib.first.getName());
269             }
270         }
271         return ret;
272     }
273
274     std::list<std::wstring>* librarieslist()
275     {
276         std::list<std::wstring>* ret = new std::list<std::wstring>();
277
278         for (auto lib : libs)
279         {
280             ret->push_back(lib.first.getName());
281         }
282
283         return ret;
284     }
285
286 private:
287     MapLibs libs;
288 };
289 }
290 #endif /* !__LIBRARIES_HXX__ */