replug funptr, newfun and clearfun
[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.name_get());
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) {};
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         MapLibs::reverse_iterator it = libs.rbegin();
134         for (; it != libs.rend() ; ++it)
135         {
136             if (it->second->empty() == false)
137             {
138                 if (_iLevel == -1 || it->second->top()->m_iLevel == _iLevel)
139                 {
140                     types::MacroFile* pMF = it->second->get(_key);
141                     if (pMF)
142                     {
143                         return (types::InternalType*)pMF;
144                     }
145                 }
146             }
147         }
148
149         return NULL;
150     }
151
152     bool remove(const Symbol& _key, int _iLevel)
153     {
154         MapLibs::iterator it = libs.find(_key);
155         if (it != libs.end())
156         {
157             if (it->second->empty() == false)
158             {
159                 if (it->second->top()->m_iLevel == _iLevel)
160                 {
161                     ScopedLibrary * pSL = it->second->top();
162                     types::Library* pIT = pSL->m_pLib;
163                     pIT->DecreaseRef();
164                     pIT->killMe();
165                     it->second->pop();
166                     delete pSL;
167                     return true;
168                 }
169             }
170         }
171
172         return false;
173     }
174
175     std::list<std::wstring>* getMacrosName()
176     {
177         std::list<std::wstring>* names = new std::list<std::wstring>();
178         MapLibs::iterator it = libs.begin();
179         MapLibs::iterator itEnd = libs.end();
180         for (; it != itEnd ; ++it)
181         {
182             std::list<std::wstring>* temp = it->second->getMacrosName();
183             names->insert(names->end(), temp->begin(), temp->end());
184             delete temp;
185         }
186
187         return names;
188     }
189
190     void clearAll()
191     {
192         for (MapLibs::iterator it = libs.begin(); it != libs.end() ; ++it)
193         {
194             while (!it->second->empty())
195             {
196                 ScopedLibrary * pSL = it->second->top();
197                 types::InternalType * pIT = pSL->m_pLib;
198                 pIT->DecreaseRef();
199                 pIT->killMe();
200                 it->second->pop();
201                 delete pSL;
202             }
203
204             delete it->second;
205         }
206     }
207
208 private:
209     MapLibs libs;
210 };
211 }
212 #endif /* !__LIBRARIES_HXX__ */